1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  *
4  * (c) by the OLSR project
5  *
6  * See our Git repository to find out who worked on this file
7  * and thus is a copyright holder on it.
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in
19  *   the documentation and/or other materials provided with the
20  *   distribution.
21  * * Neither the name of olsr.org, olsrd nor the names of its
22  *   contributors may be used to endorse or promote products derived
23  *   from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Visit http://www.olsr.org for more information.
39  *
40  * If you find this software useful feel free to make a donation
41  * to the project. For more information see the website or contact
42  * the copyright holders.
43  *
44  */
45 
46 #include <stdlib.h>
47 
48 #include "olsr_types.h"
49 #include "dllist.h"
50 
51 /*------------------------------------------------------------------------------
52  * Description : appends a node to the list specified by the head and tail
53  *               elements
54  * Parameters  : head - pointer to the head of the list
55  *               tail - pointer to the tail of the list
56  *               data - pointer to the data to store in the list
57  * Returns     : pointer to the newly created element in the list
58  * Uses data   : none
59  *------------------------------------------------------------------------------
60  */
append_node(struct node ** head,struct node ** tail,void * data)61 struct node * append_node(struct node ** head, struct node ** tail, void * data)
62 {
63   struct node * new = calloc(1, sizeof(struct node));
64 
65   if (*head == NULL) {
66     *head = new;
67   } else {
68     new->prev = *tail;
69     (*tail)->next = new;
70   }
71 
72   new->data = data;
73   *tail = new;
74 
75   return new;
76 }
77 
78 /*------------------------------------------------------------------------------
79  * Description : removes the specified element from the list specified by the
80  *               head and tail elements
81  * Parameters  : head - pointer to the head of the list
82  *               tail - pointer to the tail of the list
83  *               node - the element to remove from the list
84  *               free_data - indicator whether to free the content of the data
85  *               element
86  * Returns     : nothing
87  * Uses data   : none
88  *------------------------------------------------------------------------------
89  */
remove_node(struct node ** head,struct node ** tail,struct node * node,bool free_data)90 void remove_node(struct node ** head, struct node **tail, struct node * node, bool free_data)
91 {
92   struct node * curr = NULL;
93 
94   for (curr = *head; curr; curr = curr->next) {
95     if (curr == node) {
96       // Now we found the proper node so we can remove it
97 
98       if (free_data)
99         free(curr->data);
100 
101       if (curr == *head) {
102         // Head node
103         *head = curr->next;
104       } else if (curr == *tail) {
105         // Tail node
106         *tail = curr->prev;
107       } else {
108         // Middle node
109         curr->prev->next = curr->next;
110         curr->next->prev = curr->prev;
111       }
112 
113       if (*head != NULL)
114         (*head)->prev = NULL;
115 
116       if (*tail != NULL)
117         (*tail)->next = NULL;
118 
119       if (curr != NULL) {
120         curr->next = curr->prev = NULL;
121         free(curr);
122       }
123       break; // Bail out if we handled a remove
124     }
125   }
126 }
127 
128 /*------------------------------------------------------------------------------
129  * Description : clears the entire list specified by the head and tail elements
130  * Parameters  : head - pointer to the head of the list
131  *               tail - pointer to the tail of the list
132  *               free_data - indicator whether to free the data pointer
133  * Returns     : nothing
134  * Uses data   : none
135  *------------------------------------------------------------------------------
136  */
clear_list(struct node ** head,struct node ** tail,bool free_data)137 void clear_list(struct node **head, struct node **tail, bool free_data)
138 {
139   while (*head)
140     remove_node(head, tail, *head, free_data);
141 }
142 
143 
144