mounttab.c revision 256281
197403Sobrien/* 297403Sobrien * Copyright (c) 1999 Martin Blapp 3169691Skan * All rights reserved. 497403Sobrien * 597403Sobrien * Redistribution and use in source and binary forms, with or without 697403Sobrien * modification, are permitted provided that the following conditions 797403Sobrien * are met: 897403Sobrien * 1. Redistributions of source code must retain the above copyright 997403Sobrien * notice, this list of conditions and the following disclaimer. 1097403Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1197403Sobrien * notice, this list of conditions and the following disclaimer in the 1297403Sobrien * documentation and/or other materials provided with the distribution. 1397403Sobrien * 1497403Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1597403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1697403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1797403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1897403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19169691Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2097403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2197403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2297403Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2397403Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2497403Sobrien * SUCH DAMAGE. 2597403Sobrien * 2697403Sobrien */ 2797403Sobrien 2897403Sobrien#include <sys/cdefs.h> 2997403Sobrien__FBSDID("$FreeBSD: stable/10/usr.sbin/rpc.umntall/mounttab.c 201252 2009-12-30 06:36:42Z ed $"); 3097403Sobrien 31169691Skan#include <sys/syslog.h> 32169691Skan 33169691Skan#include <rpc/rpc.h> 34169691Skan#include <rpcsvc/mount.h> 3597403Sobrien 36132720Skan#include <err.h> 37132720Skan#include <errno.h> 3897403Sobrien#include <limits.h> 3997403Sobrien#include <stdio.h> 4097403Sobrien#include <stdlib.h> 41132720Skan#include <string.h> 42132720Skan#include <unistd.h> 4397403Sobrien 44169691Skan#include "mounttab.h" 4597403Sobrien 46169691Skanstruct mtablist *mtabhead; 47169691Skan 4897403Sobrienstatic void badline(const char *field, const char *bad); 4997403Sobrien 5097403Sobrien/* 5197403Sobrien * Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem, 5297403Sobrien * so the client can notify the NFS server even after reboot. 53132720Skan */ 54132720Skanint 55132720Skanadd_mtab(char *hostp, char *dirp) 56132720Skan{ 57132720Skan FILE *mtabfile; 58132720Skan 59132720Skan if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL) 60132720Skan return (0); 61132720Skan else { 6297403Sobrien fprintf(mtabfile, "%ld\t%s\t%s\n", 6397403Sobrien (long)time(NULL), hostp, dirp); 6497403Sobrien fclose(mtabfile); 6597403Sobrien return (1); 6697403Sobrien } 6797403Sobrien} 6897403Sobrien 6997403Sobrien/* 7097403Sobrien * Read mounttab line for line and return struct mtablist. 7197403Sobrien */ 7297403Sobrienint 7397403Sobrienread_mtab(void) 7497403Sobrien{ 7597403Sobrien struct mtablist **mtabpp, *mtabp; 76132720Skan char *hostp, *dirp, *cp; 77132720Skan char str[STRSIZ]; 78132720Skan char *timep, *endp; 79132720Skan time_t actiontime; 80132720Skan u_long ultmp; 81132720Skan FILE *mtabfile; 82132720Skan 83132720Skan if ((mtabfile = fopen(PATH_MOUNTTAB, "r")) == NULL) { 84132720Skan if (errno == ENOENT) 85132720Skan return (0); 86132720Skan else { 8797403Sobrien syslog(LOG_ERR, "can't open %s", PATH_MOUNTTAB); 88132720Skan return (0); 89132720Skan } 90132720Skan } 91132720Skan actiontime = 0; 92132720Skan mtabpp = &mtabhead; 93132720Skan while (fgets(str, STRSIZ, mtabfile) != NULL) { 94132720Skan cp = str; 95132720Skan errno = 0; 96132720Skan if (*cp == '#' || *cp == ' ' || *cp == '\n') 97132720Skan continue; 98132720Skan timep = strsep(&cp, " \t\n"); 99132720Skan if (timep == NULL || *timep == '\0') { 100132720Skan badline("time", timep); 101132720Skan continue; 102132720Skan } 103132720Skan hostp = strsep(&cp, " \t\n"); 104132720Skan if (hostp == NULL || *hostp == '\0') { 105132720Skan badline("host", hostp); 106132720Skan continue; 107132720Skan } 108132720Skan dirp = strsep(&cp, " \t\n"); 109132720Skan if (dirp == NULL || *dirp == '\0') { 110132720Skan badline("dir", dirp); 11197403Sobrien continue; 11297403Sobrien } 113132720Skan ultmp = strtoul(timep, &endp, 10); 114132720Skan if (ultmp == ULONG_MAX || *endp != '\0') { 11597403Sobrien badline("time", timep); 11697403Sobrien continue; 11797403Sobrien } 11897403Sobrien actiontime = ultmp; 11997403Sobrien if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) { 120132720Skan syslog(LOG_ERR, "malloc"); 121132720Skan fclose(mtabfile); 12297403Sobrien return (0); 123132720Skan } 12497403Sobrien mtabp->mtab_time = actiontime; 125132720Skan memmove(mtabp->mtab_host, hostp, MNTNAMLEN); 126132720Skan mtabp->mtab_host[MNTNAMLEN - 1] = '\0'; 127132720Skan memmove(mtabp->mtab_dirp, dirp, MNTPATHLEN); 128132720Skan mtabp->mtab_dirp[MNTPATHLEN - 1] = '\0'; 129132720Skan mtabp->mtab_next = (struct mtablist *)NULL; 130132720Skan *mtabpp = mtabp; 131132720Skan mtabpp = &mtabp->mtab_next; 132132720Skan } 133132720Skan fclose(mtabfile); 134132720Skan return (1); 135132720Skan} 136132720Skan 137132720Skan/* 138132720Skan * Rewrite PATH_MOUNTTAB from scratch and skip bad entries. 139132720Skan * Unlink PATH_MOUNTAB if no entry is left. 140132720Skan */ 141132720Skanint 142132720Skanwrite_mtab(int verbose) 143132720Skan{ 144132720Skan struct mtablist *mtabp, *mp; 145132720Skan FILE *mtabfile; 146132720Skan int line; 147132720Skan 148132720Skan if ((mtabfile = fopen(PATH_MOUNTTAB, "w")) == NULL) { 149132720Skan syslog(LOG_ERR, "can't write to %s", PATH_MOUNTTAB); 150132720Skan return (0); 151132720Skan } 152132720Skan line = 0; 153132720Skan for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 154132720Skan if (mtabp->mtab_host[0] == '\0') 155132720Skan continue; 156132720Skan /* Skip if a later (hence more recent) entry is identical. */ 157132720Skan for (mp = mtabp->mtab_next; mp != NULL; mp = mp->mtab_next) 158132720Skan if (strcmp(mtabp->mtab_host, mp->mtab_host) == 0 && 159132720Skan strcmp(mtabp->mtab_dirp, mp->mtab_dirp) == 0) 160132720Skan break; 161132720Skan if (mp != NULL) 162132720Skan continue; 163132720Skan 164132720Skan fprintf(mtabfile, "%ld\t%s\t%s\n", 165132720Skan (long)mtabp->mtab_time, mtabp->mtab_host, 166132720Skan mtabp->mtab_dirp); 167132720Skan if (verbose) 168132720Skan warnx("write mounttab entry %s:%s", 169132720Skan mtabp->mtab_host, mtabp->mtab_dirp); 170132720Skan line++; 171132720Skan } 172132720Skan fclose(mtabfile); 173132720Skan if (line == 0) { 174132720Skan if (unlink(PATH_MOUNTTAB) == -1) { 175132720Skan syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 176132720Skan return (0); 177132720Skan } 178132720Skan } 179132720Skan return (1); 180132720Skan} 181132720Skan 182132720Skan/* 183132720Skan * Mark the entries as clean where RPC calls have been done successfully. 184132720Skan */ 185132720Skanvoid 186132720Skanclean_mtab(char *hostp, char *dirp, int verbose) 187132720Skan{ 188132720Skan struct mtablist *mtabp; 189132720Skan char *host; 190132720Skan 191132720Skan /* Copy hostp in case it points to an entry that we are zeroing out. */ 192132720Skan host = strdup(hostp); 193132720Skan for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 194132720Skan if (strcmp(mtabp->mtab_host, host) != 0) 195132720Skan continue; 196132720Skan if (dirp != NULL && strcmp(mtabp->mtab_dirp, dirp) != 0) 197169691Skan continue; 198169691Skan 199132720Skan if (verbose) 200132720Skan warnx("delete mounttab entry%s %s:%s", 201132720Skan (dirp == NULL) ? " by host" : "", 202132720Skan mtabp->mtab_host, mtabp->mtab_dirp); 203132720Skan bzero(mtabp->mtab_host, MNTNAMLEN); 204132720Skan } 205132720Skan free(host); 206132720Skan} 207132720Skan 208132720Skan/* 209132720Skan * Free struct mtablist mtab. 210132720Skan */ 211132720Skanvoid 212132720Skanfree_mtab(void) 213132720Skan{ 214132720Skan struct mtablist *mtabp; 215132720Skan 216132720Skan while ((mtabp = mtabhead) != NULL) { 217132720Skan mtabhead = mtabhead->mtab_next; 21897403Sobrien free(mtabp); 21997403Sobrien } 220132720Skan} 221132720Skan 222132720Skan/* 223117397Skan * Print bad lines to syslog. 224132720Skan */ 225132720Skanstatic void 226132720Skanbadline(const char *field, const char *bad) 227132720Skan{ 228132720Skan syslog(LOG_ERR, "bad mounttab %s field '%s'", field, 229132720Skan (bad == NULL) ? "<null>" : bad); 230132720Skan} 231132720Skan