int get_disk_size(const char *disk_name, u64 *size_in_kilobytes) { FILE *fp; char target_file[64], buf[16], *ptr; if(size_in_kilobytes == NULL) return 0; *size_in_kilobytes = 0; // initial value. if(disk_name == NULL || !is_disk_name(disk_name)) return 0; sprintf(target_file, "%s/%s/size", SYS_BLOCK, disk_name); if((fp = fopen(target_file, "r")) == NULL) return 0; memset(buf, 0, sizeof(buf)); ptr = fgets(buf, sizeof(buf), fp); fclose(fp); if(ptr == NULL) return 0; *size_in_kilobytes = ((u64)strtoll(buf, NULL, 10))/2; return 1; }
char *get_disk_model(const char *disk_name, char *buf, const int buf_size) { FILE *fp; char target_file[64], *ptr; int len; if(buf_size <= 0) return NULL; if(disk_name == NULL || !is_disk_name(disk_name)) return NULL; sprintf(target_file, "%s/%s/device/model", SYS_BLOCK, disk_name); if((fp = fopen(target_file, "r")) == NULL) return NULL; memset(buf, 0, buf_size); ptr = fgets(buf, buf_size, fp); fclose(fp); if(ptr == NULL) return NULL; len = strlen(buf); buf[len-1] = 0; return buf; }
int get_disk_major_minor(const char *disk_name, u32 *major, u32 *minor) { FILE *fp; char target_file[64], buf[8], *ptr; if(major == NULL || minor == NULL) return 0; *major = 0; // initial value. *minor = 0; // initial value. if(disk_name == NULL || !is_disk_name(disk_name)) return 0; sprintf(target_file, "%s/%s/dev", SYS_BLOCK, disk_name); if((fp = fopen(target_file, "r")) == NULL) return 0; memset(buf, 0, sizeof(buf)); ptr = fgets(buf, sizeof(buf), fp); fclose(fp); if(ptr == NULL) return 0; if((ptr = strchr(buf, ':')) == NULL) return 0; ptr[0] = '\0'; *major = (u32)strtol(buf, NULL, 10); *minor = (u32)strtol(ptr+1, NULL, 10); return 1; }
char *get_disk_name(const char *string, char *buf, const int buf_size){ int len; if(string == NULL || buf_size <= 0) return NULL; if(!is_disk_name(string) && !is_partition_name(string, NULL)) return NULL; len = strlen(string); if(!is_disk_name(string)){ while(isdigit(string[len-1])) --len; } if(len > buf_size) return NULL; memset(buf, 0, buf_size); strncpy(buf, string, len); return buf; }
int get_disk_partitionnumber(const char *string, u32 *partition_number, u32 *mounted_number) { DIR *dp; char disk_name[8]; char target_path[64]; struct dirent *file; int len; if(partition_number == NULL) return 0; *partition_number = 0; // initial value. if(mounted_number != NULL) *mounted_number = 0; // initial value. if(string == NULL) return 0; len = strlen(string); if(!is_disk_name(string)){ while(isdigit(string[len-1])) --len; } memset(disk_name, 0, sizeof(disk_name)); strncpy(disk_name, string, len); sprintf(target_path, "%s/%s", SYS_BLOCK, disk_name); if((dp = opendir(target_path)) == NULL) return 0; len = strlen(disk_name); while((file = readdir(dp)) != NULL){ if(file->d_name[0] == '.') continue; if(!strncmp(file->d_name, disk_name, len)){ ++(*partition_number); if(mounted_number == NULL) continue; if (is_device_mounted(file->d_name)) ++(*mounted_number); } } closedir(dp); return 1; }
int main(int argc, char *argv[]){ disk_info_t *disk_info, *disk_list; partition_info_t *partition_info; char buf[PATH_MAX]; usb_dbg("%d: Using myself to get information:\n", VERSION); if(argc == 3){ get_mount_path("sdb1", buf, PATH_MAX); printf("buf=%s.\n", buf); } else if(argc == 2){ if(is_disk_name(argv[1])){ // Disk usb_dbg("%d: Get disk(%s)'s information:\n", VERSION, argv[1]); create_disk(argv[1], &disk_info); print_disk(disk_info); free_disk_data(&disk_info); } else{ usb_dbg("%d: Get partition(%s)'s information:\n", VERSION, argv[1]); create_partition(argv[1], &partition_info); print_partition(partition_info); free_partition_data(&partition_info); } } else{ usb_dbg("%d: Get all Disk information:\n", VERSION); disk_list = read_disk_data(); print_disks(disk_list); free_disk_data(&disk_list); } return 0; }
partition_info_t *create_partition(const char *device_name, partition_info_t **new_part_info) { partition_info_t *follow_part_info; u32 partition_order; u64 size_in_kilobytes = 0, total_kilobytes = 0, used_kilobytes = 0; char buf1[PATH_MAX], buf2[64], buf3[PATH_MAX]; // options of mount info needs more buffer size. int len; if(new_part_info == NULL) return NULL; *new_part_info = NULL; // initial value. if(device_name == NULL || get_device_type_by_device(device_name) != DEVICE_TYPE_DISK) return NULL; if(!is_disk_name(device_name) && !is_partition_name(device_name, &partition_order)) return NULL; if(initial_part_data(&follow_part_info) == NULL) return NULL; len = strlen(device_name); follow_part_info->device = (char *)malloc(len+1); if(!follow_part_info->device){ free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->device, device_name, len); follow_part_info->device[len] = 0; follow_part_info->partition_order = partition_order; if(read_mount_data(device_name, buf1, buf2, buf3)){ len = strlen(buf1); follow_part_info->mount_point = (char *)malloc(len+1); if(!follow_part_info->mount_point){ free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->mount_point, buf1, len); follow_part_info->mount_point[len] = 0; len = strlen(buf2); follow_part_info->file_system = (char *)malloc(len+1); if(!follow_part_info->file_system){ free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->file_system, buf2, len); follow_part_info->file_system[len] = 0; len = strlen(buf3); follow_part_info->permission = (char *)malloc(len+1); if(!follow_part_info->permission){ free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->permission, buf3, len); follow_part_info->permission[len] = 0; if(get_mount_size(follow_part_info->mount_point, &total_kilobytes, &used_kilobytes)){ follow_part_info->size_in_kilobytes = total_kilobytes; follow_part_info->used_kilobytes = used_kilobytes; } } else{ if(is_disk_name(device_name)){ // Disk free_partition_data(&follow_part_info); return NULL; } else{ len = strlen(PARTITION_TYPE_UNKNOWN); follow_part_info->file_system = (char *)malloc(len+1); if(!follow_part_info->file_system){ free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->file_system, PARTITION_TYPE_UNKNOWN, len); follow_part_info->file_system[len] = 0; get_partition_size(device_name, &size_in_kilobytes); follow_part_info->size_in_kilobytes = size_in_kilobytes; } } *new_part_info = follow_part_info; return *new_part_info; }
disk_info_t *read_disk_data(void) { FILE *fp; char line[64], device_name[32]; u32 major, minor; disk_info_t *disk_info_list, *parent_disk_info, **follow_disk_info_list; partition_info_t *new_partition_info, **follow_partition_list; unsigned long long device_size; fp = fopen(PARTITION_FILE, "r"); if (!fp) return NULL; if (!fgets(line, sizeof(line), fp)) { fclose(fp); return NULL; } fgets(line, sizeof(line), fp); disk_info_list = NULL; while (fgets(line, sizeof(line), fp)) { device_name[0] = 0; if (sscanf(line, "%u %u %llu %[^\n ]", &major, &minor, &device_size, device_name) != 4) continue; if(major != USB_DISK_MAJOR) continue; if(device_size < 10) continue; if (is_disk_name(device_name)) { follow_disk_info_list = &disk_info_list; while(*follow_disk_info_list) follow_disk_info_list = &((*follow_disk_info_list)->next); create_disk(device_name, follow_disk_info_list); } else if (is_partition_name(device_name, NULL)) { parent_disk_info = disk_info_list; while(1) { if (!parent_disk_info) goto info_exit; if (!strncmp(device_name, parent_disk_info->device, 3)) break; parent_disk_info = parent_disk_info->next; } follow_partition_list = &(parent_disk_info->partitions); while(*follow_partition_list) follow_partition_list = &((*follow_partition_list)->next); new_partition_info = create_partition(device_name, follow_partition_list); if(new_partition_info) new_partition_info->disk = parent_disk_info; } } info_exit: fclose(fp); return disk_info_list; }
disk_info_t *create_disk(const char *device_name, disk_info_t **new_disk_info) { disk_info_t *follow_disk_info; u32 major, minor; u64 size_in_kilobytes = 0; int len; char buf[128], *vendor, *model, *ptr; partition_info_t *new_partition_info, **follow_partition_list; if(!new_disk_info) return NULL; *new_disk_info = NULL; // initial value. vendor = NULL; model = NULL; if(!device_name || !is_disk_name(device_name)) return NULL; if(!initial_disk_data(&follow_disk_info)) return NULL; len = strlen(device_name); follow_disk_info->device = (char *)malloc(len+1); if (!follow_disk_info->device){ free_disk_data(follow_disk_info); return NULL; } strcpy(follow_disk_info->device, device_name); if(!get_disk_major_minor(device_name, &major, &minor)){ free_disk_data(follow_disk_info); return NULL; } follow_disk_info->major = major; follow_disk_info->minor = minor; if(!get_disk_size(device_name, &size_in_kilobytes)){ free_disk_data(follow_disk_info); return NULL; } follow_disk_info->size_in_kilobytes = size_in_kilobytes; if(!strncmp(device_name, "sd", 2)){ if(!get_usb_root_port_by_device(device_name, buf, sizeof(buf))){ free_disk_data(follow_disk_info); return NULL; } len = strlen(buf); if(len > 0){ int port_num = get_usb_root_port_number(buf); if (port_num < 0) port_num = 0; follow_disk_info->port_root = port_num; } // start get vendor. if(!get_disk_vendor(device_name, buf, sizeof(buf))){ free_disk_data(follow_disk_info); return NULL; } len = strlen(buf); if(len > 0){ vendor = (char *)malloc(len+1); if(!vendor){ free_disk_data(follow_disk_info); return NULL; } strcpy(vendor, buf); strntrim(vendor); sanity_name(vendor); follow_disk_info->vendor = vendor; } // start get model. if(get_disk_model(device_name, buf, sizeof(buf)) == NULL){ free_disk_data(follow_disk_info); return NULL; } len = strlen(buf); if(len > 0){ model = (char *)malloc(len+1); if(!model){ free_disk_data(follow_disk_info); return NULL; } strcpy(model, buf); strntrim(model); sanity_name(model); follow_disk_info->model = model; } // get USB's tag memset(buf, 0, sizeof(buf)); len = 0; ptr = buf; if(vendor){ len += strlen(vendor); strcpy(ptr, vendor); ptr += len; } if(model){ if(len > 0){ ++len; // Add a space between vendor and model. strcpy(ptr, " "); ++ptr; } len += strlen(model); strcpy(ptr, model); ptr += len; } if(len > 0){ follow_disk_info->tag = (char *)malloc(len+1); if(!follow_disk_info->tag){ free_disk_data(follow_disk_info); return NULL; } strcpy(follow_disk_info->tag, buf); } else{ len = strlen(DEFAULT_USB_TAG); follow_disk_info->tag = (char *)malloc(len+1); if(!follow_disk_info->tag){ free_disk_data(follow_disk_info); return NULL; } strcpy(follow_disk_info->tag, DEFAULT_USB_TAG); } follow_partition_list = &(follow_disk_info->partitions); while(*follow_partition_list) follow_partition_list = &((*follow_partition_list)->next); new_partition_info = create_partition(device_name, follow_partition_list); if(new_partition_info){ new_partition_info->disk = follow_disk_info; ++(follow_disk_info->partition_number); ++(follow_disk_info->mounted_number); } } if(follow_disk_info->partition_number == 0) get_disk_partitionnumber(device_name, &(follow_disk_info->partition_number), &(follow_disk_info->mounted_number)); *new_disk_info = follow_disk_info; return *new_disk_info; }
int get_disk_partitionnumber(const char *string, u32 *partition_number, u32 *mounted_number){ char disk_name[8]; char target_path[128]; DIR *dp; struct dirent *file; int len; char *mount_info = NULL, target[8]; if(string == NULL) return 0; if(partition_number == NULL) return 0; *partition_number = 0; // initial value. if(mounted_number != NULL){ *mounted_number = 0; // initial value. mount_info = read_whole_file(MOUNT_FILE); } len = strlen(string); if(!is_disk_name(string)){ while(isdigit(string[len-1])) --len; } else if(mounted_number != NULL && mount_info != NULL){ memset(target, 0, 8); sprintf(target, "%s ", string); if(strstr(mount_info, target) != NULL) ++(*mounted_number); } memset(disk_name, 0, 8); strncpy(disk_name, string, len); memset(target_path, 0, 128); sprintf(target_path, "%s/%s", SYS_BLOCK, disk_name); if((dp = opendir(target_path)) == NULL){ if(mount_info != NULL) free(mount_info); return 0; } len = strlen(disk_name); while((file = readdir(dp)) != NULL){ if(file->d_name[0] == '.') continue; if(!strncmp(file->d_name, disk_name, len)){ ++(*partition_number); if(mounted_number == NULL || mount_info == NULL) continue; memset(target, 0, 8); sprintf(target, "%s ", file->d_name); if(strstr(mount_info, target) != NULL) ++(*mounted_number); } } closedir(dp); if(mount_info != NULL) free(mount_info); return 1; }
disk_info_t *create_disk(const char *device_name, disk_info_t **new_disk_info){ disk_info_t *follow_disk_info; u32 major, minor; u64 size_in_kilobytes = 0; int len; char usb_node[32], port_path[8]; char buf[64], *port, *vendor = NULL, *model = NULL, *ptr; partition_info_t *new_partition_info, **follow_partition_list; if(new_disk_info == NULL){ usb_dbg("Bad input!!\n"); return NULL; } *new_disk_info = NULL; // initial value. if(device_name == NULL || !is_disk_name(device_name)) return NULL; if(initial_disk_data(&follow_disk_info) == NULL){ usb_dbg("No memory!!(follow_disk_info)\n"); return NULL; } len = strlen(device_name); follow_disk_info->device = (char *)malloc(len+1); if(follow_disk_info->device == NULL){ usb_dbg("No memory!!(follow_disk_info->device)\n"); free_disk_data(&follow_disk_info); return NULL; } strcpy(follow_disk_info->device, device_name); follow_disk_info->device[len] = 0; if(!get_disk_major_minor(device_name, &major, &minor)){ usb_dbg("Fail to get disk's major and minor: %s.\n", device_name); free_disk_data(&follow_disk_info); return NULL; } follow_disk_info->major = major; follow_disk_info->minor = minor; if(!get_disk_size(device_name, &size_in_kilobytes)){ usb_dbg("Fail to get disk's size_in_kilobytes: %s.\n", device_name); free_disk_data(&follow_disk_info); return NULL; } follow_disk_info->size_in_kilobytes = size_in_kilobytes; if(!strncmp(device_name, "sd", 2)){ // Get USB node. if(get_usb_node_by_device(device_name, usb_node, 32) == NULL){ usb_dbg("(%s): Fail to get usb node.\n", device_name); free_disk_data(&follow_disk_info); return NULL; } if(get_path_by_node(usb_node, port_path, 8) == NULL){ usb_dbg("(%s): Fail to get usb path.\n", usb_node); free_disk_data(&follow_disk_info); return NULL; } // Get USB port. if(get_usb_port_by_string(usb_node, buf, 64) == NULL){ usb_dbg("Fail to get usb port: %s.\n", usb_node); free_disk_data(&follow_disk_info); return NULL; } len = strlen(buf); if(len > 0){ port = (char *)malloc(8); if(port == NULL){ usb_dbg("No memory!!(port)\n"); free_disk_data(&follow_disk_info); return NULL; } memset(port, 0, 8); strncpy(port, port_path, 8); follow_disk_info->port = port; } // start get vendor. if(get_disk_vendor(device_name, buf, 64) == NULL){ usb_dbg("Fail to get disk's vendor: %s.\n", device_name); free_disk_data(&follow_disk_info); return NULL; } len = strlen(buf); if(len > 0){ vendor = (char *)malloc(len+1); if(vendor == NULL){ usb_dbg("No memory!!(vendor)\n"); free_disk_data(&follow_disk_info); return NULL; } strncpy(vendor, buf, len); vendor[len] = 0; strntrim(vendor); follow_disk_info->vendor = vendor; } // start get model. if(get_disk_model(device_name, buf, 64) == NULL){ usb_dbg("Fail to get disk's model: %s.\n", device_name); free_disk_data(&follow_disk_info); return NULL; } len = strlen(buf); if(len > 0){ model = (char *)malloc(len+1); if(model == NULL){ usb_dbg("No memory!!(model)\n"); free_disk_data(&follow_disk_info); return NULL; } strncpy(model, buf, len); model[len] = 0; strntrim(model); follow_disk_info->model = model; } // get USB's tag memset(buf, 0, 64); len = 0; ptr = buf; if(vendor != NULL){ len += strlen(vendor); strcpy(ptr, vendor); ptr += len; } if(model != NULL){ if(len > 0){ ++len; // Add a space between vendor and model. strcpy(ptr, " "); ++ptr; } len += strlen(model); strcpy(ptr, model); ptr += len; } if(len > 0){ follow_disk_info->tag = (char *)malloc(len+1); if(follow_disk_info->tag == NULL){ usb_dbg("No memory!!(follow_disk_info->tag)\n"); free_disk_data(&follow_disk_info); return NULL; } strcpy(follow_disk_info->tag, buf); follow_disk_info->tag[len] = 0; } else{ len = strlen(DEFAULT_USB_TAG); follow_disk_info->tag = (char *)malloc(len+1); if(follow_disk_info->tag == NULL){ usb_dbg("No memory!!(follow_disk_info->tag)\n"); free_disk_data(&follow_disk_info); return NULL; } strcpy(follow_disk_info->tag, DEFAULT_USB_TAG); follow_disk_info->tag[len] = 0; } follow_partition_list = &(follow_disk_info->partitions); while(*follow_partition_list != NULL) follow_partition_list = &((*follow_partition_list)->next); new_partition_info = create_partition(device_name, follow_partition_list); if(new_partition_info != NULL){ new_partition_info->disk = follow_disk_info; ++(follow_disk_info->partition_number); ++(follow_disk_info->mounted_number); if(!strcmp(new_partition_info->device, follow_disk_info->device)) new_partition_info->size_in_kilobytes = follow_disk_info->size_in_kilobytes-4; } } if(!strcmp(follow_disk_info->device, follow_disk_info->partitions->device)) get_disk_partitionnumber(device_name, &(follow_disk_info->partition_number), &(follow_disk_info->mounted_number)); *new_disk_info = follow_disk_info; return *new_disk_info; }
disk_info_t *read_disk_data(){ disk_info_t *disk_info_list = NULL, *new_disk_info, **follow_disk_info_list; char *partition_info = read_whole_file(PARTITION_FILE); char *follow_info; char line[64], device_name[16]; u32 major; disk_info_t *parent_disk_info; partition_info_t *new_partition_info, **follow_partition_list; u64 device_size; if(partition_info == NULL){ usb_dbg("Failed to open \"%s\"!!\n", PARTITION_FILE); return disk_info_list; } follow_info = partition_info; memset(device_name, 0, 16); while(get_line_from_buffer(follow_info, line, 64) != NULL){ follow_info += strlen(line); if(sscanf(line, "%u %*u %llu %[^\n ]", &major, &device_size, device_name) != 3) continue; if(major != USB_DISK_MAJOR) continue; if(device_size == 1) // extend partition. continue; if(is_disk_name(device_name)){ // Disk follow_disk_info_list = &disk_info_list; while(*follow_disk_info_list != NULL) follow_disk_info_list = &((*follow_disk_info_list)->next); new_disk_info = create_disk(device_name, follow_disk_info_list); } else if(is_partition_name(device_name, NULL)){ // Partition // Found a partition device. // Find the parent disk. parent_disk_info = disk_info_list; while(1){ if(parent_disk_info == NULL){ usb_dbg("Error while parsing %s: found " "partition '%s' but haven't seen the disk device " "of which it is a part.\n", PARTITION_FILE, device_name); free(partition_info); return disk_info_list; } if(!strncmp(device_name, parent_disk_info->device, 3)) break; parent_disk_info = parent_disk_info->next; } follow_partition_list = &(parent_disk_info->partitions); while(*follow_partition_list != NULL){ if((*follow_partition_list)->partition_order == 0){ free_partition_data(follow_partition_list); parent_disk_info->partitions = NULL; follow_partition_list = &(parent_disk_info->partitions); } else follow_partition_list = &((*follow_partition_list)->next); } new_partition_info = create_partition(device_name, follow_partition_list); if(new_partition_info != NULL) new_partition_info->disk = parent_disk_info; } } free(partition_info); return disk_info_list; }
partition_info_t *create_partition(const char *device_name, partition_info_t **new_part_info){ partition_info_t *follow_part_info; char label[128]; u32 partition_order = 0; u64 size_in_kilobytes = 0, total_kilobytes = 0, used_kilobytes = 0; char buf1[PATH_MAX], buf2[64], buf3[PATH_MAX]; // options of mount info needs more buffer size. int len; if(new_part_info == NULL){ usb_dbg("Bad input!!\n"); return NULL; } *new_part_info = NULL; // initial value. if(device_name == NULL || get_device_type_by_device(device_name) != DEVICE_TYPE_DISK) return NULL; if(!is_disk_name(device_name) && !is_partition_name(device_name, &partition_order)) return NULL; if(initial_part_data(&follow_part_info) == NULL){ usb_dbg("No memory!!(follow_part_info)\n"); return NULL; } len = strlen(device_name); follow_part_info->device = (char *)malloc(len+1); if(follow_part_info->device == NULL){ usb_dbg("No memory!!(follow_part_info->device)\n"); free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->device, device_name, len); follow_part_info->device[len] = 0; if(find_partition_label(device_name, label)){ strntrim(label); len = strlen(label); follow_part_info->label = (char *)malloc(len+1); if(follow_part_info->label == NULL){ usb_dbg("No memory!!(follow_part_info->label)\n"); free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->label, label, len); follow_part_info->label[len] = 0; } follow_part_info->partition_order = partition_order; if(read_mount_data(device_name, buf1, PATH_MAX, buf2, 64, buf3, PATH_MAX)){ len = strlen(buf1); follow_part_info->mount_point = (char *)malloc(len+1); if(follow_part_info->mount_point == NULL){ usb_dbg("No memory!!(follow_part_info->mount_point)\n"); free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->mount_point, buf1, len); follow_part_info->mount_point[len] = 0; len = strlen(buf2); follow_part_info->file_system = (char *)malloc(len+1); if(follow_part_info->file_system == NULL){ usb_dbg("No memory!!(follow_part_info->file_system)\n"); free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->file_system, buf2, len); follow_part_info->file_system[len] = 0; len = strlen(buf3); follow_part_info->permission = (char *)malloc(len+1); if(follow_part_info->permission == NULL){ usb_dbg("No memory!!(follow_part_info->permission)\n"); free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->permission, buf3, len); follow_part_info->permission[len] = 0; if(get_mount_size(follow_part_info->mount_point, &total_kilobytes, &used_kilobytes)){ follow_part_info->size_in_kilobytes = total_kilobytes; follow_part_info->used_kilobytes = used_kilobytes; } } else{ /*if(is_disk_name(device_name)){ // Disk free_partition_data(&follow_part_info); return NULL; } else{//*/ len = strlen(PARTITION_TYPE_UNKNOWN); follow_part_info->file_system = (char *)malloc(len+1); if(follow_part_info->file_system == NULL){ usb_dbg("No memory!!(follow_part_info->file_system)\n"); free_partition_data(&follow_part_info); return NULL; } strncpy(follow_part_info->file_system, PARTITION_TYPE_UNKNOWN, len); follow_part_info->file_system[len] = 0; get_partition_size(device_name, &size_in_kilobytes); follow_part_info->size_in_kilobytes = size_in_kilobytes; //} } *new_part_info = follow_part_info; return *new_part_info; }