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 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
40 #include "../lib/nfslogtab.h"
41 #include "buffer_list.h"
43 static int buildbuffer_list(struct buffer_ent
**, timestruc_t
*);
44 static void free_buffer_ent(struct buffer_ent
*);
45 static struct buffer_ent
*findbuffer(struct buffer_ent
*, char *);
46 static void free_sharepnt_list(struct sharepnt_ent
*);
47 static void free_sharepnt_ent(struct sharepnt_ent
*);
49 static void print_sharepnt_list(struct sharepnt_ent
*);
51 static struct sharepnt_ent
*findsharepnt(struct sharepnt_ent
*, char *,
52 struct sharepnt_ent
**);
55 * Builds the buffer list from NFSLOGTAB and returns it in *listpp.
56 * Returns 0 on success, non-zero error code otherwise.
59 getbuffer_list(struct buffer_ent
**listpp
, timestruc_t
*lu
)
62 return (buildbuffer_list(listpp
, lu
));
66 * If NFSLOGTAB has not been modified since the last time we read it,
67 * it simply returns the same buffer list, otherwise it re-reads NFSLOGTAB
68 * and rebuilds the list.
69 * No NFSLOGTAB is not treated as an error.
70 * Returns 0 on success, non-zero error code otherwise
73 checkbuffer_list(struct buffer_ent
**listpp
, timestruc_t
*lu
)
78 if (stat(NFSLOGTAB
, &st
) == -1) {
80 if (error
!= ENOENT
) {
81 syslog(LOG_ERR
, gettext("Can't stat %s - %s"),
82 NFSLOGTAB
, strerror(error
));
88 if (lu
->tv_sec
== st
.st_mtim
.tv_sec
&&
89 lu
->tv_nsec
== st
.st_mtim
.tv_nsec
)
92 free_buffer_list(listpp
); /* free existing list first */
93 return (buildbuffer_list(listpp
, lu
));
97 * Does the actual work of reading NFSLOGTAB, and building the
98 * buffer list. If *be_head already contains entries, it will
99 * update the list with new information.
100 * Returns 0 on success, non-zero error code otherwise.
103 buildbuffer_list(struct buffer_ent
**be_head
, timestruc_t
*lu
)
106 struct buffer_ent
*be_tail
= NULL
, *bep
;
107 struct sharepnt_ent
*se_tail
= NULL
, *sep
;
108 struct logtab_ent
*lep
;
112 if ((fd
= fopen(NFSLOGTAB
, "r+")) == NULL
) {
114 if (error
!= ENOENT
) {
115 syslog(LOG_ERR
, gettext("%s - %s\n"), NFSLOGTAB
,
122 if (lockf(fileno(fd
), F_LOCK
, 0L) < 0) {
124 syslog(LOG_ERR
, gettext("cannot lock %s - %s\n"), NFSLOGTAB
,
130 assert(*be_head
== NULL
);
131 while ((res
= logtab_getent(fd
, &lep
)) > 0) {
132 if (bep
= findbuffer(*be_head
, lep
->le_buffer
)) {
134 * Add sharepnt to buffer list
136 if (sep
= findsharepnt(bep
->be_sharepnt
,
137 lep
->le_path
, &se_tail
)) {
139 * Sharepoint already in list,
142 sep
->se_state
= lep
->le_state
;
145 * Need to add to sharepoint list
147 sep
= (struct sharepnt_ent
*)
148 malloc(sizeof (*sep
));
153 (void) memset(sep
, 0, sizeof (*sep
));
155 sep
->se_name
= strdup(lep
->le_path
);
156 if (sep
->se_name
== NULL
) {
160 sep
->se_state
= lep
->le_state
;
162 assert(se_tail
!= NULL
);
163 assert(se_tail
->se_next
== NULL
);
164 se_tail
->se_next
= sep
;
168 * Add new buffer to list
170 bep
= (struct buffer_ent
*)malloc(sizeof (*bep
));
175 (void) memset(bep
, 0, sizeof (*bep
));
177 bep
->be_name
= strdup(lep
->le_buffer
);
178 if (bep
->be_name
== NULL
) {
183 if (*be_head
== NULL
)
186 be_tail
->be_next
= bep
;
189 bep
->be_sharepnt
= (struct sharepnt_ent
*)
190 malloc(sizeof (*(bep
->be_sharepnt
)));
191 (void) memset(bep
->be_sharepnt
, 0,
192 sizeof (*(bep
->be_sharepnt
)));
194 if (bep
->be_sharepnt
== NULL
) {
198 bep
->be_sharepnt
->se_name
= strdup(lep
->le_path
);
199 if (bep
->be_sharepnt
->se_name
== NULL
) {
203 bep
->be_sharepnt
->se_state
= lep
->le_state
;
213 * Get modification time while we have the file locked.
216 if ((error
= fstat(fileno(fd
), &st
)) == -1) {
217 syslog(LOG_ERR
, gettext("Can't stat %s"), NFSLOGTAB
);
229 logtab_ent_free(lep
);
230 free_buffer_list(be_head
);
231 assert(*be_head
== NULL
);
232 syslog(LOG_ERR
, gettext("cannot read %s: %s\n"), NFSLOGTAB
,
239 * Removes the entry from the buffer list and frees it.
242 remove_buffer_ent(struct buffer_ent
**be_listpp
, struct buffer_ent
*bep
)
244 struct buffer_ent
*p
, *prev
;
246 for (p
= prev
= *be_listpp
; p
!= NULL
; p
= p
->be_next
) {
249 *be_listpp
= (*be_listpp
)->be_next
;
251 prev
->be_next
= bep
->be_next
;
252 free_buffer_ent(bep
);
260 * Frees the buffer list.
263 free_buffer_list(struct buffer_ent
**be_listpp
)
265 struct buffer_ent
*bep
, *nextp
;
267 for (bep
= *be_listpp
; bep
!= NULL
; bep
= nextp
) {
268 nextp
= bep
->be_next
;
269 free_buffer_ent(bep
);
275 free_buffer_ent(struct buffer_ent
*bep
)
279 (void) printf("freeing %s\n", bep
->be_name
);
280 if (bep
->be_name
!= NULL
)
282 if (bep
->be_sharepnt
!= NULL
)
283 free_sharepnt_list(bep
->be_sharepnt
);
288 free_sharepnt_list(struct sharepnt_ent
*sep_listp
)
290 struct sharepnt_ent
*nextp
;
292 for (; sep_listp
!= NULL
; sep_listp
= nextp
) {
293 nextp
= sep_listp
->se_next
;
294 free_sharepnt_ent(sep_listp
);
300 * Removes the entry from the sharepnt list and frees it.
303 remove_sharepnt_ent(struct sharepnt_ent
**se_listpp
, struct sharepnt_ent
*sep
)
305 struct sharepnt_ent
*p
, *prev
;
307 for (p
= prev
= *se_listpp
; p
!= NULL
; p
= p
->se_next
) {
310 *se_listpp
= (*se_listpp
)->se_next
;
312 prev
->se_next
= sep
->se_next
;
313 free_sharepnt_ent(sep
);
321 free_sharepnt_ent(struct sharepnt_ent
*sep
)
325 (void) printf("freeing %s\n", sep
->se_name
);
326 if (sep
->se_name
!= NULL
)
333 printbuffer_list(struct buffer_ent
*bep
)
335 for (; bep
!= NULL
; bep
= bep
->be_next
) {
336 (void) printf("%s\n", bep
->be_name
);
337 if (bep
->be_sharepnt
!= NULL
)
338 print_sharepnt_list(bep
->be_sharepnt
);
343 print_sharepnt_list(struct sharepnt_ent
*sep
)
345 for (; sep
!= NULL
; sep
= sep
->se_next
)
346 (void) printf("\t(%d) %s\n", sep
->se_state
, sep
->se_name
);
351 * Returns a pointer to the buffer matching 'name', NULL otherwise.
353 static struct buffer_ent
*
354 findbuffer(struct buffer_ent
*bep
, char *name
)
356 for (; bep
!= NULL
; bep
= bep
->be_next
) {
357 if (strcmp(bep
->be_name
, name
) == 0)
364 * Returns a pointer the sharepoint entry matching 'name'.
365 * Otherwise, it sets '*se_tail' to the last element of the list
366 * to make insertion of new element easier, and returns NULL.
368 static struct sharepnt_ent
*
370 struct sharepnt_ent
*sep
,
372 struct sharepnt_ent
**se_tail
)
374 struct sharepnt_ent
*tail
;
376 for (; sep
!= NULL
; sep
= sep
->se_next
) {
377 if (strcmp(sep
->se_name
, name
) == 0)