* Add ipkg for future development
[project/opkg-lede.git] / pkg_vec.c
1 /* pkg_vec.c - the itsy package management system
2
3 Steven M. Ayer
4
5 Copyright (C) 2002 Compaq Computer Corporation
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16 */
17
18 #include <stdlib.h>
19 #include <fnmatch.h>
20 #include "xregex.h"
21 #include "ipkg.h"
22 #include "pkg.h"
23
24 pkg_vec_t * pkg_vec_alloc(void)
25 {
26 pkg_vec_t * vec = (pkg_vec_t *)malloc(sizeof(pkg_vec_t));
27 if (!vec) {
28 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
29 return NULL;
30 }
31 vec->pkgs = NULL;
32 vec->len = 0;
33
34 return vec;
35 }
36
37 void pkg_vec_free(pkg_vec_t *vec)
38 {
39 free(vec->pkgs);
40 free(vec);
41 }
42
43 /*
44 * assumption: all names in a vector are identical
45 * assumption: all version strings are trimmed,
46 * so identical versions have identical version strings,
47 * implying identical packages; let's marry these
48 */
49 pkg_t *pkg_vec_insert_merge(pkg_vec_t *vec, pkg_t *pkg, int set_status,ipkg_conf_t *conf)
50 {
51 int i;
52 int found = 0;
53
54 /* look for a duplicate pkg by name, version, and architecture */
55 for (i = 0; i < vec->len; i++){
56 ipkg_message(conf, IPKG_DEBUG2, "Function: %s. Found pkg=%s version=%s arch=%s cmp=%s version=%s arch=%s \n",
57 __FUNCTION__, pkg->name, pkg->version, pkg->architecture,
58 vec->pkgs[i]->name, vec->pkgs[i]->version,vec->pkgs[i]->architecture );
59 if ((strcmp(pkg->name, vec->pkgs[i]->name) == 0)
60 && (pkg_compare_versions(pkg, vec->pkgs[i]) == 0)
61 && (strcmp(pkg->architecture, vec->pkgs[i]->architecture) == 0)) {
62 found = 1;
63 ipkg_message(conf, IPKG_DEBUG2, "Function: %s. Found duplicate for pkg=%s version=%s arch=%s\n",
64 __FUNCTION__, pkg->name, pkg->version, pkg->architecture);
65 break;
66 }
67 }
68
69 /* we didn't find one, add it */
70 if (!found){
71 ipkg_message(conf, IPKG_DEBUG2, "Function: %s. Adding new pkg=%s version=%s arch=%s\n",
72 __FUNCTION__, pkg->name, pkg->version, pkg->architecture);
73
74 vec->pkgs = (pkg_t **)realloc(vec->pkgs, (vec->len + 1) * sizeof(pkg_t *));
75 vec->pkgs[vec->len] = pkg;
76 vec->len++;
77 return pkg;
78 }
79 /* update the one that we have */
80 else {
81 ipkg_message(conf, IPKG_DEBUG2, "Function: %s. calling pkg_merge for pkg=%s version=%s arch=%s",
82 __FUNCTION__, pkg->name, pkg->version, pkg->architecture);
83 if (set_status) {
84 /* this is from the status file, so need to merge with existing database */
85 ipkg_message(conf, IPKG_DEBUG2, " with set_status\n");
86 pkg_merge(vec->pkgs[i], pkg, set_status);
87 /* XXX: CLEANUP: It's not so polite to free something here
88 that was passed in from above. */
89 pkg_deinit(pkg);
90 free(pkg);
91 } else {
92 ipkg_message(conf, IPKG_DEBUG2, " WITHOUT set_status\n");
93 /* just overwrite the old one */
94 pkg_deinit(vec->pkgs[i]);
95 free(vec->pkgs[i]);
96 vec->pkgs[i] = pkg;
97 }
98 return vec->pkgs[i];
99 }
100 }
101
102 void pkg_vec_insert(pkg_vec_t *vec, const pkg_t *pkg)
103 {
104 int i;
105 int found = 0;
106
107 /* look for a duplicate pkg by name, version, and architecture */
108 for (i = 0; i < vec->len; i++)
109 if ((strcmp(pkg->name, vec->pkgs[i]->name) == 0)
110 && (pkg_compare_versions(pkg, vec->pkgs[i]) == 0)
111 && (strcmp(pkg->architecture, vec->pkgs[i]->name) == 0)) {
112 found = 1;
113 break;
114 }
115
116 /* we didn't find one, add it */
117 if(!found){
118 vec->pkgs = (pkg_t **)realloc(vec->pkgs, (vec->len + 1) * sizeof(pkg_t *));
119 *(const pkg_t **)&vec->pkgs[vec->len] = pkg;
120 vec->len++;
121 }
122 }
123
124 int pkg_vec_contains(pkg_vec_t *vec, pkg_t *apkg)
125 {
126 int i;
127 for (i = 0; i < vec->len; i++)
128 if (vec->pkgs[i] == apkg)
129 return 1;
130 return 0;
131 }
132
133 typedef int (*compare_fcn_t)(const void *, const void *);
134 void pkg_vec_sort(pkg_vec_t *vec, int (*compar)(pkg_t *, pkg_t *))
135 {
136 qsort(vec->pkgs, vec->len, sizeof(pkg_t *), (compare_fcn_t)compar);
137 }
138
139 int pkg_vec_clear_marks(pkg_vec_t *vec)
140 {
141 int npkgs = vec->len;
142 int i;
143 for (i = 0; i < npkgs; i++) {
144 pkg_t *pkg = vec->pkgs[i];
145 pkg->state_flag &= ~SF_MARKED;
146 }
147 return 0;
148 }
149
150 int pkg_vec_mark_if_matches(pkg_vec_t *vec, const char *pattern)
151 {
152 int matching_count = 0;
153 pkg_t **pkgs = vec->pkgs;
154 int npkgs = vec->len;
155 int i;
156 for (i = 0; i < npkgs; i++) {
157 pkg_t *pkg = pkgs[i];
158 if (fnmatch(pattern, pkg->name, 0)==0) {
159 pkg->state_flag |= SF_MARKED;
160 matching_count++;
161 }
162 }
163 return matching_count;
164 }
165
166
167 abstract_pkg_vec_t * abstract_pkg_vec_alloc(void)
168 {
169 abstract_pkg_vec_t * vec ;
170 vec = (abstract_pkg_vec_t *)malloc(sizeof(abstract_pkg_vec_t));
171 if (!vec) {
172 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
173 return NULL;
174 }
175 vec->pkgs = NULL;
176 vec->len = 0;
177
178 return vec;
179 }
180
181 void abstract_pkg_vec_free(abstract_pkg_vec_t *vec)
182 {
183 free(vec->pkgs);
184 free(vec);
185 }
186
187 /*
188 * assumption: all names in a vector are unique
189 */
190 void abstract_pkg_vec_insert(abstract_pkg_vec_t *vec, abstract_pkg_t *pkg)
191 {
192 int i;
193
194 /* look for a duplicate pkg by name */
195 for(i = 0; i < vec->len; i++)
196 if (strcmp(pkg->name, vec->pkgs[i]->name) == 0)
197 break;
198
199 /* we didn't find one, add it */
200 if(i == vec->len){
201 vec->pkgs =
202 (abstract_pkg_t **)
203 realloc(vec->pkgs, (vec->len + 1) * sizeof(abstract_pkg_t *));
204 vec->pkgs[vec->len] = pkg;
205 vec->len++;
206 }
207 }
208
209 abstract_pkg_t * abstract_pkg_vec_get(abstract_pkg_vec_t *vec, int i)
210 {
211 if (vec->len > i)
212 return vec->pkgs[i];
213 else
214 return NULL;
215 }
216
217 int abstract_pkg_vec_contains(abstract_pkg_vec_t *vec, abstract_pkg_t *apkg)
218 {
219 int i;
220 for (i = 0; i < vec->len; i++)
221 if (vec->pkgs[i] == apkg)
222 return 1;
223 return 0;
224 }
225
226 void abstract_pkg_vec_sort(pkg_vec_t *vec, int (*compar)(abstract_pkg_t *, abstract_pkg_t *))
227 {
228 qsort(vec->pkgs, vec->len, sizeof(pkg_t *), (compare_fcn_t)compar);
229 }
230