1 /*
2  * scamper_list.c
3  *
4  * $Id: scamper_list.c,v 1.23 2020/03/17 07:32:16 mjl Exp $
5  *
6  * Copyright (C) 2005-2006 Matthew Luckie
7  * Copyright (C) 2006-2010 The University of Waikato
8  * Author: Matthew Luckie
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 #include "internal.h"
29 
30 #include "scamper_list.h"
31 #include "utils.h"
32 
33 /*
34  * scamper_cycle_cmp
35  *
36  * utility function for comparing two cycles.  note that the stop time
37  * parameters are not compared; one cycle with a stop time might be
38  * compared with the (same) cycle without a stop time, and be rejected
39  * incorrectly.
40  */
scamper_cycle_cmp(scamper_cycle_t * a,scamper_cycle_t * b)41 int scamper_cycle_cmp(scamper_cycle_t *a, scamper_cycle_t *b)
42 {
43   int i;
44 
45   if(a == b)
46     {
47       return 0;
48     }
49 
50   /* compare lists */
51   if((i = scamper_list_cmp(a->list, b->list)) != 0)
52     {
53       return i;
54     }
55 
56   /* compare cycle ids */
57   if(a->id < b->id) return -1;
58   if(a->id > b->id) return 1;
59 
60   /* compare start times */
61   if(a->start_time < b->start_time) return -1;
62   if(a->start_time > b->start_time) return 1;
63 
64   /* compare host names */
65   if(a->hostname != NULL || b->hostname != NULL)
66     {
67       if(a->hostname == NULL && b->hostname != NULL) return -1;
68       if(a->hostname != NULL && b->hostname == NULL) return 1;
69       if((i = strcmp(a->hostname, b->hostname)) != 0) return i;
70     }
71 
72   /* they're the same, as best we can tell */
73   return 0;
74 }
75 
scamper_cycle_alloc(scamper_list_t * list)76 scamper_cycle_t *scamper_cycle_alloc(scamper_list_t *list)
77 {
78   scamper_cycle_t *cycle;
79 
80   if(list == NULL)
81     {
82       return NULL;
83     }
84 
85   if((cycle = malloc_zero(sizeof(struct scamper_cycle))) == NULL)
86     {
87       return NULL;
88     }
89 
90   cycle->list = scamper_list_use(list);
91   cycle->refcnt = 1;
92 
93   return cycle;
94 }
95 
scamper_cycle_use(scamper_cycle_t * cycle)96 scamper_cycle_t *scamper_cycle_use(scamper_cycle_t *cycle)
97 {
98   if(cycle != NULL) cycle->refcnt++;
99   return cycle;
100 }
101 
scamper_cycle_free(scamper_cycle_t * cycle)102 void scamper_cycle_free(scamper_cycle_t *cycle)
103 {
104   if(cycle != NULL)
105     {
106       assert(cycle->refcnt > 0);
107 
108       if(--cycle->refcnt > 0)
109 	{
110 	  return;
111 	}
112 
113       if(cycle->list != NULL) scamper_list_free(cycle->list);
114       if(cycle->hostname != NULL) free(cycle->hostname);
115       free(cycle);
116     }
117 
118   return;
119 }
120 
scamper_list_cmp(const scamper_list_t * a,const scamper_list_t * b)121 int scamper_list_cmp(const scamper_list_t *a, const scamper_list_t *b)
122 {
123   int i;
124 
125   /* if the lists are in the same piece of memory, they're identical */
126   if(a == b)
127     {
128       return 0;
129     }
130 
131   /* compare list ids */
132   if(a->id < b->id) return -1;
133   if(a->id > b->id) return 1;
134 
135   /* compare name strings */
136   if(a->name != NULL || b->name != NULL)
137     {
138       if(a->name == NULL && b->name != NULL) return -1;
139       if(a->name != NULL && b->name == NULL) return 1;
140       if((i = strcmp(a->name, b->name)) != 0) return i;
141     }
142 
143   /* compare description strings */
144   if(a->descr != NULL || b->descr != NULL)
145     {
146       if(a->descr == NULL && b->descr != NULL) return -1;
147       if(a->descr != NULL && b->descr == NULL) return 1;
148       if((i = strcmp(a->descr, b->descr)) != 0) return i;
149     }
150 
151   /* compare monitor strings */
152   if(a->monitor != NULL || b->monitor != NULL)
153     {
154       if(a->monitor == NULL && b->monitor != NULL) return -1;
155       if(a->monitor != NULL && b->monitor == NULL) return 1;
156       if((i = strcmp(a->monitor, b->monitor)) != 0) return i;
157     }
158 
159   /* they're the same, as best we can tell */
160   return 0;
161 }
162 
scamper_list_alloc(const uint32_t id,const char * name,const char * descr,const char * monitor)163 scamper_list_t *scamper_list_alloc(const uint32_t id, const char *name,
164 				   const char *descr, const char *monitor)
165 {
166   scamper_list_t *list;
167 
168   if((list = malloc_zero(sizeof(struct scamper_list))) == NULL)
169     {
170       return NULL;
171     }
172 
173   list->id = id;
174   list->refcnt = 1;
175 
176   if(name != NULL && (list->name = strdup(name)) == NULL)
177     {
178       goto err;
179     }
180 
181   if(descr != NULL && (list->descr = strdup(descr)) == NULL)
182     {
183       goto err;
184     }
185 
186   if(monitor != NULL && (list->monitor = strdup(monitor)) == NULL)
187     {
188       goto err;
189     }
190 
191   return list;
192 
193  err:
194   scamper_list_free(list);
195   return NULL;
196 }
197 
scamper_list_use(scamper_list_t * list)198 scamper_list_t *scamper_list_use(scamper_list_t *list)
199 {
200   if(list != NULL) list->refcnt++;
201   return list;
202 }
203 
scamper_list_free(scamper_list_t * list)204 void scamper_list_free(scamper_list_t *list)
205 {
206   if(list != NULL)
207     {
208       assert(list->refcnt > 0);
209 
210       if(--list->refcnt > 0)
211 	{
212 	  return;
213 	}
214 
215       if(list->name != NULL) free(list->name);
216       if(list->descr != NULL) free(list->descr);
217       if(list->monitor != NULL) free(list->monitor);
218       free(list);
219     }
220 
221   return;
222 }
223