1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 3 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General
15    Public License along with this library.  If not, see
16    <http://www.gnu.org/licenses/>. */
17 
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <stdlib.h>
22 #include <mailutils/sys/list.h>
23 #include <mailutils/errno.h>
24 
25 int
_mu_list_insert_item(mu_list_t list,struct list_data * current,void * new_item,int insert_before)26 _mu_list_insert_item (mu_list_t list, struct list_data *current,
27 		      void *new_item,
28 		      int insert_before)
29 {
30   int status;
31   struct list_data *ldata = calloc (sizeof (*ldata), 1);
32   if (ldata == NULL)
33     status = ENOMEM;
34   else
35     {
36       ldata->item = new_item;
37       _mu_list_insert_sublist (list, current,
38 			       ldata, ldata,
39 			       1,
40 			       insert_before);
41       status = 0;
42     }
43   return status;
44 }
45 
46 int
mu_list_insert(mu_list_t list,void * item,void * new_item,int insert_before)47 mu_list_insert (mu_list_t list, void *item, void *new_item, int insert_before)
48 {
49   struct list_data *current;
50   mu_list_comparator_t comp;
51   int status = MU_ERR_NOENT;
52 
53   if (list == NULL)
54     return EINVAL;
55   comp = list->comp ? list->comp : _mu_list_ptr_comparator;
56 
57   mu_monitor_wrlock (list->monitor);
58   for (current = list->head.next;
59        current != &list->head;
60        current = current->next)
61     {
62       if (comp (current->item, item) == 0)
63 	{
64 	  status = _mu_list_insert_item (list, current, new_item,
65 					 insert_before);
66 	  break;
67 	}
68     }
69   mu_monitor_unlock (list->monitor);
70   return status;
71 }
72