]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libc_backends/lib/mount/mount.cc
update
[l4.git] / l4 / pkg / libc_backends / lib / mount / mount.cc
1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  * This file is part of TUD:OS and distributed under the terms of the
5  * GNU Lesser General Public License 2.1.
6  * Please see the COPYING-LGPL-2.1 file for details.
7  */
8
9 #include <fcntl.h>
10 #include <stdlib.h>
11 #include <cstdio>
12 #include <unistd.h>
13 #include <ctype.h>
14 #include <cstring>
15 #include <errno.h>
16 #include <sys/mman.h>
17 #include <sys/mount.h>
18
19 static bool verbose;
20
21 struct String
22 {
23   String(const char *s, const char *e) : _s(s), _e(e), _p(s) {}
24   const char *s() const { return _s; }
25   const char *e() const { return _e; }
26   const char *p() const { return _p; }
27   unsigned l() const { return _e - _s; }
28
29   const char *next_space()
30   {
31     const char *i = _p;
32     while (i < _e && !isspace(*i))
33       i++;
34     _p = i;
35     return _p;
36   }
37   void eat_space()
38   {
39     while (_p < e() && isspace(*_p))
40       _p++;
41   }
42
43   bool empty() const { return !(_e - _s); }
44   const char *dupnultermstr() const
45   { return strndup(s(), l()); }
46
47   const char *_s, *_e, *_p;
48 };
49
50 static void parse_fstab_line(const char *fn, int line_nr,
51                              const char *s, const char *end)
52 {
53   const char *i = s;
54   while (i < end && *i != '#')
55     ++i;
56   end = i;
57
58   if (s == end)
59     return;
60
61   String line(s, end);
62   String from(line.s(), line.next_space());
63
64   line.next_space();
65   line.eat_space();
66
67   const char *x = line.p();
68   String mountpoint(x, line.next_space());
69
70   line.next_space();
71   line.eat_space();
72
73   x = line.p();
74   String fsname(x, line.next_space());
75
76   line.next_space();
77   line.eat_space();
78
79   x = line.p();
80   String data(x, line.next_space());
81
82   if (from.empty() || mountpoint.empty() || fsname.empty())
83     {
84       if (verbose)
85         printf("libmount: Invalid line: %s.%d: %.*s\n",
86                fn, line_nr, line.l(), line.s());
87       return;
88     }
89
90   const char *s1 = from.dupnultermstr();
91   const char *s2 = mountpoint.dupnultermstr();
92   const char *s3 = fsname.dupnultermstr();
93   const char *s5 = data.dupnultermstr();
94   int r = mount(s1, *s2 == '/' ? s2 + 1 : s2, s3, 0, s5);
95   if (r < 0)
96     fprintf(stderr, "libmount: %s.%d: mount(\"%s\", \"%s\", \"%s\", %d, \"%s\"): %s\n",
97             fn, line_nr, s1, s2, s3, 0, s5, strerror(errno));
98   else if (verbose)
99     printf("libmount: Mounted '%s' to '%s' with file-system '%s'\n",
100            s1, s2, s3);
101   free((void *)s5);
102   free((void *)s3);
103   free((void *)s2);
104   free((void *)s1);
105 }
106
107 static void parse_fstab(const char *fn, char *fstab, size_t sz)
108 {
109   char *s = fstab;
110   char *end = fstab + sz;
111   int line_nr = 1;
112
113   if (verbose)
114     printf("libmount: Parsing '%s'\n", fn);
115
116   while (s != end)
117     {
118       while (s < end && *s != '\n')
119         s++;
120       parse_fstab_line(fn, line_nr, fstab, s);
121       if (s == end)
122         break;
123       fstab = ++s;
124       line_nr++;
125     }
126 }
127
128 static void libmount_init(void) __attribute__((constructor));
129 static void libmount_init()
130 {
131   verbose = getenv("FSTAB_DEBUG");
132
133   const char *fstab_path = getenv("FSTAB_FILE");
134   if (!fstab_path)
135     fstab_path = "/etc/fstab";
136
137   int fd = open(fstab_path, O_RDONLY);
138   if (fd < 0)
139     {
140       if (verbose)
141         printf("libmount: Could not open '%s': %s.\n", fstab_path, strerror(errno));
142       return;
143     }
144
145   struct stat st;
146   if (fstat(fd, &st) < 0)
147     {
148       if (verbose)
149         printf("libmount: Could not stat '%s'.\n", fstab_path);
150       return;
151     }
152
153   char *fstab = (char *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
154   if (!fstab)
155     {
156       if (verbose)
157         printf("libmount: Could not mmap '%s'.\n", fstab_path);
158       return;
159     }
160
161   parse_fstab(fstab_path, fstab, st.st_size);
162
163   munmap(fstab, st.st_size);
164   close(fd);
165 }