some coverity fixes.
[minix.git] / lib / libc / sys-minix / mount.c
blob29f8b0b0a133d8703c75780a1cf8724ebeb4c559
1 #include <sys/cdefs.h>
2 #include "namespace.h"
3 #include <lib.h>
5 #include <string.h>
6 #include <sys/mount.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <sys/stat.h>
10 #include <minix/syslib.h>
11 #include <minix/rs.h>
12 #include <paths.h>
13 #include <unistd.h>
14 #define OK 0
16 #ifdef __weak_alias
17 __weak_alias(mount, _mount)
18 __weak_alias(umount, _umount)
19 __weak_alias(umount2, _umount2)
20 #endif
22 #define FSDEFAULT "mfs"
24 static char fspath[] = "/sbin/:/usr/pkg/bin/"; /* Must include trailing '/' */
26 static int rs_down(char *label)
28 char cmd[200];
29 if(strlen(_PATH_SERVICE)+strlen(label)+50 >= sizeof(cmd))
30 return -1;
31 sprintf(cmd, _PATH_SERVICE " down '%s'", label);
32 return system(cmd);
35 char *find_rslabel(char *args_line);
36 int mount(special, name, mountflags, type, args)
37 char *name, *special, *type, *args;
38 int mountflags;
40 int r;
41 message m;
42 struct stat statbuf;
43 char label[16];
44 char path[PATH_MAX];
45 char cmd[200];
46 char *p;
47 char *rslabel;
48 int reuse = 0;
49 int use_existing = 0;
51 /* Default values. */
52 if (type == NULL) type = __UNCONST(FSDEFAULT);
53 if (args == NULL) args = __UNCONST("");
54 reuse = 0;
55 memset(path, '\0', sizeof(path));
57 /* Check mount flags */
58 if(mountflags & MS_REUSE) {
59 reuse = 1;
60 mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */
63 if(mountflags & MS_EXISTING) {
64 use_existing = 1;
65 mountflags &= ~MS_EXISTING; /* Temporary: turn off to not confuse VFS */
68 /* Make a label for the file system process. This label must be unique and
69 * may currently not exceed 16 characters including terminating null. For
70 * requests with an associated block device, we use the last path component
71 * name of the block special file (truncated to 12 characters, which is
72 * hopefully enough). For requests with no associated block device, we use
73 * the device number and inode of the mount point, in hexadecimal form.
75 if (!use_existing) {
76 if (special) {
77 p = strrchr(special, '/');
78 p = p ? p + 1 : special;
79 if (strchr(p, '\'')) {
80 errno = EINVAL;
81 return -1;
83 sprintf(label, "fs_%.12s", p);
84 } else {
85 /* check for a rslabel option in the arguments and try to use
86 * that.
88 rslabel = find_rslabel(args);
89 if (rslabel != NULL){
90 snprintf(label,16,rslabel);
91 free(rslabel);
92 } else {
93 if (stat(name, &statbuf) < 0) return -1;
94 sprintf(label, "fs_%04x%llx", statbuf.st_dev, statbuf.st_ino);
97 } else {
98 /* label to long? */
99 if (strlen(type) < 16) {
100 sprintf(label, "%s", type);
101 } else {
102 errno = ENOMEM;
103 return -1;
107 /* Tell VFS that we are passing in a 16-byte label. */
108 mountflags |= MS_LABEL16;
110 /* Sanity check on user input. */
111 if(strchr(args, '\'')) {
112 errno = EINVAL;
113 return -1;
115 /* start the fs-server if not using existing one */
116 if (!use_existing) {
117 /* See if the given type is even remotely valid. */
119 char *testpath;
120 testpath = strtok(fspath, ":");
122 do {
123 if (strlen(testpath) + strlen(type) >= sizeof(path)) {
124 errno = E2BIG;
125 return(-1);
128 strcpy(path, testpath);
129 strcat(path, type);
131 if (access(path, F_OK) == 0) break;
133 } while ((testpath = strtok(NULL, ":")) != NULL);
135 if (testpath == NULL) {
136 /* We were not able to find type somewhere in "fspath" */
137 errno = EINVAL;
138 return(-1);
141 if (strlen(_PATH_SERVICE) + strlen(path) + strlen(label) +
142 strlen(args) + 50 >= sizeof(cmd)) {
143 errno = E2BIG;
144 return -1;
147 sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -args '%s %s %s%s'",
148 reuse ? "-r ": "", path, label, special, name,
149 args[0] ? "-o " : "", args);
151 if ((r = system(cmd)) != 0) {
152 fprintf(stderr, "mount: couldn't run %s\n", cmd);
153 errno = r;
154 return -1;
158 /* Now perform mount(). */
159 m.m1_i1 = special ? strlen(special) + 1 : 0;
160 m.m1_i2 = strlen(name) + 1;
161 m.m1_i3 = mountflags;
162 m.m1_p1 = special;
163 m.m1_p2 = name;
164 m.m1_p3 = label;
165 r = _syscall(VFS_PROC_NR, MOUNT, &m);
167 if (r != OK && !use_existing) {
168 /* If mount() failed, tell RS to shutdown FS process.
169 * No error check - won't do anything with this error anyway.
171 rs_down(label);
174 return r;
177 int umount(name)
178 const char *name;
180 return umount2(name, 0);
183 int umount2(name, flags)
184 const char *name;
185 int flags;
187 message m;
188 int r;
191 _loadname(name, &m);
192 r = _syscall(VFS_PROC_NR, UMOUNT, &m);
194 /* don't shut down the driver when exist flag is set */
195 if (!(flags & MS_EXISTING)) {
196 if (r == OK) {
197 /* VFS returns the label of the unmounted file system in the reply.
198 * As of writing, the size of the m3_ca1 field is 16 bytes.
200 rs_down(m.m3_ca1);
204 return r;
207 char *find_rslabel(args_line)
208 char *args_line;
211 * Find and return the rslabel as given as optional
212 * agument to the mount command e.g.
213 * mount -o rslabel=bla
214 * or
215 * mount -o rw,rslabel=bla
216 * or as found in fstab
218 char *buf, *input,*saveptr;
219 buf = input = saveptr = NULL;
221 if (args_line == NULL) return NULL;
223 /* copy the input args_line we are going to modify it*/
224 input = strndup(args_line,20);
225 if (input == NULL) /* EOM */
226 return NULL; /* it is not that bad to not find a label */
228 /* locate rslabel= in the input */
229 buf = strstr(input,"rslabel=");
230 if (buf == NULL) {
231 free(input);
232 return NULL;
235 /* tokenise on "," starting from rslabel (e.g null terminate )*/
236 buf = strtok_r(buf,",",&saveptr);
237 /* tokenise the result again using = and take the second entry */
238 buf = strtok_r(buf,"=",&saveptr);
239 buf = strtok_r(NULL,"=",&saveptr);
240 /* buf is now either NULL if there was no second token or
241 * the value we are searchig for
243 if (buf != NULL)
244 buf = strdup(buf);
245 free(input);
246 return buf;