mirror of https://github.com/Chizi123/dnscomp.git

Joel Grunbaum
2020-10-21 54f6bed6ad3c69a2144eae4e3f301a6d9b70cfd7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <stdio.h>
#include <stdlib.h>
#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;
}