1/* $NetBSD$ */ 2 3/* 4 * Copyright (c) 1997-2009 Erez Zadok 5 * Copyright (c) 1990 Jan-Simon Pendry 6 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 7 * Copyright (c) 1990 The Regents of the University of California. 8 * All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Jan-Simon Pendry at Imperial College, London. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgment: 23 * This product includes software developed by the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * 42 * File: am-utils/conf/mtab/mtab_isc3.c 43 * 44 */ 45 46#ifdef HAVE_CONFIG_H 47# include <config.h> 48#endif /* HAVE_CONFIG_H */ 49#include <am_defs.h> 50#include <amu.h> 51 52/* fd for /etc/.mnt.lock (also act as flag for: is_locked) */ 53static int mtlckf = 0; 54static char mtlckname[] = "/etc/.mnt.lock"; 55static char mnttabname[] = "/etc/mnttab"; 56 57 58static void 59unlockmnttab(void) 60{ 61 if (mtlckf) { 62 close(mtlckf); 63 mtlckf = 0; 64 } 65} 66 67 68static 69lockfile(int fd, int type) 70{ 71 struct flock lk; 72 73 lk.l_type = type; 74 lk.l_whence = 0; 75 lk.l_start = 0; 76 lk.l_len = 0; 77 78 return fcntl(fd, F_SETLKW, &lk); 79} 80 81 82static 83lockmnttab(void) 84{ 85 if (mtlckf == 0) { /* need lock on /etc/.mnt.lock */ 86 mtlckf = open(mtlckname, O_RDWR); 87 if (mtlckf >= 0) { 88 if (lockfile(mtlckf, F_WRLCK) < 0) { 89 close(mtlckf); 90 mtlckf = 0; 91#ifdef DEBUG 92 dlog("lock failed %m"); 93#endif /* DEBUG */ 94 } else { 95 return 0; 96 } 97 } 98 } 99 plog(XLOG_ERROR, "Unable to lock %s: %m", mtlckname); 100 return -1; 101} 102 103 104void 105unlock_mntlist(void) 106{ 107 dlog("unlock_mntlist: releasing"); 108 unlockmnttab(); 109} 110 111 112/* convert from ix386 mnttab to amd mntent */ 113static mntent_t * 114mnt_dup(mntent_t *mp) 115{ 116 /* note: may not be null terminated */ 117 mntent_t *new_mp = ALLOC(mntent_t); 118 char nullcpy[128]; 119 120 xstrlcpy(nullcpy, mp->mt_dev, 32); 121 new_mp->mnt_fsname = strdup(nullcpy); 122 123 xstrlcpy(nullcpy, mp->mt_filsys, 32); 124 new_mp->mnt_dir = strdup(nullcpy); 125 126 xstrlcpy(nullcpy, mp->mt_fstyp, 16); 127 new_mp->mnt_type = strdup(nullcpy); 128 129 xstrlcpy(nullcpy, mp->mt_mntopts, 64); 130 new_mp->mnt_opts = strdup(nullcpy); 131 132 new_mp->mnt_freq = 0; 133 new_mp->mnt_passno = 0; 134 135 new_mp->mnt_time = mp->mt_time; 136 new_mp->mnt_ro = mp->mt_ro_flg; 137 138 return new_mp; 139} 140 141 142/* convert back (static alloc) */ 143static mntent_t * 144mtab_of(mntent_t *mnt) 145{ 146 static mntent_t mt; 147 148 xstrlcpy(mt.mt_dev, mnt->mnt_fsname, 32); 149 xstrlcpy(mt.mt_filsys, mnt->mnt_dir, 32); 150 151 mt.mt_ro_flg = mnt->mnt_ro; 152 mt.mt_time = mnt->mnt_time; 153 154 xstrlcpy(mt.mt_fstyp, mnt->mnt_type, 16); 155 xstrlcpy(mt.mt_mntopts, mnt->mnt_opts, 64); 156 157 return &mt; 158} 159 160 161/* 162 * Read a mount table into memory 163 */ 164mntlist * 165read_mtab(char *fs, const char *mnttabname) 166{ 167 mntlist **mpp, *mhp; 168 /* From: Piete Brooks <pb@cl.cam.ac.uk> */ 169 int fd; 170 mntent_t mountbuffer[NMOUNT], *fs_data; 171 int ret; 172 int nmts; 173 174 if (lockmnttab() != 0) 175 return (mntlist *) NULL; 176 177 fd = open(mnttabname, O_RDONLY); 178 if (fd < 0) { 179 plog(XLOG_ERROR, "Can't open %s: %m", mnttabname); 180 return (mntlist *) NULL; 181 } 182 mpp = &mhp; 183 while ((ret = read(fd, (char *) mountbuffer, NMOUNT * sizeof(mntent_t))) > 0) { 184 nmts = ret / sizeof(mntent_t); 185 for (fs_data = mountbuffer; fs_data < &mountbuffer[nmts]; fs_data++) { 186 /* 187 * Allocate a new slot 188 */ 189 *mpp = ALLOC(struct mntlist); 190 191 /* 192 * Copy the data returned by getmntent 193 */ 194 (*mpp)->mnt = mnt_dup(fs_data); 195 196 /* 197 * Move to next pointer 198 */ 199 mpp = &(*mpp)->mnext; 200 } 201 } 202 if (ret < 0) { 203 plog(XLOG_ERROR, "read error on %s: %m", mnttabname); 204 unlockmnttab(); 205 mhp = (mntlist *) NULL; 206 } 207 *mpp = NULL; 208 209 close(fd); 210 return mhp; 211} 212 213 214static 215write_mntent_to_mtab(int fd, mntent_t *mnt) 216{ 217 int wr; 218 219eagain: 220 wr = write(fd, (char *) mtab_of(mnt), sizeof(mntent_t)); 221 if (wr < 0) { 222 switch (wr) { 223 case EAGAIN: 224 goto eagain; 225 default: 226 return -1; 227 } 228 } 229 if (wr != sizeof(mntent_t)) 230 plog(XLOG_ERROR, "Can't write entry to %s: %m", mnttabname); 231 return 0; 232} 233 234 235void 236rewrite_mtab(mntlist *mp, const char *mnttabname) 237{ 238 int fd; 239 240 assert(mtlckf != 0); 241 242 fd = open(mnttabname, O_RDWR | O_TRUNC); 243 if (fd < 0) { 244 plog(XLOG_ERROR, "Can't open %s: %m", mnttabname); 245 unlockmnttab(); 246 } 247 while (mp) { 248 if (mp->mnt) 249 write_mntent_to_mtab(fd, mp->mnt); 250 mp = mp->mnext; 251 } 252 253 close(fd); 254 unlockmnttab(); 255} 256 257 258void 259write_mntent(mntent_t *mp, const char *mnttabname) 260{ 261 int fd; 262 263 if (lockmnttab() == -1) 264 return; 265 266 fd = open(mnttabname, O_RDWR | O_APPEND); 267 if (fd < 0) { 268 plog(XLOG_ERROR, "Unable to append %s: %m", mnttabname); 269 return; 270 } 271 write_mntent_to_mtab(fd, mp); 272 273 close(fd); 274 unlockmnttab(); 275} 276