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