void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, char **devname) { DIR *dir; struct dirent *dp; struct stat st; if ((dir = opendir(dirname)) == NULL) return; while ((dp = readdir(dir)) != NULL) { #ifdef _DIRENT_HAVE_D_TYPE if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_BLK && dp->d_type != DT_LNK && dp->d_type != DT_DIR) continue; #endif if (dp->d_name[0] == '.' && ((dp->d_name[1] == 0) || ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) continue; if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 0)) continue; if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { *devname = blkid_strconcat(dirname, "/", dp->d_name); DBG(DEBUG_DEVNO, printf("found 0x%llx at %s\n", (long long)devno, *devname)); break; } if (!list || !S_ISDIR(st.st_mode)) continue; /* add subdirectory (but not symlink) to the list */ #ifdef _DIRENT_HAVE_D_TYPE if (dp->d_type == DT_LNK) continue; if (dp->d_type == DT_UNKNOWN) #endif { if (fstat_at(dirfd(dir), dirname, dp->d_name, &st, 1) || !S_ISDIR(st.st_mode)) continue; /* symlink or lstat() failed */ } if (*dp->d_name == '.' || ( #ifdef _DIRENT_HAVE_D_TYPE dp->d_type == DT_DIR && #endif strcmp(dp->d_name, "shm") == 0)) /* ignore /dev/.{udev,mount,mdadm} and /dev/shm */ continue; add_to_dirlist(dirname, dp->d_name, list); } closedir(dir); return; }
/* * This function finds the pathname to a block device with a given * device number. It returns a pointer to allocated memory to the * pathname on success, and NULL on failure. */ char *ext2fs_find_block_device(dev_t device) { struct dir_list *list = NULL, *new_list = NULL; struct dir_list *current; char *ret_path = NULL; /* * Add the starting directories to search... */ add_to_dirlist("/devices", &list); add_to_dirlist("/devfs", &list); add_to_dirlist("/dev", &list); while (list) { current = list; list = list->next; #ifdef DEBUG printf("Scanning directory %s\n", current->name); #endif scan_dir(current->name, device, &new_list, &ret_path); free(current->name); free(current); if (ret_path) break; /* * If we're done checking at this level, descend to * the next level of subdirectories. (breadth-first) */ if (list == 0) { list = new_list; new_list = 0; } } free_dirlist(&list); free_dirlist(&new_list); return ret_path; }
/** * blkid_devno_to_devname: * @devno: device number * * This function finds the pathname to a block device with a given * device number. * * Returns: a pointer to allocated memory to the pathname on success, * and NULL on failure. */ char *blkid_devno_to_devname(dev_t devno) { struct dir_list *list = NULL, *new_list = NULL; char *devname = NULL; const char **dir; /* * Add the starting directories to search in reverse order of * importance, since we are using a stack... */ for (dir = devdirs; *dir; dir++) add_to_dirlist(*dir, NULL, &list); while (list) { struct dir_list *current = list; list = list->next; DBG(DEBUG_DEVNO, printf("directory %s\n", current->name)); blkid__scan_dir(current->name, devno, &new_list, &devname); free(current->name); free(current); if (devname) break; /* * If we're done checking at this level, descend to * the next level of subdirectories. (breadth-first) */ if (list == NULL) { list = new_list; new_list = NULL; } } free_dirlist(&list); free_dirlist(&new_list); if (!devname) { DBG(DEBUG_DEVNO, printf("blkid: couldn't find devno 0x%04lx\n", (unsigned long) devno)); } else { DBG(DEBUG_DEVNO, printf("found devno 0x%04llx as %s\n", (long long)devno, devname)); } return devname; }
static int scan_dir(char *dirname, dev_t device, struct dir_list **list, char **ret_path) { DIR *dir; struct dirent *dp; char path[1024], *cp; int dirlen; struct stat st; dirlen = strlen(dirname); if ((dir = opendir(dirname)) == NULL) return errno; dp = readdir(dir); while (dp) { if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path)) goto skip_to_next; if (dp->d_name[0] == '.' && ((dp->d_name[1] == 0) || ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) goto skip_to_next; sprintf(path, "%s/%s", dirname, dp->d_name); if (stat(path, &st) < 0) goto skip_to_next; if (S_ISDIR(st.st_mode)) add_to_dirlist(path, list); if (S_ISBLK(st.st_mode) && st.st_rdev == device) { cp = malloc(strlen(path)+1); if (!cp) { closedir(dir); return ENOMEM; } strcpy(cp, path); *ret_path = cp; goto success; } skip_to_next: dp = readdir(dir); } success: closedir(dir); return 0; }
void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list, char **devname) { DIR *dir; struct dirent *dp; char path[1024]; int dirlen; struct stat st; if ((dir = opendir(dirname)) == NULL) return; dirlen = strlen(dirname) + 2; while ((dp = readdir(dir)) != 0) { if (dirlen + strlen(dp->d_name) >= sizeof(path)) continue; if (dp->d_name[0] == '.' && ((dp->d_name[1] == 0) || ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) continue; sprintf(path, "%s/%s", dirname, dp->d_name); if (stat(path, &st) < 0) continue; if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { *devname = blkid_strdup(path); DBG(DEBUG_DEVNO, printf("found 0x%llx at %s (%p)\n", (long long)devno, path, *devname)); break; } if (list && S_ISDIR(st.st_mode) && !lstat(path, &st) && S_ISDIR(st.st_mode)) add_to_dirlist(path, list); } closedir(dir); return; }
static char *scandev_devno_to_devpath(dev_t devno) { struct dir_list *list = NULL, *new_list = NULL; char *devname = NULL; const char **dir; /* * Add the starting directories to search in reverse order of * importance, since we are using a stack... */ for (dir = devdirs; *dir; dir++) add_to_dirlist(*dir, NULL, &list); while (list) { struct dir_list *current = list; list = list->next; DBG(DEVNO, ul_debug("directory %s", current->name)); blkid__scan_dir(current->name, devno, &new_list, &devname); free(current->name); free(current); if (devname) break; /* * If we're done checking at this level, descend to * the next level of subdirectories. (breadth-first) */ if (list == NULL) { list = new_list; new_list = NULL; } } free_dirlist(&list); free_dirlist(&new_list); return devname; }