-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslist.c
140 lines (129 loc) · 2.84 KB
/
slist.c
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
139
140
#include "slist.h"
#include <stdio.h>
#include <stdlib.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 dns_list* a, struct dns_list* 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, b) > 0) {
out = b;
out->next = merge(a, b->next);
} else {
out = a;
out->next = merge(a->next, b);
}
return out;
}
int comp_times(struct dns_list* a, struct dns_list* b)
{
if (a->errors != b->errors) {
return a->errors > b->errors;
} else if (a->time.tv_sec == b->time.tv_sec) {
if (a->time.tv_nsec >= b->time.tv_nsec)
return 1;
else
return -1;
} else if (a->time.tv_sec > b->time.tv_sec) {
return 1;
} else
return -1;
}
int print_servers(struct dns_list* head)
{
printf("%-16s | %-11s | %s\n", "Server", "Time", "Errors");
while (head) {
printf("%-16s | %ld.%09ld | %d\n", head->server, head->time.tv_sec,
head->time.tv_nsec, head->errors);
head = head->next;
}
return 0;
}