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