6811333 Remove prom_printf() message in emlxs driver
[opensolaris.git] / usr / src / lib / libnisdb / nis_servlist.c
blobce8fff570cd11760d9fab1a1bff174d1b46db8b6
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <syslog.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include <malloc.h>
35 #include <strings.h>
36 #include "nis_servlist.h"
37 #include "nisdb_rw.h"
39 #ifdef MEM_DEBUG
40 #define XFREE xfree
41 #define XMALLOC xmalloc
42 #define XCALLOC xcalloc
43 #define XSTRDUP xstrdup
44 #ifdef __STDC__
45 extern void xfree(void *);
46 extern char *xstrdup(char *);
47 extern char *xmalloc(int);
48 extern char *xcalloc(int, int);
49 #else /* __STDC__ */
50 extern void xfree();
51 extern char *xstrdup();
52 extern char *xmalloc();
53 extern char *xcalloc();
54 #endif /* __STDC__ */
55 #else /* MEM_DEBUG */
56 #define XFREE free
57 #define XMALLOC malloc
58 #define XCALLOC calloc
59 #define XSTRDUP strdup
60 #endif /* MEM_DEBUG */
62 extern char *nis_data(char *s);
64 /* Imported from rpc.nisd/nis_subr_proc.c */
66 #define GETSERVER(o, n) (((o)->DI_data.do_servers.do_servers_val) + n)
67 #define MAXSERVER(o) (o)->DI_data.do_servers.do_servers_len
70 * This is a link list of all the directories served by this server.
72 struct nis_dir_list {
73 char *name;
74 struct nis_dir_list *next;
76 static struct nis_dir_list *dirlisthead = NULL;
77 static bool_t dir_init = FALSE;
79 DECLRWLOCK(dirlist);
81 /* this function must be protected by dirlist */
82 static int init_dir_list(const char *filename)
84 FILE *fr;
85 char buf[BUFSIZ];
86 char *name, *end;
87 struct nis_dir_list *tmp;
89 /* initialize only once */
90 if (dir_init)
91 return (1);
92 dir_init = TRUE;
94 fr = fopen(filename, "r");
95 if (fr == NULL) {
96 /* The server is just starting out */
97 return (-1);
99 while (fgets(buf, BUFSIZ, fr)) {
100 name = buf;
101 while (isspace(*name))
102 name++;
103 end = name;
104 while (!isspace(*end))
105 end++;
106 *end = NULL;
107 tmp = XMALLOC(sizeof (struct nis_dir_list));
108 if (tmp == NULL) {
109 /* Should never really happen */
110 fclose(fr);
111 return (0);
113 if ((tmp->name = strdup(name)) == NULL) {
114 /* Should never really happen */
115 XFREE(tmp);
116 fclose(fr);
117 return (0);
119 tmp->next = dirlisthead;
120 dirlisthead = tmp;
122 fclose(fr);
123 return (1);
127 * nis_server_control() controls various aspects of server administration.
130 nis_server_control(infotype, op, argp)
131 enum NIS_SERVER_INFO infotype;
132 enum NIS_SERVER_OP op;
133 void *argp;
135 char filename[BUFSIZ], tmpname[BUFSIZ];
136 char buf[BUFSIZ];
137 FILE *fr, *fw;
138 char *name, *end;
139 int ss;
140 char oldval;
141 char *dirs;
142 int i;
143 int ret;
144 struct stat st;
145 struct nis_dir_list *tmp, *prev;
147 filename[0] = NULL;
148 strcat(filename, nis_data("serving_list"));
149 switch (infotype) {
150 case SERVING_LIST:
152 * The file "serving_list" contains one directory name per
153 * line.
155 switch (op) {
156 case DIR_ADD:
157 WLOCK(dirlist);
158 (void) init_dir_list(filename);
159 /* Check whether I already serve this directory? */
160 for (tmp = dirlisthead; tmp; tmp = tmp->next)
161 if (strcasecmp(tmp->name, (char *)argp) == 0) {
162 WULOCK(dirlist);
163 return (1);
165 fw = fopen(filename, "r+");
166 if (fw == NULL) {
167 ss = stat(filename, &st);
168 if (ss == -1 && errno == ENOENT) {
169 fw = fopen(filename, "a+");
171 if (fw == NULL) {
172 syslog(LOG_ERR,
173 "could not open file %s for updating",
174 filename);
175 WULOCK(dirlist);
176 return (0);
180 /* Add it to the incore copy */
181 tmp = XMALLOC(sizeof (struct nis_dir_list));
182 if (tmp == NULL) {
183 /* Should never really happen */
184 fclose(fw);
185 WULOCK(dirlist);
186 return (0);
188 if ((tmp->name = strdup((char *)argp)) == NULL) {
189 /* Should never really happen */
190 fclose(fw);
191 XFREE(tmp);
192 WULOCK(dirlist);
193 return (0);
195 tmp->next = dirlisthead;
196 dirlisthead = tmp;
198 /* Add it to the file */
199 while (fgets(buf, BUFSIZ, fw)) {
200 name = buf;
201 while (isspace(*name))
202 name++;
203 end = name;
204 while (!isspace(*end))
205 end++;
206 *end = NULL;
207 if (strcasecmp(name, (char *)argp) == 0) {
208 /* already exists */
209 fclose(fw);
210 WULOCK(dirlist);
211 return (1);
214 fprintf(fw, "%s\n", (char *)argp);
215 fclose(fw);
216 WULOCK(dirlist);
217 return (1);
219 case DIR_DELETE:
220 WLOCK(dirlist);
221 (void) init_dir_list(filename);
222 prev = dirlisthead;
223 for (tmp = dirlisthead; tmp; tmp = tmp->next) {
224 if (strcasecmp(tmp->name, (char *)argp) == 0) {
225 if (tmp == dirlisthead)
226 dirlisthead = tmp->next;
227 else
228 prev->next = tmp->next;
229 XFREE(tmp->name);
230 XFREE(tmp);
231 break;
233 prev = tmp;
235 if (tmp == NULL) {
236 /* It wasnt found, so return success */
237 WULOCK(dirlist);
238 return (1);
241 fr = fopen(filename, "r");
242 if (fr == NULL) {
243 syslog(LOG_ERR,
244 "could not open file %s for reading",
245 filename);
246 WULOCK(dirlist);
247 return (0);
249 sprintf(tmpname, "%s.tmp", filename);
250 fw = fopen(tmpname, "w");
251 if (fw == NULL) {
252 syslog(LOG_ERR,
253 "could not open file %s for updating",
254 tmpname);
255 fclose(fr);
256 WULOCK(dirlist);
257 return (0);
259 while (fgets(buf, BUFSIZ, fr)) {
260 name = buf;
261 while (isspace(*name))
262 name++;
263 end = name;
264 while (!isspace(*end))
265 end++;
266 oldval = *end;
267 *end = NULL;
268 if (strcasecmp(name, (char *)argp) == 0) {
269 continue; /* skip this one */
271 *end = oldval;
272 fputs(buf, fw);
274 fclose(fr);
275 fclose(fw);
276 rename(tmpname, filename);
277 WULOCK(dirlist);
278 return (1);
280 case DIR_INITLIST:
281 WLOCK(dirlist);
282 ret = init_dir_list(filename);
283 WULOCK(dirlist);
284 return (ret);
286 case DIR_GETLIST:
287 /* don't acquire write lock unless not inited */
288 if (!dir_init) {
289 WLOCK(dirlist);
290 (void) init_dir_list(filename);
291 WULOCK(dirlist);
293 i = 0;
294 RLOCK(dirlist);
295 for (tmp = dirlisthead; tmp; tmp = tmp->next) {
296 i += strlen(tmp->name) + 1;
298 if (i == 0)
299 i = 1;
300 dirs = (char *)malloc(i);
301 if (dirs == NULL) {
302 RULOCK(dirlist);
303 return (0);
305 dirs[0] = '\0';
306 for (tmp = dirlisthead; tmp; tmp = tmp->next) {
307 if (*dirs != '\0')
308 strcat(dirs, " ");
309 strcat(dirs, tmp->name);
311 *((char **)argp) = dirs;
312 RULOCK(dirlist);
313 return (1);
315 case DIR_SERVED: /* Do I serve this directory */
316 /* don't acquire write lock unless not inited */
317 if (!dir_init) {
318 WLOCK(dirlist);
319 (void) init_dir_list(filename);
320 WULOCK(dirlist);
322 RLOCK(dirlist);
323 for (tmp = dirlisthead; tmp; tmp = tmp->next)
324 if (strcasecmp(tmp->name, (char *)argp) == 0) {
325 RULOCK(dirlist);
326 return (1);
328 RULOCK(dirlist);
329 return (0);
331 default:
332 return (0);
334 default:
335 return (0);
340 * nis_isserving()
342 * This function returns state indicating whether or not we serve the
343 * indicated directory.
344 * 0 = we don't serve it
345 * n = which server we are (1 == master)
348 nis_isserving(nis_object *dobj)
350 int ns, i; /* number of servers */
351 nis_name me = nis_local_host();
353 if (__type_of(dobj) != NIS_DIRECTORY_OBJ)
354 return (0);
356 ns = MAXSERVER(dobj);
358 * POLICY : Should host names be compared in a case independent
359 * mode?
360 * ANSWER : Yes, to support the semantics of DNS and existing
361 * software which assume hostnames are case insensitive.
364 if (nis_dir_cmp(me, GETSERVER(dobj, 0)->name) == SAME_NAME)
365 return (1);
367 /* Not master, check to see if we serve as a replica */
368 for (i = 1; i < ns; i++) {
369 if (nis_dir_cmp(me, GETSERVER(dobj, i)->name) == SAME_NAME)
370 return (i+1);
372 return (0);