#include #include #include #include "addrbook.h" #include "crypt.h" #define ADDRBOOK_DELIM_COUNT 4 char *addrbook_entry_to_string(const addrbook_entry_t *const ent) { size_t str_len = CRYPT_PKEY_HEXLEN + ent->name_len + ent->last_addr_len + ent->last_port_len + ADDRBOOK_DELIM_COUNT; char *str = (char *)malloc(str_len * sizeof(char)); sprintf(str, "%.128s\t%.*s\t%.*s\t%.*s\n", ent->pubk, ent->name_len, ent->name, ent->last_addr_len, ent->last_addr, ent->last_port_len, ent->last_port); return str; } int addrbook_entry_from_string(addrbook_entry_t *const ent, char * str) { char *tok = strtok(str, "\t\n"); if (tok == NULL) return -1; memcpy(ent->pubk, tok, CRYPT_PKEY_HEXLEN); tok = strtok(NULL, "\t\n"); ent->name = strdup(tok); ent->name_len = strlen(ent->name); tok = strtok(NULL, "\t\n"); ent->last_addr = strdup(tok); ent->last_addr_len = strlen(ent->last_addr); tok = strtok(NULL, "\t\n"); ent->last_port = strdup(tok); ent->last_port_len = strlen(ent->last_port); return 0; } void addrbook_destroy(addrbook_t *const ab) { free(ab->entries); ab->entries_len = 0; } int addrbook_load(addrbook_t *ab, FILE *in) { char *line = NULL; size_t line_len = 0; size_t lines = 0; while (getline(&line, &line_len, in) != -1) ++lines; if (ab->entries != NULL) free(ab->entries); ab->entries = (addrbook_entry_t *)malloc(lines * sizeof(addrbook_entry_t)); if (ab->entries == NULL) return -1; ab->entries_len = 0; ab->entries_cap = lines; fseek(in, 0, SEEK_SET); addrbook_entry_t ent; while (getline(&line, &line_len, in) != -1) { if (addrbook_entry_from_string(&ent, line) == -1) { addrbook_destroy(ab); return -1; } if (addrbook_add(ab, &ent) == -1) { addrbook_destroy(ab); return -1; } } return 0; } int addrbook_store(addrbook_t *ab, FILE *out) { for (size_t i = 0; i < ab->entries_len; ++i) { char *ent_str = addrbook_entry_to_string(&ab->entries[i]); fputs(ent_str, out); free(ent_str); } return 0; } int addrbook_add(addrbook_t *const ab, const addrbook_entry_t *const ent) { if (ab->entries == NULL) { ab->entries = (addrbook_entry_t *)malloc(sizeof(addrbook_entry_t)); ab->entries_cap = 1; ab->entries_len = 0; } else if (addrbook_get(ab, ent->pubk) != NULL) return -1; if (ab->entries_len == ab->entries_cap) ab->entries = realloc(ab->entries, ++ab->entries_cap); ab->entries[ab->entries_len++] = *ent; return 0; } addrbook_entry_t *addrbook_get(const addrbook_t *const ab, const char pkey[CRYPT_PKEY_HEXLEN]) { if (ab->entries == NULL) return NULL; for (size_t i = 0; i < ab->entries_len; ++i) if (strncmp(ab->entries[i].pubk, pkey, CRYPT_PKEY_HEXLEN) == 0) return &ab->entries[i]; return NULL; }