xref: /netbsd-src/external/bsd/am-utils/dist/conf/mtab/mtab_isc3.c (revision 8bae5d409deb915cf7c8f0539fae22ff2cb8a313)
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