|
9 | 9 | #include "iomanX_port.h" |
10 | 10 | #include "hl.h" |
11 | 11 |
|
| 12 | +unsigned int total_sectors = 0; |
| 13 | + |
12 | 14 | typedef struct |
13 | 15 | { |
14 | 16 | int setup; |
@@ -156,6 +158,63 @@ static int do_lcd(context_t *ctx, int argc, char *argv[]) |
156 | 158 | /* chdir would set errno on error */ |
157 | 159 | return (chdir(argv[1])); |
158 | 160 | } |
| 161 | +static int do_df(context_t *ctx, int argc, char *argv[]) |
| 162 | +{ |
| 163 | + char tmp[256]; |
| 164 | + if (!ctx->mount) { /* not mounted */ |
| 165 | + strcpy(tmp, "hdd0:"); |
| 166 | + unsigned int used_sectors = 0; |
| 167 | + int result; |
| 168 | + iox_dirent_t dirent; |
| 169 | + int dh = iomanX_dopen(tmp); |
| 170 | + while ((result = iomanX_dread(dh, &dirent)) && result != -1) { |
| 171 | + if (dirent.stat.mode != 0x0000 && dirent.stat.attr == 0) { |
| 172 | + used_sectors += dirent.stat.private_1; |
| 173 | + } |
| 174 | + } |
| 175 | + iomanX_close(dh); |
| 176 | + unsigned int free_sectors = total_sectors + 1 - used_sectors; |
| 177 | + |
| 178 | + printf("Device Size Used Avail Capacity\n"); |
| 179 | + printf("%s %4uGiB %4uGiB %4uGiB %3u%%\n", |
| 180 | + tmp, |
| 181 | + (total_sectors + 1) / (2048 * 1024), |
| 182 | + used_sectors / (2048 * 1024), |
| 183 | + free_sectors / (2048 * 1024), |
| 184 | + (used_sectors * 100) / (total_sectors + 1)); |
| 185 | + } else { /* mounted ctx->mount*/ |
| 186 | + iox_stat_t stat; |
| 187 | + int dh = iomanX_getstat(ctx->mount_point, &stat); |
| 188 | + if (dh < 0) { |
| 189 | + fprintf(stderr, "(!) Unable to get stats for %s: %s.\n", ctx->mount_point, strerror(-dh)); |
| 190 | + return (dh); |
| 191 | + } |
| 192 | + unsigned int total_pfs_sectors = stat.private_1 - stat.private_0 * 4 - 4 * 1024 * 2; /* 4 MiB for main header, 2 KiB for each subpartition */ |
| 193 | + |
| 194 | + strcpy(tmp, "pfs0:"); |
| 195 | + unsigned int frsize = iomanX_devctl(tmp, PDIOC_ZONESZ, NULL, 0, NULL, 0); |
| 196 | + unsigned int bavail = iomanX_devctl(tmp, PDIOC_ZONEFREE, NULL, 0, NULL, 0); |
| 197 | + unsigned int free_sectors = frsize * bavail / 512; /* 512 bytes per sector */ |
| 198 | + printf("free sectors: %08x\n", free_sectors); |
| 199 | + printf("Device Size Used Avail Capacity\n"); |
| 200 | + if (total_pfs_sectors / 2048 < 10000) { |
| 201 | + printf("%32s %4uMiB %4uMiB %4uMiB %3u%%\n", |
| 202 | + ctx->mount_point + 5, |
| 203 | + total_pfs_sectors / 2048, |
| 204 | + (total_pfs_sectors - free_sectors) / 2048, |
| 205 | + free_sectors / 2048, |
| 206 | + ((total_pfs_sectors - free_sectors) * 100) / total_pfs_sectors); |
| 207 | + } else { |
| 208 | + printf("%32s %4uGiB %4uGiB %4uGiB %3u%%\n", |
| 209 | + ctx->mount_point + 5, |
| 210 | + total_pfs_sectors / (2048 * 1024), |
| 211 | + (total_pfs_sectors - free_sectors) / (2048 * 1024), |
| 212 | + free_sectors / (2048 * 1024), |
| 213 | + ((total_pfs_sectors - free_sectors) * 100) / total_pfs_sectors); |
| 214 | + } |
| 215 | + } |
| 216 | + return (0); |
| 217 | +} |
159 | 218 |
|
160 | 219 | /* where (image of) PS2 HDD is; in fake_sdk/atad.c */ |
161 | 220 | extern void set_atad_device_path(const char *path); |
@@ -201,6 +260,8 @@ static int do_device(context_t *ctx, int argc, char *argv[]) |
201 | 260 | exit(1); |
202 | 261 | } |
203 | 262 | ctx->setup = 1; |
| 263 | + total_sectors = iomanX_devctl("hdd0:", HDIOC_TOTALSECTOR, NULL, 0, NULL, 0); |
| 264 | + do_df(ctx, 0, NULL); /* display free space on partition */ |
204 | 265 | return (0); |
205 | 266 | } |
206 | 267 |
|
@@ -634,16 +695,17 @@ static int do_help(context_t *ctx, int argc, char *argv[]) |
634 | 695 | "ls [-l] - no mount: list partitions; mount: list files/dirs; -l: verbose list;\n" |
635 | 696 | "rename <curr_name> <new_name> - no mount: rename partition; mount: rename a file/dir.\n" |
636 | 697 | "mkdir <dir_name> - create a new directory;\n" |
637 | | - "rmdir <dir_name> - delete an existing directory;\n" |
| 698 | + "rmdir <dir_name> - delete an existing empty directory;\n" |
638 | 699 | "pwd - print current PS2 HDD directory;\n" |
639 | 700 | "cd <dir_name> - change directory;\n" |
640 | 701 | "get <file_name> - copy file from PS2 HDD to current dir;\n" |
641 | 702 | "put <file_name> - copy file from current dir to PS2 HDD;\n" |
642 | 703 | "\tfile name must not contain a path;\n" |
643 | 704 | "rm <file_name> - delete a file;\n" |
644 | | - "rename <curr_name> <new_name> - rename a file/dir.\n" |
| 705 | + "rename <curr_name> <new_name> - rename a file/dir/partition.\n" |
645 | 706 | "rmpart <part_name> - remove partition (destructive).\n" |
646 | | - "exit - exits the program. (Do this before you unplug your HDD)\n", |
| 707 | + "df - display free space on partition.\n" |
| 708 | + "exit/quit/bye - exits the program. (Do this before you unplug your HDD)\n", |
647 | 709 | stderr); |
648 | 710 | return (0); |
649 | 711 | } |
@@ -680,6 +742,7 @@ static int exec(void *data, int argc, char *argv[]) |
680 | 742 | {"put", 1, need_device + need_mount, &do_put}, |
681 | 743 | {"rm", 1, need_device + need_mount, &do_rm}, |
682 | 744 | {"rmpart", 1, need_device, &do_rmpart}, |
| 745 | + {"df", 0, need_device, &do_df}, |
683 | 746 | {"rename", 2, need_device, &do_rename}, |
684 | 747 | {"help", 0, no_req, &do_help}, |
685 | 748 | }; |
|
0 commit comments