1 /* 2 * Copyright (c) 1999 Martin Blapp 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 #ifndef lint 29 static const char rcsid[] = 30 "$FreeBSD$"; 31 #endif /* not lint */ 32 33 #include <sys/syslog.h> 34 35 #include <rpc/rpc.h> 36 #include <nfs/rpcv2.h> 37 38 #include <err.h> 39 #include <errno.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45 #include "mounttab.h" 46 47 int verbose; 48 struct mtablist *mtabhead; 49 50 /* 51 * Add an entry to PATH_MOUNTTAB for each mounted NFS filesystem, 52 * so the client can notify the NFS server even after reboot. 53 */ 54 int 55 add_mtab(char *hostp, char *dirp) { 56 FILE *mtabfile; 57 time_t *now; 58 59 now = NULL; 60 if ((mtabfile = fopen(PATH_MOUNTTAB, "a")) == NULL) 61 return (0); 62 else { 63 fprintf(mtabfile, "%ld\t%s\t%s\n", time(now), hostp, dirp); 64 fclose(mtabfile); 65 return (1); 66 } 67 } 68 69 /* 70 * Read mounttab line for line and return struct mtablist. 71 */ 72 int 73 read_mtab(struct mtablist *mtabp) { 74 struct mtablist **mtabpp; 75 char *hostp, *dirp, *cp; 76 char str[STRSIZ]; 77 char *timep; 78 time_t time; 79 FILE *mtabfile; 80 81 if ((mtabfile = fopen(PATH_MOUNTTAB, "r")) == NULL) { 82 if (errno == ENOENT) 83 return (0); 84 else { 85 syslog(LOG_ERR, "can't open %s", PATH_MOUNTTAB); 86 return (0); 87 } 88 } 89 time = 0; 90 mtabpp = &mtabhead; 91 while (fgets(str, STRSIZ, mtabfile) != NULL) { 92 cp = str; 93 errno = 0; 94 if (*cp == '#' || *cp == ' ' || *cp == '\n') 95 continue; 96 timep = strsep(&cp, " \t\n"); 97 if (timep == NULL || *timep == ' ' || *timep == '\n') { 98 badline(timep); 99 continue; 100 } 101 hostp = strsep(&cp, " \t\n"); 102 if (hostp == NULL || *hostp == ' ' || *hostp == '\n') { 103 badline(hostp); 104 continue; 105 } 106 dirp = strsep(&cp, " \t\n"); 107 if (dirp == NULL || *dirp == ' ' || *dirp == '\n') { 108 badline(dirp); 109 continue; 110 } 111 time = strtoul(timep, (char **)NULL, 10); 112 if (errno == ERANGE) { 113 badline(timep); 114 continue; 115 } 116 if ((mtabp = malloc(sizeof (struct mtablist))) == NULL) { 117 syslog(LOG_ERR, "malloc"); 118 fclose(mtabfile); 119 return (0); 120 } 121 mtabp->mtab_time = time; 122 memmove(mtabp->mtab_host, hostp, RPCMNT_NAMELEN); 123 mtabp->mtab_host[RPCMNT_NAMELEN - 1] = '\0'; 124 memmove(mtabp->mtab_dirp, dirp, RPCMNT_PATHLEN); 125 mtabp->mtab_dirp[RPCMNT_PATHLEN - 1] = '\0'; 126 mtabp->mtab_next = (struct mtablist *)NULL; 127 *mtabpp = mtabp; 128 mtabpp = &mtabp->mtab_next; 129 } 130 fclose(mtabfile); 131 return (1); 132 } 133 134 /* 135 * Rewrite PATH_MOUNTTAB from scratch and skip bad entries. 136 * Unlink PATH_MOUNTAB if no entry is left. 137 */ 138 int 139 write_mtab() { 140 struct mtablist *mtabp; 141 FILE *mtabfile; 142 int line; 143 144 if ((mtabfile = fopen(PATH_MOUNTTAB, "w")) == NULL) { 145 syslog(LOG_ERR, "can't write to %s", PATH_MOUNTTAB); 146 return (0); 147 } 148 line = 0; 149 for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 150 if (mtabp->mtab_host != NULL && 151 strlen(mtabp->mtab_host) > 0) { 152 fprintf(mtabfile, "%ld\t%s\t%s\n", mtabp->mtab_time, 153 mtabp->mtab_host, mtabp->mtab_dirp); 154 line++; 155 } 156 } 157 fclose(mtabfile); 158 if (line == 0) { 159 if (unlink(PATH_MOUNTTAB) == -1) { 160 syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 161 return (0); 162 } 163 } 164 return (1); 165 } 166 167 /* 168 * Mark the entries as clean where RPC calls have been done successfully. 169 */ 170 void 171 clean_mtab(char *hostp, char *dirp) { 172 struct mtablist *mtabp; 173 char *host; 174 175 host = strdup(hostp); 176 for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 177 if (mtabp->mtab_host != NULL && 178 strcmp(mtabp->mtab_host, host) == 0) { 179 if (dirp == NULL) { 180 if (verbose) { 181 warnx("entries deleted for " 182 "host %s", host); 183 } 184 bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 185 } else { 186 if (strcmp(mtabp->mtab_dirp, dirp) == 0) { 187 if (verbose) { 188 warnx("entry deleted for " 189 "%s:%s", host, dirp); 190 } 191 bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 192 } 193 } 194 } 195 } 196 free(host); 197 } 198 199 /* 200 * Free struct mtablist mtab. 201 */ 202 void 203 free_mtab() { 204 struct mtablist *mtabp; 205 struct mtablist *mtab_next; 206 207 for (mtabp = mtabhead; mtabp != NULL; mtabp = mtab_next) { 208 mtab_next = mtabp->mtab_next; 209 free(mtabp); 210 mtabp = mtab_next; 211 } 212 } 213 214 /* 215 * Print bad lines to syslog. 216 */ 217 void 218 badline(char *bad) { 219 220 syslog(LOG_ERR, "skipped bad line in mounttab with entry %s", bad); 221 } 222