diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/array.c | 5 | ||||
-rw-r--r-- | src/common/better_string.c | 10 | ||||
-rw-r--r-- | src/common/hash_table.c | 140 | ||||
-rw-r--r-- | src/common/helpers.c | 13 | ||||
-rw-r--r-- | src/common/list.c | 78 | ||||
-rw-r--r-- | src/common/protocol.c | 20 | ||||
-rw-r--r-- | src/include/better_string.h | 1 | ||||
-rw-r--r-- | src/include/hash_table.h | 32 | ||||
-rw-r--r-- | src/include/helpers.h | 1 | ||||
-rw-r--r-- | src/include/list.h | 36 | ||||
-rw-r--r-- | src/include/opcodes.h | 4 | ||||
-rw-r--r-- | src/include/protocol.h | 10 | ||||
-rw-r--r-- | src/ramen/main.c | 50 |
13 files changed, 350 insertions, 50 deletions
diff --git a/src/common/array.c b/src/common/array.c index 4ebb67e..9648f5a 100644 --- a/src/common/array.c +++ b/src/common/array.c @@ -39,9 +39,10 @@ array_t *array_reverse(array_t *a) { void array_free(void *x, void (*freefunc)(void *)) { array_t *a = (array_t *)x; - for (int i = 0; i < a->size; i++) { + if (!x) + return; + for (int i = 0; i < a->size; i++) freefunc(a->items[i]); - } free(a->items); free(a); } diff --git a/src/common/better_string.c b/src/common/better_string.c index 366dda6..7863da0 100644 --- a/src/common/better_string.c +++ b/src/common/better_string.c @@ -18,11 +18,12 @@ string_t *init_string(const char *src) { } void string_push(string_t *s, char c) { - if (s->len >= s->size - 2) { + if (s->len >= s->size - 3) { s->size *= 2; s->buf = safe_realloc(s->buf, s->size); } s->buf[s->len] = c; + s->buf[s->len + 1] = '\0'; s->len++; } @@ -33,9 +34,8 @@ char string_pop(string_t *s) { } void string_concat_const(string_t *s1, const char *s2) { - for (int i = 0; i < strlen(s2); i++) { + for (int i = 0; i < strlen(s2); i++) string_push(s1, s2[i]); - } } void string_concat(string_t *s1, string_t *s2) { @@ -46,6 +46,10 @@ void string_concat(string_t *s1, string_t *s2) { void string_free(void *x) { string_t *s = x; + + if (!x) + return; + free(s->buf); free(s); } diff --git a/src/common/hash_table.c b/src/common/hash_table.c index 2f66d45..6b4c014 100644 --- a/src/common/hash_table.c +++ b/src/common/hash_table.c @@ -1,12 +1,148 @@ #include "../include/hash_table.h" #include "../include/helpers.h" - +#include "../include/list.h" #include <stdlib.h> +#include <string.h> + +pair_t *init_pair(char *key, void *v) { + pair_t *pair = safe_calloc(1, sizeof(pair_t)); + pair->key = key; + pair->v = v; + return pair; +} + +void *bucket_pop(list_t *b, char *key) { + node_t *cur = b->head; + node_t *prev; + pair_t *cur_pair; + node_t *tmp; + + if (b->size == 0) + return NULL; + + while (cur) { + cur_pair = cur->item; + if (strcmp(cur_pair->key, key) == 0) { + prev = cur->prev; + if (prev) { + tmp = cur->next; + prev->next = tmp; + + if (tmp) + tmp->prev = prev; + else { + b->tail = prev; + } + + b->size--; + + if (b->size <= 1) + b->head = b->tail; + + return cur; + } else { + tmp = cur->next; + if (tmp) + tmp->prev = NULL; + + b->head = tmp; + b->size--; + + if (b->size <= 1) + b->tail = b->head; + + return cur; + } + } + } + return NULL; +} + +void *bucket_get(list_t *b, char *key) { + node_t *cur = b->head; + pair_t *cur_pair; + + while (cur) { + cur_pair = cur->item; + if (strcmp(key, cur_pair->key) == 0) { + return cur_pair->v; + } + } + return NULL; +} + +void bucket_free(void *x, void (*freefunc)(void *)) { + list_t *b = x; + node_t *cur = b->head; + node_t *tmp; + pair_t *cur_pair; + + if (!x) + return; + + while (cur) { + cur_pair = cur->item; + + freefunc(cur_pair->v); + free(cur_pair->key); + free(cur_pair); + + tmp = cur->next; + free(cur); + cur = tmp; + } + free(b); +} ht_t *init_ht(size_t size) { ht_t *ht = safe_calloc(1, sizeof(size)); size_t realsize = size == 0 ? DEFAULT_HT_SIZE : size; - ht->buckets = safe_calloc(realsize, sizeof(sll_t *)); + ht->buckets = safe_calloc(realsize, sizeof(list_t *)); ht->size = realsize; return ht; } + +void ht_insert(ht_t *ht, char *key, void *value) { + unsigned long bn = hash(key) % ht->size; + list_t *bucket = ht->buckets[bn]; + if (!bucket) + ht->buckets[bn] = init_list(); + + list_push_back(bucket, init_pair(key, value)); +} + +void *ht_pop(ht_t *ht, char *key) { + unsigned long bn = hash(key) % ht->size; + list_t *bucket = ht->buckets[bn]; + if (!bucket) + return NULL; + return bucket_pop(bucket, key); +} + +void *ht_get(ht_t *ht, char *key) { + unsigned long bn = hash(key) % ht->size; + list_t *bucket = ht->buckets[bn]; + if (!bucket) + return NULL; + return bucket_get(bucket, key); +} + +void ht_free(void *x, void (*freefunc)(void *)) { + ht_t *ht = x; + for (int i = 0; i < ht->size; i++) + bucket_free(ht->buckets[i], freefunc); + + free(ht->buckets); + free(ht); +} + +/* DJB2 hash function */ +unsigned long hash(char *str) { + unsigned long hash = 5381; + int c; + + while ((c = *str++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + + return hash; +} diff --git a/src/common/helpers.c b/src/common/helpers.c index 4bf7301..4a3606a 100644 --- a/src/common/helpers.c +++ b/src/common/helpers.c @@ -4,9 +4,8 @@ #include <string.h> void die_lz(int code, const char *msg) { - if (code < 0) { + if (code < 0) die(msg); - } } void die(const char *msg) { @@ -17,17 +16,19 @@ void die(const char *msg) { void *safe_calloc(unsigned int i, size_t size) { void *x = calloc(i, size); - if (x == NULL) { + + if (x == NULL) die("abort: calloc()"); - } + return x; } void *safe_realloc(void *x, size_t size) { void *p = realloc(x, size); - if (x == NULL) { + + if (x == NULL) die("abort: realloc()"); - } + return p; } diff --git a/src/common/list.c b/src/common/list.c new file mode 100644 index 0000000..00c18ee --- /dev/null +++ b/src/common/list.c @@ -0,0 +1,78 @@ +#include "../include/list.h" +#include "../include/helpers.h" + +node_t *init_node(void *x) { + node_t *n = safe_calloc(1, sizeof(node_t)); + n->item = x; + n->next = NULL; + n->prev = NULL; + return n; +} + +list_t *init_list() { + list_t *l = safe_calloc(1, sizeof(list_t)); + l->head = NULL; + l->tail = NULL; + l->size = 0; + return l; +} + +void *list_pop_front(list_t *l) { + node_t *front = l->head; + if (!front) + return NULL; + + node_t *new = front->next; + l->head = new; + + if (!new) + l->tail = NULL; + + l->size--; + return front; +} + +void list_push_back(list_t *l, void *x) { + node_t *back = l->tail; + node_t *new = init_node(x); + if (!back) { + l->head = new; + l->tail = l->head; + } else { + back->next = new; + new->prev = back; + l->tail = new; + } + l->size++; +} + +void list_push_front(list_t *l, void *x) { + node_t *front = l->head; + node_t *new = init_node(x); + if (!front) { + l->tail = new; + l->head = l->tail; + } else { + front->prev = new; + new->next = front; + l->head = new; + } + l->size++; +} + +void list_free(void *x, void (*freefunc)(void *)) { + list_t *l = x; + node_t *cur = l->head; + node_t *tmp; + + if (!x) + return; + + while (cur) { + freefunc(cur->item); + tmp = cur->next; + free(cur); + cur = tmp; + } + free(l); +} diff --git a/src/common/protocol.c b/src/common/protocol.c new file mode 100644 index 0000000..9be3bcf --- /dev/null +++ b/src/common/protocol.c @@ -0,0 +1,20 @@ +#include "../include/protocol.h" +#include "../include/better_string.h" + +#include <stdlib.h> +#include <stdbool.h> +#include <time.h> + +string_t *date_str() { + char dateStr[11]; + time_t t = time(NULL); + struct tm *tm_info = localtime(&t); + + strftime(dateStr, sizeof(dateStr), "%d-%m-%Y", tm_info); + return init_string(dateStr); +} + +bool same_day(struct tm *date1, struct tm *date2) { + return (date1->tm_year == date2->tm_year && date1->tm_mon == date2->tm_mon && + date1->tm_mday == date2->tm_mday); +} diff --git a/src/include/better_string.h b/src/include/better_string.h index 41c0cfd..0fdc8bd 100644 --- a/src/include/better_string.h +++ b/src/include/better_string.h @@ -21,4 +21,5 @@ void string_concat_const(string_t *s, const char *src); char string_pop(string_t *s); void string_free(void *s); + #endif diff --git a/src/include/hash_table.h b/src/include/hash_table.h index ea21e37..8f19635 100644 --- a/src/include/hash_table.h +++ b/src/include/hash_table.h @@ -1,6 +1,6 @@ #ifndef HASH_TABLE_H #define HASH_TABLE_H - +#include "list.h" #include <stdlib.h> #define DEFAULT_HT_SIZE 500 @@ -9,35 +9,29 @@ typedef struct PAIR_STRUCT { void *v; } pair_t; -typedef struct NODE_STRUCT { - char *key; - void *v; - struct NODE_STRUCT *next; -} node_t; - -typedef struct { - node_t *head; - node_t *tail; -} sll_t; - typedef struct { - sll_t **buckets; + list_t **buckets; size_t size; } ht_t; -node_t *init_node(char *key, void *v); +pair_t *init_pair(char *key, void *value); + +void *bucket_get(list_t *b, char *key); -void sll_push(sll_t *sll, char *key, void *v); +void *bucket_pop(list_t *b, char *key); -void sll_delete(sll_t *sll, char *key); +void bucket_free(void *x, void (*freefunc)(void *)); -sll_t *sll_free(void *x, void (*freefunc)(void *)); +ht_t *init_ht(size_t size); void ht_insert(ht_t *ht, char *key, void *value); -void ht_delete(ht_t *ht, char *key); +void *ht_pop(ht_t *ht, char *key); void *ht_get(ht_t *ht, char *key); -ht_t *init_ht(size_t size); +void ht_free(void *x, void (*freefunc)(void *)); + +/* djb2 hash function */ +unsigned long hash(char *key); #endif diff --git a/src/include/helpers.h b/src/include/helpers.h index 5d46909..9f9dff7 100644 --- a/src/include/helpers.h +++ b/src/include/helpers.h @@ -14,4 +14,5 @@ void *safe_realloc(void *x, size_t size); void alloc_zero(void *ptr, size_t size); void nothing(void *); + #endif diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..055106a --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,36 @@ +#ifndef LIST_H +#define LIST_H +#include <stdlib.h> +#include <stdbool.h> + +typedef struct NODE_STRUCT { + void *item; + struct NODE_STRUCT *next; + struct NODE_STRUCT *prev; +} node_t; + +typedef struct { + size_t size; + node_t *head; + node_t *tail; +} list_t; + +node_t *init_node(void *item); + +void node_free(void *x, void (*freefunc)(void *)); + +list_t *init_list(); + +void list_push_front(list_t *l, void *x); + +void list_push_back(list_t *l, void *x); + +void *list_pop_back(list_t *l); + +void *list_pop_front(list_t *l); + +bool list_is_empty(list_t *l); + +void list_free(void *x, void (*freefunc)(void *)); + +#endif diff --git a/src/include/opcodes.h b/src/include/opcodes.h index ff8400f..9456574 100644 --- a/src/include/opcodes.h +++ b/src/include/opcodes.h @@ -2,6 +2,7 @@ #define OPCODES_H typedef enum { + CO_OK, CO_NOP, CO_JN, /* join */ CO_DM, @@ -27,7 +28,8 @@ typedef enum { } copcode_t; typedef enum { - SO_SUCCESS, + SO_OK, + SO_ULOG, /* update client log state */ SO_FAIL_PARSE, SO_FAIL_NOPERM, SO_FAIL_USER_TAKEN, diff --git a/src/include/protocol.h b/src/include/protocol.h index 204a507..31138c2 100644 --- a/src/include/protocol.h +++ b/src/include/protocol.h @@ -2,6 +2,7 @@ #define PROTOCOL_H #include <time.h> +#include <stdio.h> #include <stdbool.h> #include "array.h" @@ -38,7 +39,7 @@ typedef struct { } message_t; typedef struct { - array_t *messages; + FILE *messages; user_t *admin; array_t *mods; @@ -58,9 +59,14 @@ typedef struct { user_t *user1; user_t *user2; - array_t *messages; + struct tm *date; + FILE *msgs; } dm_t; +string_t *date_str(); + +bool same_day(struct tm *date1, struct tm *date2); + string_t *encode_chanstate(ht_t *chans); string_t *encode_usersstate(ht_t *u); diff --git a/src/ramen/main.c b/src/ramen/main.c index e98b452..799a5b2 100644 --- a/src/ramen/main.c +++ b/src/ramen/main.c @@ -12,20 +12,21 @@ #include <sys/time.h> #include <unistd.h> -#include "../include/tsv.h" -#include "../include/array.h" #include "../include/better_string.h" #include "../include/hash_table.h" #include "../include/helpers.h" +#include "../include/list.h" #include "../include/opcodes.h" #include "../include/protocol.h" +#include "../include/tsv.h" +#include "../include/opcodes.h" int PORT = DEFAULT_PORT; int nfds = 1; struct pollfd fds[MAX_CONNECTIONS * 2]; -ht_t *USERS; ht_t *CHAN; +ht_t *USERS; void handle_sigint(int sig) { for (int i = 0; i < nfds; i++) { @@ -33,20 +34,19 @@ void handle_sigint(int sig) { close(fds[i].fd); } } - exit(0); } -array_t *parse_args(char *buf) { +list_t *tokenize_buf(char *buf) { tsv_t *tsv = init_tsv(buf); string_t *s = tsv_next(tsv); - array_t *a = init_array(); + list_t *a = init_list(); + while (s) { - array_push(a, s); + list_push_back(a, s); s = tsv_next(tsv); } - a = array_reverse(a); return a; } @@ -156,8 +156,29 @@ int main(int argc, char **argv) { printf("Connection closed\n"); close_conn = true; } else { - /* echo server -- replace this with buffer parsing */ - /* TODO: reply to client based on user input */ + list_t *tokens = tokenize_buf(buffer); + string_t *opcode = list_pop_front(tokens); + int op = encode_server_opcode(opcode->buf); + + switch (op) { + case CO_NCK: + break; + case CO_JN: + break; + case CO_NOP: + break; + case CO_PST: + break; + case CO_DM: + break; + case CO_QT: + break; + case CO_LVE: + break; + default: + break; + } + fd_send = send(local_fds[i].fd, buffer, fd_recv, 0); if (fd_send < 0) { perror("send()"); @@ -174,14 +195,13 @@ int main(int argc, char **argv) { } if (compress_array) { - printf("switching...\n"); int cur_nfds = nfds; nfds = 0; for (int i = 0; i < cur_nfds; i++) { - if (local_fds[i].fd != 0) { - local_fds2[nfds] = local_fds[i]; - nfds ++; - } + if (local_fds[i].fd != 0) { + local_fds2[nfds] = local_fds[i]; + nfds++; + } } local_fds1 = local_fds2; |