FILE *devscan_open(struct charlist **fslist) { FILE *f; struct charlist *fl; char line[80]; /* Get a list of all filesystems registered in the kernel */ fl = scan_filesystems(); if (NULL == fl) { return NULL; } /* Get a list of available partitions on all devices * See kernel/block/genhd.c for details on interface */ f = fopen("/proc/partitions", "r"); if (NULL == f) { log_msg(lg, "Can't open /proc/partitions: %s", ERRMSG); goto free_fl; } // First two lines are bogus. fgets(line, sizeof(line), f); fgets(line, sizeof(line), f); *fslist = fl; return f; free_fl: free_charlist(fl); return NULL; }
/* Create charlist of known filesystems */ struct charlist *scan_filesystems() { char *split; struct charlist *fl; char line[80]; fl = create_charlist(8); // make a list of all known filesystems FILE *f = fopen("/proc/filesystems", "r"); if (NULL == f) { log_msg(lg, "+ can't open /proc/filesystems: %s", ERRMSG); free_charlist(fl); return NULL; } while (fgets(line, sizeof(line), f)) { line[strlen(line) - 1] = '\0'; /* kill last '\n' */ split = strchr(line, '\t'); split++; addto_charlist(fl, split); /* NOTE: strdup() may return NULL */ } fclose(f); return fl; }
int scan_devices(struct params_t *params) { struct charlist *fl; struct bootconf_t *bootconf; struct device_t dev; struct cfgdata_t cfgdata; int rc,n; FILE *f; char mount_dev[16]; char mount_fstype[16]; char str_mtd_id[3]; #ifdef USE_ICONS kx_cfg_section *sc; int i; int rows; char **xpm_data; #endif bootconf = create_bootcfg(4); if (NULL == bootconf) { DPRINTF("Can't allocate bootconf structure"); return -1; } f = devscan_open(&fl); if (NULL == f) { log_msg(lg, "Can't initiate device scan"); return -1; } #ifdef USE_ZAURUS struct zaurus_partinfo_t pinfo; int zaurus_error = 0; zaurus_error = zaurus_read_partinfo(&pinfo); if (0 == zaurus_error) { /* Fix mtdparts tag */ dispose(params->cfg->mtdparts); params->cfg->mtdparts = zaurus_mtdparts(&pinfo); } #endif for (;;) { rc = devscan_next(f, fl, &dev); if (rc < 0) continue; /* Error */ if (0 == rc) break; /* EOF */ /* initialize with defaults */ strcpy(mount_dev, dev.device); strcpy(mount_fstype, dev.fstype); /* We found an ubi erase counter */ if (!strncmp(dev.fstype, "ubi",3)) { /* attach ubi boot device - mtd id [0-15] */ if(isdigit(atoi(dev.device+strlen(dev.device)-2))) { strcpy(str_mtd_id, dev.device+strlen(dev.device)-2); strcat(str_mtd_id, dev.device+strlen(dev.device)-1); } else { strcpy(str_mtd_id, dev.device+strlen(dev.device)-1); } n = ubi_attach(str_mtd_id); /* we have attached ubiX and we mount /dev/ubiX_0 */ sprintf(mount_dev, "/dev/ubi%d", n); /* HARDCODED: first volume */ strcat(mount_dev, "_0"); /* HARDCODED: we assume it's ubifs */ strcpy(mount_fstype, "ubifs"); } /* Mount device */ if (-1 == mount(mount_dev, MOUNTPOINT, mount_fstype, MS_RDONLY, NULL)) { log_msg(lg, "+ can't mount device %s: %s", mount_dev, ERRMSG); goto free_device; } /* NOTE: Don't go out before umount'ing */ /* Search boot method and return boot info */ rc = get_bootinfo(&cfgdata); if (-1 == rc) { /* Error */ goto umount; } #ifdef USE_ICONS /* Iterate over sections found */ if (params->gui) { for (i = 0; i < cfgdata.count; i++) { sc = cfgdata.list[i]; if (!sc) continue; /* Load custom icon */ if (sc->iconpath) { rows = xpm_load_image(&xpm_data, sc->iconpath); if (-1 == rows) { log_msg(lg, "+ can't load xpm icon %s", sc->iconpath); continue; } sc->icondata = xpm_parse_image(xpm_data, rows); if (!sc->icondata) { log_msg(lg, "+ can't parse xpm icon %s", sc->iconpath); continue; } xpm_destroy_image(xpm_data, rows); } } } #endif umount: /* Umount device */ if (-1 == umount(MOUNTPOINT)) { log_msg(lg, "+ can't umount device: %s", ERRMSG); goto free_cfgdata; } if (-1 == rc) { /* Error */ goto free_cfgdata; } #ifdef USE_ZAURUS /* Fix partition sizes. We can have kernel in root and home partitions on NAND */ /* HACK: mtdblock devices are hardcoded */ if (0 == zaurus_error) { if (0 == strcmp(dev.device, "/dev/mtdblock2")) { /* root */ log_msg(lg, "+ [zaurus root] size of %s will be changed from %llu to %lu", dev.device, dev.blocks, pinfo.root); dev.blocks = pinfo.root; } else if (0 == strcmp(dev.device, "/dev/mtdblock3")) { /* home */ log_msg(lg, "+ [zaurus home] size of %s will be changed from %llu to %lu", dev.device, dev.blocks, pinfo.home); dev.blocks = pinfo.home; } } #endif /* Now we have something in cfgdata */ rc = addto_bootcfg(bootconf, &dev, &cfgdata); free_cfgdata: destroy_cfgdata(&cfgdata); free_device: free(dev.device); } free_charlist(fl); params->bootcfg = bootconf; return 0; }