/* * Get a linked list of all the shares on the system from /etc/dfs/dfstab */ fs_sharelist_t * fs_get_share_list(int *errp) { fs_sharelist_t *newp; fs_sharelist_t *headp; fs_sharelist_t *tailp; FILE *fp; headp = NULL; tailp = NULL; if ((fp = fopen(SHARETAB, "r")) != NULL) { struct share *sharetab_entry; (void) mutex_lock(&sharetab_lock); while (getshare(fp, &sharetab_entry) > 0) { newp = create_sharelist_entry(sharetab_entry, errp); if (newp == NULL) { /* * Out of memory */ fs_free_share_list(headp); (void) mutex_unlock(&sharetab_lock); (void) fclose(fp); return (NULL); } if (headp == NULL) { headp = newp; tailp = newp; } else { tailp->next = newp; tailp = newp; } } /* while (getshare(fp, &sharetab_entry) != 0) */ (void) mutex_unlock(&sharetab_lock); (void) fclose(fp); } else { *errp = errno; } /* if ((fp = fopen(SHARETAB, "r")) != NULL) */ /* * Caller must free the mount list */ return (headp); } /* fs_get_share_list */
void check_sharetab() { FILE *f; struct stat st; static timestruc_t last_sharetab_time; timestruc_t prev_sharetab_time; struct share *sh; struct sh_list *shp, *shp_prev; int res, c = 0; /* * read in /etc/dfs/sharetab if it has changed */ if (stat(SHARETAB, &st) != 0) { syslog(LOG_ERR, "Cannot stat %s: %m", SHARETAB); return; } if (st.st_mtim.tv_sec == last_sharetab_time.tv_sec && st.st_mtim.tv_nsec == last_sharetab_time.tv_nsec) { /* * No change. */ return; } /* * Remember the mod time, then after getting the * write lock check again. If another thread * already did the update, then there's no * work to do. */ prev_sharetab_time = last_sharetab_time; (void) rw_wrlock(&sharetab_lock); if (prev_sharetab_time.tv_sec != last_sharetab_time.tv_sec || prev_sharetab_time.tv_nsec != last_sharetab_time.tv_nsec) { (void) rw_unlock(&sharetab_lock); return; } f = fopen(SHARETAB, "r+"); if (f == NULL) { syslog(LOG_ERR, "Cannot open %s: %m", SHARETAB); (void) rw_unlock(&sharetab_lock); return; } /* * Lock the file so that unshare can't * truncate it while we're reading */ if (lockf(fileno(f), F_LOCK, 0L) < 0) { syslog(LOG_ERR, "Cannot lock %s: %m", SHARETAB); (void) rw_unlock(&sharetab_lock); (void) fclose(f); return; } /* * Once we are sure /etc/dfs/sharetab has been * modified, flush netgroup cache entries. */ netgrp_cache_flush(); sh_free(share_list); /* free old list */ share_list = NULL; while ((res = getshare(f, &sh)) > 0) { c++; if (strcmp(sh->sh_fstype, "nfs") != 0) continue; shp = malloc(sizeof (*shp)); if (shp == NULL) goto alloc_failed; if (share_list == NULL) share_list = shp; else /* LINTED not used before set */ shp_prev->shl_next = shp; shp_prev = shp; shp->shl_next = NULL; shp->shl_sh = sharedup(sh); if (shp->shl_sh == NULL) goto alloc_failed; } if (res < 0) syslog(LOG_ERR, "%s: invalid at line %d\n", SHARETAB, c + 1); if (stat(SHARETAB, &st) != 0) { syslog(LOG_ERR, "Cannot stat %s: %m", SHARETAB); (void) rw_unlock(&sharetab_lock); return; } last_sharetab_time = st.st_mtim; (void) fclose(f); (void) rw_unlock(&sharetab_lock); return; alloc_failed: syslog(LOG_ERR, "check_sharetab: no memory"); sh_free(share_list); share_list = NULL; (void) fclose(f); (void) rw_unlock(&sharetab_lock); }