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
127
128
129
130
131
132
133
|
#include "wheelinfo.h"
struct WheelInfo *wheelinfo_get(const char *basepath, const char *name, char *to_match[], unsigned match_mode) {
struct dirent *rec;
struct WheelInfo *result = NULL;
char package_path[PATH_MAX];
char package_name[NAME_MAX];
strncpy(package_name, name, sizeof(package_name) - 1);
package_name[sizeof(package_name) - 1] = '\0';
tolower_s(package_name);
snprintf(package_path, sizeof(package_path), "%s/%s", basepath, package_name);
DIR *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];
strncpy(filename, rec->d_name, sizeof(filename) - 1);
filename[sizeof(filename) - 1] = '\0';
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));
wheelinfo_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));
wheelinfo_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);
wheelinfo_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);
guard_array_free(parts);
wheelinfo_free(&result);
closedir(dp);
return NULL;
}
guard_array_free(parts);
break;
}
closedir(dp);
return result;
}
void wheelinfo_free(struct WheelInfo **wheel) {
struct WheelInfo *w = (*wheel);
if (!w) {
return;
}
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->platform_tag);
guard_free(w);
}
|