• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/fstools/libfstools/find.c

  1 /*
  2  * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU Lesser General Public License version 2.1
  6  * as published by the Free Software Foundation
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11  * GNU General Public License for more details.
 12  */
 13 
 14 #include <errno.h>
 15 #include <stdio.h>
 16 #include <string.h>
 17 #include <sys/stat.h>
 18 #include <sys/sysmacros.h>
 19 
 20 #include "libfstools.h"
 21 
 22 int
 23 find_overlay_mount(char *overlay)
 24 {
 25         FILE *fp = fopen("/proc/mounts", "r");
 26         size_t len = strlen(overlay);
 27         static char line[256];
 28         int ret = -1;
 29 
 30         if(!fp)
 31                 return ret;
 32 
 33         while (ret && fgets(line, sizeof(line), fp))
 34                 if (len < sizeof(line) && !strncmp(line, overlay, len) && line[len] == ' ')
 35                         ret = 0;
 36 
 37         fclose(fp);
 38 
 39         return ret;
 40 }
 41 
 42 /*
 43  * Find path of a device mounted to the given point.
 44  */
 45 char*
 46 find_mount(char *mp)
 47 {
 48         FILE *fp = fopen("/proc/mounts", "r");
 49         static char line[256];
 50 
 51         if(!fp)
 52                 return NULL;
 53 
 54         while (fgets(line, sizeof(line), fp)) {
 55                 char *s, *t = strstr(line, " ");
 56 
 57                 if (!t) {
 58                         fclose(fp);
 59                         return NULL;
 60                 }
 61                 *t = '\0';
 62                 t++;
 63                 s = strstr(t, " ");
 64                 if (!s) {
 65                         fclose(fp);
 66                         return NULL;
 67                 }
 68                 *s = '\0';
 69 
 70                 if (!strcmp(t, mp)) {
 71                         fclose(fp);
 72                         return line;
 73                 }
 74         }
 75 
 76         fclose(fp);
 77 
 78         return NULL;
 79 }
 80 
 81 /*
 82  * Match filesystem type against a bunch of valid types
 83  *
 84  * jffs2reset may ask if the filesystem type is actually ready for use
 85  * with overlayfs before wiping it...
 86  */
 87 static int fs_rootfs_only(char *fstype)
 88 {
 89         if (strncmp(fstype, "ext4", 4) &&
 90             strncmp(fstype, "f2fs", 4) &&
 91             strncmp(fstype, "jffs2", 5) &&
 92             strncmp(fstype, "ubifs", 5)) {
 93                 ULOG_ERR("block is mounted with wrong fs\n");
 94                 return 1;
 95         }
 96         return 0;
 97 }
 98 
 99 /*
100  * Check if a given device is mounted and return its mountpoint
101  */
102 char*
103 find_mount_point(char *block, int root_only)
104 {
105         FILE *fp = fopen("/proc/self/mountinfo", "r");
106         static char line[256];
107         char *point = NULL, *pos, *tmp, *cpoint, *devname, *fstype;
108         struct stat s;
109         int rstat;
110         unsigned int minor, major;
111 
112         if (!block)
113                 return NULL;
114 
115         if (!fp)
116                 return NULL;
117 
118         rstat = stat(block, &s);
119 
120         while (fgets(line, sizeof(line), fp)) {
121                 /* skip first two columns */
122                 pos = strchr(line, ' ');
123                 if (!pos)
124                         continue;
125 
126                 pos = strchr(pos + 1, ' ');
127                 if (!pos)
128                         continue;
129 
130                 /* extract block device major:minor */
131                 tmp = ++pos;
132                 pos = strchr(pos, ':');
133                 if (!pos)
134                         continue;
135 
136                 *pos = '\0';
137                 major = atoi(tmp);
138 
139                 tmp = ++pos;
140                 pos = strchr(pos, ' ');
141                 if (!pos)
142                         continue;
143 
144                 *pos = '\0';
145                 minor = atoi(tmp);
146 
147                 /* skip another column */
148                 pos = strchr(pos + 1, ' ');
149                 if (!pos)
150                         continue;
151 
152                 /* get mountpoint */
153                 tmp = ++pos;
154                 pos = strchr(pos, ' ');
155                 if (!pos)
156                         continue;
157 
158                 *pos = '\0';
159                 cpoint = tmp;
160 
161                 /* skip another two columns */
162                 pos = strchr(pos + 1, ' ');
163                 if (!pos)
164                         continue;
165 
166                 pos = strchr(pos + 1, ' ');
167                 if (!pos)
168                         continue;
169 
170                 /* get fstype */
171                 tmp = ++pos;
172                 pos = strchr(pos, ' ');
173                 if (!pos)
174                         continue;
175 
176                 *pos = '\0';
177                 fstype = tmp;
178 
179                 /* get device name */
180                 tmp = ++pos;
181                 pos = strchr(pos, ' ');
182                 if (!pos)
183                         continue;
184 
185                 *pos = '\0';
186                 devname = tmp;
187 
188                 /* if device name matches */
189                 if (!strcmp(block, devname)) {
190                         if (root_only && fs_rootfs_only(fstype))
191                                 break;
192 
193                         /* found, return mountpoint */
194                         point = strdup(cpoint);
195                         break;
196                 }
197 
198                 /* last chance: check if major:minor of block device match */
199                 if (rstat)
200                         continue;
201 
202                 if (!S_ISBLK(s.st_mode))
203                         continue;
204 
205                 if (major == major(s.st_rdev) &&
206                     minor == minor(s.st_rdev)) {
207                         if (root_only && fs_rootfs_only(fstype))
208                                 break;
209 
210                         /* found, return mountpoint */
211                         point = strdup(cpoint);
212                         break;
213                 }
214         }
215 
216         fclose(fp);
217 
218         return point;
219 }
220 
221 int
222 find_filesystem(char *fs)
223 {
224         FILE *fp = fopen("/proc/filesystems", "r");
225         static char line[256];
226         int ret = -1;
227 
228         if (!fp) {
229                 ULOG_ERR("opening /proc/filesystems failed: %m\n");
230                 goto out;
231         }
232 
233         while (ret && fgets(line, sizeof(line), fp))
234                 if (strstr(line, fs))
235                         ret = 0;
236 
237         fclose(fp);
238 
239 out:
240         return ret;
241 }
242 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt