mounttab.c revision 81070
153494Sdillon/* 253494Sdillon * Copyright (c) 1999 Martin Blapp 353494Sdillon * All rights reserved. 453494Sdillon * 553494Sdillon * Redistribution and use in source and binary forms, with or without 653494Sdillon * modification, are permitted provided that the following conditions 753494Sdillon * are met: 853494Sdillon * 1. Redistributions of source code must retain the above copyright 953494Sdillon * notice, this list of conditions and the following disclaimer. 1053494Sdillon * 2. Redistributions in binary form must reproduce the above copyright 1153494Sdillon * notice, this list of conditions and the following disclaimer in the 1253494Sdillon * documentation and/or other materials provided with the distribution. 1353494Sdillon * 1453494Sdillon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1553494Sdillon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1653494Sdillon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1753494Sdillon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1853494Sdillon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1953494Sdillon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2053494Sdillon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2153494Sdillon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2253494Sdillon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2353494Sdillon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2453494Sdillon * SUCH DAMAGE. 2553494Sdillon * 2653494Sdillon */ 2753494Sdillon 2853494Sdillon#ifndef lint 2953494Sdillonstatic const char rcsid[] = 3053494Sdillon "$FreeBSD: head/usr.sbin/rpc.umntall/mounttab.c 81070 2001-08-02 21:46:21Z iedowse $"; 3153494Sdillon#endif /* not lint */ 3253494Sdillon 3353494Sdillon#include <sys/syslog.h> 3453494Sdillon 3553494Sdillon#include <rpc/rpc.h> 3653494Sdillon#include <nfs/rpcv2.h> 3753494Sdillon 3853494Sdillon#include <err.h> 3953494Sdillon#include <errno.h> 4080146Siedowse#include <limits.h> 4153494Sdillon#include <stdio.h> 4253494Sdillon#include <stdlib.h> 4353494Sdillon#include <string.h> 4453494Sdillon#include <unistd.h> 4553494Sdillon 4653494Sdillon#include "mounttab.h" 4753494Sdillon 4853494Sdillonstruct mtablist *mtabhead; 4953494Sdillon 5080146Siedowsestatic void badline(char *field, char *bad); 5180146Siedowse 5253494Sdillon/* 5353494Sdillon * Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem, 5453494Sdillon * so the client can notify the NFS server even after reboot. 5553494Sdillon */ 5653494Sdillonint 5753494Sdillonadd_mtab(char *hostp, char *dirp) { 5853494Sdillon FILE *mtabfile; 5953494Sdillon 6053494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL) 6153494Sdillon return (0); 6253494Sdillon else { 6366814Sbde fprintf(mtabfile, "%ld\t%s\t%s\n", 6480146Siedowse (long)time(NULL), hostp, dirp); 6553494Sdillon fclose(mtabfile); 6653494Sdillon return (1); 6753494Sdillon } 6853494Sdillon} 6953494Sdillon 7053494Sdillon/* 7153494Sdillon * Read mounttab line for line and return struct mtablist. 7253494Sdillon */ 7353494Sdillonint 7480146Siedowseread_mtab() { 7580146Siedowse struct mtablist **mtabpp, *mtabp; 7653494Sdillon char *hostp, *dirp, *cp; 7753494Sdillon char str[STRSIZ]; 7880146Siedowse char *timep, *endp; 7953494Sdillon time_t time; 8080146Siedowse u_long ultmp; 8153494Sdillon FILE *mtabfile; 8253494Sdillon 8353494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "r")) == NULL) { 8453494Sdillon if (errno == ENOENT) 8553494Sdillon return (0); 8653494Sdillon else { 8753494Sdillon syslog(LOG_ERR, "can't open %s", PATH_MOUNTTAB); 8853494Sdillon return (0); 8953494Sdillon } 9053494Sdillon } 9153494Sdillon time = 0; 9253494Sdillon mtabpp = &mtabhead; 9353494Sdillon while (fgets(str, STRSIZ, mtabfile) != NULL) { 9453494Sdillon cp = str; 9553494Sdillon errno = 0; 9653494Sdillon if (*cp == '#' || *cp == ' ' || *cp == '\n') 9753494Sdillon continue; 9853494Sdillon timep = strsep(&cp, " \t\n"); 9980146Siedowse if (timep == NULL || *timep == '\0') { 10080146Siedowse badline("time", timep); 10153494Sdillon continue; 10253494Sdillon } 10353494Sdillon hostp = strsep(&cp, " \t\n"); 10480146Siedowse if (hostp == NULL || *hostp == '\0') { 10580146Siedowse badline("host", hostp); 10653494Sdillon continue; 10753494Sdillon } 10853494Sdillon dirp = strsep(&cp, " \t\n"); 10980146Siedowse if (dirp == NULL || *dirp == '\0') { 11080146Siedowse badline("dir", dirp); 11153494Sdillon continue; 11253494Sdillon } 11380146Siedowse ultmp = strtoul(timep, &endp, 10); 11480146Siedowse if (ultmp == ULONG_MAX || *endp != '\0') { 11580146Siedowse badline("time", timep); 11653494Sdillon continue; 11753494Sdillon } 11880146Siedowse time = ultmp; 11953494Sdillon if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) { 12053494Sdillon syslog(LOG_ERR, "malloc"); 12153494Sdillon fclose(mtabfile); 12253494Sdillon return (0); 12353494Sdillon } 12453494Sdillon mtabp->mtab_time = time; 12553494Sdillon memmove(mtabp->mtab_host, hostp, RPCMNT_NAMELEN); 12653494Sdillon mtabp->mtab_host[RPCMNT_NAMELEN - 1] = '\0'; 12753494Sdillon memmove(mtabp->mtab_dirp, dirp, RPCMNT_PATHLEN); 12853494Sdillon mtabp->mtab_dirp[RPCMNT_PATHLEN - 1] = '\0'; 12953494Sdillon mtabp->mtab_next = (struct mtablist *)NULL; 13053494Sdillon *mtabpp = mtabp; 13153494Sdillon mtabpp = &mtabp->mtab_next; 13253494Sdillon } 13353494Sdillon fclose(mtabfile); 13453494Sdillon return (1); 13553494Sdillon} 13653494Sdillon 13753494Sdillon/* 13853494Sdillon * Rewrite PATH_MOUNTTAB from scratch and skip bad entries. 13953494Sdillon * Unlink PATH_MOUNTAB if no entry is left. 14053494Sdillon */ 14153494Sdillonint 14280146Siedowsewrite_mtab(int verbose) { 14380146Siedowse struct mtablist *mtabp, *mp; 14453494Sdillon FILE *mtabfile; 14553494Sdillon int line; 14653494Sdillon 14753494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "w")) == NULL) { 14853494Sdillon syslog(LOG_ERR, "can't write to %s", PATH_MOUNTTAB); 14953494Sdillon return (0); 15053494Sdillon } 15153494Sdillon line = 0; 15253494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 15380146Siedowse if (mtabp->mtab_host[0] == '\0') 15480146Siedowse continue; 15580146Siedowse /* Skip if a later (hence more recent) entry is identical. */ 15680146Siedowse for (mp = mtabp->mtab_next; mp != NULL; mp = mp->mtab_next) 15780146Siedowse if (strcmp(mtabp->mtab_host, mp->mtab_host) == 0 && 15880146Siedowse strcmp(mtabp->mtab_dirp, mp->mtab_dirp) == 0) 15980146Siedowse break; 16080146Siedowse if (mp != NULL) 16180146Siedowse continue; 16280146Siedowse 16380146Siedowse fprintf(mtabfile, "%ld\t%s\t%s\n", 16480146Siedowse (long)mtabp->mtab_time, mtabp->mtab_host, 16580146Siedowse mtabp->mtab_dirp); 16680146Siedowse if (verbose) 16780146Siedowse warnx("write mounttab entry %s:%s", 16880146Siedowse mtabp->mtab_host, mtabp->mtab_dirp); 16980146Siedowse line++; 17053494Sdillon } 17153494Sdillon fclose(mtabfile); 17253494Sdillon if (line == 0) { 17353494Sdillon if (unlink(PATH_MOUNTTAB) == -1) { 17453494Sdillon syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 17553494Sdillon return (0); 17653494Sdillon } 17753494Sdillon } 17853494Sdillon return (1); 17953494Sdillon} 18053494Sdillon 18153494Sdillon/* 18253494Sdillon * Mark the entries as clean where RPC calls have been done successfully. 18353494Sdillon */ 18453494Sdillonvoid 18580146Siedowseclean_mtab(char *hostp, char *dirp, int verbose) { 18653494Sdillon struct mtablist *mtabp; 18753494Sdillon char *host; 18853494Sdillon 18980146Siedowse /* Copy hostp in case it points to an entry that we are zeroing out. */ 19053494Sdillon host = strdup(hostp); 19153494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 19281070Siedowse if (strcmp(mtabp->mtab_host, host) != 0) 19380146Siedowse continue; 19480146Siedowse if (dirp != NULL && strcmp(mtabp->mtab_dirp, dirp) != 0) 19580146Siedowse continue; 19680146Siedowse 19780146Siedowse if (verbose) 19880146Siedowse warnx("delete mounttab entry%s %s:%s", 19980146Siedowse (dirp == NULL) ? " by host" : "", 20080146Siedowse mtabp->mtab_host, mtabp->mtab_dirp); 20180146Siedowse bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 20253494Sdillon } 20353494Sdillon free(host); 20453494Sdillon} 20553494Sdillon 20653494Sdillon/* 20753494Sdillon * Free struct mtablist mtab. 20853494Sdillon */ 20953494Sdillonvoid 21053494Sdillonfree_mtab() { 21153494Sdillon struct mtablist *mtabp; 21253494Sdillon 21380146Siedowse while ((mtabp = mtabhead) != NULL) { 21480146Siedowse mtabhead = mtabhead->mtab_next; 21553494Sdillon free(mtabp); 21653494Sdillon } 21753494Sdillon} 21853494Sdillon 21953494Sdillon/* 22053494Sdillon * Print bad lines to syslog. 22153494Sdillon */ 22280146Siedowsestatic void 22380146Siedowsebadline(char *field, char *bad) { 22480146Siedowse syslog(LOG_ERR, "bad mounttab %s field '%s'", field, 22580146Siedowse (bad == NULL) ? "<null>" : bad); 22653494Sdillon} 227