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 if (verbose) { 155 warnx("write entry " "%s:%s", 156 mtabp->mtab_host, mtabp->mtab_dirp); 157 } 158 clean_mtab(mtabp->mtab_host, mtabp->mtab_dirp); 159 line++; 160 } 161 } 162 fclose(mtabfile); 163 if (line == 0) { 164 if (unlink(PATH_MOUNTTAB) == -1) { 165 syslog(LOG_ERR, "can't remove %s", PATH_MOUNTTAB); 166 return (0); 167 } 168 } 169 return (1); 170 } 171 172 /* 173 * Mark the entries as clean where RPC calls have been done successfully. 174 */ 175 void 176 clean_mtab(char *hostp, char *dirp) { 177 struct mtablist *mtabp; 178 char *host; 179 180 host = strdup(hostp); 181 for (mtabp = mtabhead; mtabp != NULL; mtabp = mtabp->mtab_next) { 182 if (mtabp->mtab_host != NULL && 183 strcmp(mtabp->mtab_host, host) == 0) { 184 if (dirp == NULL) { 185 if (verbose) { 186 warnx("delete entries " 187 "host %s", host); 188 } 189 bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 190 } else { 191 if (strcmp(mtabp->mtab_dirp, dirp) == 0) { 192 if (verbose) { 193 warnx("delete entry " 194 "%s:%s", host, dirp); 195 } 196 bzero(mtabp->mtab_host, RPCMNT_NAMELEN); 197 } 198 } 199 } 200 } 201 free(host); 202 } 203 204 /* 205 * Free struct mtablist mtab. 206 */ 207 void 208 free_mtab() { 209 struct mtablist *mtabp; 210 struct mtablist *mtab_next; 211 212 for (mtabp = mtabhead; mtabp != NULL; mtabp = mtab_next) { 213 mtab_next = mtabp->mtab_next; 214 free(mtabp); 215 mtabp = mtab_next; 216 } 217 } 218 219 /* 220 * Print bad lines to syslog. 221 */ 222 void 223 badline(char *bad) { 224 225 syslog(LOG_ERR, "skip bad line in mounttab with entry %s", bad); 226 } 227