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