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
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]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 #include <sys/types.h>
36 #include "nis_servlist.h"
41 #define XMALLOC xmalloc
42 #define XCALLOC xcalloc
43 #define XSTRDUP xstrdup
45 extern void xfree(void *);
46 extern char *xstrdup(char *);
47 extern char *xmalloc(int);
48 extern char *xcalloc(int, int);
51 extern char *xstrdup();
52 extern char *xmalloc();
53 extern char *xcalloc();
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.
74 struct nis_dir_list
*next
;
76 static struct nis_dir_list
*dirlisthead
= NULL
;
77 static bool_t dir_init
= FALSE
;
81 /* this function must be protected by dirlist */
82 static int init_dir_list(const char *filename
)
87 struct nis_dir_list
*tmp
;
89 /* initialize only once */
94 fr
= fopen(filename
, "r");
96 /* The server is just starting out */
99 while (fgets(buf
, BUFSIZ
, fr
)) {
101 while (isspace(*name
))
104 while (!isspace(*end
))
107 tmp
= XMALLOC(sizeof (struct nis_dir_list
));
109 /* Should never really happen */
113 if ((tmp
->name
= strdup(name
)) == NULL
) {
114 /* Should never really happen */
119 tmp
->next
= dirlisthead
;
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
;
135 char filename
[BUFSIZ
], tmpname
[BUFSIZ
];
145 struct nis_dir_list
*tmp
, *prev
;
148 strcat(filename
, nis_data("serving_list"));
152 * The file "serving_list" contains one directory name per
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) {
165 fw
= fopen(filename
, "r+");
167 ss
= stat(filename
, &st
);
168 if (ss
== -1 && errno
== ENOENT
) {
169 fw
= fopen(filename
, "a+");
173 "could not open file %s for updating",
180 /* Add it to the incore copy */
181 tmp
= XMALLOC(sizeof (struct nis_dir_list
));
183 /* Should never really happen */
188 if ((tmp
->name
= strdup((char *)argp
)) == NULL
) {
189 /* Should never really happen */
195 tmp
->next
= dirlisthead
;
198 /* Add it to the file */
199 while (fgets(buf
, BUFSIZ
, fw
)) {
201 while (isspace(*name
))
204 while (!isspace(*end
))
207 if (strcasecmp(name
, (char *)argp
) == 0) {
214 fprintf(fw
, "%s\n", (char *)argp
);
221 (void) init_dir_list(filename
);
223 for (tmp
= dirlisthead
; tmp
; tmp
= tmp
->next
) {
224 if (strcasecmp(tmp
->name
, (char *)argp
) == 0) {
225 if (tmp
== dirlisthead
)
226 dirlisthead
= tmp
->next
;
228 prev
->next
= tmp
->next
;
236 /* It wasnt found, so return success */
241 fr
= fopen(filename
, "r");
244 "could not open file %s for reading",
249 sprintf(tmpname
, "%s.tmp", filename
);
250 fw
= fopen(tmpname
, "w");
253 "could not open file %s for updating",
259 while (fgets(buf
, BUFSIZ
, fr
)) {
261 while (isspace(*name
))
264 while (!isspace(*end
))
268 if (strcasecmp(name
, (char *)argp
) == 0) {
269 continue; /* skip this one */
276 rename(tmpname
, filename
);
282 ret
= init_dir_list(filename
);
287 /* don't acquire write lock unless not inited */
290 (void) init_dir_list(filename
);
295 for (tmp
= dirlisthead
; tmp
; tmp
= tmp
->next
) {
296 i
+= strlen(tmp
->name
) + 1;
300 dirs
= (char *)malloc(i
);
306 for (tmp
= dirlisthead
; tmp
; tmp
= tmp
->next
) {
309 strcat(dirs
, tmp
->name
);
311 *((char **)argp
) = dirs
;
315 case DIR_SERVED
: /* Do I serve this directory */
316 /* don't acquire write lock unless not inited */
319 (void) init_dir_list(filename
);
323 for (tmp
= dirlisthead
; tmp
; tmp
= tmp
->next
)
324 if (strcasecmp(tmp
->name
, (char *)argp
) == 0) {
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
)
356 ns
= MAXSERVER(dobj
);
358 * POLICY : Should host names be compared in a case independent
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
)
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
)