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) */
49 static int mtlckf = 0;
50 static char mtlckname[] = "/etc/.mnt.lock";
51 static char mnttabname[] = "/etc/mnttab";
52
53
54 static void
unlockmnttab(void)55 unlockmnttab(void)
56 {
57 if (mtlckf) {
58 close(mtlckf);
59 mtlckf = 0;
60 }
61 }
62
63
64 static
lockfile(int fd,int type)65 lockfile(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
78 static
lockmnttab(void)79 lockmnttab(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
100 void
unlock_mntlist(void)101 unlock_mntlist(void)
102 {
103 dlog("unlock_mntlist: releasing");
104 unlockmnttab();
105 }
106
107
108 /* convert from ix386 mnttab to amd mntent */
109 static mntent_t *
mnt_dup(mntent_t * mp)110 mnt_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) */
139 static mntent_t *
mtab_of(mntent_t * mnt)140 mtab_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 */
160 mntlist *
read_mtab(char * fs,const char * mnttabname)161 read_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
210 static
write_mntent_to_mtab(int fd,mntent_t * mnt)211 write_mntent_to_mtab(int fd, mntent_t *mnt)
212 {
213 int wr;
214
215 eagain:
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
231 void
rewrite_mtab(mntlist * mp,const char * mnttabname)232 rewrite_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
254 void
write_mntent(mntent_t * mp,const char * mnttabname)255 write_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