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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "wheel.h"
struct Wheel *get_wheel_info(const char *basepath, const char *name, char *to_match[], unsigned match_mode) {
DIR *dp;
struct dirent *rec;
struct Wheel *result = NULL;
char package_path[PATH_MAX];
char package_name[NAME_MAX];
strcpy(package_name, name);
tolower_s(package_name);
sprintf(package_path, "%s/%s", basepath, package_name);
dp = opendir(package_path);
if (!dp) {
return NULL;
}
while ((rec = readdir(dp)) != NULL) {
if (!strcmp(rec->d_name, ".") || !strcmp(rec->d_name, "..")) {
continue;
}
char filename[NAME_MAX];
strcpy(filename, rec->d_name);
char *ext = strstr(filename, ".whl");
if (ext) {
*ext = '\0';
} else {
// not a wheel file. nothing to do
continue;
}
size_t match = 0;
size_t pattern_count = 0;
for (; to_match[pattern_count] != NULL; pattern_count++) {
if (strstr(filename, to_match[pattern_count])) {
match++;
}
}
if (!startswith(rec->d_name, name)) {
continue;
}
if (match_mode == WHEEL_MATCH_EXACT && match != pattern_count) {
continue;
}
result = calloc(1, sizeof(*result));
if (!result) {
SYSERROR("Unable to allocate %zu bytes for wheel struct", sizeof(*result));
closedir(dp);
return NULL;
}
result->path_name = realpath(package_path, NULL);
if (!result->path_name) {
SYSERROR("Unable to resolve absolute path to %s: %s", filename, strerror(errno));
wheel_free(&result);
closedir(dp);
return NULL;
}
result->file_name = strdup(rec->d_name);
if (!result->file_name) {
SYSERROR("Unable to allocate bytes for %s: %s", rec->d_name, strerror(errno));
wheel_free(&result);
closedir(dp);
return NULL;
}
size_t parts_total;
char **parts = split(filename, "-", 0);
if (!parts) {
// This shouldn't happen unless a wheel file is present in the
// directory with a malformed file name, or we've managed to
// exhaust the system's memory
SYSERROR("%s has no '-' separators! (Delete this file and try again)", filename);
wheel_free(&result);
closedir(dp);
return NULL;
}
for (parts_total = 0; parts[parts_total] != NULL; parts_total++);
if (parts_total == 5) {
// no build tag
result->distribution = strdup(parts[0]);
result->version = strdup(parts[1]);
result->build_tag = NULL;
result->python_tag = strdup(parts[2]);
result->abi_tag = strdup(parts[3]);
result->platform_tag = strdup(parts[4]);
} else if (parts_total == 6) {
// has build tag
result->distribution = strdup(parts[0]);
result->version = strdup(parts[1]);
result->build_tag = strdup(parts[2]);
result->python_tag = strdup(parts[3]);
result->abi_tag = strdup(parts[4]);
result->platform_tag = strdup(parts[5]);
} else {
SYSERROR("Unknown wheel name format: %s. Expected 5 or 6 strings "
"separated by '-', but got %zu instead", filename, parts_total);
GENERIC_ARRAY_FREE(parts);
wheel_free(&result);
closedir(dp);
return NULL;
}
GENERIC_ARRAY_FREE(parts);
break;
}
closedir(dp);
return result;
}
void wheel_free(struct Wheel **wheel) {
struct Wheel *w = (*wheel);
guard_free(w->path_name);
guard_free(w->file_name);
guard_free(w->distribution);
guard_free(w->version);
guard_free(w->build_tag);
guard_free(w->python_tag);
guard_free(w->abi_tag);
guard_free(w->python_tag);
guard_free(w);
}
|