mounttab.c revision 66814
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 66814 2000-10-08 09:24:45Z bde $";
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",
6466814Sbde		    (long)time(now), hostp, dirp);
6553494Sdillon		fclose(mtabfile);
6653494Sdillon		return (1);
6753494Sdillon	}
6853494Sdillon}
6953494Sdillon
7053494Sdillon/*
7153494Sdillon * Read mounttab line for line and return struct mtablist.
7253494Sdillon */
7353494Sdillonint
7453494Sdillonread_mtab(struct mtablist *mtabp) {
7553494Sdillon	struct mtablist **mtabpp;
7653494Sdillon	char *hostp, *dirp, *cp;
7753494Sdillon	char str[STRSIZ];
7853494Sdillon	char *timep;
7953494Sdillon	time_t time;
8053494Sdillon	FILE *mtabfile;
8153494Sdillon
8253494Sdillon	if ((mtabfile = fopen(PATH_MOUNTTAB, "r")) == NULL) {
8353494Sdillon		if (errno == ENOENT)
8453494Sdillon			return (0);
8553494Sdillon		else {
8653494Sdillon			syslog(LOG_ERR, "can't open %s", PATH_MOUNTTAB);
8753494Sdillon			return (0);
8853494Sdillon		}
8953494Sdillon	}
9053494Sdillon	time = 0;
9153494Sdillon	mtabpp = &mtabhead;
9253494Sdillon	while (fgets(str, STRSIZ, mtabfile) != NULL) {
9353494Sdillon		cp = str;
9453494Sdillon		errno = 0;
9553494Sdillon		if (*cp == '#' || *cp == ' ' || *cp == '\n')
9653494Sdillon			continue;
9753494Sdillon		timep = strsep(&cp, " \t\n");
9853494Sdillon		if (timep == NULL || *timep == ' ' || *timep == '\n') {
9953494Sdillon			badline(timep);
10053494Sdillon			continue;
10153494Sdillon		}
10253494Sdillon		hostp = strsep(&cp, " \t\n");
10353494Sdillon		if (hostp == NULL || *hostp == ' ' || *hostp == '\n') {
10453494Sdillon			badline(hostp);
10553494Sdillon			continue;
10653494Sdillon		}
10753494Sdillon		dirp = strsep(&cp, " \t\n");
10853494Sdillon		if (dirp == NULL || *dirp == ' ' || *dirp == '\n') {
10953494Sdillon			badline(dirp);
11053494Sdillon			continue;
11153494Sdillon		}
11253494Sdillon		time = strtoul(timep, (char **)NULL, 10);
11353494Sdillon		if (errno == ERANGE) {
11453494Sdillon			badline(timep);
11553494Sdillon			continue;
11653494Sdillon		}
11753494Sdillon		if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) {
11853494Sdillon			syslog(LOG_ERR, "malloc");
11953494Sdillon			fclose(mtabfile);
12053494Sdillon			return (0);
12153494Sdillon		}
12253494Sdillon		mtabp->mtab_time = time;
12353494Sdillon		memmove(mtabp->mtab_host, hostp, RPCMNT_NAMELEN);
12453494Sdillon		mtabp->mtab_host[RPCMNT_NAMELEN - 1] = '\0';
12553494Sdillon		memmove(mtabp->mtab_dirp, dirp, RPCMNT_PATHLEN);
12653494Sdillon		mtabp->mtab_dirp[RPCMNT_PATHLEN - 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
14053494Sdillonwrite_mtab() {
14153494Sdillon	struct mtablist *mtabp;
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) {
15153494Sdillon		if (mtabp->mtab_host != NULL &&
15253494Sdillon		    strlen(mtabp->mtab_host) > 0) {
15366814Sbde			fprintf(mtabfile, "%ld\t%s\t%s\n",
15466814Sbde			    (long)mtabp->mtab_time, mtabp->mtab_host,
15566814Sbde			    mtabp->mtab_dirp);
15656038Sgreen			if (verbose) {
15756038Sgreen				warnx("write entry " "%s:%s",
15856038Sgreen				    mtabp->mtab_host, mtabp->mtab_dirp);
15956038Sgreen			}
16056038Sgreen			clean_mtab(mtabp->mtab_host, mtabp->mtab_dirp);
16153494Sdillon			line++;
16253494Sdillon		}
16353494Sdillon	}
16453494Sdillon	fclose(mtabfile);
16553494Sdillon	if (line == 0) {
16653494Sdillon		if (unlink(PATH_MOUNTTAB) == -1) {
16753494Sdillon			syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB);
16853494Sdillon			return (0);
16953494Sdillon		}
17053494Sdillon	}
17153494Sdillon	return (1);
17253494Sdillon}
17353494Sdillon
17453494Sdillon/*
17553494Sdillon * Mark the entries as clean where RPC calls have been done successfully.
17653494Sdillon */
17753494Sdillonvoid
17853494Sdillonclean_mtab(char *hostp, char *dirp) {
17953494Sdillon	struct mtablist *mtabp;
18053494Sdillon	char *host;
18153494Sdillon
18253494Sdillon	host = strdup(hostp);
18353494Sdillon	for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) {
18453494Sdillon		if (mtabp->mtab_host != NULL &&
18553494Sdillon		    strcmp(mtabp->mtab_host, host) == 0) {
18653494Sdillon			if (dirp == NULL) {
18753494Sdillon				if (verbose) {
18856038Sgreen					warnx("delete entries "
18953494Sdillon					    "host %s", host);
19053494Sdillon				}
19153494Sdillon				bzero(mtabp->mtab_host, RPCMNT_NAMELEN);
19253494Sdillon			} else {
19353494Sdillon				if (strcmp(mtabp->mtab_dirp, dirp) == 0) {
19453494Sdillon					if (verbose) {
19556038Sgreen						warnx("delete entry "
19653494Sdillon						    "%s:%s", host, dirp);
19753494Sdillon					}
19853494Sdillon					bzero(mtabp->mtab_host, RPCMNT_NAMELEN);
19953494Sdillon				}
20053494Sdillon			}
20153494Sdillon		}
20253494Sdillon	}
20353494Sdillon	free(host);
20453494Sdillon}
20553494Sdillon
20653494Sdillon/*
20753494Sdillon * Free struct mtablist mtab.
20853494Sdillon */
20953494Sdillonvoid
21053494Sdillonfree_mtab() {
21153494Sdillon	struct mtablist *mtabp;
21253494Sdillon	struct mtablist *mtab_next;
21353494Sdillon
21453494Sdillon	for (mtabp = mtabhead; mtabp != NULL; mtabp = mtab_next) {
21553494Sdillon		mtab_next = mtabp->mtab_next;
21653494Sdillon		free(mtabp);
21753494Sdillon		mtabp = mtab_next;
21853494Sdillon	}
21953494Sdillon}
22053494Sdillon
22153494Sdillon/*
22253494Sdillon * Print bad lines to syslog.
22353494Sdillon */
22453494Sdillonvoid
22553494Sdillonbadline(char *bad) {
22653494Sdillon
22756038Sgreen	syslog(LOG_ERR, "skip bad line in mounttab with entry %s", bad);
22853494Sdillon}
229