xref: /netbsd-src/external/bsd/am-utils/dist/conf/mtab/mtab_isc3.c (revision c8da0e5fefd3800856b306200a18b2315c7fbb9f)
1 /*	$NetBSD: mtab_isc3.c,v 1.1.1.2 2009/03/20 20:26:50 christos Exp $	*/
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) */
53 static int mtlckf = 0;
54 static char mtlckname[] = "/etc/.mnt.lock";
55 static char mnttabname[] = "/etc/mnttab";
56 
57 
58 static void
59 unlockmnttab(void)
60 {
61   if (mtlckf) {
62     close(mtlckf);
63     mtlckf = 0;
64   }
65 }
66 
67 
68 static
69 lockfile(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 
82 static
83 lockmnttab(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 
104 void
105 unlock_mntlist(void)
106 {
107   dlog("unlock_mntlist: releasing");
108   unlockmnttab();
109 }
110 
111 
112 /* convert from ix386 mnttab to amd mntent */
113 static mntent_t *
114 mnt_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) */
143 static mntent_t *
144 mtab_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  */
164 mntlist *
165 read_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 
214 static
215 write_mntent_to_mtab(int fd, mntent_t *mnt)
216 {
217   int wr;
218 
219 eagain:
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 
235 void
236 rewrite_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 
258 void
259 write_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