#include #include #include "slist.h" void split(struct dns_list *head, struct dns_list **a, struct dns_list **b); struct dns_list *merge(struct dns_list *a, struct dns_list *b); int comp_times(struct timespec a, struct timespec b); int add_hosts_server(struct hosts_list **head, char *server) { struct hosts_list *end; if (!(*head)) { *head = malloc(sizeof(struct hosts_list)); end = *head; } else { end = *head; while (end->next) end = end->next; end->next = malloc(sizeof(struct hosts_list)); end = end->next; } end->next = NULL; end->server = server; return 0; } int free_hosts_list(struct hosts_list **head) { struct hosts_list *temp; while (*head) { temp = (*head)->next; free(*head); *head = temp; } return 0; } int add_dns_server(struct dns_list **head, char* server) { struct dns_list *end; if (!(*head)) { *head = malloc(sizeof(struct dns_list)); end = *head; } else { end = *head; while (end->next) end = end->next; end->next = malloc(sizeof(struct dns_list)); end = end->next; } end->next = NULL; end->server = server; end->time.tv_nsec = 0; end->time.tv_sec = 0; return 0; } int free_dns_list(struct dns_list **head) { struct dns_list *temp; while (*head) { temp = (*head)->next; free(*head); *head = temp; } return 0; } // Sort with merge sort as works well for linked lists // Copied from https://www.geeksforgeeks.org/merge-sort-for-linked-list/ int sort_servers(struct dns_list **headRef) { struct dns_list *head = *headRef; struct dns_list *a, *b; if (!head || !(head->next)) { //Empty list or containing one element return 0; } split(head, &a, &b); sort_servers(&a); sort_servers(&b); *headRef = merge(a, b); return 0; } void split(struct dns_list *head, struct dns_list **a, struct dns_list **b) { struct dns_list *fast = head->next, *slow = head; while(fast) { fast = fast->next; if (fast) { slow = slow->next; fast = fast->next; } } *a = head; *b = slow->next; slow->next = NULL; } struct dns_list *merge(struct dns_list *a, struct dns_list *b) { struct dns_list *out = NULL; if (!a) return b; if (!b) return a; if (comp_times(a->time, b->time) > 0) { out = b; out->next = merge(a, b->next); } else { out = a; out->next = merge(a->next, b); } return out; } int comp_times(struct timespec a, struct timespec b) { if (a.tv_sec == b.tv_sec) { if (a.tv_nsec >= b.tv_nsec) return 1; else return -1; } else if (a.tv_sec > b.tv_sec) { return 1; } else return -1; } int print_servers(struct dns_list *head) { printf("%-20s | %s\n", "Server", "Time"); while (head) { printf("%-20s | %ld.%09ld\n", head->server, head->time.tv_sec, head->time.tv_nsec); head = head->next; } return 0; }