mounttab.c revision 201135
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 28114601Sobrien#include <sys/cdefs.h> 29114601Sobrien__FBSDID("$FreeBSD: head/usr.sbin/rpc.umntall/mounttab.c 201135 2009-12-28 17:57:37Z delphij $"); 3053494Sdillon 3153494Sdillon#include <sys/syslog.h> 3253494Sdillon 3353494Sdillon#include <rpc/rpc.h> 34194880Sdfr#include <rpcsvc/mount.h> 3553494Sdillon 3653494Sdillon#include <err.h> 3753494Sdillon#include <errno.h> 3880146Siedowse#include <limits.h> 3953494Sdillon#include <stdio.h> 4053494Sdillon#include <stdlib.h> 4153494Sdillon#include <string.h> 4253494Sdillon#include <unistd.h> 4353494Sdillon 4453494Sdillon#include "mounttab.h" 4553494Sdillon 4653494Sdillonstruct mtablist *mtabhead; 4753494Sdillon 48201135Sdelphijstatic void badline(const char *field, const char *bad); 4980146Siedowse 5053494Sdillon/* 5153494Sdillon * Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem, 5253494Sdillon * so the client can notify the NFS server even after reboot. 5353494Sdillon */ 5453494Sdillonint 5553494Sdillonadd_mtab(char *hostp, char *dirp) { 5653494Sdillon FILE *mtabfile; 5753494Sdillon 5853494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL) 5953494Sdillon return (0); 6053494Sdillon else { 6166814Sbde fprintf(mtabfile, "%ld\t%s\t%s\n", 6280146Siedowse (long)time(NULL), hostp, dirp); 6353494Sdillon fclose(mtabfile); 6453494Sdillon return (1); 6553494Sdillon } 6653494Sdillon} 6753494Sdillon 6853494Sdillon/* 6953494Sdillon * Read mounttab line for line and return struct mtablist. 7053494Sdillon */ 7153494Sdillonint 72201135Sdelphijread_mtab(void) { 7380146Siedowse struct mtablist **mtabpp, *mtabp; 7453494Sdillon char *hostp, *dirp, *cp; 7553494Sdillon char str[STRSIZ]; 7680146Siedowse char *timep, *endp; 77201135Sdelphij time_t actiontime; 7880146Siedowse u_long ultmp; 7953494Sdillon FILE *mtabfile; 8053494Sdillon 8153494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "r")) == NULL) { 8253494Sdillon if (errno == ENOENT) 8353494Sdillon return (0); 8453494Sdillon else { 8553494Sdillon syslog(LOG_ERR, "can't open %s", PATH_MOUNTTAB); 8653494Sdillon return (0); 8753494Sdillon } 8853494Sdillon } 89201135Sdelphij actiontime = 0; 9053494Sdillon mtabpp = &mtabhead; 9153494Sdillon while (fgets(str, STRSIZ, mtabfile) != NULL) { 9253494Sdillon cp = str; 9353494Sdillon errno = 0; 9453494Sdillon if (*cp == '#' || *cp == ' ' || *cp == '\n') 9553494Sdillon continue; 9653494Sdillon timep = strsep(&cp, " \t\n"); 9780146Siedowse if (timep == NULL || *timep == '\0') { 9880146Siedowse badline("time", timep); 9953494Sdillon continue; 10053494Sdillon } 10153494Sdillon hostp = strsep(&cp, " \t\n"); 10280146Siedowse if (hostp == NULL || *hostp == '\0') { 10380146Siedowse badline("host", hostp); 10453494Sdillon continue; 10553494Sdillon } 10653494Sdillon dirp = strsep(&cp, " \t\n"); 10780146Siedowse if (dirp == NULL || *dirp == '\0') { 10880146Siedowse badline("dir", dirp); 10953494Sdillon continue; 11053494Sdillon } 11180146Siedowse ultmp = strtoul(timep, &endp, 10); 11280146Siedowse if (ultmp == ULONG_MAX || *endp != '\0') { 11380146Siedowse badline("time", timep); 11453494Sdillon continue; 11553494Sdillon } 116201135Sdelphij actiontime = ultmp; 11753494Sdillon if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) { 11853494Sdillon syslog(LOG_ERR, "malloc"); 11953494Sdillon fclose(mtabfile); 12053494Sdillon return (0); 12153494Sdillon } 122201135Sdelphij mtabp->mtab_time = actiontime; 123194880Sdfr memmove(mtabp->mtab_host, hostp, MNTNAMLEN); 124194880Sdfr mtabp->mtab_host[MNTNAMLEN - 1] = '\0'; 125194880Sdfr memmove(mtabp->mtab_dirp, dirp, MNTPATHLEN); 126194880Sdfr mtabp->mtab_dirp[MNTPATHLEN - 1] = '\0'; 12753494Sdillon mtabp->mtab_next = (struct mtablist *)NULL; 12853494Sdillon *mtabpp = mtabp; 12953494Sdillon mtabpp = &mtabp->mtab_next; 13053494Sdillon } 13153494Sdillon fclose(mtabfile); 13253494Sdillon return (1); 13353494Sdillon} 13453494Sdillon 13553494Sdillon/* 13653494Sdillon * Rewrite PATH_MOUNTTAB from scratch and skip bad entries. 13753494Sdillon * Unlink PATH_MOUNTAB if no entry is left. 13853494Sdillon */ 13953494Sdillonint 14080146Siedowsewrite_mtab(int verbose) { 14180146Siedowse struct mtablist *mtabp, *mp; 14253494Sdillon FILE *mtabfile; 14353494Sdillon int line; 14453494Sdillon 14553494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "w")) == NULL) { 14653494Sdillon syslog(LOG_ERR, "can't write to %s", PATH_MOUNTTAB); 14753494Sdillon return (0); 14853494Sdillon } 14953494Sdillon line = 0; 15053494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 15180146Siedowse if (mtabp->mtab_host[0] == '\0') 15280146Siedowse continue; 15380146Siedowse /* Skip if a later (hence more recent) entry is identical. */ 15480146Siedowse for (mp = mtabp->mtab_next; mp != NULL; mp = mp->mtab_next) 15580146Siedowse if (strcmp(mtabp->mtab_host, mp->mtab_host) == 0 && 15680146Siedowse strcmp(mtabp->mtab_dirp, mp->mtab_dirp) == 0) 15780146Siedowse break; 15880146Siedowse if (mp != NULL) 15980146Siedowse continue; 16080146Siedowse 16180146Siedowse fprintf(mtabfile, "%ld\t%s\t%s\n", 16280146Siedowse (long)mtabp->mtab_time, mtabp->mtab_host, 16380146Siedowse mtabp->mtab_dirp); 16480146Siedowse if (verbose) 16580146Siedowse warnx("write mounttab entry %s:%s", 16680146Siedowse mtabp->mtab_host, mtabp->mtab_dirp); 16780146Siedowse line++; 16853494Sdillon } 16953494Sdillon fclose(mtabfile); 17053494Sdillon if (line == 0) { 17153494Sdillon if (unlink(PATH_MOUNTTAB) == -1) { 17253494Sdillon syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 17353494Sdillon return (0); 17453494Sdillon } 17553494Sdillon } 17653494Sdillon return (1); 17753494Sdillon} 17853494Sdillon 17953494Sdillon/* 18053494Sdillon * Mark the entries as clean where RPC calls have been done successfully. 18153494Sdillon */ 18253494Sdillonvoid 18380146Siedowseclean_mtab(char *hostp, char *dirp, int verbose) { 18453494Sdillon struct mtablist *mtabp; 18553494Sdillon char *host; 18653494Sdillon 18780146Siedowse /* Copy hostp in case it points to an entry that we are zeroing out. */ 18853494Sdillon host = strdup(hostp); 18953494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 19081070Siedowse if (strcmp(mtabp->mtab_host, host) != 0) 19180146Siedowse continue; 19280146Siedowse if (dirp != NULL && strcmp(mtabp->mtab_dirp, dirp) != 0) 19380146Siedowse continue; 19480146Siedowse 19580146Siedowse if (verbose) 19680146Siedowse warnx("delete mounttab entry%s %s:%s", 19780146Siedowse (dirp == NULL) ? " by host" : "", 19880146Siedowse mtabp->mtab_host, mtabp->mtab_dirp); 199194880Sdfr bzero(mtabp->mtab_host, MNTNAMLEN); 20053494Sdillon } 20153494Sdillon free(host); 20253494Sdillon} 20353494Sdillon 20453494Sdillon/* 20553494Sdillon * Free struct mtablist mtab. 20653494Sdillon */ 20753494Sdillonvoid 20853494Sdillonfree_mtab() { 20953494Sdillon struct mtablist *mtabp; 21053494Sdillon 21180146Siedowse while ((mtabp = mtabhead) != NULL) { 21280146Siedowse mtabhead = mtabhead->mtab_next; 21353494Sdillon free(mtabp); 21453494Sdillon } 21553494Sdillon} 21653494Sdillon 21753494Sdillon/* 21853494Sdillon * Print bad lines to syslog. 21953494Sdillon */ 22080146Siedowsestatic void 221201135Sdelphijbadline(const char *field, const char *bad) { 22280146Siedowse syslog(LOG_ERR, "bad mounttab %s field '%s'", field, 22380146Siedowse (bad == NULL) ? "<null>" : bad); 22453494Sdillon} 225