8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / buffer_list.c
bloba3a74e41145f9cb9e9b1044717f24361802a5b97
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 (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <syslog.h>
33 #include <libintl.h>
34 #include <unistd.h>
35 #include <strings.h>
36 #include <string.h>
37 #include <assert.h>
38 #include <stdlib.h>
39 #include "nfslogd.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 *);
48 #ifdef DEBUG
49 static void print_sharepnt_list(struct sharepnt_ent *);
50 #endif
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.
58 int
59 getbuffer_list(struct buffer_ent **listpp, timestruc_t *lu)
61 *listpp = NULL;
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
72 int
73 checkbuffer_list(struct buffer_ent **listpp, timestruc_t *lu)
75 struct stat st;
76 int error = 0;
78 if (stat(NFSLOGTAB, &st) == -1) {
79 error = errno;
80 if (error != ENOENT) {
81 syslog(LOG_ERR, gettext("Can't stat %s - %s"),
82 NFSLOGTAB, strerror(error));
83 error = 0;
85 return (error);
88 if (lu->tv_sec == st.st_mtim.tv_sec &&
89 lu->tv_nsec == st.st_mtim.tv_nsec)
90 return (0);
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.
102 static int
103 buildbuffer_list(struct buffer_ent **be_head, timestruc_t *lu)
105 FILE *fd;
106 struct buffer_ent *be_tail = NULL, *bep;
107 struct sharepnt_ent *se_tail = NULL, *sep;
108 struct logtab_ent *lep;
109 struct stat st;
110 int error = 0, res;
112 if ((fd = fopen(NFSLOGTAB, "r+")) == NULL) {
113 error = errno;
114 if (error != ENOENT) {
115 syslog(LOG_ERR, gettext("%s - %s\n"), NFSLOGTAB,
116 strerror(error));
117 error = 0;
119 return (error);
122 if (lockf(fileno(fd), F_LOCK, 0L) < 0) {
123 error = errno;
124 syslog(LOG_ERR, gettext("cannot lock %s - %s\n"), NFSLOGTAB,
125 strerror(error));
126 (void) fclose(fd);
127 return (error);
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,
140 * update its state.
142 sep->se_state = lep->le_state;
143 } else {
145 * Need to add to sharepoint list
147 sep = (struct sharepnt_ent *)
148 malloc(sizeof (*sep));
149 if (sep == NULL) {
150 error = ENOMEM;
151 goto errout;
153 (void) memset(sep, 0, sizeof (*sep));
155 sep->se_name = strdup(lep->le_path);
156 if (sep->se_name == NULL) {
157 error = ENOMEM;
158 goto errout;
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;
166 } else {
168 * Add new buffer to list
170 bep = (struct buffer_ent *)malloc(sizeof (*bep));
171 if (bep == NULL) {
172 error = ENOMEM;
173 goto errout;
175 (void) memset(bep, 0, sizeof (*bep));
177 bep->be_name = strdup(lep->le_buffer);
178 if (bep->be_name == NULL) {
179 error = ENOMEM;
180 goto errout;
183 if (*be_head == NULL)
184 *be_head = bep;
185 else
186 be_tail->be_next = bep;
187 be_tail = 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) {
195 error = ENOMEM;
196 goto errout;
198 bep->be_sharepnt->se_name = strdup(lep->le_path);
199 if (bep->be_sharepnt->se_name == NULL) {
200 error = ENOMEM;
201 goto errout;
203 bep->be_sharepnt->se_state = lep->le_state;
207 if (res < 0) {
208 error = EIO;
209 goto errout;
213 * Get modification time while we have the file locked.
215 if (lu) {
216 if ((error = fstat(fileno(fd), &st)) == -1) {
217 syslog(LOG_ERR, gettext("Can't stat %s"), NFSLOGTAB);
218 goto errout;
220 *lu = st.st_mtim;
223 (void) fclose(fd);
224 return (error);
226 errout:
227 (void) fclose(fd);
228 if (lep)
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,
233 strerror(error));
235 return (error);
239 * Removes the entry from the buffer list and frees it.
241 void
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) {
247 if (p == bep) {
248 if (p == *be_listpp)
249 *be_listpp = (*be_listpp)->be_next;
250 else
251 prev->be_next = bep->be_next;
252 free_buffer_ent(bep);
253 break;
255 prev = p;
260 * Frees the buffer list.
262 void
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);
271 *be_listpp = NULL;
274 static void
275 free_buffer_ent(struct buffer_ent *bep)
277 assert(bep != NULL);
278 if (debug)
279 (void) printf("freeing %s\n", bep->be_name);
280 if (bep->be_name != NULL)
281 free(bep->be_name);
282 if (bep->be_sharepnt != NULL)
283 free_sharepnt_list(bep->be_sharepnt);
284 free(bep);
287 static void
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);
296 free(sep_listp);
300 * Removes the entry from the sharepnt list and frees it.
302 void
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) {
308 if (p == sep) {
309 if (p == *se_listpp)
310 *se_listpp = (*se_listpp)->se_next;
311 else
312 prev->se_next = sep->se_next;
313 free_sharepnt_ent(sep);
314 break;
316 prev = p;
320 static void
321 free_sharepnt_ent(struct sharepnt_ent *sep)
323 assert(sep != NULL);
324 if (debug)
325 (void) printf("freeing %s\n", sep->se_name);
326 if (sep->se_name != NULL)
327 free(sep->se_name);
328 free(sep);
331 #ifdef DEBUG
332 void
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);
342 static void
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);
348 #endif
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)
358 return (bep);
360 return (NULL);
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 *
369 findsharepnt(
370 struct sharepnt_ent *sep,
371 char *name,
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)
378 return (sep);
379 tail = sep;
381 *se_tail = tail;
382 return (NULL);