1 /* vi: set sw=4 ts=4: */
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
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 */
15 /* Do not reallocate all this stuff on each recursion */
16 enum { DEVNAME_MAX
= 256 };
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
];
25 static char *find_block_device_in_dir(struct arena
*ap
)
32 dir
= opendir(ap
->devpath
);
36 len
= strlen(ap
->devpath
);
37 rem
= DEVNAME_MAX
-2 - len
;
40 ap
->devpath
[len
++] = '/';
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)
47 if (S_ISBLK(ap
->st
.st_mode
) && ap
->st
.st_rdev
== ap
->dev
) {
48 retpath
= xstrdup(ap
->devpath
);
51 if (S_ISDIR(ap
->st
.st_mode
)) {
52 /* Do not recurse for '.' and '..' */
53 if (DOT_OR_DOTDOT(entry
->d_name
))
55 retpath
= find_block_device_in_dir(ap
);
65 char* FAST_FUNC
find_block_device(const char *path
)
69 if (stat(path
, &a
.st
) != 0)
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
);