119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * finddev.c -- this routine attempts to find a particular device in 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * /dev 43984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2000 Theodore Ts'o. 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library 98558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2. 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_UNISTD_H 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h> 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_SYS_TYPES_H 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h> 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_SYS_STAT_H 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/stat.h> 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <dirent.h> 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_ERRNO_H 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_SYS_MKDEV_H 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/mkdev.h> 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_fs.h" 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs.h" 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct dir_list { 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *name; 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_list *next; 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function adds an entry to the directory list 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void add_to_dirlist(const char *name, struct dir_list **list) 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_list *dp; 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dp = malloc(sizeof(struct dir_list)); 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!dp) 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dp->name = malloc(strlen(name)+1); 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!dp->name) { 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(dp); 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strcpy(dp->name, name); 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dp->next = *list; 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *list = dp; 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function frees a directory list 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void free_dirlist(struct dir_list **list) 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_list *dp, *next; 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (dp = *list; dp; dp = next) { 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project next = dp->next; 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(dp->name); 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(dp); 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *list = 0; 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int scan_dir(char *dirname, dev_t device, struct dir_list **list, 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char **ret_path) 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project DIR *dir; 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dirent *dp; 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char path[1024], *cp; 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int dirlen; 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct stat st; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirlen = strlen(dirname); 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((dir = opendir(dirname)) == NULL) 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return errno; 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dp = readdir(dir); 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (dp) { 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path)) 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto skip_to_next; 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dp->d_name[0] == '.' && 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((dp->d_name[1] == 0) || 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto skip_to_next; 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sprintf(path, "%s/%s", dirname, dp->d_name); 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (stat(path, &st) < 0) 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto skip_to_next; 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (S_ISDIR(st.st_mode)) 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project add_to_dirlist(path, list); 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (S_ISBLK(st.st_mode) && st.st_rdev == device) { 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = malloc(strlen(path)+1); 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!cp) { 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project closedir(dir); 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ENOMEM; 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strcpy(cp, path); 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *ret_path = cp; 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto success; 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project skip_to_next: 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dp = readdir(dir); 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectsuccess: 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project closedir(dir); 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function finds the pathname to a block device with a given 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * device number. It returns a pointer to allocated memory to the 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * pathname on success, and NULL on failure. 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectchar *ext2fs_find_block_device(dev_t device) 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_list *list = 0, *new_list = 0; 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dir_list *current; 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *ret_path = 0; 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Add the starting directories to search... 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project add_to_dirlist("/devices", &list); 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project add_to_dirlist("/devfs", &list); 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project add_to_dirlist("/dev", &list); 1373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (list) { 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project current = list; 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project list = list->next; 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Scanning directory %s\n", current->name); 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project scan_dir(current->name, device, &new_list, &ret_path); 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(current->name); 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(current); 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ret_path) 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we're done checking at this level, descend to 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the next level of subdirectories. (breadth-first) 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (list == 0) { 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project list = new_list; 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project new_list = 0; 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free_dirlist(&list); 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free_dirlist(&new_list); 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret_path; 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char** argv) 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *devname, *tmp; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int major, minor; 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dev_t device; 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const char *errmsg = "Couldn't parse %s: %s\n"; 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((argc != 2) && (argc != 3)) { 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, "Usage: %s device_number\n", argv[0]); 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, "\t: %s major minor\n", argv[0]); 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (argc == 2) { 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project device = strtoul(argv[1], &tmp, 0); 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*tmp) { 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, errmsg, "device number", argv[1]); 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project major = strtoul(argv[1], &tmp, 0); 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*tmp) { 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, errmsg, "major number", argv[1]); 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project minor = strtoul(argv[2], &tmp, 0); 19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*tmp) { 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, errmsg, "minor number", argv[2]); 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project device = makedev(major, minor); 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Looking for device 0x%04x (%d:%d)\n", device, 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project major, minor); 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project devname = ext2fs_find_block_device(device); 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (devname) { 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Found device! %s\n", devname); 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(devname); 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Couldn't find device.\n"); 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 2073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 209