1 /* pkg_vec.c - the opkg 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 <stdio.h> 19 #include <fnmatch.h> 20 21 #include "pkg.h" 22 #include "opkg_message.h" 23 #include "libbb/libbb.h" 24 25 pkg_vec_t *pkg_vec_alloc(void) 26 { 27 pkg_vec_t *vec = xcalloc(1, sizeof(pkg_vec_t)); 28 vec->pkgs = NULL; 29 vec->len = 0; 30 31 return vec; 32 } 33 34 void pkg_vec_free(pkg_vec_t * vec) 35 { 36 if (!vec) 37 return; 38 39 if (vec->pkgs) 40 free(vec->pkgs); 41 42 free(vec); 43 } 44 45 /* 46 * assumption: all names in a vector are identical 47 * assumption: all version strings are trimmed, 48 * so identical versions have identical version strings, 49 * implying identical packages; let's marry these 50 */ 51 void pkg_vec_insert_merge(pkg_vec_t * vec, pkg_t * pkg, int set_status) 52 { 53 int i; 54 int found = 0; 55 char *pkg_version = pkg_get_string(pkg, PKG_VERSION); 56 char *pkg_architecture = pkg_get_architecture(pkg); 57 char *vec_architecture; 58 59 /* look for a duplicate pkg by name, version, and architecture */ 60 for (i = 0; i < vec->len; i++) { 61 vec_architecture = pkg_get_architecture(vec->pkgs[i]); 62 63 opkg_msg(DEBUG2, "%s %s arch=%s vs. %s %s arch=%s.\n", 64 pkg->name, pkg_version, pkg_architecture, 65 vec->pkgs[i]->name, pkg_get_string(vec->pkgs[i], PKG_VERSION), 66 vec_architecture); 67 /* if the name,ver,arch matches, or the name matches and the 68 * package is marked deinstall/hold */ 69 if ((!strcmp(pkg->name, vec->pkgs[i]->name)) 70 && ((pkg->state_want == SW_DEINSTALL 71 && (pkg->state_flag & SF_HOLD)) 72 || ((pkg_compare_versions(pkg, vec->pkgs[i]) == 0) 73 && (!strcmp(pkg_architecture, vec_architecture))))) { 74 found = 1; 75 opkg_msg(DEBUG2, 76 "Duplicate for pkg=%s version=%s arch=%s.\n", 77 pkg->name, pkg_version, pkg_architecture); 78 break; 79 } 80 } 81 82 /* we didn't find one, add it */ 83 if (!found) { 84 opkg_msg(DEBUG2, "Adding new pkg=%s version=%s arch=%s.\n", 85 pkg->name, pkg_version, pkg_architecture); 86 pkg_vec_insert(vec, pkg); 87 return; 88 } 89 90 /* update the one that we have */ 91 opkg_msg(DEBUG2, "Merging %s %s arch=%s, set_status=%d.\n", 92 pkg->name, pkg_version, pkg_architecture, set_status); 93 if (set_status) { 94 /* This is from the status file, 95 * so need to merge with existing database */ 96 pkg_merge(pkg, vec->pkgs[i]); 97 } 98 99 /* overwrite the old one */ 100 pkg_deinit(vec->pkgs[i]); 101 free(vec->pkgs[i]); 102 vec->pkgs[i] = pkg; 103 } 104 105 void pkg_vec_insert(pkg_vec_t * vec, const pkg_t * pkg) 106 { 107 vec->pkgs = xrealloc(vec->pkgs, (vec->len + 1) * sizeof(pkg_t *)); 108 vec->pkgs[vec->len] = (pkg_t *) pkg; 109 vec->len++; 110 } 111 112 int pkg_vec_contains(pkg_vec_t * vec, pkg_t * apkg) 113 { 114 int i; 115 for (i = 0; i < vec->len; i++) 116 if (vec->pkgs[i] == apkg) 117 return 1; 118 return 0; 119 } 120 121 void pkg_vec_sort(pkg_vec_t * vec, compare_fcn_t compar) 122 { 123 qsort(vec->pkgs, vec->len, sizeof(pkg_t *), compar); 124 } 125 126 int pkg_vec_clear_marks(pkg_vec_t * vec) 127 { 128 int npkgs = vec->len; 129 int i; 130 for (i = 0; i < npkgs; i++) { 131 pkg_t *pkg = vec->pkgs[i]; 132 pkg->state_flag &= ~SF_MARKED; 133 } 134 return 0; 135 } 136 137 int pkg_vec_mark_if_matches(pkg_vec_t * vec, const char *pattern) 138 { 139 int matching_count = 0; 140 pkg_t **pkgs = vec->pkgs; 141 int npkgs = vec->len; 142 int i; 143 abstract_pkg_t **providers, *provider; 144 145 for (i = 0; i < npkgs; i++) { 146 pkg_t *pkg = pkgs[i]; 147 if (fnmatch(pattern, pkg->name, 0) == 0) { 148 pkg->state_flag |= SF_MARKED; 149 matching_count++; 150 } 151 else { 152 providers = pkg_get_ptr(pkg, PKG_PROVIDES); 153 while (providers && *providers) { 154 provider = *providers++; 155 if (fnmatch(pattern, provider->name, 0) == 0) { 156 pkg->state_flag |= SF_MARKED; 157 matching_count++; 158 } 159 } 160 } 161 } 162 return matching_count; 163 } 164 165 abstract_pkg_vec_t *abstract_pkg_vec_alloc(void) 166 { 167 abstract_pkg_vec_t *vec; 168 vec = xcalloc(1, sizeof(abstract_pkg_vec_t)); 169 vec->pkgs = NULL; 170 vec->len = 0; 171 172 return vec; 173 } 174 175 void abstract_pkg_vec_free(abstract_pkg_vec_t * vec) 176 { 177 if (!vec) 178 return; 179 free(vec->pkgs); 180 free(vec); 181 } 182 183 /* 184 * assumption: all names in a vector are unique 185 */ 186 void abstract_pkg_vec_insert(abstract_pkg_vec_t * vec, abstract_pkg_t * pkg) 187 { 188 vec->pkgs = 189 xrealloc(vec->pkgs, (vec->len + 1) * sizeof(abstract_pkg_t *)); 190 vec->pkgs[vec->len] = pkg; 191 vec->len++; 192 } 193 194 abstract_pkg_t *abstract_pkg_vec_get(abstract_pkg_vec_t * vec, int i) 195 { 196 if (vec->len > i) 197 return vec->pkgs[i]; 198 else 199 return NULL; 200 } 201 202 int abstract_pkg_vec_contains(abstract_pkg_vec_t * vec, abstract_pkg_t * apkg) 203 { 204 int i; 205 for (i = 0; i < vec->len; i++) 206 if (vec->pkgs[i] == apkg) 207 return 1; 208 return 0; 209 } 210 211 void abstract_pkg_vec_sort(abstract_pkg_vec_t * vec, compare_fcn_t compar) 212 { 213 qsort(vec->pkgs, vec->len, sizeof(pkg_t *), compar); 214 } 215 216 int pkg_compare_names(const void *p1, const void *p2) 217 { 218 const pkg_t *pkg1 = *(const pkg_t **)p1; 219 const pkg_t *pkg2 = *(const pkg_t **)p2; 220 if (pkg1->name == NULL) 221 return 1; 222 if (pkg2->name == NULL) 223 return -1; 224 return (strcmp(pkg1->name, pkg2->name)); 225 } 226
This page was automatically generated by LXR 0.3.1. • OpenWrt