source: MondoRescue/branches/stable/mindi-busybox/e2fsprogs/ext2fs/finddev.c @ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 14 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 4.0 KB
RevLine 
[821]1/*
2 * finddev.c -- this routine attempts to find a particular device in
3 *  /dev
4 *
5 * Copyright (C) 2000 Theodore Ts'o.
6 *
7 * %Begin-Header%
8 * This file may be redistributed under the terms of the GNU Public
9 * License.
10 * %End-Header%
11 */
12
13#include <stdio.h>
14#include <string.h>
15#if HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18#include <stdlib.h>
19#include <string.h>
20#if HAVE_SYS_TYPES_H
21#include <sys/types.h>
22#endif
23#if HAVE_SYS_STAT_H
24#include <sys/stat.h>
25#endif
26#include <dirent.h>
27#if HAVE_ERRNO_H
28#include <errno.h>
29#endif
30#if HAVE_SYS_MKDEV_H
31#include <sys/mkdev.h>
32#endif
33
34#include "ext2_fs.h"
35#include "ext2fs.h"
36
37struct dir_list {
38    char    *name;
39    struct dir_list *next;
40};
41
42/*
43 * This function adds an entry to the directory list
44 */
45static void add_to_dirlist(const char *name, struct dir_list **list)
46{
47    struct dir_list *dp;
48
49    dp = xmalloc(sizeof(struct dir_list));
50    dp->name = xmalloc(strlen(name)+1);
51    strcpy(dp->name, name);
52    dp->next = *list;
53    *list = dp;
54}
55
56/*
57 * This function frees a directory list
58 */
59static void free_dirlist(struct dir_list **list)
60{
61    struct dir_list *dp, *next;
62
63    for (dp = *list; dp; dp = next) {
64        next = dp->next;
65        free(dp->name);
66        free(dp);
67    }
68    *list = 0;
69}
70
71static int scan_dir(char *dir_name, dev_t device, struct dir_list **list,
72            char **ret_path)
73{
74    DIR *dir;
75    struct dirent *dp;
76    char    path[1024], *cp;
77    int dirlen;
78    struct stat st;
79
80    dirlen = strlen(dir_name);
81    if ((dir = opendir(dir_name)) == NULL)
82        return errno;
83    dp = readdir(dir);
84    while (dp) {
85        if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
86            goto skip_to_next;
87        if (dp->d_name[0] == '.' &&
88            ((dp->d_name[1] == 0) ||
89             ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
90            goto skip_to_next;
91        sprintf(path, "%s/%s", dir_name, dp->d_name);
92        if (stat(path, &st) < 0)
93            goto skip_to_next;
94        if (S_ISDIR(st.st_mode))
95            add_to_dirlist(path, list);
96        if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
97            cp = xmalloc(strlen(path)+1);
98            strcpy(cp, path);
99            *ret_path = cp;
100            goto success;
101        }
102    skip_to_next:
103        dp = readdir(dir);
104    }
105success:
106    closedir(dir);
107    return 0;
108}
109
110/*
111 * This function finds the pathname to a block device with a given
112 * device number.  It returns a pointer to allocated memory to the
113 * pathname on success, and NULL on failure.
114 */
115char *ext2fs_find_block_device(dev_t device)
116{
117    struct dir_list *list = 0, *new_list = 0;
118    struct dir_list *current;
119    char    *ret_path = 0;
120
121    /*
122     * Add the starting directories to search...
123     */
124    add_to_dirlist("/devices", &list);
125    add_to_dirlist("/devfs", &list);
126    add_to_dirlist("/dev", &list);
127
128    while (list) {
129        current = list;
130        list = list->next;
131#ifdef DEBUG
132        printf("Scanning directory %s\n", current->name);
133#endif
134        scan_dir(current->name, device, &new_list, &ret_path);
135        free(current->name);
136        free(current);
137        if (ret_path)
138            break;
139        /*
140         * If we're done checking at this level, descend to
141         * the next level of subdirectories. (breadth-first)
142         */
143        if (list == 0) {
144            list = new_list;
145            new_list = 0;
146        }
147    }
148    free_dirlist(&list);
149    free_dirlist(&new_list);
150    return ret_path;
151}
152
153
154#ifdef DEBUG
155int main(int argc, char** argv)
156{
157    char    *devname, *tmp;
158    int major, minor;
159    dev_t   device;
160    const char *errmsg = "Couldn't parse %s: %s\n";
161
162    if ((argc != 2) && (argc != 3)) {
163        fprintf(stderr, "Usage: %s device_number\n", argv[0]);
164        fprintf(stderr, "\t: %s major minor\n", argv[0]);
165        exit(1);
166    }
167    if (argc == 2) {
168        device = strtoul(argv[1], &tmp, 0);
169        if (*tmp) {
170            fprintf(stderr, errmsg, "device number", argv[1]);
171            exit(1);
172        }
173    } else {
174        major = strtoul(argv[1], &tmp, 0);
175        if (*tmp) {
176            fprintf(stderr, errmsg, "major number", argv[1]);
177            exit(1);
178        }
179        minor = strtoul(argv[2], &tmp, 0);
180        if (*tmp) {
181            fprintf(stderr, errmsg, "minor number", argv[2]);
182            exit(1);
183        }
184        device = makedev(major, minor);
185        printf("Looking for device 0x%04x (%d:%d)\n", device,
186               major, minor);
187    }
188    devname = ext2fs_find_block_device(device);
189    if (devname) {
190        printf("Found device!  %s\n", devname);
191        free(devname);
192    } else {
193        printf("Couldn't find device.\n");
194    }
195    return 0;
196}
197
198#endif
Note: See TracBrowser for help on using the repository browser.