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 (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #include <sys/types.h>
38 #include "../lib/nfslogtab.h"
39 #include "buffer_list.h"
41 static int buildbuffer_list(struct buffer_ent
**, timestruc_t
*);
42 static void free_buffer_ent(struct buffer_ent
*);
43 static struct buffer_ent
*findbuffer(struct buffer_ent
*, char *);
44 static void free_sharepnt_list(struct sharepnt_ent
*);
45 static void free_sharepnt_ent(struct sharepnt_ent
*);
47 static void print_sharepnt_list(struct sharepnt_ent
*);
49 static struct sharepnt_ent
*findsharepnt(struct sharepnt_ent
*, char *,
50 struct sharepnt_ent
**);
53 * Builds the buffer list from NFSLOGTAB and returns it in *listpp.
54 * Returns 0 on success, non-zero error code otherwise.
57 getbuffer_list(struct buffer_ent
**listpp
, timestruc_t
*lu
)
60 return (buildbuffer_list(listpp
, lu
));
64 * If NFSLOGTAB has not been modified since the last time we read it,
65 * it simply returns the same buffer list, otherwise it re-reads NFSLOGTAB
66 * and rebuilds the list.
67 * No NFSLOGTAB is not treated as an error.
68 * Returns 0 on success, non-zero error code otherwise
71 checkbuffer_list(struct buffer_ent
**listpp
, timestruc_t
*lu
)
76 if (stat(NFSLOGTAB
, &st
) == -1) {
78 if (error
!= ENOENT
) {
79 syslog(LOG_ERR
, gettext("Can't stat %s - %s"),
80 NFSLOGTAB
, strerror(error
));
86 if (lu
->tv_sec
== st
.st_mtim
.tv_sec
&&
87 lu
->tv_nsec
== st
.st_mtim
.tv_nsec
)
90 free_buffer_list(listpp
); /* free existing list first */
91 return (buildbuffer_list(listpp
, lu
));
95 * Does the actual work of reading NFSLOGTAB, and building the
96 * buffer list. If *be_head already contains entries, it will
97 * update the list with new information.
98 * Returns 0 on success, non-zero error code otherwise.
101 buildbuffer_list(struct buffer_ent
**be_head
, timestruc_t
*lu
)
104 struct buffer_ent
*be_tail
= NULL
, *bep
;
105 struct sharepnt_ent
*se_tail
= NULL
, *sep
;
106 struct logtab_ent
*lep
;
110 if ((fd
= fopen(NFSLOGTAB
, "r+")) == NULL
) {
112 if (error
!= ENOENT
) {
113 syslog(LOG_ERR
, gettext("%s - %s\n"), NFSLOGTAB
,
120 if (lockf(fileno(fd
), F_LOCK
, 0L) < 0) {
122 syslog(LOG_ERR
, gettext("cannot lock %s - %s\n"), NFSLOGTAB
,
128 assert(*be_head
== NULL
);
129 while ((res
= logtab_getent(fd
, &lep
)) > 0) {
130 if (bep
= findbuffer(*be_head
, lep
->le_buffer
)) {
132 * Add sharepnt to buffer list
134 if (sep
= findsharepnt(bep
->be_sharepnt
,
135 lep
->le_path
, &se_tail
)) {
137 * Sharepoint already in list,
140 sep
->se_state
= lep
->le_state
;
143 * Need to add to sharepoint list
145 sep
= (struct sharepnt_ent
*)
146 malloc(sizeof (*sep
));
151 (void) memset(sep
, 0, sizeof (*sep
));
153 sep
->se_name
= strdup(lep
->le_path
);
154 if (sep
->se_name
== NULL
) {
158 sep
->se_state
= lep
->le_state
;
160 assert(se_tail
!= NULL
);
161 assert(se_tail
->se_next
== NULL
);
162 se_tail
->se_next
= sep
;
166 * Add new buffer to list
168 bep
= (struct buffer_ent
*)malloc(sizeof (*bep
));
173 (void) memset(bep
, 0, sizeof (*bep
));
175 bep
->be_name
= strdup(lep
->le_buffer
);
176 if (bep
->be_name
== NULL
) {
181 if (*be_head
== NULL
)
184 be_tail
->be_next
= bep
;
187 bep
->be_sharepnt
= (struct sharepnt_ent
*)
188 malloc(sizeof (*(bep
->be_sharepnt
)));
189 (void) memset(bep
->be_sharepnt
, 0,
190 sizeof (*(bep
->be_sharepnt
)));
192 if (bep
->be_sharepnt
== NULL
) {
196 bep
->be_sharepnt
->se_name
= strdup(lep
->le_path
);
197 if (bep
->be_sharepnt
->se_name
== NULL
) {
201 bep
->be_sharepnt
->se_state
= lep
->le_state
;
211 * Get modification time while we have the file locked.
214 if ((error
= fstat(fileno(fd
), &st
)) == -1) {
215 syslog(LOG_ERR
, gettext("Can't stat %s"), NFSLOGTAB
);
227 logtab_ent_free(lep
);
228 free_buffer_list(be_head
);
229 assert(*be_head
== NULL
);
230 syslog(LOG_ERR
, gettext("cannot read %s: %s\n"), NFSLOGTAB
,
237 * Removes the entry from the buffer list and frees it.
240 remove_buffer_ent(struct buffer_ent
**be_listpp
, struct buffer_ent
*bep
)
242 struct buffer_ent
*p
, *prev
;
244 for (p
= prev
= *be_listpp
; p
!= NULL
; p
= p
->be_next
) {
247 *be_listpp
= (*be_listpp
)->be_next
;
249 prev
->be_next
= bep
->be_next
;
250 free_buffer_ent(bep
);
258 * Frees the buffer list.
261 free_buffer_list(struct buffer_ent
**be_listpp
)
263 struct buffer_ent
*bep
, *nextp
;
265 for (bep
= *be_listpp
; bep
!= NULL
; bep
= nextp
) {
266 nextp
= bep
->be_next
;
267 free_buffer_ent(bep
);
273 free_buffer_ent(struct buffer_ent
*bep
)
277 (void) printf("freeing %s\n", bep
->be_name
);
279 if (bep
->be_sharepnt
!= NULL
)
280 free_sharepnt_list(bep
->be_sharepnt
);
285 free_sharepnt_list(struct sharepnt_ent
*sep_listp
)
287 struct sharepnt_ent
*nextp
;
289 for (; sep_listp
!= NULL
; sep_listp
= nextp
) {
290 nextp
= sep_listp
->se_next
;
291 free_sharepnt_ent(sep_listp
);
297 * Removes the entry from the sharepnt list and frees it.
300 remove_sharepnt_ent(struct sharepnt_ent
**se_listpp
, struct sharepnt_ent
*sep
)
302 struct sharepnt_ent
*p
, *prev
;
304 for (p
= prev
= *se_listpp
; p
!= NULL
; p
= p
->se_next
) {
307 *se_listpp
= (*se_listpp
)->se_next
;
309 prev
->se_next
= sep
->se_next
;
310 free_sharepnt_ent(sep
);
318 free_sharepnt_ent(struct sharepnt_ent
*sep
)
322 (void) printf("freeing %s\n", sep
->se_name
);
329 printbuffer_list(struct buffer_ent
*bep
)
331 for (; bep
!= NULL
; bep
= bep
->be_next
) {
332 (void) printf("%s\n", bep
->be_name
);
333 if (bep
->be_sharepnt
!= NULL
)
334 print_sharepnt_list(bep
->be_sharepnt
);
339 print_sharepnt_list(struct sharepnt_ent
*sep
)
341 for (; sep
!= NULL
; sep
= sep
->se_next
)
342 (void) printf("\t(%d) %s\n", sep
->se_state
, sep
->se_name
);
347 * Returns a pointer to the buffer matching 'name', NULL otherwise.
349 static struct buffer_ent
*
350 findbuffer(struct buffer_ent
*bep
, char *name
)
352 for (; bep
!= NULL
; bep
= bep
->be_next
) {
353 if (strcmp(bep
->be_name
, name
) == 0)
360 * Returns a pointer the sharepoint entry matching 'name'.
361 * Otherwise, it sets '*se_tail' to the last element of the list
362 * to make insertion of new element easier, and returns NULL.
364 static struct sharepnt_ent
*
366 struct sharepnt_ent
*sep
,
368 struct sharepnt_ent
**se_tail
)
370 struct sharepnt_ent
*tail
;
372 for (; sep
!= NULL
; sep
= sep
->se_next
) {
373 if (strcmp(sep
->se_name
, name
) == 0)