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"
30 * Manipulates the nfslogtab
37 #include <sys/types.h>
47 #include "nfslogtab.h"
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.
65 logtab_getent(FILE *fd
, struct logtab_ent
**lepp
)
67 char line
[MAXBUFSIZE
+ 1];
71 struct logtab_ent
*lep
= NULL
;
74 if ((lep
= (struct logtab_ent
*)malloc(sizeof (*lep
))) == NULL
) {
77 (void) memset((char *)lep
, 0, sizeof (*lep
));
79 if ((p
= fgets(line
, MAXBUFSIZE
, fd
)) == NULL
) {
84 line
[strlen(line
) - 1] = '\0';
86 tmp
= (char *)strtok_r(p
, w
, &lasts
);
91 if ((lep
->le_buffer
= strdup(tmp
)) == NULL
) {
96 tmp
= (char *)strtok_r(NULL
, w
, &lasts
);
101 if ((lep
->le_path
= strdup(tmp
)) == NULL
) {
106 tmp
= (char *)strtok_r(NULL
, w
, &lasts
);
111 if ((lep
->le_tag
= strdup(tmp
)) == NULL
) {
116 tmp
= (char *)strtok_r(NULL
, w
, &lasts
);
121 lep
->le_state
= atoi(tmp
);
127 logtab_ent_free(lep
);
133 * Append an entry to the logtab file.
136 logtab_putent(FILE *fd
, struct logtab_ent
*lep
)
140 if (fseek(fd
, 0L, SEEK_END
) < 0)
143 r
= fprintf(fd
, "%s\t%s\t%s\t%d\n",
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
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)) {
177 found
= strcmp(buffer
, (*lepp
)->le_buffer
) == 0;
179 found
= found
&& (strcmp(path
, (*lepp
)->le_path
) == 0);
181 found
= found
&& (strcmp(tag
, (*lepp
)->le_tag
) == 0);
183 found
= found
&& (state
== (*lepp
)->le_state
);
185 logtab_ent_free(*lepp
);
188 return (found
? 0 : ENOENT
);
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
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 */
219 while ((error
= logtab_getent(fd
, &lep
)) > 0) {
222 found
= strcmp(buffer
, lep
->le_buffer
) == 0;
224 found
= found
&& (strcmp(path
, lep
->le_path
) == 0);
226 found
= found
&& (strcmp(tag
, lep
->le_tag
) == 0);
228 found
= found
&& (state
== lep
->le_state
);
231 logtab_ent_free(lep
);
233 tmpl
= (struct logtab_ent_list
*)
234 malloc(sizeof (struct logtab_ent
));
241 tmpl
->lel_next
= NULL
;
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 */
263 * Entry not found, nothing to do
268 if (ftruncate(fileno(fd
), 0) < 0) {
273 for (tmpl
= head
; tmpl
!= NULL
; tmpl
= tmpl
->lel_next
)
274 (void) logtab_putent(fd
, tmpl
->lel_le
);
277 logtab_ent_list_free(head
);
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
;
303 while ((error
= logtab_getent(fd
, &lep
)) > 0) {
306 found
= strcmp(buffer
, lep
->le_buffer
) == 0;
308 found
= found
&& (strcmp(path
, lep
->le_path
) == 0);
310 found
= found
&& (strcmp(tag
, lep
->le_tag
) == 0);
311 if (found
&& (lep
->le_state
== LES_ACTIVE
)) {
313 lep
->le_state
= LES_INACTIVE
;
316 lelp
= (struct logtab_ent_list
*)
317 malloc(sizeof (struct logtab_ent
));
324 lelp
->lel_next
= NULL
;
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 */
351 if (ftruncate(fileno(fd
), 0) < 0) {
356 for (lelp
= head
; lelp
!= NULL
; lelp
= lelp
->lel_next
)
357 (void) logtab_putent(fd
, lelp
->lel_le
);
360 logtab_ent_list_free(head
);
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
)
375 struct utmpx
*utmpxp
;
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
))
389 logtab_ent_free(struct logtab_ent
*lep
)
392 free(lep
->le_buffer
);
401 logtab_ent_list_free(struct logtab_ent_list
*head
)
403 struct logtab_ent_list
*lelp
, *next
;
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
;