mounttab.c revision 53494
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 53494 1999-11-21 08:06:00Z dillon $"; 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> 4053494Sdillon#include <stdio.h> 4153494Sdillon#include <stdlib.h> 4253494Sdillon#include <string.h> 4353494Sdillon#include <unistd.h> 4453494Sdillon 4553494Sdillon#include "mounttab.h" 4653494Sdillon 4753494Sdillonint verbose; 4853494Sdillonstruct mtablist *mtabhead; 4953494Sdillon 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 time_t *now; 5853494Sdillon 5953494Sdillon now = NULL; 6053494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL) 6153494Sdillon return (0); 6253494Sdillon else { 6366814Sbde fprintf(mtabfile, "%ld\t%s\t%s\n", time(now), hostp, dirp); 6466814Sbde fclose(mtabfile); 6553494Sdillon return (1); 6653494Sdillon } 6753494Sdillon} 6853494Sdillon 6953494Sdillon/* 7053494Sdillon * Read mounttab line for line and return struct mtablist. 7153494Sdillon */ 7253494Sdillonint 7353494Sdillonread_mtab(struct mtablist *mtabp) { 7453494Sdillon struct mtablist **mtabpp; 7553494Sdillon char *hostp, *dirp, *cp; 7653494Sdillon char str[STRSIZ]; 7753494Sdillon char *timep; 7853494Sdillon time_t time; 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 } 8953494Sdillon time = 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"); 9753494Sdillon if (timep == NULL || *timep == ' ' || *timep == '\n') { 9853494Sdillon badline(timep); 9953494Sdillon continue; 10053494Sdillon } 10153494Sdillon hostp = strsep(&cp, " \t\n"); 10253494Sdillon if (hostp == NULL || *hostp == ' ' || *hostp == '\n') { 10353494Sdillon badline(hostp); 10453494Sdillon continue; 10553494Sdillon } 10653494Sdillon dirp = strsep(&cp, " \t\n"); 10753494Sdillon if (dirp == NULL || *dirp == ' ' || *dirp == '\n') { 10853494Sdillon badline(dirp); 10953494Sdillon continue; 11053494Sdillon } 11153494Sdillon time = strtoul(timep, (char **)NULL, 10); 11253494Sdillon if (errno == ERANGE) { 11353494Sdillon badline(timep); 11453494Sdillon continue; 11553494Sdillon } 11653494Sdillon if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) { 11753494Sdillon syslog(LOG_ERR, "malloc"); 11853494Sdillon fclose(mtabfile); 11953494Sdillon return (0); 12053494Sdillon } 12153494Sdillon mtabp->mtab_time = time; 12253494Sdillon memmove(mtabp->mtab_host, hostp, RPCMNT_NAMELEN); 12353494Sdillon mtabp->mtab_host[RPCMNT_NAMELEN - 1] = '\0'; 12453494Sdillon memmove(mtabp->mtab_dirp, dirp, RPCMNT_PATHLEN); 12553494Sdillon mtabp->mtab_dirp[RPCMNT_PATHLEN - 1] = '\0'; 12653494Sdillon mtabp->mtab_next = (struct mtablist *)NULL; 12753494Sdillon *mtabpp = mtabp; 12853494Sdillon mtabpp = &mtabp->mtab_next; 12953494Sdillon } 13053494Sdillon fclose(mtabfile); 13153494Sdillon return (1); 13253494Sdillon} 13353494Sdillon 13453494Sdillon/* 13553494Sdillon * Rewrite PATH_MOUNTTAB from scratch and skip bad entries. 13653494Sdillon * Unlink PATH_MOUNTAB if no entry is left. 13753494Sdillon */ 13853494Sdillonint 13953494Sdillonwrite_mtab() { 14053494Sdillon struct mtablist *mtabp; 14153494Sdillon FILE *mtabfile; 14253494Sdillon int line; 14353494Sdillon 14453494Sdillon if ((mtabfile = fopen(PATH_MOUNTTAB, "w")) == NULL) { 14553494Sdillon syslog(LOG_ERR, "can't write to %s", PATH_MOUNTTAB); 14653494Sdillon return (0); 14753494Sdillon } 14853494Sdillon line = 0; 14953494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 15053494Sdillon if (mtabp->mtab_host != NULL && 15153494Sdillon strlen(mtabp->mtab_host) > 0) { 15253494Sdillon fprintf(mtabfile, "%ld\t%s\t%s\n", mtabp->mtab_time, 15366814Sbde mtabp->mtab_host, mtabp->mtab_dirp); 15466814Sbde line++; 15566814Sbde } 15656038Sgreen } 15756038Sgreen fclose(mtabfile); 15856038Sgreen if (line == 0) { 15956038Sgreen if (unlink(PATH_MOUNTTAB) == -1) { 16056038Sgreen syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 16153494Sdillon return (0); 16253494Sdillon } 16353494Sdillon } 16453494Sdillon return (1); 16553494Sdillon} 16653494Sdillon 16753494Sdillon/* 16853494Sdillon * Mark the entries as clean where RPC calls have been done successfully. 16953494Sdillon */ 17053494Sdillonvoid 17153494Sdillonclean_mtab(char *hostp, char *dirp) { 17253494Sdillon struct mtablist *mtabp; 17353494Sdillon char *host; 17453494Sdillon 17553494Sdillon host = strdup(hostp); 17653494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 17753494Sdillon if (mtabp->mtab_host != NULL && 17853494Sdillon strcmp(mtabp->mtab_host, host) == 0) { 17953494Sdillon if (dirp == NULL) { 18053494Sdillon if (verbose) { 18153494Sdillon warnx("entries deleted for " 18253494Sdillon "host %s", host); 18353494Sdillon } 18453494Sdillon bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 18553494Sdillon } else { 18653494Sdillon if (strcmp(mtabp->mtab_dirp, dirp) == 0) { 18753494Sdillon if (verbose) { 18856038Sgreen warnx("entry deleted for " 18953494Sdillon "%s:%s", host, dirp); 19053494Sdillon } 19153494Sdillon bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 19253494Sdillon } 19353494Sdillon } 19453494Sdillon } 19556038Sgreen } 19653494Sdillon free(host); 19753494Sdillon} 19853494Sdillon 19953494Sdillon/* 20053494Sdillon * Free struct mtablist mtab. 20153494Sdillon */ 20253494Sdillonvoid 20353494Sdillonfree_mtab() { 20453494Sdillon struct mtablist *mtabp; 20553494Sdillon struct mtablist *mtab_next; 20653494Sdillon 20753494Sdillon for (mtabp = mtabhead; mtabp != NULL; mtabp = mtab_next) { 20853494Sdillon mtab_next = mtabp->mtab_next; 20953494Sdillon free(mtabp); 21053494Sdillon mtabp = mtab_next; 21153494Sdillon } 21253494Sdillon} 21353494Sdillon 21453494Sdillon/* 21553494Sdillon * Print bad lines to syslog. 21653494Sdillon */ 21753494Sdillonvoid 21853494Sdillonbadline(char *bad) { 21953494Sdillon 22053494Sdillon syslog(LOG_ERR, "skipped bad line in mounttab with entry %s", bad); 22153494Sdillon} 22253494Sdillon