]> granicus.if.org Git - shadow/blob - libmisc/list.c
Added missing include file (assert.h).
[shadow] / libmisc / list.c
1 /*
2  * Copyright (c) 1991 - 1994, Julianne Frances Haugh
3  * Copyright (c) 1996 - 1997, Marek Michałkiewicz
4  * Copyright (c) 2003 - 2005, Tomasz Kłoczko
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the copyright holders or contributors may not be used to
16  *    endorse or promote products derived from this software without
17  *    specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
23  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 /* Removed duplicated code from gpmain.c, useradd.c, userdel.c and
33    usermod.c.  --marekm */
34
35 #include <config.h>
36
37 #ident "$Id$"
38
39 #include <assert.h>
40 #include "prototypes.h"
41 #include "defines.h"
42 /*
43  * add_list - add a member to a list of group members
44  *
45  *      the array of member names is searched for the new member
46  *      name, and if not present it is added to a freshly allocated
47  *      list of users.
48  */
49 char **add_list (char **list, const char *member)
50 {
51         int i;
52         char **tmp;
53
54         assert (NULL != member);
55
56         /*
57          * Scan the list for the new name.  Return the original list
58          * pointer if it is present.
59          */
60
61         for (i = 0; list[i] != (char *) 0; i++) {
62                 if (strcmp (list[i], member) == 0) {
63                         return list;
64                 }
65         }
66
67         /*
68          * Allocate a new list pointer large enough to hold all the
69          * old entries, and the new entries as well.
70          */
71
72         tmp = (char **) xmalloc ((i + 2) * sizeof member);
73
74         /*
75          * Copy the original list to the new list, then append the
76          * new member and NULL terminate the result.  This new list
77          * is returned to the invoker.
78          */
79
80         for (i = 0; list[i] != (char *) 0; i++) {
81                 tmp[i] = list[i];
82         }
83
84         tmp[i] = xstrdup (member);
85         tmp[i+1] = (char *) 0;
86
87         return tmp;
88 }
89
90 /*
91  * del_list - delete a member from a list of group members
92  *
93  *      the array of member names is searched for the old member
94  *      name, and if present it is deleted from a freshly allocated
95  *      list of users.
96  */
97
98 char **del_list (char **list, const char *member)
99 {
100         int i, j;
101         char **tmp;
102
103         assert (NULL != member);
104
105         /*
106          * Scan the list for the old name.  Return the original list
107          * pointer if it is not present.
108          */
109
110         for (i = j = 0; list[i] != (char *) 0; i++) {
111                 if (strcmp (list[i], member) != 0) {
112                         j++;
113                 }
114         }
115
116         if (j == i) {
117                 return list;
118         }
119
120         /*
121          * Allocate a new list pointer large enough to hold all the
122          * old entries.
123          */
124
125         tmp = (char **) xmalloc ((j + 1) * sizeof member);
126
127         /*
128          * Copy the original list except the deleted members to the
129          * new list, then NULL terminate the result.  This new list
130          * is returned to the invoker.
131          */
132
133         for (i = j = 0; list[i] != (char *) 0; i++) {
134                 if (strcmp (list[i], member) != 0) {
135                         tmp[j] = list[i];
136                         j++;
137                 }
138         }
139
140         tmp[j] = (char *) 0;
141
142         return tmp;
143 }
144
145 char **dup_list (char *const *list)
146 {
147         int i;
148         char **tmp;
149
150         for (i = 0; NULL != list[i]; i++);
151
152         tmp = (char **) xmalloc ((i + 1) * sizeof (char *));
153
154         i = 0;
155         while (NULL != *list) {
156                 tmp[i] = xstrdup (*list);
157                 i++;
158                 list++;
159         }
160
161         tmp[i] = (char *) 0;
162         return tmp;
163 }
164
165 bool is_on_list (char *const *list, const char *member)
166 {
167         assert (NULL != member);
168
169         while (NULL != *list) {
170                 if (strcmp (*list, member) == 0) {
171                         return true;
172                 }
173                 list++;
174         }
175
176         return false;
177 }
178
179 /*
180  * comma_to_list - convert comma-separated list to (char *) array
181  */
182
183 char **comma_to_list (const char *comma)
184 {
185         char *members;
186         char **array;
187         int i;
188         char *cp, *cp2;
189
190         assert (NULL != comma);
191
192         /*
193          * Make a copy since we are going to be modifying the list
194          */
195
196         members = xstrdup (comma);
197
198         /*
199          * Count the number of commas in the list
200          */
201
202         for (cp = members, i = 0;; i++) {
203                 cp2 = strchr (cp, ',');
204                 if (NULL != cp2) {
205                         cp = cp2 + 1;
206                 } else {
207                         break;
208                 }
209         }
210
211         /*
212          * Add 2 - one for the ending NULL, the other for the last item
213          */
214
215         i += 2;
216
217         /*
218          * Allocate the array we're going to store the pointers into.
219          */
220
221         array = (char **) xmalloc (sizeof (char *) * i);
222
223         /*
224          * Empty list is special - 0 members, not 1 empty member.  --marekm
225          */
226
227         if ('\0' == *members) {
228                 *array = (char *) 0;
229                 return array;
230         }
231
232         /*
233          * Now go walk that list all over again, this time building the
234          * array of pointers.
235          */
236
237         for (cp = members, i = 0;; i++) {
238                 array[i] = cp;
239                 cp2 = strchr (cp, ',');
240                 if (NULL != cp2) {
241                         *cp2 = '\0';
242                         cp2++;
243                         cp = cp2;
244                 } else {
245                         array[i + 1] = (char *) 0;
246                         break;
247                 }
248         }
249
250         /*
251          * Return the new array of pointers
252          */
253
254         return array;
255 }
256