mounttab.c revision 80146
1233294Sstas/* 255682Smarkm * Copyright (c) 1999 Martin Blapp 3233294Sstas * All rights reserved. 4233294Sstas * 5233294Sstas * Redistribution and use in source and binary forms, with or without 655682Smarkm * modification, are permitted provided that the following conditions 7233294Sstas * are met: 8233294Sstas * 1. Redistributions of source code must retain the above copyright 9233294Sstas * notice, this list of conditions and the following disclaimer. 1055682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer in the 12233294Sstas * documentation and/or other materials provided with the distribution. 1355682Smarkm * 14233294Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1755682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2155682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24233294Sstas * SUCH DAMAGE. 25233294Sstas * 26233294Sstas */ 27233294Sstas 28233294Sstas#ifndef lint 29233294Sstasstatic const char rcsid[] = 30233294Sstas "$FreeBSD: head/usr.sbin/rpc.umntall/mounttab.c 80146 2001-07-22 12:17:51Z iedowse $"; 31233294Sstas#endif /* not lint */ 32233294Sstas 3355682Smarkm#include <sys/syslog.h> 3455682Smarkm 35233294Sstas#include <rpc/rpc.h> 3655682Smarkm#include <nfs/rpcv2.h> 3755682Smarkm 3855682Smarkm#include <err.h> 3955682Smarkm#include <errno.h> 4055682Smarkm#include <limits.h> 4155682Smarkm#include <stdio.h> 4255682Smarkm#include <stdlib.h> 4355682Smarkm#include <string.h> 4455682Smarkm#include <unistd.h> 4555682Smarkm 4655682Smarkm#include "mounttab.h" 4755682Smarkm 4872445Sassarstruct mtablist *mtabhead; 4972445Sassar 5072445Sassarstatic void badline(char *field, char *bad); 5155682Smarkm 5255682Smarkm/* 5355682Smarkm * Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem, 5455682Smarkm * so the client can notify the NFS server even after reboot. 5555682Smarkm */ 5655682Smarkmint 5755682Smarkmadd_mtab(char *hostp, char *dirp) { 5855682Smarkm FILE *mtabfile; 5955682Smarkm 60233294Sstas if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL) 61233294Sstas return (0); 62233294Sstas else { 63233294Sstas fprintf(mtabfile, "%ld\t%s\t%s\n", 64233294Sstas (long)time(NULL), hostp, dirp); 6555682Smarkm fclose(mtabfile); 6655682Smarkm return (1); 6755682Smarkm } 6855682Smarkm} 6955682Smarkm 7055682Smarkm/* 7155682Smarkm * Read mounttab line for line and return struct mtablist. 7255682Smarkm */ 7372445Sassarint 7472445Sassarread_mtab() { 7555682Smarkm struct mtablist **mtabpp, *mtabp; 7655682Smarkm char *hostp, *dirp, *cp; 7755682Smarkm char str[STRSIZ]; 7855682Smarkm char *timep, *endp; 7955682Smarkm time_t time; 8055682Smarkm u_long ultmp; 8172445Sassar FILE *mtabfile; 8272445Sassar 8372445Sassar if ((mtabfile = fopen(PATH_MOUNTTAB, "r")) == NULL) { 8455682Smarkm if (errno == ENOENT) 8555682Smarkm return (0); 8672445Sassar else { 8755682Smarkm syslog(LOG_ERR, "can't open %s", PATH_MOUNTTAB); 8855682Smarkm return (0); 8972445Sassar } 9072445Sassar } 9172445Sassar time = 0; 9272445Sassar mtabpp = &mtabhead; 9372445Sassar while (fgets(str, STRSIZ, mtabfile) != NULL) { 9472445Sassar cp = str; 9572445Sassar errno = 0; 9655682Smarkm if (*cp == '#' || *cp == ' ' || *cp == '\n') 9755682Smarkm continue; 9855682Smarkm timep = strsep(&cp, " \t\n"); 9955682Smarkm if (timep == NULL || *timep == '\0') { 100233294Sstas badline("time", timep); 101233294Sstas continue; 10255682Smarkm } 10355682Smarkm hostp = strsep(&cp, " \t\n"); 10455682Smarkm if (hostp == NULL || *hostp == '\0') { 10555682Smarkm badline("host", hostp); 106233294Sstas continue; 10755682Smarkm } 10855682Smarkm dirp = strsep(&cp, " \t\n"); 10955682Smarkm if (dirp == NULL || *dirp == '\0') { 11055682Smarkm badline("dir", dirp); 11155682Smarkm continue; 11255682Smarkm } 11355682Smarkm ultmp = strtoul(timep, &endp, 10); 11455682Smarkm if (ultmp == ULONG_MAX || *endp != '\0') { 11555682Smarkm badline("time", timep); 11655682Smarkm continue; 11755682Smarkm } 118233294Sstas time = ultmp; 11955682Smarkm if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) { 12055682Smarkm syslog(LOG_ERR, "malloc"); 12155682Smarkm fclose(mtabfile); 12255682Smarkm return (0); 123233294Sstas } 12455682Smarkm mtabp->mtab_time = time; 12555682Smarkm memmove(mtabp->mtab_host, hostp, RPCMNT_NAMELEN); 12655682Smarkm mtabp->mtab_host[RPCMNT_NAMELEN - 1] = '\0'; 12755682Smarkm memmove(mtabp->mtab_dirp, dirp, RPCMNT_PATHLEN); 128233294Sstas mtabp->mtab_dirp[RPCMNT_PATHLEN - 1] = '\0'; 12955682Smarkm mtabp->mtab_next = (struct mtablist *)NULL; 13055682Smarkm *mtabpp = mtabp; 13155682Smarkm mtabpp = &mtabp->mtab_next; 13255682Smarkm } 13355682Smarkm fclose(mtabfile); 134127808Snectar return (1); 135127808Snectar} 136127808Snectar 137127808Snectar/* 138233294Sstas * Rewrite PATH_MOUNTTAB from scratch and skip bad entries. 139127808Snectar * Unlink PATH_MOUNTAB if no entry is left. 140233294Sstas */ 141233294Sstasint 142178825Sdfrwrite_mtab(int verbose) { 143178825Sdfr struct mtablist *mtabp, *mp; 144178825Sdfr FILE *mtabfile; 145178825Sdfr int line; 146178825Sdfr 147178825Sdfr if ((mtabfile = fopen(PATH_MOUNTTAB, "w")) == NULL) { 148178825Sdfr syslog(LOG_ERR, "can't write to %s", PATH_MOUNTTAB); 149127808Snectar return (0); 150127808Snectar } 151127808Snectar line = 0; 152127808Snectar for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 153127808Snectar if (mtabp->mtab_host[0] == '\0') 154127808Snectar continue; 155233294Sstas /* Skip if a later (hence more recent) entry is identical. */ 156233294Sstas for (mp = mtabp->mtab_next; mp != NULL; mp = mp->mtab_next) 157127808Snectar if (strcmp(mtabp->mtab_host, mp->mtab_host) == 0 && 158127808Snectar strcmp(mtabp->mtab_dirp, mp->mtab_dirp) == 0) 159127808Snectar break; 160127808Snectar if (mp != NULL) 161233294Sstas continue; 162233294Sstas 163127808Snectar fprintf(mtabfile, "%ld\t%s\t%s\n", 164233294Sstas (long)mtabp->mtab_time, mtabp->mtab_host, 165233294Sstas mtabp->mtab_dirp); 166127808Snectar if (verbose) 167127808Snectar warnx("write mounttab entry %s:%s", 168127808Snectar mtabp->mtab_host, mtabp->mtab_dirp); 169127808Snectar line++; 170178825Sdfr } 171178825Sdfr fclose(mtabfile); 172178825Sdfr if (line == 0) { 173178825Sdfr if (unlink(PATH_MOUNTTAB) == -1) { 174178825Sdfr syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 175178825Sdfr return (0); 176178825Sdfr } 177178825Sdfr } 178178825Sdfr return (1); 179178825Sdfr} 180233294Sstas 181178825Sdfr/* 182178825Sdfr * Mark the entries as clean where RPC calls have been done successfully. 183178825Sdfr */ 184178825Sdfrvoid 185178825Sdfrclean_mtab(char *hostp, char *dirp, int verbose) { 186178825Sdfr struct mtablist *mtabp; 187178825Sdfr char *host; 188178825Sdfr 189178825Sdfr /* Copy hostp in case it points to an entry that we are zeroing out. */ 190178825Sdfr host = strdup(hostp); 191178825Sdfr for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 192178825Sdfr if (strcmp(mtabp->mtab_host, hostp) != 0) 193178825Sdfr continue; 194178825Sdfr if (dirp != NULL && strcmp(mtabp->mtab_dirp, dirp) != 0) 195178825Sdfr continue; 196178825Sdfr 197178825Sdfr if (verbose) 198178825Sdfr warnx("delete mounttab entry%s %s:%s", 199178825Sdfr (dirp == NULL) ? " by host" : "", 200178825Sdfr mtabp->mtab_host, mtabp->mtab_dirp); 201178825Sdfr bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 202178825Sdfr } 203178825Sdfr free(host); 204178825Sdfr} 205178825Sdfr 206178825Sdfr/* 207178825Sdfr * Free struct mtablist mtab. 208178825Sdfr */ 209178825Sdfrvoid 210178825Sdfrfree_mtab() { 211178825Sdfr struct mtablist *mtabp; 212178825Sdfr 213178825Sdfr while ((mtabp = mtabhead) != NULL) { 214178825Sdfr mtabhead = mtabhead->mtab_next; 215178825Sdfr free(mtabp); 216233294Sstas } 217178825Sdfr} 218178825Sdfr 219178825Sdfr/* 220178825Sdfr * Print bad lines to syslog. 221178825Sdfr */ 222178825Sdfrstatic void 223233294Sstasbadline(char *field, char *bad) { 22455682Smarkm syslog(LOG_ERR, "bad mounttab %s field '%s'", field, 22555682Smarkm (bad == NULL) ? "<null>" : bad); 22655682Smarkm} 22755682Smarkm