Skip to content

Commit e516a6d

Browse files
committed
Add 'df' command to display free space on the mounted partition or on the whole hdd
1 parent 2d8b89a commit e516a6d

2 files changed

Lines changed: 80 additions & 13 deletions

File tree

src/iomanX_port.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ extern int _init_hdlfs(int argc, char *argv[]);
8787
#define FIO_S_IXOTH 0x0001 // execute
8888

8989
// File mode checking macros
90-
#define FIO_S_ISLNK(m) (((m)&FIO_S_IFMT) == FIO_S_IFLNK)
91-
#define FIO_S_ISREG(m) (((m)&FIO_S_IFMT) == FIO_S_IFREG)
92-
#define FIO_S_ISDIR(m) (((m)&FIO_S_IFMT) == FIO_S_IFDIR)
90+
#define FIO_S_ISLNK(m) (((m) & FIO_S_IFMT) == FIO_S_IFLNK)
91+
#define FIO_S_ISREG(m) (((m) & FIO_S_IFMT) == FIO_S_IFREG)
92+
#define FIO_S_ISDIR(m) (((m) & FIO_S_IFMT) == FIO_S_IFDIR)
9393

9494
/* File attributes that are retrieved using the getstat and dread calls, and
9595
set using chstat. */
@@ -102,11 +102,15 @@ extern int _init_hdlfs(int argc, char *argv[]);
102102
#define HIOCNSUB 0x6803
103103
#define HIOCFLUSH 0x6804
104104

105+
// DEVCTL commands
106+
#define HDIOC_TOTALSECTOR 0x4802
107+
#define HDIOC_FREESECTOR 0x480A
108+
105109
// Arbitrarily-named commands
106-
#define HIOCTRANSFER 0x6832 // Used by PFS.IRX to read/write data
107-
#define HIOCGETSIZE 0x6833 // For main(0)/subs(1+)
108-
#define HIOCSETPARTERROR 0x6834 // Set (sector of a partition) that has an error
109-
#define HIOCGETPARTERROR 0x6835 // Get (sector of a partition) that has an error
110+
#define HIOCTRANSFER 0x6832 // Used by PFS.IRX to read/write data
111+
#define HIOCGETSIZE 0x6833 // For main(0)/subs(1+)
112+
#define HIOCSETPARTERROR 0x6834 // Set (sector of a partition) that has an error
113+
#define HIOCGETPARTERROR 0x6835 // Get (sector of a partition) that has an error
110114

111115
// pfs
112116

@@ -162,11 +166,11 @@ typedef struct
162166
/*1c*/ unsigned char mtime[8];
163167
/*24*/ unsigned int hisize;
164168
/*28*/ unsigned int private_0; // Number of subs (main) / subpart number (sub)
165-
/*2c*/ unsigned int private_1;
166-
/*30*/ unsigned int private_2;
169+
/*2c*/ unsigned int private_1; // partition size low part
170+
/*30*/ unsigned int private_2; // partition size high part
167171
/*34*/ unsigned int private_3;
168172
/*38*/ unsigned int private_4;
169-
/*3c*/ unsigned int private_5; /* Sector start. */
173+
/*3c*/ unsigned int private_5; // Sector start
170174
} iox_stat_t;
171175

172176
typedef struct

src/shell.c

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "iomanX_port.h"
1010
#include "hl.h"
1111

12+
unsigned int total_sectors = 0;
13+
1214
typedef struct
1315
{
1416
int setup;
@@ -156,6 +158,63 @@ static int do_lcd(context_t *ctx, int argc, char *argv[])
156158
/* chdir would set errno on error */
157159
return (chdir(argv[1]));
158160
}
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+
}
159218

160219
/* where (image of) PS2 HDD is; in fake_sdk/atad.c */
161220
extern void set_atad_device_path(const char *path);
@@ -201,6 +260,8 @@ static int do_device(context_t *ctx, int argc, char *argv[])
201260
exit(1);
202261
}
203262
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 */
204265
return (0);
205266
}
206267

@@ -634,16 +695,17 @@ static int do_help(context_t *ctx, int argc, char *argv[])
634695
"ls [-l] - no mount: list partitions; mount: list files/dirs; -l: verbose list;\n"
635696
"rename <curr_name> <new_name> - no mount: rename partition; mount: rename a file/dir.\n"
636697
"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"
638699
"pwd - print current PS2 HDD directory;\n"
639700
"cd <dir_name> - change directory;\n"
640701
"get <file_name> - copy file from PS2 HDD to current dir;\n"
641702
"put <file_name> - copy file from current dir to PS2 HDD;\n"
642703
"\tfile name must not contain a path;\n"
643704
"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"
645706
"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",
647709
stderr);
648710
return (0);
649711
}
@@ -680,6 +742,7 @@ static int exec(void *data, int argc, char *argv[])
680742
{"put", 1, need_device + need_mount, &do_put},
681743
{"rm", 1, need_device + need_mount, &do_rm},
682744
{"rmpart", 1, need_device, &do_rmpart},
745+
{"df", 0, need_device, &do_df},
683746
{"rename", 2, need_device, &do_rename},
684747
{"help", 0, no_req, &do_help},
685748
};

0 commit comments

Comments
 (0)