8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / lib / nfslogtab.c
blob46ffb52ff60b0df57fbffc69018b9d2ce058c8a3
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"
30 * Manipulates the nfslogtab
33 #ifndef _REENTRANT
34 #define _REENTRANT
35 #endif
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <errno.h>
40 #include <utmpx.h>
41 #include <assert.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <strings.h>
46 #include <string.h>
47 #include "nfslogtab.h"
49 #ifndef LINTHAPPY
50 #define LINTHAPPY
51 #endif
53 static void logtab_ent_list_free(struct logtab_ent_list *);
56 * Retrieves the next entry from nfslogtab.
57 * Assumes the file is locked.
58 * '*lepp' points to the new entry if successful.
59 * Returns:
60 * > 0 valid entry
61 * = 0 end of file
62 * < 0 error
64 int
65 logtab_getent(FILE *fd, struct logtab_ent **lepp)
67 char line[MAXBUFSIZE + 1];
68 char *p;
69 char *lasts, *tmp;
70 char *w = " \t";
71 struct logtab_ent *lep = NULL;
72 int error = 0;
74 if ((lep = (struct logtab_ent *)malloc(sizeof (*lep))) == NULL) {
75 return (-1);
77 (void) memset((char *)lep, 0, sizeof (*lep));
79 if ((p = fgets(line, MAXBUFSIZE, fd)) == NULL) {
80 error = 0;
81 goto errout;
84 line[strlen(line) - 1] = '\0';
86 tmp = (char *)strtok_r(p, w, &lasts);
87 if (tmp == NULL) {
88 error = -1;
89 goto errout;
91 if ((lep->le_buffer = strdup(tmp)) == NULL) {
92 error = -1;
93 goto errout;
96 tmp = (char *)strtok_r(NULL, w, &lasts);
97 if (tmp == NULL) {
98 error = -1;
99 goto errout;
101 if ((lep->le_path = strdup(tmp)) == NULL) {
102 error = -1;
103 goto errout;
106 tmp = (char *)strtok_r(NULL, w, &lasts);
107 if (tmp == NULL) {
108 error = -1;
109 goto errout;
111 if ((lep->le_tag = strdup(tmp)) == NULL) {
112 error = -1;
113 goto errout;
116 tmp = (char *)strtok_r(NULL, w, &lasts);
117 if (tmp == NULL) {
118 error = -1;
119 goto errout;
121 lep->le_state = atoi(tmp);
123 *lepp = lep;
124 return (1);
126 errout:
127 logtab_ent_free(lep);
129 return (error);
133 * Append an entry to the logtab file.
136 logtab_putent(FILE *fd, struct logtab_ent *lep)
138 int r;
140 if (fseek(fd, 0L, SEEK_END) < 0)
141 return (errno);
143 r = fprintf(fd, "%s\t%s\t%s\t%d\n",
144 lep->le_buffer,
145 lep->le_path,
146 lep->le_tag,
147 lep->le_state);
149 return (r);
152 #ifndef LINTHAPPY
154 * Searches the nfslogtab file looking for the next entry which matches
155 * the search criteria. The search is continued at the current position
156 * in the nfslogtab file.
157 * If 'buffer' != NULL, then buffer is matched.
158 * If 'path' != NULL, then path is matched.
159 * If 'tag' != NULL, then tag is matched.
160 * If 'state' != -1, then state is matched.
161 * 'buffer', 'path' and 'tag' can all be non-NULL, which means the entry must
162 * satisfy all requirements.
164 * Returns 0 on success, ENOENT otherwise.
165 * If found, '*lepp' points to the matching entry, otherwise '*lepp' is
166 * undefined.
168 static int
169 logtab_findent(FILE *fd, char *buffer, char *path, char *tag, int state,
170 struct logtab_ent **lepp)
172 boolean_t found = B_FALSE;
174 while (!found && (logtab_getent(fd, lepp) > 0)) {
175 found = B_TRUE;
176 if (buffer != NULL)
177 found = strcmp(buffer, (*lepp)->le_buffer) == 0;
178 if (path != NULL)
179 found = found && (strcmp(path, (*lepp)->le_path) == 0);
180 if (tag != NULL)
181 found = found && (strcmp(tag, (*lepp)->le_tag) == 0);
182 if (state != -1)
183 found = found && (state == (*lepp)->le_state);
184 if (!found)
185 logtab_ent_free(*lepp);
188 return (found ? 0 : ENOENT);
190 #endif
193 * Remove all entries which match the search criteria.
194 * If 'buffer' != NULL, then buffer is matched.
195 * If 'path' != NULL, then path is matched.
196 * If 'tag' != NULL, then tag is matched.
197 * If 'state' != -1, then state is matched.
198 * 'buffer', 'path' and 'tag' can all be non-NULL, which means the entry must
199 * satisfy all requirements.
200 * The file is assumed to be locked.
201 * Read the entries into a linked list of logtab_ent structures
202 * minus the entries to be removed, then truncate the nfslogtab
203 * file and write it back to the file from the linked list.
205 * On success returns 0, -1 otherwise.
206 * Entry not found is treated as success since it was going to be removed
207 * anyway.
210 logtab_rement(FILE *fd, char *buffer, char *path, char *tag, int state)
212 struct logtab_ent_list *head = NULL, *tail = NULL, *tmpl;
213 struct logtab_ent *lep;
214 int remcnt = 0; /* remove count */
215 int error = 0;
216 boolean_t found;
218 rewind(fd);
219 while ((error = logtab_getent(fd, &lep)) > 0) {
220 found = B_TRUE;
221 if (buffer != NULL)
222 found = strcmp(buffer, lep->le_buffer) == 0;
223 if (path != NULL)
224 found = found && (strcmp(path, lep->le_path) == 0);
225 if (tag != NULL)
226 found = found && (strcmp(tag, lep->le_tag) == 0);
227 if (state != -1)
228 found = found && (state == lep->le_state);
229 if (found) {
230 remcnt++;
231 logtab_ent_free(lep);
232 } else {
233 tmpl = (struct logtab_ent_list *)
234 malloc(sizeof (struct logtab_ent));
235 if (tmpl == NULL) {
236 error = ENOENT;
237 break;
240 tmpl->lel_le = lep;
241 tmpl->lel_next = NULL;
242 if (head == NULL) {
244 * empty list
246 head = tail = tmpl;
247 } else {
249 * Add to the end of the list and remember
250 * the new last element.
252 tail->lel_next = tmpl;
253 tail = tmpl; /* remember the last element */
258 if (error)
259 goto deallocate;
261 if (remcnt == 0) {
263 * Entry not found, nothing to do
265 goto deallocate;
268 if (ftruncate(fileno(fd), 0) < 0) {
269 error = -1;
270 goto deallocate;
273 for (tmpl = head; tmpl != NULL; tmpl = tmpl->lel_next)
274 (void) logtab_putent(fd, tmpl->lel_le);
276 deallocate:
277 logtab_ent_list_free(head);
279 return (error);
283 * Deactivate all entries matching search criteria.
284 * If 'buffer' != NULL then match buffer.
285 * If 'path' != NULL then match path.
286 * If 'tag' != NULL then match tag.
287 * Note that 'buffer', 'path' and 'tag' can al be non-null at the same time.
289 * Rewrites the nfslogtab file with the updated state for each entry.
290 * Assumes the nfslogtab file has been locked for writing.
291 * Returns 0 on success, -1 on failure.
294 logtab_deactivate(FILE *fd, char *buffer, char *path, char *tag)
296 struct logtab_ent_list *lelp, *head = NULL, *tail = NULL;
297 struct logtab_ent *lep;
298 boolean_t found;
299 int error = 0;
300 int count = 0;
302 rewind(fd);
303 while ((error = logtab_getent(fd, &lep)) > 0) {
304 found = B_TRUE;
305 if (buffer != NULL)
306 found = strcmp(buffer, lep->le_buffer) == 0;
307 if (path != NULL)
308 found = found && (strcmp(path, lep->le_path) == 0);
309 if (tag != NULL)
310 found = found && (strcmp(tag, lep->le_tag) == 0);
311 if (found && (lep->le_state == LES_ACTIVE)) {
312 count++;
313 lep->le_state = LES_INACTIVE;
316 lelp = (struct logtab_ent_list *)
317 malloc(sizeof (struct logtab_ent));
318 if (lelp == NULL) {
319 error = ENOENT;
320 break;
323 lelp->lel_le = lep;
324 lelp->lel_next = NULL;
325 if (head == NULL) {
327 * empty list
329 head = tail = lelp;
330 } else {
332 * Add to the end of the list and remember
333 * the new last element.
335 tail->lel_next = lelp;
336 tail = lelp; /* remember the last element */
340 if (error)
341 goto deallocate;
343 if (count == 0) {
345 * done
347 error = 0;
348 goto deallocate;
351 if (ftruncate(fileno(fd), 0) < 0) {
352 error = -1;
353 goto deallocate;
356 for (lelp = head; lelp != NULL; lelp = lelp->lel_next)
357 (void) logtab_putent(fd, lelp->lel_le);
359 deallocate:
360 logtab_ent_list_free(head);
362 return (error);
366 * Deactivates all entries if nfslogtab exists and is older than boot time
367 * This will only happen the first time it is called.
368 * Assumes 'fd' has been locked by the caller.
369 * Returns 0 on success, otherwise -1.
372 logtab_deactivate_after_boot(FILE *fd)
374 struct stat st;
375 struct utmpx *utmpxp;
376 int error = 0;
378 if ((fstat(fileno(fd), &st) == 0) &&
379 ((utmpxp = getutxent()) != NULL) &&
380 (utmpxp->ut_xtime > st.st_mtime)) {
381 if (logtab_deactivate(fd, NULL, NULL, NULL))
382 error = -1;
385 return (error);
388 void
389 logtab_ent_free(struct logtab_ent *lep)
391 if (lep->le_buffer)
392 free(lep->le_buffer);
393 if (lep->le_path)
394 free(lep->le_path);
395 if (lep->le_tag)
396 free(lep->le_tag);
397 free(lep);
400 static void
401 logtab_ent_list_free(struct logtab_ent_list *head)
403 struct logtab_ent_list *lelp, *next;
405 if (head == NULL)
406 return;
408 for (lelp = head; lelp != NULL; lelp = next) {
409 if (lelp->lel_le != NULL)
410 logtab_ent_free(lelp->lel_le);
411 next = lelp->lel_next;
412 free(lelp);