1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
/* set by scan_fat, used by next */
short *fat = NULL;
int type_size, nb_clusters, bad_cluster_value;
char *fat_flag_map;
unsigned int next(unsigned int cluster) {
short *p = fat + type_size * cluster;
if (cluster > nb_clusters + 2) croak("fat::next: cluster %d outside filesystem", cluster);
return type_size == 1 ? *p : *((unsigned int *) p);
}
MODULE = resize_fat::c_rewritten PACKAGE = resize_fat::c_rewritten
void
scan_fat(fat_, nb_clusters_, type_size_)
char *fat_
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_;
bad_cluster_value = type_size ? 0xffffff7 : 0xfff7;
if (type_size % 16) fprintf(stderr, "unable to handle type_size"), exit(1);
type_size /= 16;
for (p = fat + 2 * type_size; p < fat + type_size * (nb_clusters + 2); p += type_size) {
v = type_size == 1 ? *p : *((unsigned int *) p);
if (v == 0) free++;
else if (v == bad_cluster_value) bad++;
}
used = nb_clusters - free - bad;
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(free)));
PUSHs(sv_2mortal(newSViv(bad)));
PUSHs(sv_2mortal(newSViv(used)));
unsigned int
next(unused, cluster)
void *unused
unsigned int cluster
CODE:
RETVAL = next(cluster);
OUTPUT:
RETVAL
int
checkFat(fat_flag_map_, cluster, type, name)
char *fat_flag_map_
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);
if (fat_flag_map[cluster]) croak("Bad FAT: cluster $cluster is cross-linked for %s\n", name);
fat_flag_map[cluster] = type;
nb++;
}
RETVAL = nb;
OUTPUT:
RETVAL
unsigned int
flag(cluster)
unsigned int cluster
CODE:
RETVAL = fat_flag_map[cluster];
OUTPUT:
RETVAL
void
set_flag(cluster, flag)
unsigned int cluster
int flag
CODE:
fat_flag_map[cluster] = flag;
|