Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/libbb/find_root_device.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/libbb/find_root_device.c
r821 r1770 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 */ 21 9 22 #include <limits.h>23 #include <stdio.h>24 #include <string.h>25 #include <dirent.h>26 #include <stdlib.h>27 10 #include "libbb.h" 28 11 29 char *find_block_device(char *path) 12 /* Find block device /dev/XXX which contains specified file 13 * We handle /dev/dir/dir/dir too, at a cost of ~80 more bytes code */ 14 15 /* Do not reallocate all this stuff on each recursion */ 16 enum { DEVNAME_MAX = 256 }; 17 struct arena { 18 struct stat st; 19 dev_t dev; 20 /* Was PATH_MAX, but we recurse _/dev_. We can assume 21 * people are not crazy enough to have mega-deep tree there */ 22 char devpath[DEVNAME_MAX]; 23 }; 24 25 static char *find_block_device_in_dir(struct arena *ap) 30 26 { 31 27 DIR *dir; 32 28 struct dirent *entry; 33 struct stat st; 34 dev_t dev; 35 char *retpath=NULL; 29 char *retpath = NULL; 30 int len, rem; 36 31 37 if(stat(path, &st) || !(dir = opendir("/dev"))) return NULL; 38 dev = (st.st_mode & S_IFMT) == S_IFBLK ? st.st_rdev : st.st_dev; 39 while((entry = readdir(dir)) != NULL) { 40 char devpath[PATH_MAX]; 41 sprintf(devpath,"/dev/%s", entry->d_name); 42 if(!stat(devpath, &st) && S_ISBLK(st.st_mode) && st.st_rdev == dev) { 43 retpath = bb_xstrdup(devpath); 32 dir = opendir(ap->devpath); 33 if (!dir) 34 return NULL; 35 36 len = strlen(ap->devpath); 37 rem = DEVNAME_MAX-2 - len; 38 if (rem <= 0) 39 return NULL; 40 ap->devpath[len++] = '/'; 41 42 while ((entry = readdir(dir)) != NULL) { 43 safe_strncpy(ap->devpath + len, entry->d_name, rem); 44 /* lstat: do not follow links */ 45 if (lstat(ap->devpath, &ap->st) != 0) 46 continue; 47 if (S_ISBLK(ap->st.st_mode) && ap->st.st_rdev == ap->dev) { 48 retpath = xstrdup(ap->devpath); 44 49 break; 50 } 51 if (S_ISDIR(ap->st.st_mode)) { 52 /* Do not recurse for '.' and '..' */ 53 if (DOT_OR_DOTDOT(entry->d_name)) 54 continue; 55 retpath = find_block_device_in_dir(ap); 56 if (retpath) 57 break; 45 58 } 46 59 } … … 49 62 return retpath; 50 63 } 64 65 char *find_block_device(const char *path) 66 { 67 struct arena a; 68 69 if (stat(path, &a.st) != 0) 70 return NULL; 71 a.dev = S_ISBLK(a.st.st_mode) ? a.st.st_rdev : a.st.st_dev; 72 strcpy(a.devpath, "/dev"); 73 return find_block_device_in_dir(&a); 74 }
Note:
See TracChangeset
for help on using the changeset viewer.