summaryrefslogtreecommitdiffstats
path: root/perl-install/resize_fat/c_rewritten.xs
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/resize_fat/c_rewritten.xs')
-rw-r--r--perl-install/resize_fat/c_rewritten.xs100
1 files changed, 93 insertions, 7 deletions
diff --git a/perl-install/resize_fat/c_rewritten.xs b/perl-install/resize_fat/c_rewritten.xs
index a42f3d133..388f8b9ea 100644
--- a/perl-install/resize_fat/c_rewritten.xs
+++ b/perl-install/resize_fat/c_rewritten.xs
@@ -4,8 +4,10 @@
/* set by scan_fat, used by next */
short *fat = NULL;
+char *fat_flag_map = NULL;
+unsigned int *fat_remap = NULL;
+int fat_remap_size;
int type_size, nb_clusters, bad_cluster_value;
-char *fat_flag_map;
unsigned int next(unsigned int cluster) {
short *p = fat + type_size * cluster;
@@ -13,19 +15,63 @@ unsigned int next(unsigned int cluster) {
return type_size == 1 ? *p : *((unsigned int *) p);
}
+void set_next(unsigned int cluster, unsigned int val) {
+ short *p = fat + type_size * cluster;
+ if (cluster > nb_clusters + 2) croak("fat::set_next: cluster %d outside filesystem", cluster);
+ type_size == 1 ? *p : *((unsigned int *) p) = val;
+}
+
MODULE = resize_fat::c_rewritten PACKAGE = resize_fat::c_rewritten
+void
+read_fat(fd, offset, size, magic)
+ int fd
+ int offset
+ int size
+ unsigned char magic
+ PPCODE:
+{
+ fat = (short *) malloc(size);
+ if (lseek(fd, offset, SEEK_SET) != offset ||
+ read(fd, fat, size) != size) {
+ free(fat); fat = NULL;
+ croak("reading FAT failed");
+ }
+ if (magic != *(unsigned char *) fat) {
+ free(fat); fat = NULL;
+ croak("FAT has invalid signature");
+ }
+}
+
void
-scan_fat(fat_, nb_clusters_, type_size_)
- char *fat_
+write_fat(fd, size)
+ int fd
+ int size
+ PPCODE:
+{
+ if (write(fd, fat, size) != size) croak("write_fat: write failed");
+}
+
+void
+free_all()
+ PPCODE:
+#define FREE(p) if (p) free(p), p = NULL;
+ FREE(fat);
+ FREE(fat_flag_map);
+ FREE(fat_remap);
+#undef FREE
+
+void
+scan_fat(nb_clusters_, type_size_)
int nb_clusters_
int type_size_
PPCODE:
+{
unsigned int v;
int free = 0, bad = 0, used = 0;
short *p;
- fat = (short*) fat_; type_size = type_size_; nb_clusters = nb_clusters_;
+ type_size = type_size_; nb_clusters = nb_clusters_;
bad_cluster_value = type_size ? 0xffffff7 : 0xfff7;
if (type_size % 16) fprintf(stderr, "unable to handle type_size"), exit(1);
@@ -42,6 +88,7 @@ scan_fat(fat_, nb_clusters_, type_size_)
PUSHs(sv_2mortal(newSViv(free)));
PUSHs(sv_2mortal(newSViv(bad)));
PUSHs(sv_2mortal(newSViv(used)));
+}
unsigned int
next(unused, cluster)
@@ -52,15 +99,27 @@ next(unused, cluster)
OUTPUT:
RETVAL
+void
+set_next(unused, cluster, val)
+ void *unused
+ unsigned int cluster
+ unsigned int val
+ CODE:
+ set_next(cluster, val);
+
+void
+allocate_fat_flag(size)
+ int size
+ CODE:
+ fat_flag_map = malloc(size);
+
int
-checkFat(fat_flag_map_, cluster, type, name)
- char *fat_flag_map_
+checkFat(cluster, type, name)
unsigned int cluster
int type
char *name
CODE:
int nb = 0;
- fat_flag_map = fat_flag_map_;
for (; cluster < bad_cluster_value; cluster = next(cluster)) {
if (cluster == 0) croak("Bad FAT: unterminated chain for %s\n", name);
@@ -88,3 +147,30 @@ set_flag(cluster, flag)
CODE:
fat_flag_map[cluster] = flag;
+void
+allocate_fat_remap(size)
+ int size
+ CODE:
+ fat_remap_size = size / 4;
+ fat_remap = (unsigned int *) malloc(size);
+
+unsigned int
+fat_remap(cluster)
+ unsigned int cluster
+ CODE:
+ if (cluster >= bad_cluster_value) {
+ RETVAL = cluster; /* special cases */
+ } else {
+ if (fat_remap == NULL) croak("fat_remap NULL in fat_remap");
+ if (cluster >= fat_remap_size) croak("cluster %d >= %d in fat_remap", cluster, fat_remap_size);
+ RETVAL = fat_remap[cluster];
+ }
+ OUTPUT:
+ RETVAL
+
+void
+set_fat_remap(cluster, val)
+ unsigned int cluster
+ unsigned int val
+ CODE:
+ fat_remap[cluster] = val;