2 * Copyright (c) 2018, SUSE LLC
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
11 * Support repodata with a filelist filtered by a custom filter
27 static Id default_filelist_filter;
32 #define FF_SUB 3 /* FF_END | FF_START */
37 repodata_free_filelistfilter(Repodata *data)
39 if (data->filelistfilter)
41 if (data->filelistfilter != &default_filelist_filter)
42 solv_free(data->filelistfilter);
43 data->filelistfilter = 0;
45 data->filelistfilterdata = solv_free(data->filelistfilterdata);
49 repodata_set_filelistfilter(Repodata *data)
57 if (data->filelistfilter && data->filelistfilter != &default_filelist_filter)
58 data->filelistfilter = solv_free(data->filelistfilter);
59 data->filelistfilterdata = solv_free(data->filelistfilterdata);
60 type = repodata_lookup_type(data, SOLVID_META, REPOSITORY_FILTEREDFILELIST);
61 if (type != REPOKEY_TYPE_IDARRAY)
63 data->filelistfilter = &default_filelist_filter;
67 repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_FILTEREDFILELIST, &q);
70 /* check if this is the default filter */
72 for (i = 0; i < 3; i++)
74 Id id = q.elements[i];
75 const char *g = data->localpool ? stringpool_id2str(&data->spool, id) : pool_id2str(data->repo->pool, id);
76 if (!strcmp(g, "*bin/*"))
78 else if (!strcmp(g, "/etc/*"))
80 else if (!strcmp(g, "/usr/lib/sendmail"))
86 data->filelistfilter = &default_filelist_filter;
90 data->filelistfilter = solv_calloc(q.count * 2 + 1, sizeof(Id));
91 filterdata = solv_calloc_block(1, 1, 255);
94 for (i = j = 0; i < q.count; i++)
96 Id id = q.elements[i];
97 const char *g = data->localpool ? stringpool_id2str(&data->spool, id) : pool_id2str(data->repo->pool, id);
101 if (!id || !g || !*g)
103 for (p = g; *p && t != FF_GLOB; p++)
114 else if (*p == '[' || *p == '?')
118 if (t == FF_END) /* not supported */
120 if (t == FF_START && gl == 5)
122 filterdata = solv_extend(filterdata, nfilterdata, gl + 1, 1, 255);
123 data->filelistfilter[j++] = nfilterdata;
124 data->filelistfilter[j++] = t;
129 strcpy(filterdata + nfilterdata, g);
130 filterdata[nfilterdata + gl - 1] = 0;
134 strcpy(filterdata + nfilterdata, g + 1);
135 filterdata[nfilterdata + gl - 2] = 0;
136 nfilterdata += gl - 1;
139 strcpy(filterdata + nfilterdata, g);
140 nfilterdata += gl + 1;
144 filterdata = solv_realloc(filterdata, nfilterdata);
145 data->filelistfilter[j++] = 0;
146 data->filelistfilterdata = filterdata;
151 repodata_filelistfilter_matches(Repodata *data, const char *str)
154 if (data && !data->filelistfilter)
155 repodata_set_filelistfilter(data);
156 if (!data || data->filelistfilter == &default_filelist_filter)
158 /* '.*bin\/.*', '^\/etc\/.*', '^\/usr\/lib\/sendmail$' */
159 if (strstr(str, "bin/"))
161 if (!strncmp(str, "/etc/", 5))
163 if (!strcmp(str, "/usr/lib/sendmail"))
167 for (ff = data->filelistfilter; *ff; ff += 2)
169 const char *g = data->filelistfilterdata + *ff;
177 if (!strncmp(str, g, strlen(g)))
185 if (!strncmp(str, g, 5))
189 if (!fnmatch(g, str, 0))