]>
git.cameronkatri.com Git - pw-darwin.git/blob - libutil/gr_util.c
2 * Copyright (c) 2008 Sean C. Farley <scf@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
41 static const char GroupLineFormat
[] = "%s:%s:%ju:";
45 * Compares two struct group's.
48 gr_equal(const struct group
*gr1
, const struct group
*gr2
)
55 /* Check that the non-member information is the same. */
56 equal
= strcmp(gr1
->gr_name
, gr2
->gr_name
) == 0 &&
57 strcmp(gr1
->gr_passwd
, gr2
->gr_passwd
) == 0 &&
58 gr1
->gr_gid
== gr2
->gr_gid
;
60 /* Check all members in both groups. */
62 for (found
= false, gr1Ndx
= 0; gr1
->gr_mem
[gr1Ndx
] != NULL
;
64 for (gr2Ndx
= 0; gr2
->gr_mem
[gr2Ndx
] != NULL
; gr2Ndx
++)
65 if (strcmp(gr1
->gr_mem
[gr1Ndx
],
66 gr2
->gr_mem
[gr2Ndx
]) == 0) {
76 /* Check that group2 does not have more members than group1. */
77 if (gr2
->gr_mem
[gr1Ndx
] != NULL
)
86 * Make a group line out of a struct group.
89 gr_make(const struct group
*gr
)
95 /* Calculate the length of the group line. */
96 lineSize
= snprintf(NULL
, 0, GroupLineFormat
, gr
->gr_name
,
97 gr
->gr_passwd
, (uintmax_t)gr
->gr_gid
) + 1;
98 for (ndx
= 0; gr
->gr_mem
[ndx
] != NULL
; ndx
++)
99 lineSize
+= strlen(gr
->gr_mem
[ndx
]) + 1;
103 /* Create the group line and fill it. */
104 if ((line
= malloc(lineSize
)) == NULL
)
106 lineSize
= snprintf(line
, lineSize
, GroupLineFormat
, gr
->gr_name
,
107 gr
->gr_passwd
, (uintmax_t)gr
->gr_gid
);
108 for (ndx
= 0; gr
->gr_mem
[ndx
] != NULL
; ndx
++) {
109 strcat(line
, gr
->gr_mem
[ndx
]);
110 if (gr
->gr_mem
[ndx
+ 1] != NULL
)
119 * Duplicate a struct group.
122 gr_dup(const struct group
*gr
)
129 /* Calculate size of group. */
131 (gr
->gr_name
!= NULL
? strlen(gr
->gr_name
) + 1 : 0) +
132 (gr
->gr_passwd
!= NULL
? strlen(gr
->gr_passwd
) + 1 : 0);
134 if (gr
->gr_mem
!= NULL
) {
135 for (; gr
->gr_mem
[numMem
] != NULL
; numMem
++)
136 len
+= strlen(gr
->gr_mem
[numMem
]) + 1;
137 len
+= (numMem
+ 1) * sizeof(*(gr
->gr_mem
));
140 /* Create new group and copy old group into it. */
141 if ((ngr
= calloc(1, len
)) == NULL
)
144 ngr
->gr_gid
= gr
->gr_gid
;
145 if (gr
->gr_name
!= NULL
) {
146 ngr
->gr_name
= (char *)ngr
+ len
;
147 len
+= sprintf(ngr
->gr_name
, "%s", gr
->gr_name
) + 1;
149 if (gr
->gr_passwd
!= NULL
) {
150 ngr
->gr_passwd
= (char *)ngr
+ len
;
151 len
+= sprintf(ngr
->gr_passwd
, "%s", gr
->gr_passwd
) + 1;
153 if (gr
->gr_mem
!= NULL
) {
154 ngr
->gr_mem
= (char **)((char *)ngr
+ len
);
155 len
+= (numMem
+ 1) * sizeof(*(ngr
->gr_mem
));
156 for (ndx
= 0; gr
->gr_mem
[ndx
] != NULL
; ndx
++) {
157 ngr
->gr_mem
[ndx
] = (char *)ngr
+ len
;
158 len
+= sprintf(ngr
->gr_mem
[ndx
], "%s",
159 gr
->gr_mem
[ndx
]) + 1;
161 ngr
->gr_mem
[ndx
] = NULL
;
169 * Scan a line and place it into a group structure.
172 __gr_scan(char *line
, struct group
*gr
)
177 /* Assign non-member information to structure. */
179 if ((loc
= strchr(line
, ':')) == NULL
)
182 gr
->gr_passwd
= loc
+ 1;
183 if (*(gr
->gr_passwd
) == ':')
184 *(gr
->gr_passwd
) = '\0';
186 if ((loc
= strchr(loc
+ 1, ':')) == NULL
)
190 if (sscanf(loc
+ 1, "%u", &(gr
->gr_gid
)) != 1)
193 /* Assign member information to structure. */
194 if ((loc
= strchr(loc
+ 1, ':')) == NULL
)
201 if ((gr
->gr_mem
= reallocf(gr
->gr_mem
,
202 sizeof(*(gr
->gr_mem
)) * (ndx
+ 1))) == NULL
)
204 gr
->gr_mem
[ndx
] = strsep(&line
, ",");
205 } while (gr
->gr_mem
[ndx
++] != NULL
);
213 * Create a struct group from a line.
216 gr_scan(const char *line
)
222 if ((lineCopy
= strdup(line
)) == NULL
)
224 if (!__gr_scan(lineCopy
, &gr
)) {
230 if (gr
.gr_mem
!= NULL
)