Commit 4d9e6ffad97f632139a75acce899d6a6b0594576

Authored by Silvan Calarco
1 parent 4f56214e72
Exists in master

Make contentslist generation optional using --gencontentslist

backend-sqlite: only output data for local repository to work also when executed with other arguments

Showing 4 changed files with 279 additions and 235 deletions Inline Diff

src/backend-sqlite3.c
1 /* 1 /*
2 * distromatic - tool for RPM based repositories 2 * distromatic - tool for RPM based repositories
3 * 3 *
4 * Copyright (C) 2013 by Silvan Calarco <silvan.calarco@mambasoft.it> 4 * Copyright (C) 2013-2015 by Silvan Calarco <silvan.calarco@mambasoft.it>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it under 6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of version 2 of the GNU General Public License as published by the 7 * the terms of version 2 of the GNU General Public License as published by the
8 * Free Software Foundation. 8 * Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY, to the extent permitted by law; without even the implied 11 * ANY WARRANTY, to the extent permitted by law; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details. 13 * See the GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License along with 15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18 */ 18 */
19 19
20 #include <sqlite3.h> 20 #include <sqlite3.h>
21 #include "config.h" 21 #include "config.h"
22 #include "headerlist.h" 22 #include "headerlist.h"
23 #include "changelog.h" 23 #include "changelog.h"
24 #include "backend-sqlite3.h" 24 #include "backend-sqlite3.h"
25 #include "functions.h" 25 #include "functions.h"
26 26
27 char sqlite3_query[PATH_MAX]; 27 char sqlite3_query[PATH_MAX];
28 sqlite3_stmt *stmt; 28 sqlite3_stmt *stmt;
29 29
30 #define sqlite3_transaction_maxsize 10485760 30 #define sqlite3_transaction_maxsize 10485760
31 long sqlite3_transaction_size; 31 long sqlite3_transaction_size;
32 32
33 int SQLite_init_table(sqlite3 *db, const char* table_name, const char* table_query) { 33 int SQLite_init_table(sqlite3 *db, const char* table_name, const char* table_query) {
34 34
35 char myquery[PATH_MAX]; 35 char myquery[PATH_MAX];
36 36
37 snprintf(myquery, PATH_MAX, "CREATE TABLE IF NOT EXISTS %s(%s)", table_name, table_query); 37 snprintf(myquery, PATH_MAX, "CREATE TABLE IF NOT EXISTS %s(%s)", table_name, table_query);
38 38
39 if (sqlite3_exec(db, myquery, 0, 0, 0)) { 39 if (sqlite3_exec(db, myquery, 0, 0, 0)) {
40 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", myquery, sqlite3_errmsg(db)); 40 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", myquery, sqlite3_errmsg(db));
41 return 2; 41 return 2;
42 } 42 }
43 return 0; 43 return 0;
44 } 44 }
45 45
46 int SQLite_begin_transaction(sqlite3 *db) { 46 int SQLite_begin_transaction(sqlite3 *db) {
47 47
48 if (sqlite3_exec(db, "BEGIN TRANSACTION;", 0, 0, 0)) { 48 if (sqlite3_exec(db, "BEGIN TRANSACTION;", 0, 0, 0)) {
49 fprintf(stderr, "ERROR: SQLite: (BEGIN TRANSACTION) %s\n", sqlite3_errmsg(db)); 49 fprintf(stderr, "ERROR: SQLite: (BEGIN TRANSACTION) %s\n", sqlite3_errmsg(db));
50 return 1; 50 return 1;
51 } 51 }
52 52
53 sqlite3_transaction_size = 0; 53 sqlite3_transaction_size = 0;
54 return 0; 54 return 0;
55 } 55 }
56 56
57 int SQLite_commit_transaction(sqlite3 *db) { 57 int SQLite_commit_transaction(sqlite3 *db) {
58 if (sqlite3_exec(db, "COMMIT;", 0, 0, 0)) { 58 if (sqlite3_exec(db, "COMMIT;", 0, 0, 0)) {
59 fprintf(stderr, "ERROR: SQLite: (COMMIT) %s\n", sqlite3_errmsg(db)); 59 fprintf(stderr, "ERROR: SQLite: (COMMIT) %s\n", sqlite3_errmsg(db));
60 return 1; 60 return 1;
61 } 61 }
62 sqlite3_transaction_size = 0; 62 sqlite3_transaction_size = 0;
63 return 0; 63 return 0;
64 } 64 }
65 65
66 int SQLite_print_contents_subtree(sqlite3 *db, 66 int SQLite_print_contents_subtree(sqlite3 *db,
67 struct fileTree* ft, 67 struct fileTree* ft,
68 struct configTag* ct, 68 struct configTag* ct,
69 int arch) { 69 int arch) {
70 70
71 int thisrep, i;
72
71 while (ft) { 73 while (ft) {
72 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO files VALUES(%ld,?,%ld,%ld,%ld,%d);", 74 i = 0;
73 ft->id, 75 thisrep = 0;
74 (ft->firstchild?ft->firstchild->id:-1), 76 for (i = 0; i < ft->numproviders; i++) {
75 (ft->next?ft->next->id:-1), 77 if (ft->provider[i]->altrepository == ct->repository_level) {
76 (ft->parent?ft->parent->id:-1), 78 thisrep = 1;
77 ft->numproviders); 79 break;
78 sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL); 80 }
79 sqlite3_bind_text(stmt, 1, ft->name, -1, SQLITE_STATIC);
80 if (sqlite3_step(stmt) != SQLITE_DONE) {
81 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
82 return 1;
83 } 81 }
84 sqlite3_finalize(stmt); 82 if (thisrep) {
83 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO files VALUES(%ld,?,%ld,%ld,%ld,%d);",
84 ft->id,
85 (ft->firstchild?ft->firstchild->id:-1),
86 (ft->next?ft->next->id:-1),
87 (ft->parent?ft->parent->id:-1),
88 ft->numproviders);
89 sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL);
90 sqlite3_bind_text(stmt, 1, ft->name, -1, SQLITE_STATIC);
91 if (sqlite3_step(stmt) != SQLITE_DONE) {
92 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
93 return 1;
94 }
95 sqlite3_finalize(stmt);
85 96
86 sqlite3_transaction_size += strlen(sqlite3_query); 97 sqlite3_transaction_size += strlen(sqlite3_query);
87 if (sqlite3_transaction_size >= sqlite3_transaction_maxsize) { 98 if (sqlite3_transaction_size >= sqlite3_transaction_maxsize) {
88 SQLite_commit_transaction(db); 99 SQLite_commit_transaction(db);
89 SQLite_begin_transaction(db); 100 SQLite_begin_transaction(db);
90 } 101 }
91 102
92 if (ft->firstchild) { 103 if (ft->firstchild) {
93 if (SQLite_print_contents_subtree(db, ft->firstchild, ct, arch)) return 1; 104 if (SQLite_print_contents_subtree(db, ft->firstchild, ct, arch)) return 1;
105 }
94 } 106 }
95 ft=ft->next; 107 ft=ft->next;
96 } 108 }
97 return 0; 109 return 0;
98 } 110 }
99 111
100 #define SQLITE_TABLE_files "id INTEGER PRIMARY KEY, "\ 112 #define SQLITE_TABLE_files "id INTEGER PRIMARY KEY, "\
101 "name STRING, firstchild INTEGER, next INTEGER, parent INTEGER, numproviders INTEGER" 113 "name STRING, firstchild INTEGER, next INTEGER, parent INTEGER, numproviders INTEGER"
102 /* struct headerList **provider; */ 114 /* struct headerList **provider; */
103 115
104 #define SQLITE_TABLE_packages_files_rel "id INTEGER PRIMARY KEY, id_package INTEGER, id_file INTEGER, "\ 116 #define SQLITE_TABLE_packages_files_rel "id INTEGER PRIMARY KEY, id_package INTEGER, id_file INTEGER, "\
105 "id_user INTEGER, id_group INTEGER, flags INTEGER, "\ 117 "id_user INTEGER, id_group INTEGER, flags INTEGER, "\
106 "name STRING, version STRING, release STRING" 118 "name STRING, version STRING, release STRING"
107 #define SQLITE_TABLE_fileusers "id INTEGER PRIMARY KEY, name STRING" 119 #define SQLITE_TABLE_fileusers "id INTEGER PRIMARY KEY, name STRING"
108 #define SQLITE_TABLE_filegroups "id INTEGER PRIMARY KEY, name STRING" 120 #define SQLITE_TABLE_filegroups "id INTEGER PRIMARY KEY, name STRING"
109 121
110 int generateSQLite_files(struct configTag* ct, sqlite3 *db, int arch) { 122 int generateSQLite_files(struct configTag* ct, sqlite3 *db, int arch) {
111 123
112 int i; 124 int i;
113 struct headerList* currpackage; 125 struct headerList* currpackage;
114 struct fileUserList *fileUser = ct->fileuserlist[arch]; 126 struct fileUserList *fileUser = ct->fileuserlist[arch];
115 struct fileGroupList *fileGroup = ct->filegrouplist[arch]; 127 struct fileGroupList *fileGroup = ct->filegrouplist[arch];
116 128
117 snprintf(sqlite3_query, PATH_MAX, "packages_files_rel"); 129 snprintf(sqlite3_query, PATH_MAX, "packages_files_rel");
118 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_packages_files_rel); 130 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_packages_files_rel);
119 131
120 snprintf(sqlite3_query, PATH_MAX, "files"); 132 snprintf(sqlite3_query, PATH_MAX, "files");
121 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_files); 133 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_files);
122 134
123 snprintf(sqlite3_query, PATH_MAX, "fileusers"); 135 snprintf(sqlite3_query, PATH_MAX, "fileusers");
124 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_fileusers); 136 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_fileusers);
125 137
126 snprintf(sqlite3_query, PATH_MAX, "filegroups"); 138 snprintf(sqlite3_query, PATH_MAX, "filegroups");
127 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_filegroups); 139 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_filegroups);
128 140
129 while (fileUser) { 141 while (fileUser) {
130 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO fileusers VALUES(%ld,?);", 142 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO fileusers VALUES(%ld,?);",
131 fileUser->id); 143 fileUser->id);
132 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 144 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
133 fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query); 145 fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
134 return 1; 146 return 1;
135 } 147 }
136 sqlite3_bind_text(stmt, 1, fileUser->name, -1, SQLITE_STATIC); 148 sqlite3_bind_text(stmt, 1, fileUser->name, -1, SQLITE_STATIC);
137 if (sqlite3_step(stmt) != SQLITE_DONE) { 149 if (sqlite3_step(stmt) != SQLITE_DONE) {
138 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db)); 150 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db));
139 return 3; 151 return 3;
140 } 152 }
141 sqlite3_finalize(stmt); 153 sqlite3_finalize(stmt);
142 fileUser = fileUser->next; 154 fileUser = fileUser->next;
143 } 155 }
144 156
145 while (fileGroup) { 157 while (fileGroup) {
146 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO filegroups VALUES(%ld,?);", 158 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO filegroups VALUES(%ld,?);",
147 fileGroup->id); 159 fileGroup->id);
148 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 160 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
149 fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query); 161 fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
150 return 1; 162 return 1;
151 } 163 }
152 sqlite3_bind_text(stmt, 1, fileGroup->name, -1, SQLITE_STATIC); 164 sqlite3_bind_text(stmt, 1, fileGroup->name, -1, SQLITE_STATIC);
153 if (sqlite3_step(stmt) != SQLITE_DONE) { 165 if (sqlite3_step(stmt) != SQLITE_DONE) {
154 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db)); 166 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db));
155 return 3; 167 return 3;
156 } 168 }
157 sqlite3_finalize(stmt); 169 sqlite3_finalize(stmt);
158 fileGroup = fileGroup->next; 170 fileGroup = fileGroup->next;
159 } 171 }
160 172
161 SQLite_begin_transaction(db); 173 SQLite_begin_transaction(db);
162 if (SQLite_print_contents_subtree(db, ct->filetree[arch], ct, arch)) return 1; 174 if (SQLite_print_contents_subtree(db, ct->filetree[arch], ct, arch)) return 1;
163 175
164 currpackage = ct->headerlist[arch]; 176 currpackage = ct->headerlist[arch];
165 while (currpackage) { 177 while (currpackage) {
166 /* packages <-> files relations */ 178 if (currpackage->altrepository == ct->repository_level) {
167 for (i = 0; i < currpackage->filenamecount; i++) { 179 /* packages <-> files relations */
168 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packages_files_rel VALUES(NULL,%ld,%ld,%ld,%ld,%d,?,?,?);", 180 for (i = 0; i < currpackage->filenamecount; i++) {
169 currpackage->id, 181 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packages_files_rel VALUES(NULL,%ld,%ld,%ld,%ld,%d,?,?,?);",
170 currpackage->file[i]->id, 182 currpackage->id,
171 currpackage->fileuser[i]->id, 183 currpackage->file[i]->id,
172 currpackage->filegroup[i]->id, 184 currpackage->fileuser[i]->id,
173 currpackage->fileflags[i]); 185 currpackage->filegroup[i]->id,
174 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 186 currpackage->fileflags[i]);
175 fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query); 187 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
176 return 1; 188 fprintf(stderr, "ERROR: sqlite3_prepare_v2: %s (%s)\n", sqlite3_errmsg(db), sqlite3_query);
177 } 189 return 1;
178 sqlite3_bind_text(stmt, 1, currpackage->name, -1, SQLITE_STATIC); 190 }
179 sqlite3_bind_text(stmt, 2, currpackage->version, -1, SQLITE_STATIC); 191 sqlite3_bind_text(stmt, 1, currpackage->name, -1, SQLITE_STATIC);
180 sqlite3_bind_text(stmt, 3, currpackage->release, -1, SQLITE_STATIC); 192 sqlite3_bind_text(stmt, 2, currpackage->version, -1, SQLITE_STATIC);
181 if (sqlite3_step(stmt) != SQLITE_DONE) { 193 sqlite3_bind_text(stmt, 3, currpackage->release, -1, SQLITE_STATIC);
182 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db)); 194 if (sqlite3_step(stmt) != SQLITE_DONE) {
183 return 3; 195 fprintf(stderr, "ERROR: sqlite3_step: %s (%s)\n", sqlite3_query, sqlite3_errmsg(db));
184 } 196 return 3;
185 sqlite3_finalize(stmt); 197 }
186 sqlite3_transaction_size += strlen(sqlite3_query); 198 sqlite3_finalize(stmt);
187 if (sqlite3_transaction_size >= sqlite3_transaction_maxsize) { 199 sqlite3_transaction_size += strlen(sqlite3_query);
188 SQLite_commit_transaction(db); 200 if (sqlite3_transaction_size >= sqlite3_transaction_maxsize) {
189 SQLite_begin_transaction(db); 201 SQLite_commit_transaction(db);
190 } 202 SQLite_begin_transaction(db);
191 } 203 }
192 currpackage = currpackage->next; 204 }
205 }
206 currpackage = currpackage->next;
193 } 207 }
194 SQLite_commit_transaction(db); 208 SQLite_commit_transaction(db);
195
196 return 0; 209 return 0;
197 } 210 }
198 211
199 #define SQLITE_TABLE_provided "id INTEGER PRIMARY KEY, "\ 212 #define SQLITE_TABLE_provided "id INTEGER PRIMARY KEY, "\
200 "name STRING, flags INTEGER, numproviders INTEGER" 213 "name STRING, flags INTEGER, numproviders INTEGER"
201 214
202 int generateSQLite_provided(struct configTag* ct, sqlite3 *db, int arch) { 215 int generateSQLite_provided(struct configTag* ct, sqlite3 *db, int arch) {
203 216
204 struct providedList* provided; 217 struct providedList* provided;
218 int i, thisrep;
205 219
206 snprintf(sqlite3_query, PATH_MAX, "provided"); 220 snprintf(sqlite3_query, PATH_MAX, "provided");
207 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_provided); 221 SQLite_init_table(db, sqlite3_query, SQLITE_TABLE_provided);
208 SQLite_begin_transaction(db); 222 SQLite_begin_transaction(db);
209 223
210 provided = ct->providedlist_idx[arch][0]; 224 provided = ct->providedlist_idx[arch][0];
211 while (provided) { 225 while (provided) {
212 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO provided VALUES(%ld,?,%ld,%d);", 226 i = 0;
213 provided->id, 227 thisrep = 0;
214 provided->flags, 228 for (i = 0; i < provided->numproviders; i++) {
215 provided->numproviders); 229 if (provided->provider[i]->altrepository == ct->repository_level) {
216 sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL); 230 thisrep = 1;
217 sqlite3_bind_text(stmt, 1, provided->name, -1, SQLITE_STATIC); 231 break;
218 if (sqlite3_step(stmt) != SQLITE_DONE) { 232 }
219 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
220 return 1;
221 } 233 }
222 sqlite3_finalize(stmt); 234 if (thisrep) {
235 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO provided VALUES(%ld,?,%ld,%d);",
236 provided->id,
237 provided->flags,
238 provided->numproviders);
239 sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL);
240 sqlite3_bind_text(stmt, 1, provided->name, -1, SQLITE_STATIC);
241 if (sqlite3_step(stmt) != SQLITE_DONE) {
242 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
243 return 1;
244 }
245 sqlite3_finalize(stmt);
246 }
223 provided = provided->next; 247 provided = provided->next;
224 } 248 }
225
226 SQLite_commit_transaction(db); 249 SQLite_commit_transaction(db);
227
228 return 0; 250 return 0;
229 } 251 }
230 252
231 #define SQLITE_TABLE_packagers "id INTEGER PRIMARY KEY, "\ 253 #define SQLITE_TABLE_packagers "id INTEGER PRIMARY KEY, "\
232 "name STRING, role INTEGER, changes_count INTEGER, packages_count INTEGER" 254 "name STRING, role INTEGER, changes_count INTEGER, packages_count INTEGER"
233 /* char *alias[PACKAGER_MAXALIASES]; */ 255 /* char *alias[PACKAGER_MAXALIASES]; */
234 256
235 int generateSQLite_packagers(sqlite3 *db) { 257 int generateSQLite_packagers(sqlite3 *db) {
236 258
237 struct Packager* packager = firstPackager(); 259 struct Packager* packager = firstPackager();
238 260
239 SQLite_init_table(db, "packagers", SQLITE_TABLE_packagers); 261 SQLite_init_table(db, "packagers", SQLITE_TABLE_packagers);
240 SQLite_begin_transaction(db); 262 SQLite_begin_transaction(db);
241 263
242 while (packager) { 264 while (packager) {
243 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packagers VALUES(NULL,?,%d,%d,%d);", 265 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packagers VALUES(NULL,?,%d,%d,%d);",
244 packager->role, 266 packager->role,
245 packager->changes_count, 267 packager->changes_count,
246 packager->packages_count); 268 packager->packages_count);
247 269
248 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 270 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
249 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 271 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
250 } 272 }
251 sqlite3_bind_text(stmt, 1, packager->name, -1, SQLITE_STATIC); 273 sqlite3_bind_text(stmt, 1, packager->name, -1, SQLITE_STATIC);
252 if (sqlite3_step(stmt) != SQLITE_DONE) { 274 if (sqlite3_step(stmt) != SQLITE_DONE) {
253 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 275 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
254 return 3; 276 return 3;
255 } 277 }
256 packager->id = sqlite3_last_insert_rowid(db); 278 packager->id = sqlite3_last_insert_rowid(db);
257 sqlite3_finalize(stmt); 279 sqlite3_finalize(stmt);
258 packager = packager->next; 280 packager = packager->next;
259 } 281 }
260 SQLite_commit_transaction(db); 282 SQLite_commit_transaction(db);
261 return 0; 283 return 0;
262 } 284 }
263 285
264 long generateSQLite_add_changelog(sqlite3 *db, struct changeLog* firstchangelog, long id_source) { 286 long generateSQLite_add_changelog(sqlite3 *db, struct changeLog* firstchangelog, long id_source) {
265 287
266 struct changeLog* changelog = firstchangelog; 288 struct changeLog* changelog = firstchangelog;
267 long lastchangelogid = 0; 289 long lastchangelogid = 0;
268 290
269 while (changelog) { 291 while (changelog) {
270 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO changelog VALUES(NULL,%ld,%ld,%ld,?,?);", 292 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO changelog VALUES(NULL,%ld,%ld,%ld,?,?);",
271 id_source, 293 id_source,
272 changelog->time, 294 changelog->time,
273 changelog->pkg->id); 295 changelog->pkg->id);
274 296
275 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 297 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
276 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 298 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
277 } 299 }
278 sqlite3_bind_text(stmt, 1, changelog->release, -1, SQLITE_STATIC); 300 sqlite3_bind_text(stmt, 1, changelog->release, -1, SQLITE_STATIC);
279 sqlite3_bind_text(stmt, 2, changelog->text, -1, SQLITE_STATIC); 301 sqlite3_bind_text(stmt, 2, changelog->text, -1, SQLITE_STATIC);
280 if (sqlite3_step(stmt) != SQLITE_DONE) { 302 if (sqlite3_step(stmt) != SQLITE_DONE) {
281 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 303 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
282 return 3; 304 return 3;
283 } 305 }
284 changelog->id = sqlite3_last_insert_rowid(db); 306 changelog->id = sqlite3_last_insert_rowid(db);
285 lastchangelogid = changelog->id; 307 lastchangelogid = changelog->id;
286 sqlite3_finalize(stmt); 308 sqlite3_finalize(stmt);
287 changelog = changelog->next; 309 changelog = changelog->next;
288 } 310 }
289 return lastchangelogid; 311 return lastchangelogid;
290 } 312 }
291 313
292 #define SQLITE_TABLE_packages "id INTEGER PRIMARY KEY, "\ 314 #define SQLITE_TABLE_packages "id INTEGER PRIMARY KEY, "\
293 "name STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, "\ 315 "name STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, "\
294 "groupdescr STRING, description STRING, size INTEGER, id_source INTEGER" 316 "groupdescr STRING, description STRING, size INTEGER, id_source INTEGER"
295 317
296 #define SQLITE_TABLE_obsoletes "id INTEGER PRIMARY KEY, "\ 318 #define SQLITE_TABLE_obsoletes "id INTEGER PRIMARY KEY, "\
297 "id_package INTEGER, obsoletename STRING, obsoleteflags INTEGER, obsoleteversion STRING" 319 "id_package INTEGER, obsoletename STRING, obsoleteflags INTEGER, obsoleteversion STRING"
298 320
299 #define SQLITE_TABLE_provides "id INTEGER PRIMARY KEY, "\ 321 #define SQLITE_TABLE_provides "id INTEGER PRIMARY KEY, "\
300 "id_package INTEGER, id_provided INTEGER, provideflags INTEGER, provideversion STRING" 322 "id_package INTEGER, id_provided INTEGER, provideflags INTEGER, provideversion STRING"
301 323
302 #define SQLITE_TABLE_requires "id INTEGER PRIMARY KEY, "\ 324 #define SQLITE_TABLE_requires "id INTEGER PRIMARY KEY, "\
303 "id_package INTEGER, id_provided STRING, requireflags INTEGER, requireversion STRING" 325 "id_package INTEGER, id_provided STRING, requireflags INTEGER, requireversion STRING"
304 326
305 int 327 int
306 generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) { 328 generateSQLite_packages(struct configTag *ct, sqlite3 *db, int arch) {
307 329
308 struct headerList* currpackage; 330 struct headerList* currpackage;
309 int i; 331 int i;
310 332
311 SQLite_init_table(db, "packages", SQLITE_TABLE_packages); 333 SQLite_init_table(db, "packages", SQLITE_TABLE_packages);
312 SQLite_init_table(db, "obsoletes", SQLITE_TABLE_obsoletes); 334 SQLite_init_table(db, "obsoletes", SQLITE_TABLE_obsoletes);
313 SQLite_init_table(db, "provides", SQLITE_TABLE_provides); 335 SQLite_init_table(db, "provides", SQLITE_TABLE_provides);
314 SQLite_init_table(db, "requires", SQLITE_TABLE_requires); 336 SQLite_init_table(db, "requires", SQLITE_TABLE_requires);
315 SQLite_begin_transaction(db); 337 SQLite_begin_transaction(db);
316 338
317 currpackage = ct->headerlist[arch]; 339 currpackage = ct->headerlist[arch];
318 while (currpackage) { 340 while (currpackage) {
341 if (currpackage->altrepository == ct->repository_level) {
342 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packages VALUES(NULL,?,%d,%ld,?,?,?,?,?,%ld,%ld);",
343 currpackage->altrepository,
344 currpackage->epoch,
345 currpackage->size,
346 currpackage->sourceheader->id);
347 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
348 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
349 return 1;
350 }
319 351
320 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO packages VALUES(NULL,?,%d,%ld,?,?,?,?,?,%ld,%ld);", 352 sqlite3_bind_text(stmt, 1, currpackage->name, -1, SQLITE_STATIC);
321 currpackage->altrepository, 353 sqlite3_bind_text(stmt, 2, currpackage->version, -1, SQLITE_STATIC);
322 currpackage->epoch, 354 sqlite3_bind_text(stmt, 3, currpackage->release, -1, SQLITE_STATIC);
323 currpackage->size, 355 sqlite3_bind_text(stmt, 4, currpackage->summary, -1, SQLITE_STATIC);
324 currpackage->sourceheader->id); 356 sqlite3_bind_text(stmt, 5, currpackage->group, -1, SQLITE_STATIC);
325 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 357 sqlite3_bind_text(stmt, 6, currpackage->description, -1, SQLITE_STATIC);
326 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
327 return 1;
328 }
329 358
330 sqlite3_bind_text(stmt, 1, currpackage->name, -1, SQLITE_STATIC); 359 if (sqlite3_step(stmt) != SQLITE_DONE) {
331 sqlite3_bind_text(stmt, 2, currpackage->version, -1, SQLITE_STATIC); 360 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
332 sqlite3_bind_text(stmt, 3, currpackage->release, -1, SQLITE_STATIC); 361 return 3;
333 sqlite3_bind_text(stmt, 4, currpackage->summary, -1, SQLITE_STATIC); 362 }
334 sqlite3_bind_text(stmt, 5, currpackage->group, -1, SQLITE_STATIC); 363 currpackage->id = sqlite3_last_insert_rowid(db);
335 sqlite3_bind_text(stmt, 6, currpackage->description, -1, SQLITE_STATIC); 364 sqlite3_finalize(stmt);
336 365
337 if (sqlite3_step(stmt) != SQLITE_DONE) { 366 /* obsoletes */
338 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 367 for (i = 0; i < currpackage->obsoletecount; i++) {
339 return 3; 368 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO obsoletes VALUES(NULL,%ld,?,%d,?);",
340 } 369 currpackage->id,
341 currpackage->id = sqlite3_last_insert_rowid(db); 370 currpackage->obsoleteflags[i]);
342 sqlite3_finalize(stmt);
343 371
344 /* obsoletes */ 372 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
345 for (i = 0; i < currpackage->obsoletecount; i++) { 373 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
346 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO obsoletes VALUES(NULL,%ld,?,%d,?);", 374 }
347 currpackage->id, 375 sqlite3_bind_text(stmt, 1, currpackage->obsoletename[i], -1, SQLITE_STATIC);
348 currpackage->obsoleteflags[i]); 376 sqlite3_bind_text(stmt, 2, currpackage->obsoleteversion[i], -1, SQLITE_STATIC);
377 if (sqlite3_step(stmt) != SQLITE_DONE) {
378 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
379 return 3;
380 }
381 sqlite3_finalize(stmt);
382 }
349 383
350 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 384 /* provides */
351 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 385 for (i = 0; i < currpackage->providecount; i++) {
352 } 386 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO provides VALUES(NULL,%ld,%ld,%d,?);",
353 sqlite3_bind_text(stmt, 1, currpackage->obsoletename[i], -1, SQLITE_STATIC); 387 currpackage->id,
354 sqlite3_bind_text(stmt, 2, currpackage->obsoleteversion[i], -1, SQLITE_STATIC); 388 currpackage->provided[i]->id,
355 if (sqlite3_step(stmt) != SQLITE_DONE) { 389 currpackage->provideflags[i]);
356 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
357 return 3;
358 }
359 sqlite3_finalize(stmt);
360 }
361 390
362 /* provides */ 391 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
363 for (i = 0; i < currpackage->providecount; i++) { 392 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
364 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO provides VALUES(NULL,%ld,%ld,%d,?);", 393 }
365 currpackage->id, 394 sqlite3_bind_text(stmt, 1, currpackage->provideversion[i], -1, SQLITE_STATIC);
366 currpackage->provided[i]->id, 395 if (sqlite3_step(stmt) != SQLITE_DONE) {
367 currpackage->provideflags[i]); 396 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
397 return 3;
398 }
399 sqlite3_finalize(stmt);
400 }
368 401
369 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 402 /* requires */
370 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 403 for (i = 0; i < currpackage->requirecount; i++) {
371 } 404 if (currpackage->require[i]->resolved) {
372 sqlite3_bind_text(stmt, 1, currpackage->provideversion[i], -1, SQLITE_STATIC); 405 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO requires VALUES(NULL,%ld,%ld,%ld,?);",
373 if (sqlite3_step(stmt) != SQLITE_DONE) { 406 currpackage->id,
374 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 407 currpackage->require[i]->resolved->id,
375 return 3; 408 currpackage->require[i]->flags);
376 }
377 sqlite3_finalize(stmt);
378 }
379 409
380 /* requires */ 410 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
381 for (i = 0; i < currpackage->requirecount; i++) { 411 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
382 if (currpackage->require[i]->resolved) { 412 }
383 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO requires VALUES(NULL,%ld,%ld,%ld,?);", 413 sqlite3_bind_text(stmt, 1, currpackage->require[i]->version, -1, SQLITE_STATIC);
384 currpackage->id, 414 if (sqlite3_step(stmt) != SQLITE_DONE) {
385 currpackage->require[i]->resolved->id, 415 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
386 currpackage->require[i]->flags); 416 return 3;
387 417 }
388 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 418 sqlite3_finalize(stmt);
389 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 419 } else if (strstr(currpackage->require[i]->name,"rpmlib(") != currpackage->require[i]->name) {
390 } 420 fprintf(stderr, "WARNING: package %s require %s not in provided list\n", currpackage->name, currpackage->require[i]->name);
391 sqlite3_bind_text(stmt, 1, currpackage->require[i]->version, -1, SQLITE_STATIC); 421 }
392 if (sqlite3_step(stmt) != SQLITE_DONE) {
393 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
394 return 3;
395 }
396 sqlite3_finalize(stmt);
397 } else if (strstr(currpackage->require[i]->name,"rpmlib(") != currpackage->require[i]->name) {
398 fprintf(stderr, "WARNING: package %s require %s not in provided list\n", currpackage->name, currpackage->require[i]->name);
399 } 422 }
400 } 423 }
401 currpackage = currpackage->next; 424 currpackage = currpackage->next;
402 } 425 }
403 SQLite_commit_transaction(db); 426 SQLite_commit_transaction(db);
404 return 0; 427 return 0;
405 } 428 }
406 429
407 #define SQLITE_TABLE_sources_source "id INTEGER PRIMARY KEY, id_source INTEGER, source STRING" 430 #define SQLITE_TABLE_sources_source "id INTEGER PRIMARY KEY, id_source INTEGER, source STRING"
408 #define SQLITE_TABLE_sources_patch "id INTEGER PRIMARY KEY, id_source INTEGER, patch STRING" 431 #define SQLITE_TABLE_sources_patch "id INTEGER PRIMARY KEY, id_source INTEGER, patch STRING"
409 #define SQLITE_TABLE_sources "id INTEGER PRIMARY KEY, "\ 432 #define SQLITE_TABLE_sources "id INTEGER PRIMARY KEY, "\
410 "name STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, id_packager INTEGER, "\ 433 "name STRING, altrepository INTEGER, epoch INTEGER, version STRING, release STRING, summary STRING, id_packager INTEGER, "\
411 "groupdescr STRING, description STRING, url STRING, license STRING, arch STRING, buildarchs STRING, " \ 434 "groupdescr STRING, description STRING, url STRING, license STRING, arch STRING, buildarchs STRING, " \
412 "excludearch STRING, buildtime INTEGER, size INTEGER, id_changelog INTEGER" 435 "excludearch STRING, buildtime INTEGER, size INTEGER, id_changelog INTEGER"
413 //#define SQLITE_TABLE_sources_files_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_files INTEGER" 436 //#define SQLITE_TABLE_sources_files_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_files INTEGER"
414 //#define SQLITE_TABLE_sources_provided_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_provided INTEGER" 437 //#define SQLITE_TABLE_sources_provided_rel "id INTEGER PRIMARY KEY, id_source INTEGER, id_provided INTEGER"
415 #define SQLITE_TABLE_changelog "id INTEGER PRIMARY KEY, "\ 438 #define SQLITE_TABLE_changelog "id INTEGER PRIMARY KEY, "\
416 "id_source INTEGER, time INTEGER, id_packager INTEGER, release STRING, text STRING" 439 "id_source INTEGER, time INTEGER, id_packager INTEGER, release STRING, text STRING"
417 #define SQLITE_TABLE_buildrequires "id INTEGER PRIMARY KEY, "\ 440 #define SQLITE_TABLE_buildrequires "id INTEGER PRIMARY KEY, "\
418 "id_source INTEGER, buildrequirename STRING, buildrequireflags INTEGER, buildrequireversion STRING" 441 "id_source INTEGER, buildrequirename STRING, buildrequireflags INTEGER, buildrequireversion STRING"
419 442
420 int 443 int
421 generateSQLite_sources(struct configTag *ct, sqlite3 *db) { 444 generateSQLite_sources(struct configTag *ct, sqlite3 *db) {
422 445
423 struct headerSourceList* currsource; 446 struct headerSourceList* currsource;
424 int i; 447 int i;
425 long nextchangelogid = 1; 448 long nextchangelogid = 1;
426 449
427 SQLite_init_table(db, "sources", SQLITE_TABLE_sources); 450 SQLite_init_table(db, "sources", SQLITE_TABLE_sources);
428 SQLite_init_table(db, "sources_source", SQLITE_TABLE_sources_source); 451 SQLite_init_table(db, "sources_source", SQLITE_TABLE_sources_source);
429 SQLite_init_table(db, "sources_patch", SQLITE_TABLE_sources_patch); 452 SQLite_init_table(db, "sources_patch", SQLITE_TABLE_sources_patch);
430 // SQLite_init_table(db, "sources_files_rel", SQLITE_TABLE_sources_files_rel); 453 // SQLite_init_table(db, "sources_files_rel", SQLITE_TABLE_sources_files_rel);
431 // SQLite_init_table(db, "sources_provided_rel", SQLITE_TABLE_sources_provided_rel); 454 // SQLite_init_table(db, "sources_provided_rel", SQLITE_TABLE_sources_provided_rel);
432 SQLite_init_table(db, "changelog", SQLITE_TABLE_changelog); 455 SQLite_init_table(db, "changelog", SQLITE_TABLE_changelog);
433 SQLite_init_table(db, "buildrequires", SQLITE_TABLE_buildrequires); 456 SQLite_init_table(db, "buildrequires", SQLITE_TABLE_buildrequires);
434 SQLite_begin_transaction(db); 457 SQLite_begin_transaction(db);
435 458
436 currsource = ct->headersourcelist; 459 currsource = ct->headersourcelist;
437 while (currsource != NULL) { 460 while (currsource != NULL) {
461 if (currsource->altrepository == ct->repository_level) {
462 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources VALUES(%ld,?,%d,%ld,?,?,?,%ld,?,?,?,?,?,?,?,%ld,%ld,%ld);",
463 currsource->id,
464 currsource->altrepository,
465 currsource->epoch,
466 currsource->packager->id,
467 currsource->buildtime,
468 currsource->size,
469 (currsource->changelog?nextchangelogid:0));
470 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
471 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
472 }
438 473
439 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources VALUES(%ld,?,%d,%ld,?,?,?,%ld,?,?,?,?,?,?,?,%ld,%ld,%ld);", 474 sqlite3_bind_text(stmt, 1, currsource->name, -1, SQLITE_STATIC);
440 currsource->id, 475 sqlite3_bind_text(stmt, 2, currsource->version, -1, SQLITE_STATIC);
441 currsource->altrepository, 476 sqlite3_bind_text(stmt, 3, currsource->release, -1, SQLITE_STATIC);
442 currsource->epoch, 477 sqlite3_bind_text(stmt, 4, currsource->summary, -1, SQLITE_STATIC);
443 currsource->packager->id, 478 sqlite3_bind_text(stmt, 5, currsource->group, -1, SQLITE_STATIC);
444 currsource->buildtime, 479 sqlite3_bind_text(stmt, 6, currsource->description, -1, SQLITE_STATIC);
445 currsource->size, 480 sqlite3_bind_text(stmt, 7, currsource->url, -1, SQLITE_STATIC);
446 (currsource->changelog?nextchangelogid:0)); 481 sqlite3_bind_text(stmt, 8, currsource->license, -1, SQLITE_STATIC);
447 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 482 sqlite3_bind_text(stmt, 9, currsource->arch, -1, SQLITE_STATIC);
448 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 483 sqlite3_bind_text(stmt, 10, currsource->buildarchs, -1, SQLITE_STATIC);
449 } 484 sqlite3_bind_text(stmt, 11, currsource->excludearch, -1, SQLITE_STATIC);
450 485
451 sqlite3_bind_text(stmt, 1, currsource->name, -1, SQLITE_STATIC); 486 if (sqlite3_step(stmt) != SQLITE_DONE) {
452 sqlite3_bind_text(stmt, 2, currsource->version, -1, SQLITE_STATIC); 487 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
453 sqlite3_bind_text(stmt, 3, currsource->release, -1, SQLITE_STATIC); 488 return 3;
454 sqlite3_bind_text(stmt, 4, currsource->summary, -1, SQLITE_STATIC); 489 }
455 sqlite3_bind_text(stmt, 5, currsource->group, -1, SQLITE_STATIC); 490 currsource->id = sqlite3_last_insert_rowid(db);
456 sqlite3_bind_text(stmt, 6, currsource->description, -1, SQLITE_STATIC); 491 sqlite3_finalize(stmt);
457 sqlite3_bind_text(stmt, 7, currsource->url, -1, SQLITE_STATIC);
458 sqlite3_bind_text(stmt, 8, currsource->license, -1, SQLITE_STATIC);
459 sqlite3_bind_text(stmt, 9, currsource->arch, -1, SQLITE_STATIC);
460 sqlite3_bind_text(stmt, 10, currsource->buildarchs, -1, SQLITE_STATIC);
461 sqlite3_bind_text(stmt, 11, currsource->excludearch, -1, SQLITE_STATIC);
462 492
463 if (sqlite3_step(stmt) != SQLITE_DONE) { 493 /* source */
464 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 494 if (currsource->source) {
465 return 3; 495 i=0;
466 } 496 while (currsource->source[i]) {
467 currsource->id = sqlite3_last_insert_rowid(db); 497 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources_source VALUES(NULL,%ld,?);",
468 sqlite3_finalize(stmt); 498 currsource->id);
469 499
470 /* source */ 500 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
471 if (currsource->source) { 501 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
472 i=0; 502 }
473 while (currsource->source[i]) { 503 sqlite3_bind_text(stmt, 1, currsource->source[i], -1, SQLITE_STATIC);
474 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources_source VALUES(NULL,%ld,?);", 504 if (sqlite3_step(stmt) != SQLITE_DONE) {
475 currsource->id); 505 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
506 return 3;
507 }
508 sqlite3_finalize(stmt);
509 i++;
510 }
511 }
476 512
477 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 513 /* patch */
478 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 514 if (currsource->patch) {
515 i=0;
516 while (currsource->patch[i]) {
517 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources_patch VALUES(NULL,%ld,?);",
518 currsource->id);
519
520 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
521 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
522 }
523 sqlite3_bind_text(stmt, 1, currsource->patch[i], -1, SQLITE_STATIC);
524 if (sqlite3_step(stmt) != SQLITE_DONE) {
525 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
526 return 3;
527 }
528 sqlite3_finalize(stmt);
529 i++;
479 } 530 }
480 sqlite3_bind_text(stmt, 1, currsource->source[i], -1, SQLITE_STATIC);
481 if (sqlite3_step(stmt) != SQLITE_DONE) {
482 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
483 return 3;
484 }
485 sqlite3_finalize(stmt);
486 i++;
487 } 531 }
488 }
489 532
490 /* patch */ 533 /* buildrequires */
491 if (currsource->patch) { 534 for (i = 0; i < currsource->requirecount; i++) {
492 i=0; 535 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO buildrequires VALUES(NULL,%ld,?,%ld,?);",
493 while (currsource->patch[i]) { 536 currsource->id,
494 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources_patch VALUES(NULL,%ld,?);", 537 currsource->require[i]->flags);
495 currsource->id);
496 538
497 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 539 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
498 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 540 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
499 } 541 }
500 sqlite3_bind_text(stmt, 1, currsource->patch[i], -1, SQLITE_STATIC); 542 sqlite3_bind_text(stmt, 1, currsource->require[i]->name, -1, SQLITE_STATIC);
543 sqlite3_bind_text(stmt, 2, currsource->require[i]->version, -1, SQLITE_STATIC);
501 if (sqlite3_step(stmt) != SQLITE_DONE) { 544 if (sqlite3_step(stmt) != SQLITE_DONE) {
502 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 545 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
503 return 3; 546 return 3;
504 } 547 }
505 sqlite3_finalize(stmt); 548 sqlite3_finalize(stmt);
506 i++;
507 } 549 }
508 }
509 550
510 /* buildrequires */
511 for (i = 0; i < currsource->requirecount; i++) {
512 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO buildrequires VALUES(NULL,%ld,?,%ld,?);",
513 currsource->id,
514 currsource->require[i]->flags);
515
516 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
517 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
518 }
519 sqlite3_bind_text(stmt, 1, currsource->require[i]->name, -1, SQLITE_STATIC);
520 sqlite3_bind_text(stmt, 2, currsource->require[i]->version, -1, SQLITE_STATIC);
521 if (sqlite3_step(stmt) != SQLITE_DONE) {
522 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
523 return 3;
524 }
525 sqlite3_finalize(stmt);
526 }
527
528 /* sources <-> provided relations (buildrequirements) */ 551 /* sources <-> provided relations (buildrequirements) */
529 /* for (i=0; i<currsource->providecount; i++) { 552 /* for (i=0; i<currsource->providecount; i++) {
530 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources_provided_rel VALUES(NULL,%d,%d);", 553 snprintf(sqlite3_query, PATH_MAX, "INSERT INTO sources_provided_rel VALUES(NULL,%d,%d);",
531 currsource->id, 554 currsource->id,
532 currsource->required[i]->id); 555 currsource->required[i]->id);
533 556
534 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) { 557 if (sqlite3_prepare_v2(db, sqlite3_query, -1, &stmt, NULL)) {
535 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 558 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
536 } 559 }
537 if (sqlite3_step(stmt) != SQLITE_DONE) { 560 if (sqlite3_step(stmt) != SQLITE_DONE) {
538 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db)); 561 fprintf(stderr, "ERROR: SQLite: (%s) %s\n", sqlite3_query, sqlite3_errmsg(db));
539 return 3; 562 return 3;
540 } 563 }
541 sqlite3_finalize(stmt); 564 sqlite3_finalize(stmt);
542 }*/ 565 }*/
543 566
544 if (currsource->changelog) { 567 if (currsource->changelog) {
545 nextchangelogid = generateSQLite_add_changelog(db, currsource->changelog, currsource->id) + 1; 568 nextchangelogid = generateSQLite_add_changelog(db, currsource->changelog, currsource->id) + 1;
569 }
546 } 570 }
547 currsource = currsource->next; 571 currsource = currsource->next;
548 } 572 }
549 SQLite_commit_transaction(db); 573 SQLite_commit_transaction(db);
1 /* 1 /*
2 * distromatic - tool for RPM based repositories 2 * distromatic - tool for RPM based repositories
3 * 3 *
4 * Copyright (C) 2004-2015 by Silvan Calarco <silvan.calarco@mambasoft.it> 4 * Copyright (C) 2004-2015 by Silvan Calarco <silvan.calarco@mambasoft.it>
5 * Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com> 5 * Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it under 7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of version 2 of the GNU General Public License as published by the 8 * the terms of version 2 of the GNU General Public License as published by the
9 * Free Software Foundation. 9 * Free Software Foundation.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT 11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY, to the extent permitted by law; without even the implied 12 * ANY WARRANTY, to the extent permitted by law; without even the implied
13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details. 14 * See the GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along with 16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21 #include "config.h" 21 #include "config.h"
22 22
23 /* Tell glibc's <time.h> to provide a prototype for strptime() */ 23 /* Tell glibc's <time.h> to provide a prototype for strptime() */
24 #ifndef __USE_XOPEN 24 #ifndef __USE_XOPEN
25 # define __USE_XOPEN 25 # define __USE_XOPEN
26 #endif 26 #endif
27 27
28 #ifndef _GNU_SOURCE 28 #ifndef _GNU_SOURCE
29 # define _GNU_SOURCE 29 # define _GNU_SOURCE
30 #endif 30 #endif
31 31
32 #include <getopt.h> 32 #include <getopt.h>
33 #include <errno.h> 33 #include <errno.h>
34 #include <stdio.h> 34 #include <stdio.h>
35 #include <fcntl.h> 35 #include <fcntl.h>
36 #include <pthread.h> 36 #include <pthread.h>
37 #include <signal.h> 37 #include <signal.h>
38 38
39 #if HAVE_UNISTD_H 39 #if HAVE_UNISTD_H
40 # include <unistd.h> 40 # include <unistd.h>
41 #endif 41 #endif
42 42
43 #include <dirent.h> 43 #include <dirent.h>
44 #include <sys/stat.h> 44 #include <sys/stat.h>
45 45
46 #if HAVE_STRING_H 46 #if HAVE_STRING_H
47 # if !STDC_HEADERS && HAVE_MEMORY_H 47 # if !STDC_HEADERS && HAVE_MEMORY_H
48 # include <memory.h> 48 # include <memory.h>
49 # endif 49 # endif
50 /* Tell glibc's <string.h> to provide a prototype for strndup() */ 50 /* Tell glibc's <string.h> to provide a prototype for strndup() */
51 # ifndef __USE_GNU 51 # ifndef __USE_GNU
52 # define __USE_GNU 52 # define __USE_GNU
53 # endif 53 # endif
54 # include <string.h> 54 # include <string.h>
55 #endif 55 #endif
56 #if HAVE_STRINGS_H 56 #if HAVE_STRINGS_H
57 # include <strings.h> 57 # include <strings.h>
58 #endif 58 #endif
59 59
60 60
61 #if TIME_WITH_SYS_TIME 61 #if TIME_WITH_SYS_TIME
62 # include <sys/time.h> 62 # include <sys/time.h>
63 # include <time.h> 63 # include <time.h>
64 #else 64 #else
65 # if HAVE_SYS_TIME_H 65 # if HAVE_SYS_TIME_H
66 # include <sys/time.h> 66 # include <sys/time.h>
67 # else 67 # else
68 # include <time.h> 68 # include <time.h>
69 # endif 69 # endif
70 #endif 70 #endif
71 71
72 #if !HAVE_STRCHR 72 #if !HAVE_STRCHR
73 # define strchr index 73 # define strchr index
74 #endif 74 #endif
75 75
76 #include "buildtools.h" 76 #include "buildtools.h"
77 #include "changelog.h" 77 #include "changelog.h"
78 #include "distromatic.h" 78 #include "distromatic.h"
79 #include "reports.h" 79 #include "reports.h"
80 #include "headerlist.h" 80 #include "headerlist.h"
81 #include "requirelist.h" 81 #include "requirelist.h"
82 #include "functions.h" 82 #include "functions.h"
83 #include "rpmfunctions.h" 83 #include "rpmfunctions.h"
84 #include "backend-sqlite3.h" 84 #include "backend-sqlite3.h"
85 85
86 #define MODE_DATA_TABLES 1 86 #define MODE_DATA_TABLES 1
87 #define MODE_FIND_DEPS 2 87 #define MODE_FIND_DEPS 2
88 #define MODE_CHANGELOG 4 88 #define MODE_CHANGELOG 4
89 #define MODE_HTML 8 89 #define MODE_HTML 8
90 #define MODE_GENSRCPKGLIST 16 90 #define MODE_GENSRCPKGLIST 16
91 #define MODE_GENBUILDINFO 32 91 #define MODE_GENBUILDINFO 32
92 #define MODE_GENPKGLIST 64 92 #define MODE_GENPKGLIST 64
93 #define MODE_SQLITE3 128 93 #define MODE_SQLITE3 128
94 #define MODE_SQLITE3_FILES 256 94 #define MODE_SQLITE3_FILES 256
95 #define MODE_GENCONTENTSLIST 512
95 96
96 static void program_usage(int exit_code); 97 static void program_usage(int exit_code);
97 static void program_version(void); 98 static void program_version(void);
98 99
99 static int resolveFirstLevelDependencies( 100 static int resolveFirstLevelDependencies(
100 struct configTag *ct, int arch); 101 struct configTag *ct, int arch);
101 102
102 static int 103 static int
103 resolveFirstLevelSourceDependencies(struct configTag *ct, int archidx); 104 resolveFirstLevelSourceDependencies(struct configTag *ct, int archidx);
104 105
105 static int clearRecursionFlag(struct headerList *headerlist); 106 static int clearRecursionFlag(struct headerList *headerlist);
106 107
107 static int resolveRecursiveDependencies( 108 static int resolveRecursiveDependencies(
108 struct headerList *headerlist); 109 struct headerList *headerlist);
109 110
110 int compareRequiredList(const void *ptr1, const void *ptr2); 111 int compareRequiredList(const void *ptr1, const void *ptr2);
111 112
112 int handleObsoletedPackages(struct configTag *ct, int arch); 113 int handleObsoletedPackages(struct configTag *ct, int arch);
113 114
114 static const char *copyright[] = { 115 static const char *copyright[] = {
115 PROGRAMNAME " version " PROGRAMVERSION, 116 PROGRAMNAME " version " PROGRAMVERSION,
116 "Copyright (C) 2004-2015 by Silvan Calarco <silvan.calarco@mambasoft.it>", 117 "Copyright (C) 2004-2015 by Silvan Calarco <silvan.calarco@mambasoft.it>",
117 "Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>", 118 "Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>",
118 (char *)0 119 (char *)0
119 }; 120 };
120 121
121 static struct configTag *firstconfigtag = NULL, *configtag = NULL; 122 static struct configTag *firstconfigtag = NULL, *configtag = NULL;
122 123
123 unsigned int quietmode = 0; 124 unsigned int quietmode = 0;
124 unsigned int genheader_mode = GENHEADER_BASE + GENHEADER_REQUIREMENTS; 125 unsigned int genheader_mode = GENHEADER_BASE + GENHEADER_REQUIREMENTS;
125 unsigned int mode = 0; 126 unsigned int mode = 0;
126 unsigned int recursive_mode = 0; 127 unsigned int recursive_mode = 0;
127 unsigned int incremental_mode = 1; 128 unsigned int incremental_mode = 1;
128 unsigned int obsolete_packages = 1; 129 unsigned int obsolete_packages = 1;
129 unsigned int resolve_dependencies = 1; 130 unsigned int resolve_dependencies = 1;
130 131
131 /* *INDENT-OFF* */ 132 /* *INDENT-OFF* */
132 static const char *freelicense[] = { 133 static const char *freelicense[] = {
133 "This is free software; see the source for copying conditions. There is NO", 134 "This is free software; see the source for copying conditions. There is NO",
134 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.", 135 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
135 (char *)0 136 (char *)0
136 }; 137 };
137 138
138 static const char *helpmsg[] = { 139 static const char *helpmsg[] = {
139 "Usage:", 140 "Usage:",
140 "distromatic [options] [command [arguments] ]...", 141 "distromatic [options] [command [arguments] ]...",
141 "", 142 "",
142 "Commands:", 143 "Commands:",
143 " --gendatatables write dependencies, buildinfo and apt db files", 144 " --gendatatables write dependencies, buildinfo and apt db files",
144 " --genbuildinfo generate build info files for all SRPMS packages", 145 " --genbuildinfo generate build info files for all SRPMS packages",
145 " --genhtml generate HTML code for repository", 146 " --genhtml generate HTML code for repository",
146 " --genpkglist generate binary packages list with version and size", 147 " --genpkglist generate binary packages list with version and size",
147 " --gensrcpkglist generate a source packages list with version", 148 " --gensrcpkglist generate a source packages list with version",
148 " --gensqlite3 dump data to SQLite3 databases", 149 " --gensqlite3 dump data to SQLite3 databases",
149 " --gensqlite3files dump files to SQLite3 databases", 150 " --gensqlite3files dump files to SQLite3 databases",
151 " --gencontentslist generate files listing all files in packages",
150 " --find-deps <package> find dependencies for given package name", 152 " --find-deps <package> find dependencies for given package name",
151 " --changelog <package> print changelog for given package name", 153 " --changelog <package> print changelog for given package name",
152 " --changelogsince <mmddyy> print changelog for all packages since given date", 154 " --changelogsince <mmddyy> print changelog for all packages since given date",
153 "", 155 "",
154 "Options:", 156 "Options:",
155 " -t, --tag use repository identified by tag in config file", 157 " -t, --tag use repository identified by tag in config file",
156 " -a, --arch specify a target architecture (default: " DEFAULT_ARCH ")", 158 " -a, --arch specify a target architecture (default: " DEFAULT_ARCH ")",
157 " -c, --conf <file> specify configuration file (default: " DEFAULT_CONFIGFILE ")", 159 " -c, --conf <file> specify configuration file (default: " DEFAULT_CONFIGFILE ")",
158 " -q, --quiet suppress all messages excluding warnings and errors", 160 " -q, --quiet suppress all messages excluding warnings and errors",
159 " -d, --debug display debug level messages", 161 " -d, --debug display debug level messages",
160 " -v, --version display version and exit", 162 " -v, --version display version and exit",
161 "", 163 "",
162 "Examples:", 164 "Examples:",
163 " distromatic -t devel --genhtml --deps-table", 165 " distromatic -t devel --genhtml --deps-table",
164 " distromatic -t stable/2.0 --changelogsince 010106", 166 " distromatic -t stable/2.0 --changelogsince 010106",
165 "", 167 "",
166 "Please report bugs to <"PACKAGE_BUGREPORT">.", 168 "Please report bugs to <"PACKAGE_BUGREPORT">.",
167 (char *)0 169 (char *)0
168 }; 170 };
169 /* *INDENT-ON* */ 171 /* *INDENT-ON* */
170 172
171 static void 173 static void
172 program_usage(int exit_code) { 174 program_usage(int exit_code) {
173 int linenum; 175 int linenum;
174 176
175 for (linenum = 0; copyright[linenum]; linenum++) 177 for (linenum = 0; copyright[linenum]; linenum++)
176 printf("%s\n", copyright[linenum]); 178 printf("%s\n", copyright[linenum]);
177 printf("\n"); 179 printf("\n");
178 180
179 for (linenum = 0; helpmsg[linenum]; linenum++) 181 for (linenum = 0; helpmsg[linenum]; linenum++)
180 printf("%s\n", helpmsg[linenum]); 182 printf("%s\n", helpmsg[linenum]);
181 183
182 exit(exit_code); 184 exit(exit_code);
183 } 185 }
184 186
185 static void 187 static void
186 program_version(void) { 188 program_version(void) {
187 int linenum; 189 int linenum;
188 190
189 for (linenum = 0; copyright[linenum]; linenum++) 191 for (linenum = 0; copyright[linenum]; linenum++)
190 printf("%s\n", copyright[linenum]); 192 printf("%s\n", copyright[linenum]);
191 printf("\n"); 193 printf("\n");
192 194
193 for (linenum = 0; freelicense[linenum]; linenum++) 195 for (linenum = 0; freelicense[linenum]; linenum++)
194 printf("%s\n", freelicense[linenum]); 196 printf("%s\n", freelicense[linenum]);
195 } 197 }
196 198
197 /* 199 /*
198 * checks if given single requirement is met by given provides 200 * checks if given single requirement is met by given provides
199 * 201 *
200 * returns: 0 if check is unsuccessful 202 * returns: 0 if check is unsuccessful
201 * 1 if successful 203 * 1 if successful
202 * 204 *
203 * FIXME: this just checks for names equality, not for version */ 205 * FIXME: this just checks for names equality, not for version */
204 static int 206 static int
205 checkRequireWithProvides(char *requirename, 207 checkRequireWithProvides(char *requirename,
206 struct headerList *provideheader) 208 struct headerList *provideheader)
207 { 209 {
208 int j; 210 int j;
209 211
210 /* assuming requirename is a library or a virtual package */ 212 /* assuming requirename is a library or a virtual package */
211 for (j = 0; j < provideheader->providecount; j++) { 213 for (j = 0; j < provideheader->providecount; j++) {
212 if (!strcmp 214 if (!strcmp
213 (provideheader->provided[j]->name,requirename)) return 1; 215 (provideheader->provided[j]->name,requirename)) return 1;
214 } 216 }
215 return 0; 217 return 0;
216 } 218 }
217 219
218 int 220 int
219 compareRequiredList(const void *ptr1, const void *ptr2) 221 compareRequiredList(const void *ptr1, const void *ptr2)
220 { 222 {
221 #define require1 (*(struct Require**)ptr1) 223 #define require1 (*(struct Require**)ptr1)
222 #define require2 (*(struct Require**)ptr2) 224 #define require2 (*(struct Require**)ptr2)
223 225
224 if (!require1 && !require2) return 0; 226 if (!require1 && !require2) return 0;
225 if (!require1 || !require1->name) return 1; 227 if (!require1 || !require1->name) return 1;
226 if (!require2 || !require2->name) return -1; 228 if (!require2 || !require2->name) return -1;
227 /* if (require1->resolved->numproviders != require2->resolved->numproviders) 229 /* if (require1->resolved->numproviders != require2->resolved->numproviders)
228 return require2->resolved->numproviders - require1->resolved->numproviders; 230 return require2->resolved->numproviders - require1->resolved->numproviders;
229 231
230 if (require1->resolved->numproviders == 1) 232 if (require1->resolved->numproviders == 1)
231 return strcmp(require1->resolved->provider[0]->name,require2->resolved->provider[0]->name); 233 return strcmp(require1->resolved->provider[0]->name,require2->resolved->provider[0]->name);
232 else*/ 234 else*/
233 return strcmp(require1->name,require2->name); 235 return strcmp(require1->name,require2->name);
234 } 236 }
235 237
236 /* 238 /*
237 * inspect multiple providing packages in providedList 239 * inspect multiple providing packages in providedList
238 * and remove providers that are obsoleted by others 240 * and remove providers that are obsoleted by others
239 */ 241 */
240 int 242 int
241 handleObsoletedPackages(struct configTag *ct, int archidx) 243 handleObsoletedPackages(struct configTag *ct, int archidx)
242 { 244 {
243 struct providedList *prov = ct->providedlist_idx[archidx][0]; 245 struct providedList *prov = ct->providedlist_idx[archidx][0];
244 int i,j,k; 246 int i,j,k;
245 int obs[256]; 247 int obs[256];
246 char buf[PATH_MAX]; 248 char buf[PATH_MAX];
247 struct headerList *currheader; 249 struct headerList *currheader;
248 250
249 while (prov) { 251 while (prov) {
250 252
251 if (prov->numproviders > 256) { 253 if (prov->numproviders > 256) {
252 return 1; 254 return 1;
253 } 255 }
254 256
255 if (prov->numproviders > 1) { 257 if (prov->numproviders > 1) {
256 for (i = 0; i < prov->numproviders; i++) obs[i]=-1; 258 for (i = 0; i < prov->numproviders; i++) obs[i]=-1;
257 for (i = 0; i < prov->numproviders; i++) 259 for (i = 0; i < prov->numproviders; i++)
258 for (j = 0; j < prov->provider[i]->obsoletecount; j++) 260 for (j = 0; j < prov->provider[i]->obsoletecount; j++)
259 for (k = 0; k < prov->numproviders; k++) 261 for (k = 0; k < prov->numproviders; k++)
260 if (!strcmp(prov->provider[i]->obsoletename[j],prov->provider[k]->name) 262 if (!strcmp(prov->provider[i]->obsoletename[j],prov->provider[k]->name)
261 && strcmp(prov->provider[i]->name,prov->provider[k]->name)) { 263 && strcmp(prov->provider[i]->name,prov->provider[k]->name)) {
262 if (prov->provider[i]->obsoleteflags[j] & (RPMSENSE_EQUAL|RPMSENSE_GREATER|RPMSENSE_LESS)) { 264 if (prov->provider[i]->obsoleteflags[j] & (RPMSENSE_EQUAL|RPMSENSE_GREATER|RPMSENSE_LESS)) {
263 snprintf(buf, PATH_MAX, "%s-%s",prov->provider[k]->version,prov->provider[k]->release); 265 snprintf(buf, PATH_MAX, "%s-%s",prov->provider[k]->version,prov->provider[k]->release);
264 if (!checkVersionWithFlags( 266 if (!checkVersionWithFlags(
265 prov->provider[i]->obsoleteversion[j], 267 prov->provider[i]->obsoleteversion[j],
266 prov->provider[i]->obsoleteflags[j], 268 prov->provider[i]->obsoleteflags[j],
267 buf)) continue; 269 buf)) continue;
268 } 270 }
269 /* print 'obsoletes' warning for binary packages belonging to target repository, 271 /* print 'obsoletes' warning for binary packages belonging to target repository,
270 and 'obsoleted by' for all obsoletions in upper level repositories */ 272 and 'obsoleted by' for all obsoletions in upper level repositories */
271 if (prov->provider[k]->altrepository != ct->repository_level) { 273 if (prov->provider[k]->altrepository != ct->repository_level) {
272 currheader = prov->provider[k]->sourceheader->firstchild[archidx]; 274 currheader = prov->provider[k]->sourceheader->firstchild[archidx];
273 while (currheader) { 275 while (currheader) {
274 if (!strcmp(currheader->name, prov->provider[k]->name)) { 276 if (!strcmp(currheader->name, prov->provider[k]->name)) {
275 prov->provider[k]->obsoleted = 1; 277 prov->provider[k]->obsoleted = 1;
276 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoleted by %s(%s,%s)", 278 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoleted by %s(%s,%s)",
277 prov->provider[k]->name, 279 prov->provider[k]->name,
278 prov->provider[k]->arch, 280 prov->provider[k]->arch,
279 ct->repository[prov->provider[k]->altrepository]->tag, 281 ct->repository[prov->provider[k]->altrepository]->tag,
280 prov->provider[i]->name, 282 prov->provider[i]->name,
281 prov->provider[i]->arch, 283 prov->provider[i]->arch,
282 ct->repository[prov->provider[i]->altrepository]->tag); 284 ct->repository[prov->provider[i]->altrepository]->tag);
283 addWarning(prov->provider[k]->sourceheader, buf); 285 addWarning(prov->provider[k]->sourceheader, buf);
284 logmsg(LOG_WARNING,"%s", buf); 286 logmsg(LOG_WARNING,"%s", buf);
285 break; 287 break;
286 } 288 }
287 currheader = currheader -> nextbrother; 289 currheader = currheader -> nextbrother;
288 } 290 }
289 } else { 291 } else {
290 prov->provider[k]->obsoleted = 1; 292 prov->provider[k]->obsoleted = 1;
291 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s(%s,%s)", 293 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s(%s,%s)",
292 prov->provider[i]->name, 294 prov->provider[i]->name,
293 prov->provider[i]->arch, 295 prov->provider[i]->arch,
294 ct->repository[prov->provider[i]->altrepository]->tag, 296 ct->repository[prov->provider[i]->altrepository]->tag,
295 prov->provider[k]->name, 297 prov->provider[k]->name,
296 prov->provider[k]->arch, 298 prov->provider[k]->arch,
297 ct->repository[prov->provider[k]->altrepository]->tag); 299 ct->repository[prov->provider[k]->altrepository]->tag);
298 addWarning(prov->provider[i]->sourceheader, buf); 300 addWarning(prov->provider[i]->sourceheader, buf);
299 logmsg(LOG_WARNING,"%s", buf); 301 logmsg(LOG_WARNING,"%s", buf);
300 } 302 }
301 obs[k]=i; 303 obs[k]=i;
302 } 304 }
303 305
304 // now delete found obsoleted providers 306 // now delete found obsoleted providers
305 j = prov->numproviders; 307 j = prov->numproviders;
306 for (i = 0; i < prov->numproviders; i++) { 308 for (i = 0; i < prov->numproviders; i++) {
307 if (obs[i] >=0) { 309 if (obs[i] >=0) {
308 j--; 310 j--;
309 prov->provider[i]->obsoleted=1; 311 prov->provider[i]->obsoleted=1;
310 prov->provider[i]=NULL; 312 prov->provider[i]=NULL;
311 } 313 }
312 } 314 }
313 315
314 if (j < prov->numproviders) { 316 if (j < prov->numproviders) {
315 for (i = 0; i < j; i++) { 317 for (i = 0; i < j; i++) {
316 if (prov->provider[i] == NULL) { 318 if (prov->provider[i] == NULL) {
317 k=i+1; 319 k=i+1;
318 while (k < prov->numproviders && !prov->provider[k]) k++; 320 while (k < prov->numproviders && !prov->provider[k]) k++;
319 prov->provider[i]=prov->provider[k]; 321 prov->provider[i]=prov->provider[k];
320 prov->provider[k]=NULL; 322 prov->provider[k]=NULL;
321 } 323 }
322 } 324 }
323 prov->numproviders = j; 325 prov->numproviders = j;
324 } 326 }
325 } 327 }
326 328
327 prov=prov->next; 329 prov=prov->next;
328 } 330 }
329 331
330 /* mark obsoleted elements which are provided by other packages */ 332 /* mark obsoleted elements which are provided by other packages */
331 currheader = ct->headerlist[archidx]; 333 currheader = ct->headerlist[archidx];
332 while (currheader) { 334 while (currheader) {
333 if (currheader->obsoleted == 0) 335 if (currheader->obsoleted == 0)
334 for (j = 0; j < currheader->obsoletecount; j++) { 336 for (j = 0; j < currheader->obsoletecount; j++) {
335 prov=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx], 337 prov=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx],
336 currheader->obsoletename[j],0,archidx); 338 currheader->obsoletename[j],0,archidx);
337 if (prov) { 339 if (prov) {
338 for (i = 0; i < prov->numproviders; i++) { 340 for (i = 0; i < prov->numproviders; i++) {
339 if (strcmp(currheader->name,prov->provider[i]->name)) { 341 if (strcmp(currheader->name,prov->provider[i]->name)) {
340 // if (currheader->sourceheader != prov->provider[i]->sourceheader) { 342 // if (currheader->sourceheader != prov->provider[i]->sourceheader) {
341 if (prov->provider[i]->sourceheader == currheader->sourceheader) { 343 if (prov->provider[i]->sourceheader == currheader->sourceheader) {
342 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s provided by %s(%s,%s) which comes from its own source; ignoring", 344 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s provided by %s(%s,%s) which comes from its own source; ignoring",
343 currheader->name, 345 currheader->name,
344 currheader->arch, 346 currheader->arch,
345 ct->repository[currheader->altrepository]->tag, 347 ct->repository[currheader->altrepository]->tag,
346 prov->name, 348 prov->name,
347 prov->provider[i]->name, 349 prov->provider[i]->name,
348 prov->provider[i]->arch, 350 prov->provider[i]->arch,
349 ct->repository[prov->provider[i]->altrepository]->tag); 351 ct->repository[prov->provider[i]->altrepository]->tag);
350 } else if (!strcmp(prov->provider[i]->sourceheader->name,currheader->sourceheader->name)) { 352 } else if (!strcmp(prov->provider[i]->sourceheader->name,currheader->sourceheader->name)) {
351 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s provided by %s(%s,%s) which comes from same source name; ignoring", 353 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s provided by %s(%s,%s) which comes from same source name; ignoring",
352 currheader->name, 354 currheader->name,
353 currheader->arch, 355 currheader->arch,
354 ct->repository[currheader->altrepository]->tag, 356 ct->repository[currheader->altrepository]->tag,
355 prov->name, 357 prov->name,
356 prov->provider[i]->name, 358 prov->provider[i]->name,
357 prov->provider[i]->arch, 359 prov->provider[i]->arch,
358 ct->repository[prov->provider[i]->altrepository]->tag); 360 ct->repository[prov->provider[i]->altrepository]->tag);
359 } else { 361 } else {
360 prov->provider[i]->obsoleted = 1; 362 prov->provider[i]->obsoleted = 1;
361 if (!strcmp(prov->name,prov->provider[i]->name)) { 363 if (!strcmp(prov->name,prov->provider[i]->name)) {
362 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s(%s,%s)", 364 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s(%s,%s)",
363 currheader->name, 365 currheader->name,
364 currheader->arch, 366 currheader->arch,
365 ct->repository[currheader->altrepository]->tag, 367 ct->repository[currheader->altrepository]->tag,
366 prov->provider[i]->name, 368 prov->provider[i]->name,
367 prov->provider[i]->arch, 369 prov->provider[i]->arch,
368 ct->repository[prov->provider[i]->altrepository]->tag); 370 ct->repository[prov->provider[i]->altrepository]->tag);
369 } else { 371 } else {
370 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s provided by %s(%s,%s)", 372 snprintf(buf, PATH_MAX, "%s(%s,%s) obsoletes %s provided by %s(%s,%s)",
371 currheader->name, 373 currheader->name,
372 currheader->arch, 374 currheader->arch,
373 ct->repository[currheader->altrepository]->tag, 375 ct->repository[currheader->altrepository]->tag,
374 prov->name, 376 prov->name,
375 prov->provider[i]->name, 377 prov->provider[i]->name,
376 prov->provider[i]->arch, 378 prov->provider[i]->arch,
377 ct->repository[prov->provider[i]->altrepository]->tag); 379 ct->repository[prov->provider[i]->altrepository]->tag);
378 } 380 }
379 } 381 }
380 addWarning(currheader->sourceheader, buf); 382 addWarning(currheader->sourceheader, buf);
381 logmsg(LOG_WARNING,"%s", buf); 383 logmsg(LOG_WARNING,"%s", buf);
382 } 384 }
383 } 385 }
384 } 386 }
385 } 387 }
386 currheader = currheader->next; 388 currheader = currheader->next;
387 } 389 }
388 390
389 return 0; 391 return 0;
390 } 392 }
391 393
392 /* 394 /*
393 * resolve first level requires for given headerList 395 * resolve first level requires for given headerList
394 * note: this function doesn't free allocated memory so it should be called 396 * note: this function doesn't free allocated memory so it should be called
395 * only once */ 397 * only once */
396 static int 398 static int
397 resolveFirstLevelDependencies(struct configTag *ct, int archidx) 399 resolveFirstLevelDependencies(struct configTag *ct, int archidx)
398 { 400 {
399 struct headerList *currheader, *scanheader, **newprovider; 401 struct headerList *currheader, *scanheader, **newprovider;
400 struct providedList *provided; 402 struct providedList *provided;
401 struct fileTree *file; 403 struct fileTree *file;
402 int i,j,k,found,foundprovider, foundupstreamprovider; 404 int i,j,k,found,foundprovider, foundupstreamprovider;
403 char warning[PATH_MAX]; 405 char warning[PATH_MAX];
404 char ** newversion; 406 char ** newversion;
405 407
406 currheader = ct->headerlist[archidx]; 408 currheader = ct->headerlist[archidx];
407 409
408 logmsg(LOG_DEBUG,"resolveFirstLevelDependencies - binaries"); 410 logmsg(LOG_DEBUG,"resolveFirstLevelDependencies - binaries");
409 411
410 while (currheader) { 412 while (currheader) {
411 scanheader = ct->headerlist[archidx]; 413 scanheader = ct->headerlist[archidx];
412 currheader->requirelist = NULL; 414 currheader->requirelist = NULL;
413 if ((!currheader->obsoleted) && (currheader->next) && (currheader->sourceheader->updatingparent)) { 415 if ((!currheader->obsoleted) && (currheader->next) && (currheader->sourceheader->updatingparent)) {
414 // mark obsoleted any package with same name in upper level repositories 416 // mark obsoleted any package with same name in upper level repositories
415 if (currheader->altrepository < currheader->sourceheader->updatingparent->altrepository) { 417 if (currheader->altrepository < currheader->sourceheader->updatingparent->altrepository) {
416 currheader->obsoleted = 1; 418 currheader->obsoleted = 1;
417 if (checkVersionWithFlags( 419 if (checkVersionWithFlags(
418 currheader->version, 420 currheader->version,
419 RPMSENSE_GREATER & RPMSENSE_EQUAL, 421 RPMSENSE_GREATER & RPMSENSE_EQUAL,
420 currheader->next->version)) { 422 currheader->next->version)) {
421 snprintf(warning,PATH_MAX,"%s(%s,%s): same or higher version than package with same name in %s (%s >= %s)", 423 snprintf(warning,PATH_MAX,"%s(%s,%s): same or higher version than package with same name in %s (%s >= %s)",
422 currheader->name, 424 currheader->name,
423 ct->arch[archidx], 425 ct->arch[archidx],
424 ct->repository[currheader->altrepository]->tag, 426 ct->repository[currheader->altrepository]->tag,
425 ct->repository[currheader->next->altrepository]->tag, 427 ct->repository[currheader->next->altrepository]->tag,
426 currheader->version, 428 currheader->version,
427 currheader->next->version); 429 currheader->next->version);
428 fprintf(stderr,"Warning: %s\n",warning); 430 fprintf(stderr,"Warning: %s\n",warning);
429 addWarning(currheader->sourceheader,warning); 431 addWarning(currheader->sourceheader,warning);
430 } 432 }
431 } else if (currheader->altrepository >= currheader->sourceheader->updatingparent->altrepository) { 433 } else if (currheader->altrepository >= currheader->sourceheader->updatingparent->altrepository) {
432 currheader->next->obsoleted = 1; 434 currheader->next->obsoleted = 1;
433 if (checkVersionWithFlags( 435 if (checkVersionWithFlags(
434 currheader->version, 436 currheader->version,
435 RPMSENSE_LESS & RPMSENSE_EQUAL, 437 RPMSENSE_LESS & RPMSENSE_EQUAL,
436 currheader->next->version)) { 438 currheader->next->version)) {
437 snprintf(warning,PATH_MAX,"%s(%s,%s): same or higher version than package with same name in %s (%s >= %s)", 439 snprintf(warning,PATH_MAX,"%s(%s,%s): same or higher version than package with same name in %s (%s >= %s)",
438 currheader->next->name, 440 currheader->next->name,
439 ct->arch[archidx], 441 ct->arch[archidx],
440 ct->repository[currheader->next->altrepository]->tag, 442 ct->repository[currheader->next->altrepository]->tag,
441 ct->repository[currheader->altrepository]->tag, 443 ct->repository[currheader->altrepository]->tag,
442 currheader->next->version, 444 currheader->next->version,
443 currheader->version); 445 currheader->version);
444 fprintf(stderr,"Warning: %s\n",warning); 446 fprintf(stderr,"Warning: %s\n",warning);
445 addWarning(currheader->sourceheader,warning); 447 addWarning(currheader->sourceheader,warning);
446 } 448 }
447 } 449 }
448 } 450 }
449 451
450 if (currheader->obsoleted || currheader->sourceheader->updatingparent) { 452 if (currheader->obsoleted || currheader->sourceheader->updatingparent) {
451 currheader = currheader->next; 453 currheader = currheader->next;
452 continue; 454 continue;
453 } 455 }
454 // currheader->require.resolved = malloc(sizeof(struct providedList*)*currheader->requirecount); 456 // currheader->require.resolved = malloc(sizeof(struct providedList*)*currheader->requirecount);
455 457
456 for (i = 0; i < currheader->requirecount; i++) { 458 for (i = 0; i < currheader->requirecount; i++) {
457 459
458 if (!strncmp("executable(",currheader->require[i]->name,11)) { 460 if (!strncmp("executable(",currheader->require[i]->name,11)) {
459 /* dynamic requirement for executable file */ 461 /* dynamic requirement for executable file */
460 /* fprintf(stderr,"Warning: skipping unhandled requirement %s for package %s\n", 462 /* fprintf(stderr,"Warning: skipping unhandled requirement %s for package %s\n",
461 currheader->require[i]->name,currheader->name);*/ 463 currheader->require[i]->name,currheader->name);*/
462 currheader->require[i]->resolved=NULL; 464 currheader->require[i]->resolved=NULL;
463 } else if (strncmp("rpmlib(",currheader->require[i]->name,7) != 0) { 465 } else if (strncmp("rpmlib(",currheader->require[i]->name,7) != 0) {
464 provided=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx], 466 provided=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx],
465 currheader->require[i]->name,1,archidx); 467 currheader->require[i]->name,1,archidx);
466 if (provided->numproviders == 0) { 468 if (provided->numproviders == 0) {
467 // check if require[i]->name requirement is met 469 // check if require[i]->name requirement is met
468 scanheader = ct->headerlist[archidx]; 470 scanheader = ct->headerlist[archidx];
469 471
470 if ((currheader->require[i]->name)[0] == '/') { 472 if ((currheader->require[i]->name)[0] == '/') {
471 /* requirement is a file, find who provides it */ 473 /* requirement is a file, find who provides it */
472 file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currheader->require[i]->name, archidx); 474 file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currheader->require[i]->name, archidx);
473 if (file->numproviders > 0) { 475 if (file->numproviders > 0) {
474 scanheader=file->provider[0]; 476 scanheader=file->provider[0];
475 provided->numproviders=file->numproviders; 477 provided->numproviders=file->numproviders;
476 provided->numbuildproviders=0; 478 provided->numbuildproviders=0;
477 provided->provider=file->provider; 479 provided->provider=file->provider;
478 provided->flags=0; 480 provided->flags=0;
479 } else { 481 } else {
480 scanheader=NULL; 482 scanheader=NULL;
481 } 483 }
482 } else { 484 } else {
483 /* requirement is not a file, cross-check with provides */ 485 /* requirement is not a file, cross-check with provides */
484 while (scanheader && 486 while (scanheader &&
485 !checkRequireWithProvides( 487 !checkRequireWithProvides(
486 currheader->require[i]->name, 488 currheader->require[i]->name,
487 scanheader)) scanheader = scanheader->next; 489 scanheader)) scanheader = scanheader->next;
488 if (scanheader) { 490 if (scanheader) {
489 provided->numproviders=1; 491 provided->numproviders=1;
490 provided->numbuildproviders=0; 492 provided->numbuildproviders=0;
491 provided->provider=malloc(sizeof(struct headerList*)); 493 provided->provider=malloc(sizeof(struct headerList*));
492 provided->provider[0]=scanheader; 494 provided->provider[0]=scanheader;
493 provided->flags=0; 495 provided->flags=0;
494 } 496 }
495 } 497 }
496 if (!scanheader && incremental_mode) { 498 if (!scanheader && incremental_mode) {
497 snprintf(warning,PATH_MAX,"%s(%s,%s): missing provider for %s", 499 snprintf(warning,PATH_MAX,"%s(%s,%s): missing provider for %s",
498 currheader->name, 500 currheader->name,
499 ct->arch[archidx], 501 ct->arch[archidx],
500 ct->repository[currheader->altrepository]->tag, 502 ct->repository[currheader->altrepository]->tag,
501 currheader->require[i]->name); 503 currheader->require[i]->name);
502 fprintf(stderr,"Warning: %s\n",warning); 504 fprintf(stderr,"Warning: %s\n",warning);
503 addWarning(currheader->sourceheader,warning); 505 addWarning(currheader->sourceheader,warning);
504 } 506 }
505 } else { /* provided->numproviders > 0 */ 507 } else { /* provided->numproviders > 0 */
506 /* warn about provides only provided by older packages */ 508 /* warn about provides only provided by older packages */
507 k=0; 509 k=0;
508 for (j = 0; j < provided->numproviders; j++) { 510 for (j = 0; j < provided->numproviders; j++) {
509 if (provided->provider[j]->sourceheader->updatingparent && 511 if (provided->provider[j]->sourceheader->updatingparent &&
510 provided->provider[j]->sourceheader->updatingparent->firstchild[archidx] && /* skip if not built for arch */ 512 provided->provider[j]->sourceheader->updatingparent->firstchild[archidx] && /* skip if not built for arch */
511 !currheader->obsoleted) k++; 513 !currheader->obsoleted) k++;
512 } 514 }
513 if (k == provided->numproviders) { // all provides are from older packages 515 if (k == provided->numproviders) { // all provides are from older packages
514 snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by older package(s):", 516 snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by older package(s):",
515 currheader->name, 517 currheader->name,
516 currheader->arch, 518 currheader->arch,
517 ct->repository[currheader->altrepository]->tag, 519 ct->repository[currheader->altrepository]->tag,
518 provided->name); 520 provided->name);
519 for (j = 0; j < provided->numproviders; j++) { 521 for (j = 0; j < provided->numproviders; j++) {
520 snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)", 522 snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)",
521 provided->provider[j]->name, 523 provided->provider[j]->name,
522 provided->provider[j]->arch, 524 provided->provider[j]->arch,
523 ct->repository[provided->provider[j]->altrepository]->tag); 525 ct->repository[provided->provider[j]->altrepository]->tag);
524 addRebuild(provided->provider[j]->sourceheader,currheader->sourceheader,provided->provider[j]); 526 addRebuild(provided->provider[j]->sourceheader,currheader->sourceheader,provided->provider[j]);
525 addWarning(provided->provider[j]->sourceheader,warning); 527 addWarning(provided->provider[j]->sourceheader,warning);
526 } 528 }
527 fprintf(stderr,"Warning: %s\n",warning); 529 fprintf(stderr,"Warning: %s\n",warning);
528 } else { 530 } else {
529 /* warn about provides provided by obsoleted packages */ 531 /* warn about provides provided by obsoleted packages */
530 k=0; 532 k=0;
531 for (j = 0; j < provided->numproviders; j++) { 533 for (j = 0; j < provided->numproviders; j++) {
532 if (provided->provider[j]->obsoleted && 534 if (provided->provider[j]->obsoleted &&
533 !provided->provider[j]->sourceheader->updatingparent && // don't fall in case above 535 !provided->provider[j]->sourceheader->updatingparent && // don't fall in case above
534 !currheader->obsoleted) k++; 536 !currheader->obsoleted) k++;
535 } 537 }
536 if (k == provided->numproviders) { // all provides are obsoleted 538 if (k == provided->numproviders) { // all provides are obsoleted
537 snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by obsoleted package(s):", 539 snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s which is only provided by obsoleted package(s):",
538 currheader->name, 540 currheader->name,
539 currheader->arch, 541 currheader->arch,
540 ct->repository[currheader->altrepository]->tag, 542 ct->repository[currheader->altrepository]->tag,
541 provided->name); 543 provided->name);
542 for (j = 0; j < provided->numproviders; j++) { 544 for (j = 0; j < provided->numproviders; j++) {
543 snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)", 545 snprintf(&warning[strlen(warning)], PATH_MAX - strlen(warning), " %s(%s,%s)",
544 provided->provider[j]->name, 546 provided->provider[j]->name,
545 provided->provider[j]->arch, 547 provided->provider[j]->arch,
546 ct->repository[provided->provider[j]->altrepository]->tag); 548 ct->repository[provided->provider[j]->altrepository]->tag);
547 } 549 }
548 fprintf(stderr,"Warning: %s\n",warning); 550 fprintf(stderr,"Warning: %s\n",warning);
549 addWarning(currheader->sourceheader,warning); 551 addWarning(currheader->sourceheader,warning);
550 for (j = 0; j < provided->numproviders; j++) { 552 for (j = 0; j < provided->numproviders; j++) {
551 addWarning(provided->provider[j]->sourceheader,warning); 553 addWarning(provided->provider[j]->sourceheader,warning);
552 } 554 }
553 } 555 }
554 } 556 }
555 if ((currheader->require[i]->name)[0] == '/') { 557 if ((currheader->require[i]->name)[0] == '/') {
556 /* when there is a Requires: /file/requirement add provide from file tree as well */ 558 /* when there is a Requires: /file/requirement add provide from file tree as well */
557 file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currheader->require[i]->name, archidx); 559 file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currheader->require[i]->name, archidx);
558 for (k = 0; k < file->numproviders; k++) { 560 for (k = 0; k < file->numproviders; k++) {
559 for (j = 0, found = 0; j < provided->numproviders; j++) { 561 for (j = 0, found = 0; j < provided->numproviders; j++) {
560 /* avoid duplicates */ 562 /* avoid duplicates */
561 if (file->provider[k] == provided->provider[j]) { 563 if (file->provider[k] == provided->provider[j]) {
562 found = 1; 564 found = 1;
563 break; 565 break;
564 } 566 }
565 } 567 }
566 if (! found) { 568 if (! found) {
567 //printf("%s also provided by %s\n", currheader->require[i]->name, file->provider[k]->name); 569 //printf("%s also provided by %s\n", currheader->require[i]->name, file->provider[k]->name);
568 provided->numproviders++; 570 provided->numproviders++;
569 newprovider=malloc(sizeof(struct headerList*)*provided->numproviders); 571 newprovider=malloc(sizeof(struct headerList*)*provided->numproviders);
570 for (j = 0; j < provided->numproviders-1; j++) { 572 for (j = 0; j < provided->numproviders-1; j++) {
571 newprovider[j]=provided->provider[j]; 573 newprovider[j]=provided->provider[j];
572 } 574 }
573 newprovider[provided->numproviders-1] = file->provider[k]; 575 newprovider[provided->numproviders-1] = file->provider[k];
574 if (provided->provider) free(provided->provider); 576 if (provided->provider) free(provided->provider);
575 provided->provider=newprovider; 577 provided->provider=newprovider;
576 newversion=malloc(sizeof(char *)*provided->numproviders); 578 newversion=malloc(sizeof(char *)*provided->numproviders);
577 for (j = 0; j < provided->numproviders-1; j++) { 579 for (j = 0; j < provided->numproviders-1; j++) {
578 newversion[j]=provided->version[j]; 580 newversion[j]=provided->version[j];
579 } 581 }
580 newversion[provided->numproviders-1] = strdup(provided->provider[j]->version); 582 newversion[provided->numproviders-1] = strdup(provided->provider[j]->version);
581 if (provided->version) free(provided->version); 583 if (provided->version) free(provided->version);
582 provided->version=newversion; 584 provided->version=newversion;
583 } 585 }
584 } 586 }
585 } 587 }
586 } 588 }
587 589
588 if (provided->numproviders > 0) { 590 if (provided->numproviders > 0) {
589 if (strcmp(currheader->require[i]->version,"") && 591 if (strcmp(currheader->require[i]->version,"") &&
590 (currheader->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL))) { 592 (currheader->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL))) {
591 593
592 found = 0; 594 found = 0;
593 foundprovider = -1; 595 foundprovider = -1;
594 foundupstreamprovider = 0; 596 foundupstreamprovider = 0;
595 for (j = 0; j < provided->numproviders; j++) { 597 for (j = 0; j < provided->numproviders; j++) {
596 /* updated packages: ignore check with upstream package */ 598 /* updated packages: ignore check with upstream package */
597 if ((foundprovider >= 0) && 599 if ((foundprovider >= 0) &&
598 !strcmp(provided->provider[foundprovider]->name,provided->provider[j]->name) && 600 !strcmp(provided->provider[foundprovider]->name,provided->provider[j]->name) &&
599 provided->provider[foundprovider]->altrepository < provided->provider[j]->altrepository) { 601 provided->provider[foundprovider]->altrepository < provided->provider[j]->altrepository) {
600 found -= 1; 602 found -= 1;
601 foundupstreamprovider = foundprovider; 603 foundupstreamprovider = foundprovider;
602 foundprovider = -1; 604 foundprovider = -1;
603 } 605 }
604 if (!strcmp(provided->version[j],"")) { 606 if (!strcmp(provided->version[j],"")) {
605 /* provider with no version; assume ok */ 607 /* provider with no version; assume ok */
606 found += 1; 608 found += 1;
607 foundupstreamprovider = foundprovider; 609 foundupstreamprovider = foundprovider;
608 foundprovider = j; 610 foundprovider = j;
609 } else { 611 } else {
610 if (checkVersionWithFlags( 612 if (checkVersionWithFlags(
611 currheader->require[i]->version, 613 currheader->require[i]->version,
612 currheader->require[i]->flags, 614 currheader->require[i]->flags,
613 provided->version[j])) { 615 provided->version[j])) {
614 found += 1; 616 found += 1;
615 foundupstreamprovider = foundprovider; 617 foundupstreamprovider = foundprovider;
616 foundprovider = j; 618 foundprovider = j;
617 } 619 }
618 } 620 }
619 /*if (!strcmp(provided->name,"pkgconfig(gio-2.0)")) 621 /*if (!strcmp(provided->name,"pkgconfig(gio-2.0)"))
620 printf("provided->name=pkgconfig(gio-2.0) found=%d foundprovider=%d foundupstreamprovider=%d provided->version[j]=%s\n", 622 printf("provided->name=pkgconfig(gio-2.0) found=%d foundprovider=%d foundupstreamprovider=%d provided->version[j]=%s\n",
621 found, foundprovider, foundupstreamprovider, provided->version[j]);*/ 623 found, foundprovider, foundupstreamprovider, provided->version[j]);*/
622 } /* for */ 624 } /* for */
623 if ((found >= 1) && (!foundupstreamprovider) && 625 if ((found >= 1) && (!foundupstreamprovider) &&
624 (currheader->altrepository != 0) && 626 (currheader->altrepository != 0) &&
625 (currheader->altrepository = ct->repository_level) && 627 (currheader->altrepository = ct->repository_level) &&
626 (provided->provider[foundprovider]->sourceheader != currheader->sourceheader) && 628 (provided->provider[foundprovider]->sourceheader != currheader->sourceheader) &&
627 (provided->provider[foundprovider]->altrepository == currheader->altrepository)) { 629 (provided->provider[foundprovider]->altrepository == currheader->altrepository)) {
628 snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) because it needs %s=%s", 630 snprintf(warning, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) because it needs %s=%s",
629 currheader->name, 631 currheader->name,
630 currheader->arch, 632 currheader->arch,
631 ct->repository[currheader->altrepository]->tag, 633 ct->repository[currheader->altrepository]->tag,
632 provided->provider[foundprovider]->name, 634 provided->provider[foundprovider]->name,
633 provided->provider[foundprovider]->arch, 635 provided->provider[foundprovider]->arch,
634 ct->repository[provided->provider[foundprovider]->altrepository]->tag, 636 ct->repository[provided->provider[foundprovider]->altrepository]->tag,
635 provided->name, 637 provided->name,
636 provided->version[foundprovider]); 638 provided->version[foundprovider]);
637 logmsg(LOG_WARNING,"%s", warning); 639 logmsg(LOG_WARNING,"%s", warning);
638 addWarning(currheader->sourceheader, warning); 640 addWarning(currheader->sourceheader, warning);
639 } else if (!found) { 641 } else if (!found) {
640 for (j = 0; j < provided->numproviders; j++) { 642 for (j = 0; j < provided->numproviders; j++) {
641 if (!checkVersionWithFlags( 643 if (!checkVersionWithFlags(
642 currheader->require[i]->version, 644 currheader->require[i]->version,
643 currheader->require[i]->flags, 645 currheader->require[i]->flags,
644 provided->version[j])) { 646 provided->version[j])) {
645 snprintf(warning, PATH_MAX, "%s=%s from %s(%s,%s) fails to provide %s", 647 snprintf(warning, PATH_MAX, "%s=%s from %s(%s,%s) fails to provide %s",
646 provided->name, 648 provided->name,
647 provided->version[j], 649 provided->version[j],
648 provided->provider[j]->name, 650 provided->provider[j]->name,
649 provided->provider[j]->arch, 651 provided->provider[j]->arch,
650 ct->repository[provided->provider[j]->altrepository]->tag, 652 ct->repository[provided->provider[j]->altrepository]->tag,
651 provided->name); 653 provided->name);
652 if (currheader->require[i]->flags & RPMSENSE_LESS) snprintf(&warning[strlen(warning)], PATH_MAX,"<"); 654 if (currheader->require[i]->flags & RPMSENSE_LESS) snprintf(&warning[strlen(warning)], PATH_MAX,"<");
653 if (currheader->require[i]->flags & RPMSENSE_GREATER) snprintf(&warning[strlen(warning)], PATH_MAX, ">"); 655 if (currheader->require[i]->flags & RPMSENSE_GREATER) snprintf(&warning[strlen(warning)], PATH_MAX, ">");
654 if (currheader->require[i]->flags & RPMSENSE_EQUAL) snprintf(&warning[strlen(warning)], PATH_MAX, "="); 656 if (currheader->require[i]->flags & RPMSENSE_EQUAL) snprintf(&warning[strlen(warning)], PATH_MAX, "=");
655 snprintf(&warning[strlen(warning)], PATH_MAX, "%s to %s(%s,%s)", 657 snprintf(&warning[strlen(warning)], PATH_MAX, "%s to %s(%s,%s)",
656 currheader->require[i]->version, 658 currheader->require[i]->version,
657 currheader->name, 659 currheader->name,
658 currheader->arch, 660 currheader->arch,
659 ct->repository[currheader->altrepository]->tag); 661 ct->repository[currheader->altrepository]->tag);
660 logmsg(LOG_WARNING,"%s", warning); 662 logmsg(LOG_WARNING,"%s", warning);
661 for (k = 0; k < provided->numproviders; k++) { 663 for (k = 0; k < provided->numproviders; k++) {
662 if (provided->provider[k]->sourceheader && 664 if (provided->provider[k]->sourceheader &&
663 (provided->provider[k]->altrepository == ct->repository_level)) { 665 (provided->provider[k]->altrepository == ct->repository_level)) {
664 addWarning(provided->provider[k]->sourceheader, warning); 666 addWarning(provided->provider[k]->sourceheader, warning);
665 } 667 }
666 if ((currheader->altrepository == ct->repository_level)) { 668 if ((currheader->altrepository == ct->repository_level)) {
667 addWarning(currheader->sourceheader, warning); 669 addWarning(currheader->sourceheader, warning);
668 } 670 }
669 } 671 }
670 } 672 }
671 } 673 }
672 } 674 }
673 675
674 } 676 }
675 } 677 }
676 currheader->require[i]->resolved=provided; 678 currheader->require[i]->resolved=provided;
677 } else { 679 } else {
678 currheader->require[i]->resolved=NULL; 680 currheader->require[i]->resolved=NULL;
679 } 681 }
680 } 682 }
681 // sort required list by first provider's name 683 // sort required list by first provider's name
682 qsort((void *) &currheader->require[0], 684 qsort((void *) &currheader->require[0],
683 currheader->requirecount, 685 currheader->requirecount,
684 sizeof(struct Require *), 686 sizeof(struct Require *),
685 compareRequiredList); 687 compareRequiredList);
686 currheader = currheader->next; 688 currheader = currheader->next;
687 } 689 }
688 logmsg(LOG_DEBUG,"resolveFirstLevelDependencies - done"); 690 logmsg(LOG_DEBUG,"resolveFirstLevelDependencies - done");
689 return 0; 691 return 0;
690 } 692 }
691 693
692 static int 694 static int
693 resolveFirstLevelSourceDependencies(struct configTag *ct, int archidx) 695 resolveFirstLevelSourceDependencies(struct configTag *ct, int archidx)
694 { 696 {
695 struct headerSourceList *currsourceheader = ct->headersourcelist; 697 struct headerSourceList *currsourceheader = ct->headersourcelist;
696 struct headerList *scanheader; 698 struct headerList *scanheader;
697 struct providedList *provided; 699 struct providedList *provided;
698 struct fileTree *file; 700 struct fileTree *file;
699 char warning[PATH_MAX]; 701 char warning[PATH_MAX];
700 int i; 702 int i;
701 int j,found; 703 int j,found;
702 704
703 logmsg(LOG_DEBUG,"resolveFirstLevelSourceDependencies - sources"); 705 logmsg(LOG_DEBUG,"resolveFirstLevelSourceDependencies - sources");
704 while (currsourceheader) { 706 while (currsourceheader) {
705 if (!currsourceheader->firstchild[archidx]) { // ignore SRPMs with no builds 707 if (!currsourceheader->firstchild[archidx]) { // ignore SRPMs with no builds
706 currsourceheader = currsourceheader->next; 708 currsourceheader = currsourceheader->next;
707 continue; 709 continue;
708 } 710 }
709 scanheader = ct->headerlist[archidx]; 711 scanheader = ct->headerlist[archidx];
710 currsourceheader->requirelist = NULL; 712 currsourceheader->requirelist = NULL;
711 // currsourceheader->require.resolved = malloc(sizeof(struct providedList*)*currsourceheader->requirecount); 713 // currsourceheader->require.resolved = malloc(sizeof(struct providedList*)*currsourceheader->requirecount);
712 for (i = 0; i < currsourceheader->requirecount; i++) { 714 for (i = 0; i < currsourceheader->requirecount; i++) {
713 /* if (strncmp("a2ps",currsourceheader->name,4) == 0) { 715 /* if (strncmp("a2ps",currsourceheader->name,4) == 0) {
714 fprintf(stderr,"a2ps:%s\n",currheader->require[i]->name); 716 fprintf(stderr,"a2ps:%s\n",currheader->require[i]->name);
715 }*/ 717 }*/
716 if (strncmp("rpmlib(",currsourceheader->require[i]->name,7) != 0) { 718 if (strncmp("rpmlib(",currsourceheader->require[i]->name,7) != 0) {
717 provided=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx], 719 provided=findOrCreateProvidedListEntry((struct providedList**) &ct->providedlist_idx[archidx],
718 currsourceheader->require[i]->name,1,archidx); 720 currsourceheader->require[i]->name,1,archidx);
719 if (provided->numbuildproviders == 0) { 721 if (provided->numbuildproviders == 0) {
720 // check if require[i]->name requirement is met 722 // check if require[i]->name requirement is met
721 723
722 if ((currsourceheader->require[i]->name)[0] == '/') { 724 if ((currsourceheader->require[i]->name)[0] == '/') {
723 /* requirement is a file, find who provides it */ 725 /* requirement is a file, find who provides it */
724 file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currsourceheader->require[i]->name, archidx); 726 file=findOrCreateFileTreeEntry(&ct->filetree[archidx],currsourceheader->require[i]->name, archidx);
725 if (file->numproviders > 0) { 727 if (file->numproviders > 0) {
726 provided->numbuildproviders=file->numproviders; 728 provided->numbuildproviders=file->numproviders;
727 provided->buildprovider=file->provider; 729 provided->buildprovider=file->provider;
728 provided->flags=0; 730 provided->flags=0;
729 logmsg(LOG_DEBUG,"file %s is a build provider for %s",currsourceheader->require[i]->name,currsourceheader->name); 731 logmsg(LOG_DEBUG,"file %s is a build provider for %s",currsourceheader->require[i]->name,currsourceheader->name);
730 } 732 }
731 } else { 733 } else {
732 /* requirement is not a file, cross-check with provides */ 734 /* requirement is not a file, cross-check with provides */
733 scanheader = ct->headerlist[archidx]; 735 scanheader = ct->headerlist[archidx];
734 while (scanheader) { 736 while (scanheader) {
735 if (checkRequireWithProvides( 737 if (checkRequireWithProvides(
736 currsourceheader->require[i]->name, 738 currsourceheader->require[i]->name,
737 scanheader)) provided->numbuildproviders+=1; 739 scanheader)) provided->numbuildproviders+=1;
738 scanheader = scanheader->next; 740 scanheader = scanheader->next;
739 } 741 }
740 if (provided->numbuildproviders > 0) { 742 if (provided->numbuildproviders > 0) {
741 provided->buildprovider = malloc(sizeof(struct headerList*) * provided->numbuildproviders); 743 provided->buildprovider = malloc(sizeof(struct headerList*) * provided->numbuildproviders);
742 provided->flags = 0; 744 provided->flags = 0;
743 scanheader = ct->headerlist[archidx]; 745 scanheader = ct->headerlist[archidx];
744 j = 0; 746 j = 0;
745 while (scanheader) { 747 while (scanheader) {
746 if (checkRequireWithProvides( 748 if (checkRequireWithProvides(
747 currsourceheader->require[i]->name, 749 currsourceheader->require[i]->name,
748 scanheader)) provided->buildprovider[j++] = scanheader; 750 scanheader)) provided->buildprovider[j++] = scanheader;
749 scanheader = scanheader->next; 751 scanheader = scanheader->next;
750 } 752 }
751 logmsg(LOG_DEBUG,"%s is a build provider for %s",provided->name,currsourceheader->name); 753 logmsg(LOG_DEBUG,"%s is a build provider for %s",provided->name,currsourceheader->name);
752 } 754 }
753 } 755 }
754 if (provided->numbuildproviders == 0 && incremental_mode) { 756 if (provided->numbuildproviders == 0 && incremental_mode) {
755 snprintf(warning,PATH_MAX,"missing build provider for %s",currsourceheader->require[i]->name); 757 snprintf(warning,PATH_MAX,"missing build provider for %s",currsourceheader->require[i]->name);
756 fprintf(stderr,"Warning: %s(source,%s): %s\n", 758 fprintf(stderr,"Warning: %s(source,%s): %s\n",
757 currsourceheader->name, 759 currsourceheader->name,
758 ct->repository[currsourceheader->altrepository]->tag, 760 ct->repository[currsourceheader->altrepository]->tag,
759 warning); 761 warning);
760 addWarning(currsourceheader,warning); 762 addWarning(currsourceheader,warning);
761 } 763 }
762 //} else if (provided->numbuildproviders > 1) { 764 //} else if (provided->numbuildproviders > 1) {
763 /*printf("Multiple providers for %s in package %s\n",currsourceheader->require[i]->name,currsourceheader->name);*/ 765 /*printf("Multiple providers for %s in package %s\n",currsourceheader->require[i]->name,currsourceheader->name);*/
764 } 766 }
765 767
766 if (provided->numbuildproviders > 0) { 768 if (provided->numbuildproviders > 0) {
767 if (strcmp(currsourceheader->require[i]->version,"") && 769 if (strcmp(currsourceheader->require[i]->version,"") &&
768 (currsourceheader->require[i]->flags & (RPMSENSE_LESS+RPMSENSE_GREATER+RPMSENSE_EQUAL))) { 770 (currsourceheader->require[i]->flags & (RPMSENSE_LESS+RPMSENSE_GREATER+RPMSENSE_EQUAL))) {
769 found = 0; 771 found = 0;
770 for (j = 0; j < provided->numproviders; j++) { 772 for (j = 0; j < provided->numproviders; j++) {
771 if (!strcmp(provided->version[j],"")) { 773 if (!strcmp(provided->version[j],"")) {
772 /* provider with no version; assume ok */ 774 /* provider with no version; assume ok */
773 found = 1; 775 found = 1;
774 } else { 776 } else {
775 if (checkVersionWithFlags( 777 if (checkVersionWithFlags(
776 currsourceheader->require[i]->version, 778 currsourceheader->require[i]->version,
777 currsourceheader->require[i]->flags, 779 currsourceheader->require[i]->flags,
778 provided->version[j])) found = 1; 780 provided->version[j])) found = 1;
779 } 781 }
780 } /* for */ 782 } /* for */
781 if (!found) { 783 if (!found) {
782 if (currsourceheader->altrepository == ct->repository_level) { 784 if (currsourceheader->altrepository == ct->repository_level) {
783 fprintf(stderr,"Warning: %s(source): build requires %s ",currsourceheader->name,currsourceheader->require[i]->name); 785 fprintf(stderr,"Warning: %s(source): build requires %s ",currsourceheader->name,currsourceheader->require[i]->name);
784 if (currsourceheader->require[i]->flags & RPMSENSE_LESS) fprintf(stderr,"<"); 786 if (currsourceheader->require[i]->flags & RPMSENSE_LESS) fprintf(stderr,"<");
785 if (currsourceheader->require[i]->flags & RPMSENSE_GREATER) fprintf(stderr,">"); 787 if (currsourceheader->require[i]->flags & RPMSENSE_GREATER) fprintf(stderr,">");
786 if (currsourceheader->require[i]->flags & RPMSENSE_EQUAL) fprintf(stderr,"="); 788 if (currsourceheader->require[i]->flags & RPMSENSE_EQUAL) fprintf(stderr,"=");
787 fprintf(stderr," %s (failing build provider(s):", currsourceheader->require[i]->version); 789 fprintf(stderr," %s (failing build provider(s):", currsourceheader->require[i]->version);
788 for (j = 0; j < provided->numbuildproviders; j++) { 790 for (j = 0; j < provided->numbuildproviders; j++) {
789 fprintf(stderr," %s#%s", 791 fprintf(stderr," %s#%s",
790 provided->provider[j]->name, provided->buildprovider[j]->version); 792 provided->provider[j]->name, provided->buildprovider[j]->version);
791 /* printrpmversion(buffer,PATH_MAX, 793 /* printrpmversion(buffer,PATH_MAX,
792 provided->provider[j]->epoch, 794 provided->provider[j]->epoch,
793 provided->provider[j]->version, 795 provided->provider[j]->version,
794 provided->provider[j]->release));*/ 796 provided->provider[j]->release));*/
795 } 797 }
796 fprintf(stderr,")\n"); 798 fprintf(stderr,")\n");
797 } 799 }
798 } 800 }
799 801
800 } 802 }
801 } 803 }
802 currsourceheader->require[i]->resolved=provided; 804 currsourceheader->require[i]->resolved=provided;
803 } else { 805 } else {
804 currsourceheader->require[i]->resolved=NULL; 806 currsourceheader->require[i]->resolved=NULL;
805 } 807 }
806 } 808 }
807 809
808 // sort required list by first provider's name 810 // sort required list by first provider's name
809 qsort((void *) &currsourceheader->require[0], 811 qsort((void *) &currsourceheader->require[0],
810 currsourceheader->requirecount, 812 currsourceheader->requirecount,
811 sizeof(struct Require *), 813 sizeof(struct Require *),
812 compareRequiredList); 814 compareRequiredList);
813 currsourceheader = currsourceheader->next; 815 currsourceheader = currsourceheader->next;
814 } 816 }
815 logmsg(LOG_DEBUG,"resolveFirstLevelSourceDependencies - done"); 817 logmsg(LOG_DEBUG,"resolveFirstLevelSourceDependencies - done");
816 return 0; 818 return 0;
817 } 819 }
818 820
819 static int 821 static int
820 clearRecursionFlag(struct headerList *headerlist) 822 clearRecursionFlag(struct headerList *headerlist)
821 { 823 {
822 while (headerlist) { 824 while (headerlist) {
823 if (headerlist->recursed == 1) { 825 if (headerlist->recursed == 1) {
824 headerlist->recursed = 0; 826 headerlist->recursed = 0;
825 } 827 }
826 headerlist = headerlist->next; 828 headerlist = headerlist->next;
827 } 829 }
828 830
829 return 0; 831 return 0;
830 } 832 }
831 833
832 /* 834 /*
833 * resolve recursive requirement dependencies 835 * resolve recursive requirement dependencies
834 * (first level dependencies should have been resolved already) */ 836 * (first level dependencies should have been resolved already) */
835 static int 837 static int
836 resolveRecursiveDependencies(struct headerList *headerlist) 838 resolveRecursiveDependencies(struct headerList *headerlist)
837 { 839 {
838 while (headerlist) { 840 while (headerlist) {
839 clearRecursionFlag(headerlist); 841 clearRecursionFlag(headerlist);
840 headerlist->requirelist = recurseRequireList(headerlist); 842 headerlist->requirelist = recurseRequireList(headerlist);
841 headerlist->recursed = 2; 843 headerlist->recursed = 2;
842 headerlist = headerlist->next; 844 headerlist = headerlist->next;
843 } 845 }
844 846
845 return 0; 847 return 0;
846 } 848 }
847 849
848 void *threadArchScan(void* arg) { 850 void *threadArchScan(void* arg) {
849 int arch = *(int *)arg; 851 int arch = *(int *)arg;
850 852
851 if (generateHeaderList(configtag,arch,incremental_mode)) { 853 if (generateHeaderList(configtag,arch,incremental_mode)) {
852 fprintf(stderr, 854 fprintf(stderr,
853 "Fatal error: could not generate header list\n"); 855 "Fatal error: could not generate header list\n");
854 exit(1); 856 exit(1);
855 } 857 }
856 858
857 if (genheader_mode & GENHEADER_REQUIREMENTS) { 859 if (genheader_mode & GENHEADER_REQUIREMENTS) {
858 860
859 if (obsolete_packages) { 861 if (obsolete_packages) {
860 if (!quietmode) fprintf(stdout, "%s: handling obsoleted packages...\n",configtag->arch[arch]); 862 if (!quietmode) fprintf(stdout, "%s: handling obsoleted packages...\n",configtag->arch[arch]);
861 if (handleObsoletedPackages(configtag,arch)) { 863 if (handleObsoletedPackages(configtag,arch)) {
862 fprintf(stderr, 864 fprintf(stderr,
863 "Fatal error: maximum number of multiple providing packages reached. Aborting."); 865 "Fatal error: maximum number of multiple providing packages reached. Aborting.");
864 exit(1); 866 exit(1);
865 } 867 }
866 } 868 }
867 869
868 if (resolve_dependencies) { 870 if (resolve_dependencies) {
869 if (!quietmode) fprintf(stdout, "%s: resolving dependencies...\n",configtag->arch[arch]); 871 if (!quietmode) fprintf(stdout, "%s: resolving dependencies...\n",configtag->arch[arch]);
870 if (resolveFirstLevelDependencies(configtag, arch)) { 872 if (resolveFirstLevelDependencies(configtag, arch)) {
871 fprintf(stderr, 873 fprintf(stderr,
872 "Fatal error: could not generate first level requires table\n"); 874 "Fatal error: could not generate first level requires table\n");
873 exit(1); 875 exit(1);
874 } 876 }
875 877
876 if (arch == 0) /* fixme? */ { 878 if (arch == 0) /* fixme? */ {
877 if (!quietmode) fprintf(stdout, "%s: resolving source dependencies\n",configtag->arch[arch]); 879 if (!quietmode) fprintf(stdout, "%s: resolving source dependencies\n",configtag->arch[arch]);
878 if (resolveFirstLevelSourceDependencies(configtag, arch)) { 880 if (resolveFirstLevelSourceDependencies(configtag, arch)) {
879 fprintf(stderr, 881 fprintf(stderr,
880 "Fatal error: could not generate first level requires table\n"); 882 "Fatal error: could not generate first level requires table\n");
881 exit(1); 883 exit(1);
882 } 884 }
883 } 885 }
884 886
885 if (recursive_mode) { 887 if (recursive_mode) {
886 if (!quietmode) fprintf(stdout, "%s: resolving recursive dependencies...\n",configtag->arch[arch]); 888 if (!quietmode) fprintf(stdout, "%s: resolving recursive dependencies...\n",configtag->arch[arch]);
887 889
888 if (resolveRecursiveDependencies 890 if (resolveRecursiveDependencies
889 (configtag->headerlist[arch])) { 891 (configtag->headerlist[arch])) {
890 fprintf(stderr,"Fatal error: could not resolve recursive dependencies\n"); 892 fprintf(stderr,"Fatal error: could not resolve recursive dependencies\n");
891 exit(1); 893 exit(1);
892 } 894 }
893 } 895 }
894 } 896 }
895 } 897 }
896 898
897 if (mode & MODE_DATA_TABLES) { 899 if (mode & MODE_DATA_TABLES) {
898 if (!quietmode) fprintf(stdout,"%s: writing dependencies table...\n",configtag->arch[arch]); 900 if (!quietmode) fprintf(stdout,"%s: writing dependencies tables...\n",configtag->arch[arch]);
899 print_datatables(configtag,arch); 901 print_datatables(configtag,arch);
900 } 902 }
901 903
904
905 if (mode & MODE_GENCONTENTSLIST) {
906 if (!quietmode) fprintf(stdout,"%s: writing contentslist files...\n",configtag->arch[arch]);
907 print_contentslist(configtag,arch);
908 }
909
902 if (genheader_mode & GENHEADER_STATS) { 910 if (genheader_mode & GENHEADER_STATS) {
903 if (!quietmode) fprintf(stdout,"%s: generating statistics...\n",configtag->arch[arch]); 911 if (!quietmode) fprintf(stdout,"%s: generating statistics...\n",configtag->arch[arch]);
904 912
905 logmsg(LOG_DEBUG,"%s: generateHeaderStats - start",configtag->arch[arch]); 913 logmsg(LOG_DEBUG,"%s: generateHeaderStats - start",configtag->arch[arch]);
906 if (generateHeaderStats(configtag, arch)) { 914 if (generateHeaderStats(configtag, arch)) {
907 fprintf(stderr,"Fatal error: could not generate statistic for headers\n"); 915 fprintf(stderr,"Fatal error: could not generate statistic for headers\n");
908 exit(1); 916 exit(1);
909 } 917 }
910 logmsg(LOG_DEBUG,"%s: generateHeaderStats - done",configtag->arch[arch]); 918 logmsg(LOG_DEBUG,"%s: generateHeaderStats - done",configtag->arch[arch]);
911 } 919 }
912 920
913 if (mode & MODE_HTML) { 921 if (mode & MODE_HTML) {
914 // printf("Generating HTML files for binary RPMs...\n"); 922 // printf("Generating HTML files for binary RPMs...\n");
915 logmsg(LOG_DEBUG,"%s: generateHTMLFiles - start",configtag->arch[arch]); 923 logmsg(LOG_DEBUG,"%s: generateHTMLFiles - start",configtag->arch[arch]);
916 generateHTMLFiles(configtag, arch); 924 generateHTMLFiles(configtag, arch);
917 logmsg(LOG_DEBUG,"%s: generateHTMLFiles - done",configtag->arch[arch]); 925 logmsg(LOG_DEBUG,"%s: generateHTMLFiles - done",configtag->arch[arch]);
918 } 926 }
919 927
920 if (mode & MODE_GENPKGLIST) { 928 if (mode & MODE_GENPKGLIST) {
921 /* currheaderlist = headerlist; */ 929 /* currheaderlist = headerlist; */
922 generatePkgList(configtag, arch); 930 generatePkgList(configtag, arch);
923 } 931 }
924 return NULL; 932 return NULL;
925 } 933 }
926 934
927 int 935 int
928 main(int argc, char *argv[]) 936 main(int argc, char *argv[])
929 { 937 {
930 char *name = NULL, *date = NULL, 938 char *name = NULL, *date = NULL,
931 *repository_dir = NULL, *repository_tag = NULL, 939 *repository_dir = NULL, *repository_tag = NULL,
932 *configfile = NULL, *passed_arch = NULL; 940 *configfile = NULL, *passed_arch = NULL;
933 941
934 struct headerList *currheaderlist; 942 struct headerList *currheaderlist;
935 struct headerSourceList *currheadersourcelist = NULL, *oldheadersourcelist; 943 struct headerSourceList *currheadersourcelist = NULL, *oldheadersourcelist;
936 struct rebuildList *currrebuild; 944 struct rebuildList *currrebuild;
937 945
938 int i = 0,hasbuilds[ARCHS_MAX],ptharg[ARCHS_MAX]; 946 int i = 0,hasbuilds[ARCHS_MAX],ptharg[ARCHS_MAX];
939 pthread_t pth[ARCHS_MAX]; 947 pthread_t pth[ARCHS_MAX];
940 char warning[8096]; 948 char warning[8096];
941 949
942 time_t start_time, stop_time; 950 time_t start_time, stop_time;
943 951
944 /* options args for 'getopt_long()' */ 952 /* options args for 'getopt_long()' */
945 static const char *optstring = "+a:c:t:qhvd"; 953 static const char *optstring = "+a:c:t:qhvd";
946 static struct option longopts[] = { 954 static struct option longopts[] = {
947 { "deps-table", no_argument, 0, 0 }, 955 { "deps-table", no_argument, 0, 0 },
948 { "data-tables", no_argument, 0, 0 }, 956 { "data-tables", no_argument, 0, 0 },
949 { "gendatatables", no_argument, 0, 0 }, 957 { "gendatatables", no_argument, 0, 0 },
950 { "find-deps", required_argument, 0, 0 }, 958 { "find-deps", required_argument, 0, 0 },
951 { "changelog", required_argument, 0, 0 }, 959 { "changelog", required_argument, 0, 0 },
952 { "changelogsince", required_argument, 0, 0 }, 960 { "changelogsince", required_argument, 0, 0 },
953 { "genbuildinfo", no_argument, 0, 0 }, 961 { "genbuildinfo", no_argument, 0, 0 },
954 { "genhtml", no_argument, 0, 0 }, 962 { "genhtml", no_argument, 0, 0 },
955 { "genpkglist", no_argument, 0, 0 }, 963 { "genpkglist", no_argument, 0, 0 },
956 { "gensrcpkglist", no_argument, 0, 0 }, 964 { "gensrcpkglist", no_argument, 0, 0 },
957 { "gensqlite3", no_argument, 0, 0 }, 965 { "gensqlite3", no_argument, 0, 0 },
958 { "gensqlite3files", no_argument, 0, 0 }, 966 { "gensqlite3files", no_argument, 0, 0 },
967 { "gencontentslist", no_argument, 0, 0 },
959 { "arch", required_argument, 0, 'a' }, 968 { "arch", required_argument, 0, 'a' },
960 { "conf", required_argument, 0, 'c' }, 969 { "conf", required_argument, 0, 'c' },
961 { "help", no_argument, 0, 'h' }, 970 { "help", no_argument, 0, 'h' },
962 { "quiet", no_argument, 0, 'q' }, 971 { "quiet", no_argument, 0, 'q' },
963 { "tag", required_argument, 0, 't' }, 972 { "tag", required_argument, 0, 't' },
964 { "version", no_argument, 0, 'v' }, 973 { "version", no_argument, 0, 'v' },
965 { "debug", no_argument, 0, 'd' }, 974 { "debug", no_argument, 0, 'd' },
966 { 0, 0, 0, 0 } 975 { 0, 0, 0, 0 }
967 }; 976 };
968 977
969 // install backtrace handler 978 // install backtrace handler
970 signal(SIGSEGV, backtraceHandler); 979 signal(SIGSEGV, backtraceHandler);
971 980
972 start_time=time(NULL); 981 start_time=time(NULL);
973 982
974 opterr = 1; 983 opterr = 1;
975 unsigned int syntaxerr = 0; 984 unsigned int syntaxerr = 0;
976 985
977 while (1) { 986 while (1) {
978 int longindex = 0; 987 int longindex = 0;
979 int argval = getopt_long(argc, argv, optstring, longopts, &longindex); 988 int argval = getopt_long(argc, argv, optstring, longopts, &longindex);
980 if (argval == -1) { 989 if (argval == -1) {
981 break; 990 break;
982 } 991 }
983 992
984 switch (argval) { 993 switch (argval) {
985 case 0: 994 case 0:
986 if (!strcmp(longopts[longindex].name, "gendatatables")) { 995 if (!strcmp(longopts[longindex].name, "gendatatables")) {
987 mode |= MODE_DATA_TABLES; 996 mode |= MODE_DATA_TABLES;
988 } else if (!strcmp(longopts[longindex].name, "deps-table") || 997 } else if (!strcmp(longopts[longindex].name, "deps-table") ||
989 !strcmp(longopts[longindex].name, "data-tables")) { 998 !strcmp(longopts[longindex].name, "data-tables")) {
990 fprintf(stderr,"Warning: use of --deps-table and --data-tables is obsolete; use --gendatatables instead.\n"); 999 fprintf(stderr,"Warning: use of --deps-table and --data-tables is obsolete; use --gendatatables instead.\n");
991 mode |= MODE_DATA_TABLES; 1000 mode |= MODE_DATA_TABLES;
992 } else if (!strcmp(longopts[longindex].name, "find-deps")) { 1001 } else if (!strcmp(longopts[longindex].name, "find-deps")) {
993 mode |= MODE_FIND_DEPS; 1002 mode |= MODE_FIND_DEPS;
994 name = optarg; 1003 name = optarg;
995 } else if (!strcmp(longopts[longindex].name, "changelog")) { 1004 } else if (!strcmp(longopts[longindex].name, "changelog")) {
996 mode |= MODE_CHANGELOG; 1005 mode |= MODE_CHANGELOG;
997 genheader_mode |= GENHEADER_CHANGELOG | GENHEADER_STATS; 1006 genheader_mode |= GENHEADER_CHANGELOG | GENHEADER_STATS;
998 name = optarg; 1007 name = optarg;
999 } else if (!strcmp(longopts[longindex].name, "changelogsince")) { 1008 } else if (!strcmp(longopts[longindex].name, "changelogsince")) {
1000 mode |= MODE_CHANGELOG; 1009 mode |= MODE_CHANGELOG;
1001 genheader_mode |= GENHEADER_CHANGELOG | GENHEADER_STATS; 1010 genheader_mode |= GENHEADER_CHANGELOG | GENHEADER_STATS;
1002 date = optarg; 1011 date = optarg;
1003 name = NULL; 1012 name = NULL;
1004 } else if (!strcmp(longopts[longindex].name, "genhtml")) { 1013 } else if (!strcmp(longopts[longindex].name, "genhtml")) {
1005 mode |= MODE_HTML; 1014 mode |= MODE_HTML;
1006 genheader_mode |= GENHEADER_CHANGELOG | GENHEADER_STATS; 1015 genheader_mode |= GENHEADER_CHANGELOG | GENHEADER_STATS;
1007 recursive_mode = 1; 1016 recursive_mode = 1;
1008 name = NULL; 1017 name = NULL;
1009 } else if (!strcmp(longopts[longindex].name, "gensqlite3")) { 1018 } else if (!strcmp(longopts[longindex].name, "gensqlite3")) {
1010 mode |= MODE_SQLITE3; 1019 mode |= MODE_SQLITE3;
1011 } else if (!strcmp(longopts[longindex].name, "gensqlite3files")) { 1020 } else if (!strcmp(longopts[longindex].name, "gensqlite3files")) {
1012 mode |= MODE_SQLITE3_FILES; 1021 mode |= MODE_SQLITE3_FILES;
1013 } else if (!strcmp(longopts[longindex].name, "gensrcpkglist")) { 1022 } else if (!strcmp(longopts[longindex].name, "gensrcpkglist")) {
1014 mode |= MODE_GENSRCPKGLIST; 1023 mode |= MODE_GENSRCPKGLIST;
1015 name = NULL; 1024 name = NULL;
1016 } else if (!strcmp(longopts[longindex].name, "genpkglist")) { 1025 } else if (!strcmp(longopts[longindex].name, "genpkglist")) {
1017 mode |= MODE_GENPKGLIST; 1026 mode |= MODE_GENPKGLIST;
1018 name = NULL; 1027 name = NULL;
1019 } else if (!strcmp(longopts[longindex].name, "genbuildinfo")) { 1028 } else if (!strcmp(longopts[longindex].name, "genbuildinfo")) {
1020 mode |= MODE_GENBUILDINFO; 1029 mode |= MODE_GENBUILDINFO;
1021 genheader_mode |= GENHEADER_BASE; 1030 genheader_mode |= GENHEADER_BASE;
1031 name = NULL;
1032 } else if (!strcmp(longopts[longindex].name, "gencontentslist")) {
1033 mode |= MODE_GENCONTENTSLIST;
1022 name = NULL; 1034 name = NULL;
1023 } 1035 }
1024 break; 1036 break;
1025 case 'a': 1037 case 'a':
1026 passed_arch = optarg; 1038 passed_arch = optarg;
1027 break; 1039 break;
1028 case 'c': 1040 case 'c':
1029 configfile = optarg; 1041 configfile = optarg;
1030 break; 1042 break;
1031 case 't': 1043 case 't':
1032 repository_tag = optarg; 1044 repository_tag = optarg;
1033 break; 1045 break;
1034 case 'h': 1046 case 'h':
1035 program_usage(0); 1047 program_usage(0);
1036 break; 1048 break;
1037 case 'q': 1049 case 'q':
1038 quietmode=1; 1050 quietmode=1;
1039 break; 1051 break;
1040 case 'v': 1052 case 'v':
1041 program_version(); 1053 program_version();
1042 exit(0); 1054 exit(0);
1043 break; 1055 break;
1044 case '?': 1056 case '?':
1045 /* program_usage(1); */ 1057 /* program_usage(1); */
1046 exit(1); 1058 exit(1);
1047 break; 1059 break;
1048 case 'd': 1060 case 'd':
1049 log_debug_set(1); 1061 log_debug_set(1);
1050 logmsg(LOG_DEBUG,"debug logging enabled"); 1062 logmsg(LOG_DEBUG,"debug logging enabled");
1051 break; 1063 break;
1052 default: 1064 default:
1053 fprintf(stderr, 1065 fprintf(stderr,
1054 "Fatal error while parsing command line arguments\n"); 1066 "Fatal error while parsing command line arguments\n");
1055 exit(1); 1067 exit(1);
1056 break; 1068 break;
1057 } 1069 }
1058 } 1070 }
1059 1071
1060 if (optind < argc) { 1072 if (optind < argc) {
1061 fprintf(stderr, "Non-option elements found: "); 1073 fprintf(stderr, "Non-option elements found: ");
1062 while (optind < argc) 1074 while (optind < argc)
1063 fprintf(stderr, "`%s' ", argv[optind++]); 1075 fprintf(stderr, "`%s' ", argv[optind++]);
1064 fprintf(stderr, "\n"); 1076 fprintf(stderr, "\n");
1065 exit(1); 1077 exit(1);
1066 } else if (syntaxerr || !mode || !repository_tag ) { 1078 } else if (syntaxerr || !mode || !repository_tag ) {
1067 program_usage(1); 1079 program_usage(1);
1068 } 1080 }
1069 1081
1070 /* if only target is sqlite3 db minimize operations */ 1082 /* if only target is sqlite3 db minimize operations */
1071 if (mode == MODE_SQLITE3 || mode == MODE_SQLITE3_FILES || mode == (MODE_SQLITE3 | MODE_SQLITE3_FILES)) { 1083 if (mode == MODE_SQLITE3 || mode == MODE_SQLITE3_FILES || mode == (MODE_SQLITE3 | MODE_SQLITE3_FILES)) {
1072 genheader_mode |= GENHEADER_CHANGELOG; 1084 genheader_mode |= GENHEADER_CHANGELOG;
1073 recursive_mode = 0; 1085 recursive_mode = 0;
1074 incremental_mode = 0; 1086 incremental_mode = 0;
1075 obsolete_packages = 0; 1087 obsolete_packages = 0;
1076 //resolve_dependencies = 0; 1088 //resolve_dependencies = 0;
1077 name = NULL; 1089 name = NULL;
1078 } 1090 }
1079 1091
1080 if (!configfile) { 1092 if (!configfile) {
1081 configfile = malloc(sizeof DEFAULT_CONFIGFILE); 1093 configfile = malloc(sizeof DEFAULT_CONFIGFILE);
1082 if (!configfile) { 1094 if (!configfile) {
1083 fprintf(stderr, "The system is out of memory\n"); 1095 fprintf(stderr, "The system is out of memory\n");
1084 exit(1); 1096 exit(1);
1085 } 1097 }
1086 strcpy(configfile, DEFAULT_CONFIGFILE); 1098 strcpy(configfile, DEFAULT_CONFIGFILE);
1087 } 1099 }
1088 1100
1089 firstconfigtag = read_configuration(configfile); 1101 firstconfigtag = read_configuration(configfile);
1090 if (!firstconfigtag) { 1102 if (!firstconfigtag) {
1091 fprintf(stderr, 1103 fprintf(stderr,
1092 "Fatal error while parsing config file %s; aborting.\n",configfile); 1104 "Fatal error while parsing config file %s; aborting.\n",configfile);
1093 exit(1); 1105 exit(1);
1094 } 1106 }
1095 1107
1096 configtag = findRepositoryByTag(repository_tag); 1108 configtag = findRepositoryByTag(repository_tag);
1097 if (!configtag) { 1109 if (!configtag) {
1098 fprintf(stderr, 1110 fprintf(stderr,
1099 "Fatal error: configuration missing for given tag\n"); 1111 "Fatal error: configuration missing for given tag\n");
1100 exit(1); 1112 exit(1);
1101 } 1113 }
1102 1114
1103 if (passed_arch) { 1115 if (passed_arch) {
1104 configtag->arch[0] = malloc(sizeof passed_arch); 1116 configtag->arch[0] = malloc(sizeof passed_arch);
1105 if (!configtag->arch[0]) { 1117 if (!configtag->arch[0]) {
1106 fprintf(stderr, "The system is out of memory\n"); 1118 fprintf(stderr, "The system is out of memory\n");
1107 exit(1); 1119 exit(1);
1108 } 1120 }
1109 strcpy(configtag->arch[0], passed_arch); 1121 strcpy(configtag->arch[0], passed_arch);
1110 configtag->arch[1] = NULL; 1122 configtag->arch[1] = NULL;
1111 } 1123 }
1112 1124
1113 rpminit(); 1125 rpminit();
1114 1126
1115 if (!quietmode) 1127 if (!quietmode)
1116 fprintf(stdout, "Starting operations on '%s' repository\n", configtag->tag); 1128 fprintf(stdout, "Starting operations on '%s' repository\n", configtag->tag);
1117 1129
1118 if (!repository_dir) 1130 if (!repository_dir)
1119 repository_dir = configtag->repository_dir; 1131 repository_dir = configtag->repository_dir;
1120 1132
1121 if (!quietmode) 1133 if (!quietmode)
1122 fprintf(stdout, "Scanning source packages...\n"); 1134 fprintf(stdout, "Scanning source packages...\n");
1123 else 1135 else
1124 logmsg(LOG_MARK,"Source packages check for %s:", configtag->tag); 1136 logmsg(LOG_MARK,"Source packages check for %s:", configtag->tag);
1125 1137
1126 if (generateSourceHeaderList(configtag, genheader_mode, incremental_mode)) { 1138 if (generateSourceHeaderList(configtag, genheader_mode, incremental_mode)) {
1127 fprintf(stderr, 1139 fprintf(stderr,
1128 "Fatal error: could not generate source header list\n"); 1140 "Fatal error: could not generate source header list\n");
1129 exit(1); 1141 exit(1);
1130 } 1142 }
1131 1143
1132 if (genheader_mode) { 1144 if (genheader_mode) {
1133 1145
1134 if (mode & MODE_HTML) { 1146 if (mode & MODE_HTML) {
1135 logmsg(LOG_DEBUG,"cleanHTMLPackagesFiles - start"); 1147 logmsg(LOG_DEBUG,"cleanHTMLPackagesFiles - start");
1136 cleanHTMLPackagesFiles(configtag); 1148 cleanHTMLPackagesFiles(configtag);
1137 logmsg(LOG_DEBUG,"cleanHTMLPackagesFiles - done"); 1149 logmsg(LOG_DEBUG,"cleanHTMLPackagesFiles - done");
1138 } 1150 }
1139 1151
1140 warning[0]=0; 1152 warning[0]=0;
1141 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 1153 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
1142 snprintf(&warning[strlen(warning)],sizeof(warning)-strlen(warning)," %s", configtag->arch[i]); 1154 snprintf(&warning[strlen(warning)],sizeof(warning)-strlen(warning)," %s", configtag->arch[i]);
1143 } 1155 }
1144 if (!quietmode) 1156 if (!quietmode)
1145 fprintf(stdout, "Scanning binary packages for archs:%s...\n",warning); 1157 fprintf(stdout, "Scanning binary packages for archs:%s...\n",warning);
1146 else 1158 else
1147 logmsg(LOG_MARK, "Binary packages check for archs:%s", warning); 1159 logmsg(LOG_MARK, "Binary packages check for archs:%s", warning);
1148 1160
1149 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 1161 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
1150 ptharg[i]=i; 1162 ptharg[i]=i;
1151 pthread_create(&pth[i],NULL,threadArchScan,&ptharg[i]); 1163 pthread_create(&pth[i],NULL,threadArchScan,&ptharg[i]);
1152 } // archs threads loop 1164 } // archs threads loop
1153 1165
1154 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 1166 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
1155 pthread_join(pth[i], NULL); 1167 pthread_join(pth[i], NULL);
1156 } 1168 }
1157 1169
1158 if (!passed_arch) { // can't do missing builds and ports check in single arch mode 1170 if (!passed_arch) { // can't do missing builds and ports check in single arch mode
1159 if (!quietmode) 1171 if (!quietmode)
1160 fprintf(stdout, "Checking for SRPMS with no builds and missing ports...\n"); 1172 fprintf(stdout, "Checking for SRPMS with no builds and missing ports...\n");
1161 else 1173 else
1162 logmsg(LOG_MARK, "Missing ports and SRPMS with no builds check"); 1174 logmsg(LOG_MARK, "Missing ports and SRPMS with no builds check");
1163 1175
1164 currheadersourcelist = configtag->headersourcelist; 1176 currheadersourcelist = configtag->headersourcelist;
1165 while (currheadersourcelist != NULL) { 1177 while (currheadersourcelist != NULL) {
1166 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) 1178 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++)
1167 hasbuilds[i] = 0; 1179 hasbuilds[i] = 0;
1168 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 1180 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
1169 if (currheadersourcelist->firstchild[i]) 1181 if (currheadersourcelist->firstchild[i])
1170 hasbuilds[i] = 1; 1182 hasbuilds[i] = 1;
1171 else if (currheadersourcelist->old && currheadersourcelist->old->firstchild[i]) 1183 else if (currheadersourcelist->old && currheadersourcelist->old->firstchild[i])
1172 hasbuilds[i] = -1; 1184 hasbuilds[i] = -1;
1173 } 1185 }
1174 warning[0] = '\0'; 1186 warning[0] = '\0';
1175 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 1187 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
1176 if (hasbuilds[i] == 1) { 1188 if (hasbuilds[i] == 1) {
1177 strncat(warning, " ", sizeof(warning) - strlen(warning)); 1189 strncat(warning, " ", sizeof(warning) - strlen(warning));
1178 strncat(warning, configtag->arch[i], sizeof(warning) - strlen(warning)); 1190 strncat(warning, configtag->arch[i], sizeof(warning) - strlen(warning));
1179 } 1191 }
1180 } 1192 }
1181 if (warning[0] == '\0') { 1193 if (warning[0] == '\0') {
1182 snprintf(warning, PATH_MAX, "SRPM does not have any valid RPM build"); 1194 snprintf(warning, PATH_MAX, "SRPM does not have any valid RPM build");
1183 logmsg(LOG_WARNING, "%s: %s", 1195 logmsg(LOG_WARNING, "%s: %s",
1184 currheadersourcelist->name, 1196 currheadersourcelist->name,
1185 warning); 1197 warning);
1186 addWarning(currheadersourcelist, warning); 1198 addWarning(currheadersourcelist, warning);
1187 } 1199 }
1188 1200
1189 warning[0] = '\0'; 1201 warning[0] = '\0';
1190 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 1202 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
1191 if ((hasbuilds[i] == -1) && 1203 if ((hasbuilds[i] == -1) &&
1192 (currheadersourcelist->altrepository == configtag->repository_level)) { 1204 (currheadersourcelist->altrepository == configtag->repository_level)) {
1193 if (warning[0] == '\0') 1205 if (warning[0] == '\0')
1194 strncat(warning, "requires port to arch(s):", sizeof(warning) - strlen(warning)); 1206 strncat(warning, "requires port to arch(s):", sizeof(warning) - strlen(warning));
1195 strncat(warning," ", sizeof(warning) - strlen(warning)); 1207 strncat(warning," ", sizeof(warning) - strlen(warning));
1196 strncat(warning,configtag->arch[i], sizeof(warning) - strlen(warning)); 1208 strncat(warning,configtag->arch[i], sizeof(warning) - strlen(warning));
1197 } 1209 }
1198 } 1210 }
1199 if (warning[0] != '\0') { 1211 if (warning[0] != '\0') {
1200 logmsg(LOG_WARNING, "%s: %s", 1212 logmsg(LOG_WARNING, "%s: %s",
1201 currheadersourcelist->name, 1213 currheadersourcelist->name,
1202 warning); 1214 warning);
1203 addWarning(currheadersourcelist, warning); 1215 addWarning(currheadersourcelist, warning);
1204 } 1216 }
1205 1217
1206 warning[0] = '\0'; 1218 warning[0] = '\0';
1207 1219
1208 currrebuild = currheadersourcelist->firstrebuild; 1220 currrebuild = currheadersourcelist->firstrebuild;
1209 oldheadersourcelist = currheadersourcelist->old; 1221 oldheadersourcelist = currheadersourcelist->old;
1210 while (!currrebuild && oldheadersourcelist) { 1222 while (!currrebuild && oldheadersourcelist) {
1211 currrebuild = oldheadersourcelist->firstrebuild; 1223 currrebuild = oldheadersourcelist->firstrebuild;
1212 oldheadersourcelist = oldheadersourcelist->old; 1224 oldheadersourcelist = oldheadersourcelist->old;
1213 } 1225 }
1214 1226
1215 if (currrebuild) { 1227 if (currrebuild) {
1216 strncat(warning,"need to be rebuilt:", sizeof(warning) - strlen(warning)); 1228 strncat(warning,"need to be rebuilt:", sizeof(warning) - strlen(warning));
1217 while (currrebuild) { 1229 while (currrebuild) {
1218 strncat(warning," ", sizeof(warning) - strlen(warning)); 1230 strncat(warning," ", sizeof(warning) - strlen(warning));
1219 strncat(warning,currrebuild->sourceheader->name, sizeof(warning) - strlen(warning)); 1231 strncat(warning,currrebuild->sourceheader->name, sizeof(warning) - strlen(warning));
1220 strncat(warning,"(", sizeof(warning) - strlen(warning)); 1232 strncat(warning,"(", sizeof(warning) - strlen(warning));
1221 strncat(warning,currrebuild->provider->arch, sizeof(warning) - strlen(warning)); 1233 strncat(warning,currrebuild->provider->arch, sizeof(warning) - strlen(warning));
1222 strncat(warning,")", sizeof(warning) - strlen(warning)); 1234 strncat(warning,")", sizeof(warning) - strlen(warning));
1223 currrebuild = currrebuild->next; 1235 currrebuild = currrebuild->next;
1224 } 1236 }
1225 } 1237 }
1226 1238
1227 if (warning[0] != '\0') { 1239 if (warning[0] != '\0') {
1228 logmsg(LOG_WARNING, "%s: %s", 1240 logmsg(LOG_WARNING, "%s: %s",
1229 currheadersourcelist->name, 1241 currheadersourcelist->name,
1230 warning); 1242 warning);
1231 addWarning(currheadersourcelist, warning); 1243 addWarning(currheadersourcelist, warning);
1232 } 1244 }
1233 currheadersourcelist = currheadersourcelist->next; 1245 currheadersourcelist = currheadersourcelist->next;
1234 } 1246 }
1235 } 1247 }
1236 } // if (genheader_mode) 1248 } // if (genheader_mode)
1237 1249
1238 if (mode & MODE_SQLITE3) { 1250 if (mode & MODE_SQLITE3) {
1239 if (!quietmode) printf("Generating SQLite databases...\n"); 1251 if (!quietmode) printf("Generating SQLite databases...\n");
1240 logmsg(LOG_DEBUG,"generateSQLite3 - start"); 1252 logmsg(LOG_DEBUG,"generateSQLite3 - start");
1241 if (generateSQLite(configtag)) { 1253 if (generateSQLite(configtag)) {
1242 logmsg(LOG_ERROR, "could not generate SQLite databases; aborting."); 1254 logmsg(LOG_ERROR, "could not generate SQLite databases; aborting.");
1243 exit(1); 1255 exit(1);
1244 } 1256 }
1245 logmsg(LOG_DEBUG,"generateSQLite3 - done"); 1257 logmsg(LOG_DEBUG,"generateSQLite3 - done");
1246 } 1258 }
1247 1259
1248 if (mode & MODE_SQLITE3_FILES) { 1260 if (mode & MODE_SQLITE3_FILES) {
1249 if (!quietmode) printf("Generating sqlite3 files databases...\n"); 1261 if (!quietmode) printf("Generating sqlite3 files databases...\n");
1250 logmsg(LOG_DEBUG,"generateSQLite3_files - start"); 1262 logmsg(LOG_DEBUG,"generateSQLite3_files - start");
1251 if (generateSQLiteFiles(configtag)) { 1263 if (generateSQLiteFiles(configtag)) {
1252 logmsg(LOG_ERROR, "could not generate sqlite3 files databases; aborting."); 1264 logmsg(LOG_ERROR, "could not generate sqlite3 files databases; aborting.");
1253 exit(1); 1265 exit(1);
1254 } 1266 }
1255 logmsg(LOG_DEBUG,"generateSQLite3_files - done"); 1267 logmsg(LOG_DEBUG,"generateSQLite3_files - done");
1256 } 1268 }
1257 1269
1258 if (genheader_mode & GENHEADER_STATS) { 1270 if (genheader_mode & GENHEADER_STATS) {
1259 if (!quietmode) 1271 if (!quietmode)
1260 fprintf(stdout, " - generating source statistics...\n"); 1272 fprintf(stdout, " - generating source statistics...\n");
1261 1273
1262 logmsg(LOG_DEBUG,"generateHeaderSourceStats - start"); 1274 logmsg(LOG_DEBUG,"generateHeaderSourceStats - start");
1263 if (generateHeaderSourceStats(configtag)) { 1275 if (generateHeaderSourceStats(configtag)) {
1264 fprintf(stderr, 1276 fprintf(stderr,
1265 "Fatal error: could not generate statistic for headers\n"); 1277 "Fatal error: could not generate statistic for headers\n");
1266 exit(1); 1278 exit(1);
1267 } 1279 }
1268 logmsg(LOG_DEBUG,"generateHeaderSourceStats - done"); 1280 logmsg(LOG_DEBUG,"generateHeaderSourceStats - done");
1269 } 1281 }
1270 1282
1271 if (mode & MODE_FIND_DEPS) { 1283 if (mode & MODE_FIND_DEPS) {
1272 currheaderlist = findPackageByName(configtag->headerlist[i], name); 1284 currheaderlist = findPackageByName(configtag->headerlist[i], name);
1273 1285
1274 if (currheaderlist) { 1286 if (currheaderlist) {
1275 printf("%s: ", currheaderlist->name); 1287 printf("%s: ", currheaderlist->name);
1276 printRequireList(stdout,currheaderlist->requirelist); 1288 printRequireList(stdout,currheaderlist->requirelist);
1277 /* currrequirelist = currheaderlist->requirelist; */ 1289 /* currrequirelist = currheaderlist->requirelist; */
1278 printf("\n"); 1290 printf("\n");
1279 } else { 1291 } else {
1280 fprintf(stderr, "Error: package %s not found\n", name); 1292 fprintf(stderr, "Error: package %s not found\n", name);
1281 } 1293 }
1282 } 1294 }
1283 1295
1284 if (mode & MODE_CHANGELOG) { 1296 if (mode & MODE_CHANGELOG) {
1285 if (name) { 1297 if (name) {
1286 currheadersourcelist = 1298 currheadersourcelist =
1287 findSourcePackage(configtag->headersourcelist, name, 1299 findSourcePackage(configtag->headersourcelist, name,
1288 NULL, NULL,-1); 1300 NULL, NULL,-1);
1289 if (currheadersourcelist) { 1301 if (currheadersourcelist) {
1290 printChangelog(currheadersourcelist->changelog); 1302 printChangelog(currheadersourcelist->changelog);
1291 } else { 1303 } else {
1292 fprintf(stderr, "Error: package %s not found\n", name); 1304 fprintf(stderr, "Error: package %s not found\n", name);
1293 } 1305 }
1294 } else { 1306 } else {
1295 struct tm tmdate; 1307 struct tm tmdate;
1296 1308
1297 tmdate.tm_min = 0; 1309 tmdate.tm_min = 0;
1298 tmdate.tm_hour = 0; 1310 tmdate.tm_hour = 0;
1299 tmdate.tm_sec = 0; 1311 tmdate.tm_sec = 0;
1300 1312
1301 const char *cp; 1313 const char *cp;
1302 1314
1303 cp = (char *) strptime((const char *) date, "%m%d%y", &tmdate); 1315 cp = (char *) strptime((const char *) date, "%m%d%y", &tmdate);
1304 if (!cp) { 1316 if (!cp) {
1305 fprintf(stderr, "Error: date \"%s\" is invalid!\n", date); 1317 fprintf(stderr, "Error: date \"%s\" is invalid!\n", date);
1306 exit(1); 1318 exit(1);
1307 } 1319 }
1308 printChangelogSince(stdout,configtag, &tmdate, 0); 1320 printChangelogSince(stdout,configtag, &tmdate, 0);
1309 } 1321 }
1310 } 1322 }
1311 1323
1312 if (mode & MODE_HTML) { 1324 if (mode & MODE_HTML) {
1313 logmsg(LOG_DEBUG,"cleanHTMLFiles - start"); 1325 logmsg(LOG_DEBUG,"cleanHTMLFiles - start");
1314 cleanHTMLFiles(configtag); 1326 cleanHTMLFiles(configtag);
1315 logmsg(LOG_DEBUG,"cleanHTMLFiles - done"); 1327 logmsg(LOG_DEBUG,"cleanHTMLFiles - done");
1316 1328
1317 if (!quietmode) 1329 if (!quietmode)
1318 fprintf(stdout, "Generating HTML reports...\n"); 1330 fprintf(stdout, "Generating HTML reports...\n");
1319 generateHTMLMainIndex(firstconfigtag); 1331 generateHTMLMainIndex(firstconfigtag);
1320 1332
1321 // printf("Generating HTML files for source RPMs...\n"); 1333 // printf("Generating HTML files for source RPMs...\n");
1322 generateHTML_SRPMSFiles(configtag); 1334 generateHTML_SRPMSFiles(configtag);
1323 1335
1324 // printf("Generating Maintainers pages...\n"); 1336 // printf("Generating Maintainers pages...\n");
1325 generateMaintainersPages(configtag); 1337 generateMaintainersPages(configtag);
1326 1338
1327 } 1339 }
1328 1340
1329 // NOTE: generateStats must be called after generateHTML_SRPMSFiles for warnings to appear 1341 // NOTE: generateStats must be called after generateHTML_SRPMSFiles for warnings to appear
1330 if (mode & MODE_HTML) { 1342 if (mode & MODE_HTML) {
1331 logmsg(LOG_DEBUG,"generateStats - start"); 1343 logmsg(LOG_DEBUG,"generateStats - start");
1332 generateStats(configtag,i); 1344 generateStats(configtag,i);
1333 logmsg(LOG_DEBUG,"generateStats - done"); 1345 logmsg(LOG_DEBUG,"generateStats - done");
1334 } 1346 }
1335 1347
1336 if (mode & MODE_GENSRCPKGLIST) { 1348 if (mode & MODE_GENSRCPKGLIST) {
1337 /* currheaderlist = headerlist; */ 1349 /* currheaderlist = headerlist; */
1338 generateSrcPkgList(configtag); 1350 generateSrcPkgList(configtag);
1339 } 1351 }
1340 1352
1341 if (mode & MODE_GENBUILDINFO) { 1353 if (mode & MODE_GENBUILDINFO) {
1342 /* currheaderlist = headerlist; */ 1354 /* currheaderlist = headerlist; */
1343 printf("Generating build information files...\n"); 1355 printf("Generating build information files...\n");
1344 generateBuildInfo(configtag,0); 1356 generateBuildInfo(configtag,0);
1345 } 1357 }
1346 1358
1347 stop_time=time(NULL); 1359 stop_time=time(NULL);
1348 1360
1349 if (!quietmode) 1361 if (!quietmode)
1350 fprintf(stdout, "Execution time: %ld.%02ld minutes\n",(stop_time-start_time)/60,(stop_time-start_time)%60); 1362 fprintf(stdout, "Execution time: %ld.%02ld minutes\n",(stop_time-start_time)/60,(stop_time-start_time)%60);
1351 1363
1352 exit(0); 1364 exit(0);
1353 } 1365 }
1354 1366
src/include/reports.h
1 /* 1 /*
2 * distromatic - tool for RPM based repositories 2 * distromatic - tool for RPM based repositories
3 * 3 *
4 * Copyright (C) 2004-2007 by Silvan Calarco <silvan.calarco@mambasoft.it> 4 * Copyright (C) 2004-2007 by Silvan Calarco <silvan.calarco@mambasoft.it>
5 * Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com> 5 * Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
6 */ 6 */
7 7
8 #ifndef GENHTML_H 8 #ifndef GENHTML_H
9 #define GENHTML_H 9 #define GENHTML_H
10 10
11 #ifndef DISTROMATIC_H 11 #ifndef DISTROMATIC_H
12 # include "distromatic.h" 12 # include "distromatic.h"
13 #endif 13 #endif
14 #ifndef HEADERLIST_H 14 #ifndef HEADERLIST_H
15 # include "headerlist.h" 15 # include "headerlist.h"
16 #endif 16 #endif
17 17
18 int comparePackagers(const void *ptr1, const void *ptr2); 18 int comparePackagers(const void *ptr1, const void *ptr2);
19 int generateMaintainersPages(struct configTag *configtag); 19 int generateMaintainersPages(struct configTag *configtag);
20 int printHTMLWarnings(FILE *fout,struct configTag *configtag, struct headerSourceList* pkg, int mode); 20 int printHTMLWarnings(FILE *fout,struct configTag *configtag, struct headerSourceList* pkg, int mode);
21 void printpkgicon(FILE *fout, struct configTag *configtag, struct headerSourceList *s); 21 void printpkgicon(FILE *fout, struct configTag *configtag, struct headerSourceList *s);
22 int generateStats(struct configTag *configtag,int arch); 22 int generateStats(struct configTag *configtag,int arch);
23 int cleanHTMLFilesInc(char* dir); 23 int cleanHTMLFilesInc(char* dir);
24 int cleanHTMLPackagesFiles(struct configTag *ct); 24 int cleanHTMLPackagesFiles(struct configTag *ct);
25 int cleanHTMLFiles(struct configTag *ct); 25 int cleanHTMLFiles(struct configTag *ct);
26 int generateHTMLFiles(struct configTag *configtag,int arch); 26 int generateHTMLFiles(struct configTag *configtag,int arch);
27 int generateHTML_SRPMSFiles(struct configTag *configtag); 27 int generateHTML_SRPMSFiles(struct configTag *configtag);
28 int generateHTMLMainIndex(struct configTag *configtag); 28 int generateHTMLMainIndex(struct configTag *configtag);
29 char *groupdirname(char *group,char *dest,unsigned int max); 29 char *groupdirname(char *group,char *dest,unsigned int max);
30 int write_RPM_HTML(struct configTag *ct,FILE *fout, struct headerList *currheaderlist); 30 int write_RPM_HTML(struct configTag *ct,FILE *fout, struct headerList *currheaderlist);
31 int print_contentslist(struct configTag *ct, int arch);
31 int print_datatables(struct configTag *ct, int arch); 32 int print_datatables(struct configTag *ct, int arch);
32 char *ftname(struct fileTree* ft, char* buf, unsigned int bufsize); 33 char *ftname(struct fileTree* ft, char* buf, unsigned int bufsize);
33 void print_contents_subtree(FILE *f, 34 void print_contents_subtree(FILE *f,
34 struct fileTree* ft, 35 struct fileTree* ft,
35 struct configTag* ct, 36 struct configTag* ct,
36 char* buf, int bufsize); 37 char* buf, int bufsize);
37 int generatePkgList(struct configTag *ct, int arch); 38 int generatePkgList(struct configTag *ct, int arch);
38 int generateSrcPkgList(struct configTag *ct); 39 int generateSrcPkgList(struct configTag *ct);
39 40
40 #endif // HEADERLIST_H 41 #endif // HEADERLIST_H
41 42
1 /* 1 /*
2 * distromatic - tool for RPM based repositories 2 * distromatic - tool for RPM based repositories
3 * 3 *
4 * Copyright (C) 2004-2015 by Silvan Calarco <silvan.calarco@mambasoft.it> 4 * Copyright (C) 2004-2015 by Silvan Calarco <silvan.calarco@mambasoft.it>
5 * Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com> 5 * Copyright (C) 2006 by Davide Madrisan <davide.madrisan@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it under 7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of version 2 of the GNU General Public License as published by the 8 * the terms of version 2 of the GNU General Public License as published by the
9 * Free Software Foundation. 9 * Free Software Foundation.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT 11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY, to the extent permitted by law; without even the implied 12 * ANY WARRANTY, to the extent permitted by law; without even the implied
13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details. 14 * See the GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along with 16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21 #ifdef HAVE_CONFIG_H 21 #ifdef HAVE_CONFIG_H
22 # include "config.h" 22 # include "config.h"
23 #endif 23 #endif
24 24
25 #if HAVE_STRING_H 25 #if HAVE_STRING_H
26 # if !STDC_HEADERS && HAVE_MEMORY_H 26 # if !STDC_HEADERS && HAVE_MEMORY_H
27 # include <memory.h> 27 # include <memory.h>
28 # endif 28 # endif
29 # include <string.h> 29 # include <string.h>
30 #endif 30 #endif
31 #if HAVE_STRINGS_H 31 #if HAVE_STRINGS_H
32 # include <strings.h> 32 # include <strings.h>
33 #endif 33 #endif
34 34
35 #include "changelog.h" 35 #include "changelog.h"
36 #include "reports.h" 36 #include "reports.h"
37 #include "rpmfunctions.h" 37 #include "rpmfunctions.h"
38 #include "functions.h" 38 #include "functions.h"
39 #include "requirelist.h" 39 #include "requirelist.h"
40 #include <errno.h> 40 #include <errno.h>
41 #include <time.h> 41 #include <time.h>
42 42
43 #define HTMLSTATS_NUM 200 43 #define HTMLSTATS_NUM 200
44 #define HTMLOLDSTATS_NUM 200 44 #define HTMLOLDSTATS_NUM 200
45 #define RSSSTATS_NUM 20 45 #define RSSSTATS_NUM 20
46 46
47 char *groupdirname(char *group,char *dest,unsigned int max) 47 char *groupdirname(char *group,char *dest,unsigned int max)
48 { 48 {
49 strncpy(dest,group,max); 49 strncpy(dest,group,max);
50 50
51 unsigned int i=0; 51 unsigned int i=0;
52 52
53 while (dest[i] && i<max) { 53 while (dest[i] && i<max) {
54 switch (dest[i]) { 54 switch (dest[i]) {
55 case '/': dest[i]=':'; break; 55 case '/': dest[i]=':'; break;
56 case ' ': dest[i]='_'; break; 56 case ' ': dest[i]='_'; break;
57 default: break; 57 default: break;
58 } 58 }
59 i++; 59 i++;
60 } 60 }
61 return dest; 61 return dest;
62 } 62 }
63 63
64 int 64 int
65 comparePackagers(const void *ptr1, const void *ptr2) 65 comparePackagers(const void *ptr1, const void *ptr2)
66 { 66 {
67 int ret; 67 int ret;
68 68
69 if (! (*(struct headerSourceList **)ptr1)->packager) return -1; 69 if (! (*(struct headerSourceList **)ptr1)->packager) return -1;
70 else if (! (*(struct headerSourceList **)ptr2)->packager) return +1; 70 else if (! (*(struct headerSourceList **)ptr2)->packager) return +1;
71 else { 71 else {
72 ret=strcasecmp((*(struct headerSourceList **)ptr1)->packager->name, 72 ret=strcasecmp((*(struct headerSourceList **)ptr1)->packager->name,
73 (*(struct headerSourceList **)ptr2)->packager->name); 73 (*(struct headerSourceList **)ptr2)->packager->name);
74 74
75 if (!ret) { 75 if (!ret) {
76 ret=strcasecmp((*(struct headerSourceList **)ptr1)->name, 76 ret=strcasecmp((*(struct headerSourceList **)ptr1)->name,
77 (*(struct headerSourceList **)ptr2)->name); 77 (*(struct headerSourceList **)ptr2)->name);
78 } 78 }
79 return ret; 79 return ret;
80 } 80 }
81 } 81 }
82 82
83 int 83 int
84 printHTMLWarnings(FILE *fout, struct configTag *configtag, struct headerSourceList* pkg, int mode) { 84 printHTMLWarnings(FILE *fout, struct configTag *configtag, struct headerSourceList* pkg, int mode) {
85 85
86 char warningsfile[PATH_MAX]; 86 char warningsfile[PATH_MAX];
87 char buf[PATH_MAX]; 87 char buf[PATH_MAX];
88 struct stat s; 88 struct stat s;
89 FILE *fin; 89 FILE *fin;
90 int n; 90 int n;
91 struct warningList *firstwarning,*currwarning; 91 struct warningList *firstwarning,*currwarning;
92 92
93 if (!pkg) return 0; 93 if (!pkg) return 0;
94 94
95 snprintf(warningsfile,PATH_MAX,"%swarnings/%s.in",configtag->html_dir,pkg->name); 95 snprintf(warningsfile,PATH_MAX,"%swarnings/%s.in",configtag->html_dir,pkg->name);
96 96
97 /* find pointer to first warning also looking into old packages */ 97 /* find pointer to first warning also looking into old packages */
98 firstwarning = pkg->firstwarning; 98 firstwarning = pkg->firstwarning;
99 while (!firstwarning && pkg->old) { 99 while (!firstwarning && pkg->old) {
100 pkg = pkg->old; 100 pkg = pkg->old;
101 firstwarning = pkg->firstwarning; 101 firstwarning = pkg->firstwarning;
102 } 102 }
103 103
104 if (firstwarning || !stat(warningsfile,&s)) { 104 if (firstwarning || !stat(warningsfile,&s)) {
105 if (mode == 0) { 105 if (mode == 0) {
106 fprintf(fout, 106 fprintf(fout,
107 "<img src=\"%s/warning-icon.png\" title=\"", 107 "<img src=\"%s/warning-icon.png\" title=\"",
108 configtag->configdefaults->url_dir); 108 configtag->configdefaults->url_dir);
109 } else if (mode == 1) { 109 } else if (mode == 1) {
110 fprintf(fout, 110 fprintf(fout,
111 "<div class=\"warning\"><img src=\"%s/warning-icon.png\" title=\"Beware: this package has warnings.\">&nbsp;<b>Beware, this package has warnings:</b><br>", 111 "<div class=\"warning\"><img src=\"%s/warning-icon.png\" title=\"Beware: this package has warnings.\">&nbsp;<b>Beware, this package has warnings:</b><br>",
112 configtag->configdefaults->url_dir); 112 configtag->configdefaults->url_dir);
113 } 113 }
114 } 114 }
115 115
116 if (!stat(warningsfile,&s)) { 116 if (!stat(warningsfile,&s)) {
117 117
118 if ((fin = fopen(warningsfile, "r")) == NULL) { 118 if ((fin = fopen(warningsfile, "r")) == NULL) {
119 perror(warningsfile); 119 perror(warningsfile);
120 return 0; 120 return 0;
121 } 121 }
122 122
123 fprintf(fout,"&nbsp;&bull;&nbsp;Comment:"); 123 fprintf(fout,"&nbsp;&bull;&nbsp;Comment:");
124 while (!feof(fin)) { 124 while (!feof(fin)) {
125 n = fread(buf, 1, sizeof(buf), fin); 125 n = fread(buf, 1, sizeof(buf), fin);
126 fwrite(buf,1,n,fout); 126 fwrite(buf,1,n,fout);
127 } 127 }
128 if (mode == 0) { 128 if (mode == 0) {
129 fprintf(fout,"\n"); 129 fprintf(fout,"\n");
130 } else if (mode == 1) { 130 } else if (mode == 1) {
131 fprintf(fout,"<br>"); 131 fprintf(fout,"<br>");
132 } 132 }
133 fclose(fin); 133 fclose(fin);
134 } 134 }
135 135
136 currwarning = firstwarning; 136 currwarning = firstwarning;
137 while (currwarning || pkg->old) { 137 while (currwarning || pkg->old) {
138 if (currwarning) { 138 if (currwarning) {
139 if (mode == 0) { 139 if (mode == 0) {
140 fprintf(fout,"&nbsp;&bull;&nbsp;%s\n",currwarning->text); 140 fprintf(fout,"&nbsp;&bull;&nbsp;%s\n",currwarning->text);
141 } else if (mode == 1) { 141 } else if (mode == 1) {
142 fprintf(fout,"&nbsp;&bull;&nbsp;%s<br>",currwarning->text); 142 fprintf(fout,"&nbsp;&bull;&nbsp;%s<br>",currwarning->text);
143 } else if (mode == 2) { 143 } else if (mode == 2) {
144 fprintf(fout,"%s %s\n",pkg->name,currwarning->text); 144 fprintf(fout,"%s %s\n",pkg->name,currwarning->text);
145 } 145 }
146 currwarning = currwarning->next; 146 currwarning = currwarning->next;
147 } 147 }
148 while (!currwarning && pkg->old) { 148 while (!currwarning && pkg->old) {
149 /* print warnings coming from updated packages */ 149 /* print warnings coming from updated packages */
150 pkg = pkg->old; 150 pkg = pkg->old;
151 currwarning = pkg->firstwarning; 151 currwarning = pkg->firstwarning;
152 } 152 }
153 } 153 }
154 if (firstwarning || !stat(warningsfile,&s)) { 154 if (firstwarning || !stat(warningsfile,&s)) {
155 if (mode == 0) { 155 if (mode == 0) {
156 fprintf(fout,"\">"); 156 fprintf(fout,"\">");
157 } else if (mode == 1) { 157 } else if (mode == 1) {
158 fprintf(fout,"</div><br>\n"); 158 fprintf(fout,"</div><br>\n");
159 } 159 }
160 return 1; 160 return 1;
161 } 161 }
162 return 0; 162 return 0;
163 } 163 }
164 164
165 void printpkgicon(FILE *fout, struct configTag *configtag, struct headerSourceList *s) { 165 void printpkgicon(FILE *fout, struct configTag *configtag, struct headerSourceList *s) {
166 166
167 char buffer[PATH_MAX]; 167 char buffer[PATH_MAX];
168 char strdate[16]; 168 char strdate[16];
169 int i; 169 int i;
170 170
171 if (s->old) { 171 if (s->old) {
172 fprintf(fout, 172 fprintf(fout,
173 "<img src=\"%s/pkgup.png\" ", 173 "<img src=\"%s/pkgup.png\" ",
174 configtag->configdefaults->url_dir); 174 configtag->configdefaults->url_dir);
175 } else { 175 } else {
176 fprintf(fout, 176 fprintf(fout,
177 "<img src=\"%s/pkg.png\" ", 177 "<img src=\"%s/pkg.png\" ",
178 configtag->configdefaults->url_dir); 178 configtag->configdefaults->url_dir);
179 } 179 }
180 180
181 if (s->changelog) { 181 if (s->changelog) {
182 simpleTimeToHuman(s->changelog->time, (humanDate *) & strdate); 182 simpleTimeToHuman(s->changelog->time, (humanDate *) & strdate);
183 fprintf(fout, 183 fprintf(fout,
184 "title=\"%s - %s (%s)\n%s", 184 "title=\"%s - %s (%s)\n%s",
185 strdate, 185 strdate,
186 s->changelog->pkg->name, 186 s->changelog->pkg->name,
187 s->changelog->release, 187 s->changelog->release,
188 htmlcleanNoBr(s->changelog->text,buffer,PATH_MAX)); 188 htmlcleanNoBr(s->changelog->text,buffer,PATH_MAX));
189 if (s->changelog->next) { 189 if (s->changelog->next) {
190 simpleTimeToHuman(s->changelog->next->time, (humanDate *) & strdate); 190 simpleTimeToHuman(s->changelog->next->time, (humanDate *) & strdate);
191 fprintf(fout, 191 fprintf(fout,
192 "\n%s - %s (%s)\n%s", 192 "\n%s - %s (%s)\n%s",
193 strdate, 193 strdate,
194 s->changelog->next->pkg->name, 194 s->changelog->next->pkg->name,
195 s->changelog->next->release, 195 s->changelog->next->release,
196 htmlcleanNoBr(s->changelog->next->text,buffer,PATH_MAX)); 196 htmlcleanNoBr(s->changelog->next->text,buffer,PATH_MAX));
197 } 197 }
198 } else { 198 } else {
199 fprintf(fout, 199 fprintf(fout,
200 "title=\"WARNING: missing changelog"); 200 "title=\"WARNING: missing changelog");
201 } 201 }
202 202
203 fprintf(fout,"\n\nArchs:"); 203 fprintf(fout,"\n\nArchs:");
204 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 204 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
205 if (s->firstchild[i]) fprintf(fout," %s", configtag->arch[i]); 205 if (s->firstchild[i]) fprintf(fout," %s", configtag->arch[i]);
206 } 206 }
207 207
208 if (s->old) { 208 if (s->old) {
209 fprintf(fout, 209 fprintf(fout,
210 "\n\nUpdates %s(%s,%s,%ld:%s-%s)\">", 210 "\n\nUpdates %s(%s,%s,%ld:%s-%s)\">",
211 s->old->name, 211 s->old->name,
212 configtag->repository[s->old->altrepository]->tag, 212 configtag->repository[s->old->altrepository]->tag,
213 s->old->arch, 213 s->old->arch,
214 s->old->epoch, 214 s->old->epoch,
215 s->old->version, 215 s->old->version,
216 s->old->release); 216 s->old->release);
217 } else { 217 } else {
218 fprintf(fout, "\">"); 218 fprintf(fout, "\">");
219 } 219 }
220 220
221 } 221 }
222 222
223 int 223 int
224 generateMaintainersPages(struct configTag *configtag) 224 generateMaintainersPages(struct configTag *configtag)
225 { 225 {
226 char idxfile[PATH_MAX],outfile[PATH_MAX],unmaintfile[PATH_MAX]; 226 char idxfile[PATH_MAX],outfile[PATH_MAX],unmaintfile[PATH_MAX];
227 FILE *idx=NULL,*out=NULL,*unmaint=NULL; 227 FILE *idx=NULL,*out=NULL,*unmaint=NULL;
228 int i,pkgnum,unmaintpkgnum; 228 int i,pkgnum,unmaintpkgnum;
229 struct stat buf; 229 struct stat buf;
230 struct Packager *currpackager = NULL; 230 struct Packager *currpackager = NULL;
231 231
232 /* sort headersourcelistvec by packager name */ 232 /* sort headersourcelistvec by packager name */
233 qsort((void *) &configtag->stats.headersourcelistvec[0], 233 qsort((void *) &configtag->stats.headersourcelistvec[0],
234 configtag->stats.headersourcecount, sizeof(struct headerSourceList *), 234 configtag->stats.headersourcecount, sizeof(struct headerSourceList *),
235 comparePackagers); 235 comparePackagers);
236 236
237 snprintf(outfile, PATH_MAX, "%smaintainers", configtag->html_dir); 237 snprintf(outfile, PATH_MAX, "%smaintainers", configtag->html_dir);
238 if (stat(outfile,&buf)) { 238 if (stat(outfile,&buf)) {
239 if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { 239 if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
240 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile); 240 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile);
241 exit(1); 241 exit(1);
242 } 242 }
243 } else { 243 } else {
244 if (!S_ISDIR(buf.st_mode)) { 244 if (!S_ISDIR(buf.st_mode)) {
245 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile); 245 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile);
246 exit(1); 246 exit(1);
247 } 247 }
248 } 248 }
249 249
250 snprintf(idxfile, PATH_MAX, "%s_maintainers.inc", configtag->html_dir); 250 snprintf(idxfile, PATH_MAX, "%s_maintainers.inc", configtag->html_dir);
251 251
252 if ((idx = fopen(idxfile, "w")) == NULL) { 252 if ((idx = fopen(idxfile, "w")) == NULL) {
253 perror(idxfile); 253 perror(idxfile);
254 return 1; 254 return 1;
255 } 255 }
256 256
257 fprintf(idx, 257 fprintf(idx,
258 "<br>Maintainers for packages in the <b>%s</b> repository (%s):<br><br>\n", 258 "<br>Maintainers for packages in the <b>%s</b> repository (%s):<br><br>\n",
259 configtag->tag, 259 configtag->tag,
260 configtag->description); 260 configtag->description);
261 261
262 snprintf(unmaintfile, PATH_MAX, "%smaintainers/unmaintained.inc", configtag->html_dir); 262 snprintf(unmaintfile, PATH_MAX, "%smaintainers/unmaintained.inc", configtag->html_dir);
263 263
264 if ((unmaint = fopen(unmaintfile, "w")) == NULL) { 264 if ((unmaint = fopen(unmaintfile, "w")) == NULL) {
265 perror(unmaintfile); 265 perror(unmaintfile);
266 return 1; 266 return 1;
267 } 267 }
268 268
269 fprintf(unmaint, 269 fprintf(unmaint,
270 "<br>Packages that are <b>unmaintained</b> in the %s repository:<br><br>\n",configtag->tag); 270 "<br>Packages that are <b>unmaintained</b> in the %s repository:<br><br>\n",configtag->tag);
271 271
272 i=0; 272 i=0;
273 out=NULL; 273 out=NULL;
274 pkgnum=0; 274 pkgnum=0;
275 unmaintpkgnum=0; 275 unmaintpkgnum=0;
276 276
277 while (i < configtag->stats.headersourcecount) { 277 while (i < configtag->stats.headersourcecount) {
278 if ((configtag->stats.headersourcelistvec[i])->packager) { 278 if ((configtag->stats.headersourcelistvec[i])->packager) {
279 279
280 if ((i == 0) || 280 if ((i == 0) ||
281 ((configtag->stats.headersourcelistvec[i-1])->packager != (configtag->stats.headersourcelistvec[i])->packager)) { 281 ((configtag->stats.headersourcelistvec[i-1])->packager != (configtag->stats.headersourcelistvec[i])->packager)) {
282 282
283 if ((configtag->stats.headersourcelistvec[i])->packager->role & 283 if ((configtag->stats.headersourcelistvec[i])->packager->role &
284 PACKAGER_ROLE_MAINTAINER) { 284 PACKAGER_ROLE_MAINTAINER) {
285 285
286 snprintf(outfile, PATH_MAX, "%smaintainers/%s.inc", 286 snprintf(outfile, PATH_MAX, "%smaintainers/%s.inc",
287 configtag->html_dir, 287 configtag->html_dir,
288 (configtag->stats.headersourcelistvec[i])->packager->name); 288 (configtag->stats.headersourcelistvec[i])->packager->name);
289 289
290 if ((out = fopen(outfile, "w")) == NULL) { 290 if ((out = fopen(outfile, "w")) == NULL) {
291 perror(outfile); 291 perror(outfile);
292 return 1; 292 return 1;
293 } 293 }
294 294
295 fprintf(out, 295 fprintf(out,
296 "<br>Packages maintained by <b>%s</b> in the %s repository:<br><br>\n", 296 "<br>Packages maintained by <b>%s</b> in the %s repository:<br><br>\n",
297 (configtag->stats.headersourcelistvec[i])->packager->name, 297 (configtag->stats.headersourcelistvec[i])->packager->name,
298 configtag->tag); 298 configtag->tag);
299 } // new maintainer file created 299 } // new maintainer file created
300 300
301 } // check for changed packager 301 } // check for changed packager
302 302
303 if ((configtag->stats.headersourcelistvec[i])->packager->role & PACKAGER_ROLE_MAINTAINER) { 303 if ((configtag->stats.headersourcelistvec[i])->packager->role & PACKAGER_ROLE_MAINTAINER) {
304 fprintf(out, 304 fprintf(out,
305 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s</a>: %s<br>\n", 305 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s</a>: %s<br>\n",
306 configtag->configdefaults->url_prefix, 306 configtag->configdefaults->url_prefix,
307 configtag->tag, 307 configtag->tag,
308 (configtag->stats.headersourcelistvec)[i]->name, 308 (configtag->stats.headersourcelistvec)[i]->name,
309 (configtag->stats.headersourcelistvec)[i]->name, 309 (configtag->stats.headersourcelistvec)[i]->name,
310 (configtag->stats.headersourcelistvec)[i]->summary); 310 (configtag->stats.headersourcelistvec)[i]->summary);
311 pkgnum++; 311 pkgnum++;
312 312
313 if ((i+1 >= configtag->stats.headersourcecount) || 313 if ((i+1 >= configtag->stats.headersourcecount) ||
314 ((configtag->stats.headersourcelistvec[i])->packager != 314 ((configtag->stats.headersourcelistvec[i])->packager !=
315 (configtag->stats.headersourcelistvec[i+1])->packager)) { 315 (configtag->stats.headersourcelistvec[i+1])->packager)) {
316 316
317 fprintf(idx, 317 fprintf(idx,
318 "<a href=\"%stag=%s&amp;maintainer=%s\">%s </a>(pkg:%d; act:%5.2f%%)<br>\n", 318 "<a href=\"%stag=%s&amp;maintainer=%s\">%s </a>(pkg:%d; act:%5.2f%%)<br>\n",
319 configtag->configdefaults->url_prefix, 319 configtag->configdefaults->url_prefix,
320 configtag->tag, 320 configtag->tag,
321 configtag->stats.headersourcelistvec[i]->packager->name, 321 configtag->stats.headersourcelistvec[i]->packager->name,
322 configtag->stats.headersourcelistvec[i]->packager->name, 322 configtag->stats.headersourcelistvec[i]->packager->name,
323 pkgnum, 323 pkgnum,
324 ((double)(configtag->stats.headersourcelistvec[i]->packager->changes_count) * 100) / configtag->stats.changelog_total ); 324 ((double)(configtag->stats.headersourcelistvec[i]->packager->changes_count) * 100) / configtag->stats.changelog_total );
325 pkgnum=0; 325 pkgnum=0;
326 fclose(out); 326 fclose(out);
327 327
328 } 328 }
329 329
330 } else { // unmaintained package 330 } else { // unmaintained package
331 331
332 fprintf(unmaint, 332 fprintf(unmaint,
333 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s</a>: %s<br>\n", 333 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s</a>: %s<br>\n",
334 configtag->configdefaults->url_prefix, 334 configtag->configdefaults->url_prefix,
335 configtag->tag, 335 configtag->tag,
336 (configtag->stats.headersourcelistvec)[i]->name, 336 (configtag->stats.headersourcelistvec)[i]->name,
337 (configtag->stats.headersourcelistvec)[i]->name, 337 (configtag->stats.headersourcelistvec)[i]->name,
338 (configtag->stats.headersourcelistvec)[i]->summary); 338 (configtag->stats.headersourcelistvec)[i]->summary);
339 unmaintpkgnum++; 339 unmaintpkgnum++;
340 340
341 } 341 }
342 342
343 } 343 }
344 i++; 344 i++;
345 } // while 345 } // while
346 346
347 fclose(unmaint); 347 fclose(unmaint);
348 348
349 currpackager = firstPackager(); 349 currpackager = firstPackager();
350 350
351 // write stats for maintainer with 0 packages but changes (e.g. autodist) 351 // write stats for maintainer with 0 packages but changes (e.g. autodist)
352 while (currpackager) { 352 while (currpackager) {
353 if ((currpackager->role & PACKAGER_ROLE_MAINTAINER) && 353 if ((currpackager->role & PACKAGER_ROLE_MAINTAINER) &&
354 (currpackager->packages_count == 0) && 354 (currpackager->packages_count == 0) &&
355 (currpackager->changes_count > 0) ) { 355 (currpackager->changes_count > 0) ) {
356 fprintf(idx, 356 fprintf(idx,
357 "%s (pkg:%d; act:%5.2f%%)<br>\n", 357 "%s (pkg:%d; act:%5.2f%%)<br>\n",
358 currpackager->name, 358 currpackager->name,
359 0, 359 0,
360 ((double)(currpackager->changes_count) * 100) / configtag->stats.changelog_total ); 360 ((double)(currpackager->changes_count) * 100) / configtag->stats.changelog_total );
361 } 361 }
362 /* else { 362 /* else {
363 printf("skipped %s packages:%d changes:%d\n",currpackager->name,currpackager->packages_count,currpackager->changes_count); 363 printf("skipped %s packages:%d changes:%d\n",currpackager->name,currpackager->packages_count,currpackager->changes_count);
364 }*/ 364 }*/
365 currpackager = currpackager->next; 365 currpackager = currpackager->next;
366 } 366 }
367 367
368 if (unmaintpkgnum) 368 if (unmaintpkgnum)
369 fprintf(idx, 369 fprintf(idx,
370 "<a href=\"%stag=%s&amp;maintainer=unmaintained\">unmaintained packages</a> (pkg:%d)<br>\n", 370 "<a href=\"%stag=%s&amp;maintainer=unmaintained\">unmaintained packages</a> (pkg:%d)<br>\n",
371 configtag->configdefaults->url_prefix, 371 configtag->configdefaults->url_prefix,
372 configtag->tag, 372 configtag->tag,
373 unmaintpkgnum); 373 unmaintpkgnum);
374 374
375 fclose(idx); 375 fclose(idx);
376 376
377 return 0; 377 return 0;
378 } 378 }
379 379
380 int 380 int
381 generateStats(struct configTag *configtag,int arch) 381 generateStats(struct configTag *configtag,int arch)
382 { 382 {
383 char outfile[PATH_MAX]; 383 char outfile[PATH_MAX];
384 char rssfile[PATH_MAX]; 384 char rssfile[PATH_MAX];
385 char buffer[PATH_MAX]; 385 char buffer[PATH_MAX];
386 FILE *htmlout=NULL,*htmloldout,*rssout,*groupout; 386 FILE *htmlout=NULL,*htmloldout,*rssout,*groupout;
387 struct stat buf; 387 struct stat buf;
388 int i,pkgnum; 388 int i,pkgnum;
389 humanDate strdate,strolddate; 389 humanDate strdate,strolddate;
390 sizeString strsize; 390 sizeString strsize;
391 391
392 struct tm *ytm; 392 struct tm *ytm;
393 time_t timesec; 393 time_t timesec;
394 394
395 timesec = time(&timesec); 395 timesec = time(&timesec);
396 ytm = localtime((time_t *) &timesec); 396 ytm = localtime((time_t *) &timesec);
397 ytm->tm_sec = 0; 397 ytm->tm_sec = 0;
398 ytm->tm_min = 0; 398 ytm->tm_min = 0;
399 ytm->tm_hour = 0; 399 ytm->tm_hour = 0;
400 ytm->tm_mday = 1; 400 ytm->tm_mday = 1;
401 ytm->tm_mon = 0; 401 ytm->tm_mon = 0;
402 timesec = mktime(ytm); 402 timesec = mktime(ytm);
403 403
404 if (!configtag->configdefaults->html_basedir) { 404 if (!configtag->configdefaults->html_basedir) {
405 return 2; 405 return 2;
406 } 406 }
407 407
408 /* sort headersourcelistvec by Group */ 408 /* sort headersourcelistvec by Group */
409 qsort((void *) &configtag->stats.headersourcelistvec[0], 409 qsort((void *) &configtag->stats.headersourcelistvec[0],
410 configtag->stats.headersourcecount, sizeof(struct headerSourceList *), 410 configtag->stats.headersourcecount, sizeof(struct headerSourceList *),
411 compareGroup); 411 compareGroup);
412 412
413 snprintf(outfile, PATH_MAX, "%s_groups.inc", configtag->html_dir); 413 snprintf(outfile, PATH_MAX, "%s_groups.inc", configtag->html_dir);
414 414
415 if ((groupout = fopen(outfile, "w")) == NULL) { 415 if ((groupout = fopen(outfile, "w")) == NULL) {
416 perror(outfile); 416 perror(outfile);
417 return 1; 417 return 1;
418 } 418 }
419 419
420 /* create groups directory */ 420 /* create groups directory */
421 snprintf(outfile, PATH_MAX, "%sgroups",configtag->html_dir); 421 snprintf(outfile, PATH_MAX, "%sgroups",configtag->html_dir);
422 if (stat(outfile,&buf)) { 422 if (stat(outfile,&buf)) {
423 if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { 423 if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
424 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile); 424 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile);
425 exit(1); 425 exit(1);
426 } 426 }
427 } else { 427 } else {
428 if (!S_ISDIR(buf.st_mode)) { 428 if (!S_ISDIR(buf.st_mode)) {
429 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile); 429 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile);
430 exit(1); 430 exit(1);
431 } 431 }
432 } 432 }
433 433
434 fprintf(groupout, 434 fprintf(groupout,
435 "<br>Groups in the <b>%s</b> repository (%s):<br><br>\n", 435 "<br>Groups in the <b>%s</b> repository (%s):<br><br>\n",
436 configtag->tag, 436 configtag->tag,
437 configtag->description); 437 configtag->description);
438 438
439 i=0; 439 i=0;
440 pkgnum=0; 440 pkgnum=0;
441 if (configtag->stats.headersourcecount) do { 441 if (configtag->stats.headersourcecount) do {
442 442
443 if (pkgnum==0) { 443 if (pkgnum==0) {
444 444
445 snprintf(outfile, PATH_MAX, "%sgroups/%s", 445 snprintf(outfile, PATH_MAX, "%sgroups/%s",
446 configtag->html_dir, 446 configtag->html_dir,
447 groupdirname(configtag->stats.headersourcelistvec[i]->group,buffer,PATH_MAX)); 447 groupdirname(configtag->stats.headersourcelistvec[i]->group,buffer,PATH_MAX));
448 448
449 if (stat(outfile,&buf)) { 449 if (stat(outfile,&buf)) {
450 if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { 450 if (mkdir(outfile,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
451 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile); 451 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",outfile);
452 exit(1); 452 exit(1);
453 } 453 }
454 } else { 454 } else {
455 if (!S_ISDIR(buf.st_mode)) { 455 if (!S_ISDIR(buf.st_mode)) {
456 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile); 456 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",outfile);
457 exit(1); 457 exit(1);
458 } 458 }
459 } 459 }
460 strncat(outfile, "/_index.inc", sizeof(outfile) - strlen(outfile)); 460 strncat(outfile, "/_index.inc", sizeof(outfile) - strlen(outfile));
461 if ((htmlout = fopen(outfile, "w")) == NULL) { 461 if ((htmlout = fopen(outfile, "w")) == NULL) {
462 perror(outfile); 462 perror(outfile);
463 return 1; 463 return 1;
464 } 464 }
465 465
466 fprintf(htmlout, 466 fprintf(htmlout,
467 "<br>Packages in the <b>%s</b> group of the <b>%s</b> repository (%s):<br><br>\n", 467 "<br>Packages in the <b>%s</b> group of the <b>%s</b> repository (%s):<br><br>\n",
468 configtag->stats.headersourcelistvec[i]->group, 468 configtag->stats.headersourcelistvec[i]->group,
469 configtag->tag, 469 configtag->tag,
470 configtag->description); 470 configtag->description);
471 471
472 } 472 }
473 fprintf(htmlout, 473 fprintf(htmlout,
474 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s</a>: %s<br>\n", 474 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s</a>: %s<br>\n",
475 configtag->configdefaults->url_prefix, 475 configtag->configdefaults->url_prefix,
476 configtag->tag, 476 configtag->tag,
477 (configtag->stats.headersourcelistvec)[i]->name, 477 (configtag->stats.headersourcelistvec)[i]->name,
478 (configtag->stats.headersourcelistvec)[i]->name, 478 (configtag->stats.headersourcelistvec)[i]->name,
479 (configtag->stats.headersourcelistvec)[i]->summary); 479 (configtag->stats.headersourcelistvec)[i]->summary);
480 i++; 480 i++;
481 pkgnum++; 481 pkgnum++;
482 482
483 if ((i >= configtag->stats.headersourcecount) || 483 if ((i >= configtag->stats.headersourcecount) ||
484 (strcmp(configtag->stats.headersourcelistvec[i-1]->group, 484 (strcmp(configtag->stats.headersourcelistvec[i-1]->group,
485 configtag->stats.headersourcelistvec[i]->group))) { 485 configtag->stats.headersourcelistvec[i]->group))) {
486 fprintf(groupout, 486 fprintf(groupout,
487 "<a href=\"%stag=%s&amp;group=%s\">%s <b>(%d)</b></a><br>\n", 487 "<a href=\"%stag=%s&amp;group=%s\">%s <b>(%d)</b></a><br>\n",
488 configtag->configdefaults->url_prefix, 488 configtag->configdefaults->url_prefix,
489 configtag->tag, 489 configtag->tag,
490 groupdirname(configtag->stats.headersourcelistvec[i-1]->group,buffer,PATH_MAX), 490 groupdirname(configtag->stats.headersourcelistvec[i-1]->group,buffer,PATH_MAX),
491 (configtag->stats.headersourcelistvec)[i-1]->group, 491 (configtag->stats.headersourcelistvec)[i-1]->group,
492 pkgnum); 492 pkgnum);
493 pkgnum=0; 493 pkgnum=0;
494 fclose(htmlout); 494 fclose(htmlout);
495 } 495 }
496 496
497 } while (i < configtag->stats.headersourcecount); 497 } while (i < configtag->stats.headersourcecount);
498 498
499 if (i>0) { 499 if (i>0) {
500 fclose(groupout); 500 fclose(groupout);
501 } 501 }
502 502
503 strncpy(outfile, configtag->html_dir, PATH_MAX); 503 strncpy(outfile, configtag->html_dir, PATH_MAX);
504 strncat(outfile, "_recent.inc", sizeof(outfile) - strlen(outfile)); 504 strncat(outfile, "_recent.inc", sizeof(outfile) - strlen(outfile));
505 if ((htmlout = fopen(outfile, "w")) == NULL) { 505 if ((htmlout = fopen(outfile, "w")) == NULL) {
506 perror(outfile); 506 perror(outfile);
507 return 1; 507 return 1;
508 } 508 }
509 /*else { 509 /*else {
510 fprintf(htmlout, "<a href=\"%s/%s/recent.rss\">" 510 fprintf(htmlout, "<a href=\"%s/%s/recent.rss\">"
511 "<img src=\"%s/feed-icon.png\" " 511 "<img src=\"%s/feed-icon.png\" "
512 "alt=\"RSS 2.0 news feed\"></a>", 512 "alt=\"RSS 2.0 news feed\"></a>",
513 configtag->configdefaults->url_dir, 513 configtag->configdefaults->url_dir,
514 configtag->tag, 514 configtag->tag,
515 configtag->configdefaults->url_dir); 515 configtag->configdefaults->url_dir);
516 fprintf(htmlout, "Recent builds:<br>\n"); 516 fprintf(htmlout, "Recent builds:<br>\n");
517 }*/ 517 }*/
518 518
519 strncpy(outfile, configtag->html_dir, PATH_MAX); 519 strncpy(outfile, configtag->html_dir, PATH_MAX);
520 strncat(outfile, "_oldest.inc", sizeof(outfile) - strlen(outfile)); 520 strncat(outfile, "_oldest.inc", sizeof(outfile) - strlen(outfile));
521 if ((htmloldout = fopen(outfile, "w")) == NULL) { 521 if ((htmloldout = fopen(outfile, "w")) == NULL) {
522 perror(outfile); 522 perror(outfile);
523 return 1; 523 return 1;
524 } 524 }
525 525
526 /* else { 526 /* else {
527 fprintf(htmloldout, "Oldest builds:<br>\n"); 527 fprintf(htmloldout, "Oldest builds:<br>\n");
528 }*/ 528 }*/
529 529
530 strncpy(rssfile, configtag->html_dir, PATH_MAX); 530 strncpy(rssfile, configtag->html_dir, PATH_MAX);
531 strncat(rssfile, "recent.rss", sizeof(rssfile) - strlen(rssfile)); 531 strncat(rssfile, "recent.rss", sizeof(rssfile) - strlen(rssfile));
532 if ((rssout = fopen(rssfile, "w")) == NULL) { 532 if ((rssout = fopen(rssfile, "w")) == NULL) {
533 perror(rssfile); 533 perror(rssfile);
534 return 1; 534 return 1;
535 } else { 535 } else {
536 fprintf(rssout,"<?xml version=\"1.0\" ?>\n"); 536 fprintf(rssout,"<?xml version=\"1.0\" ?>\n");
537 fprintf(rssout,"<rss version=\"2.0\">\n"); 537 fprintf(rssout,"<rss version=\"2.0\">\n");
538 fprintf(rssout,"<channel>\n"); 538 fprintf(rssout,"<channel>\n");
539 fprintf(rssout," <title>Recent packages for the %s repository</title>\n",configtag->tag); 539 fprintf(rssout," <title>Recent packages for the %s repository</title>\n",configtag->tag);
540 fprintf(rssout," <link>http://%s/%s</link>\n", 540 fprintf(rssout," <link>http://%s/%s</link>\n",
541 configtag->configdefaults->url_address, 541 configtag->configdefaults->url_address,
542 configtag->configdefaults->url_prefix); 542 configtag->configdefaults->url_prefix);
543 //fprintf(rssout," <description></description>\n"); 543 //fprintf(rssout," <description></description>\n");
544 fprintf(rssout," <language>en-us</language>\n"); 544 fprintf(rssout," <language>en-us</language>\n");
545 fprintf(rssout," <docs>http://blogs.law.harvard.edu/tech/rss</docs>"); 545 fprintf(rssout," <docs>http://blogs.law.harvard.edu/tech/rss</docs>");
546 fprintf(rssout," <generator>Distromatic %s</generator>\n",VERSION); 546 fprintf(rssout," <generator>Distromatic %s</generator>\n",VERSION);
547 } 547 }
548 548
549 /* sort headersourcelistvec by BuildDate */ 549 /* sort headersourcelistvec by BuildDate */
550 qsort((void *) &configtag->stats.headersourcelistvec[0], 550 qsort((void *) &configtag->stats.headersourcelistvec[0],
551 configtag->stats.headersourcecount, sizeof(struct headerSourceList *), 551 configtag->stats.headersourcecount, sizeof(struct headerSourceList *),
552 compareSourceHeaderBuildDate); 552 compareSourceHeaderBuildDate);
553 553
554 fprintf(htmlout, "<a href=\"%stag=%s\">SRPMS</a>(%d;%s)", 554 fprintf(htmlout, "<a href=\"%stag=%s\">SRPMS</a>(%d;%s)",
555 configtag->configdefaults->url_prefix, 555 configtag->configdefaults->url_prefix,
556 configtag->tag, 556 configtag->tag,
557 configtag->stats.headersourcecount, 557 configtag->stats.headersourcecount,
558 humanSize(configtag->stats.headersourcesize, &strsize)); 558 humanSize(configtag->stats.headersourcesize, &strsize));
559 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) { 559 for (i = 0; i < ARCHS_MAX && configtag->arch[i]; i++) {
560 fprintf(htmlout, " <a href=\"%stag=%s&arch=%s\">%s</a>(%d;%s) ", 560 fprintf(htmlout, " <a href=\"%stag=%s&arch=%s\">%s</a>(%d;%s) ",
561 configtag->configdefaults->url_prefix, 561 configtag->configdefaults->url_prefix,
562 configtag->tag, 562 configtag->tag,
563 configtag->arch[i], 563 configtag->arch[i],
564 configtag->arch[i], 564 configtag->arch[i],
565 configtag->stats.headercount[i], 565 configtag->stats.headercount[i],
566 humanSize(configtag->stats.headersize[i], &strsize)); 566 humanSize(configtag->stats.headersize[i], &strsize));
567 if (i % 2 == 0) fprintf(htmlout,"<br>"); 567 if (i % 2 == 0) fprintf(htmlout,"<br>");
568 } 568 }
569 if (i % 2 == 0) fprintf(htmlout,"<br>"); 569 if (i % 2 == 0) fprintf(htmlout,"<br>");
570 570
571 i=0; 571 i=0;
572 while ((i < configtag->stats.headersourcecount) && 572 while ((i < configtag->stats.headersourcecount) &&
573 ((i < HTMLSTATS_NUM) || (i < RSSSTATS_NUM))) { 573 ((i < HTMLSTATS_NUM) || (i < RSSSTATS_NUM))) {
574 if ((configtag->stats.headersourcelistvec)[i]->buildtime < timesec) { 574 if ((configtag->stats.headersourcelistvec)[i]->buildtime < timesec) {
575 simpleTimeToTemplate( 575 simpleTimeToTemplate(
576 (configtag->stats.headersourcelistvec)[i]->buildtime, 576 (configtag->stats.headersourcelistvec)[i]->buildtime,
577 "%Y/%m/%d",&strdate); 577 "%Y/%m/%d",&strdate);
578 } else { 578 } else {
579 simpleTimeToTemplate( 579 simpleTimeToTemplate(
580 (configtag->stats.headersourcelistvec)[i]->buildtime, 580 (configtag->stats.headersourcelistvec)[i]->buildtime,
581 "%m/%d",&strdate); 581 "%m/%d",&strdate);
582 } 582 }
583 if (i < HTMLSTATS_NUM) { 583 if (i < HTMLSTATS_NUM) {
584 // HTML statistics 584 // HTML statistics
585 printpkgicon(htmlout, configtag, (configtag->stats.headersourcelistvec)[i]); 585 printpkgicon(htmlout, configtag, (configtag->stats.headersourcelistvec)[i]);
586 fprintf(htmlout, 586 fprintf(htmlout,
587 "<a href=\"%stag=%s&amp;pkg=%s.source\" title=\"%s\">%s %s %s-%s</a>&nbsp;", 587 "<a href=\"%stag=%s&amp;pkg=%s.source\" title=\"%s\">%s %s %s-%s</a>&nbsp;",
588 configtag->configdefaults->url_prefix, 588 configtag->configdefaults->url_prefix,
589 configtag->tag, 589 configtag->tag,
590 (configtag->stats.headersourcelistvec)[i]->name, 590 (configtag->stats.headersourcelistvec)[i]->name,
591 htmlclean((configtag->stats.headersourcelistvec)[i]->summary,buffer,PATH_MAX), 591 htmlclean((configtag->stats.headersourcelistvec)[i]->summary,buffer,PATH_MAX),
592 strdate, 592 strdate,
593 (configtag->stats.headersourcelistvec)[i]->name, 593 (configtag->stats.headersourcelistvec)[i]->name,
594 (configtag->stats.headersourcelistvec)[i]->version, 594 (configtag->stats.headersourcelistvec)[i]->version,
595 (configtag->stats.headersourcelistvec)[i]->release); 595 (configtag->stats.headersourcelistvec)[i]->release);
596 596
597 // FIXME: warnings are printed before SRPMS warning are added below so SRPMS warning are missing in HTML pages 597 // FIXME: warnings are printed before SRPMS warning are added below so SRPMS warning are missing in HTML pages
598 printHTMLWarnings(htmlout,configtag,(configtag->stats.headersourcelistvec)[i],0); 598 printHTMLWarnings(htmlout,configtag,(configtag->stats.headersourcelistvec)[i],0);
599 fprintf(htmlout,"<br>\n"); 599 fprintf(htmlout,"<br>\n");
600 } 600 }
601 601
602 if (i < HTMLOLDSTATS_NUM) { 602 if (i < HTMLOLDSTATS_NUM) {
603 // HTML statistics 603 // HTML statistics
604 simpleTimeToTemplate((configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->buildtime,"%Y/%m/%d",&strolddate); 604 simpleTimeToTemplate((configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->buildtime,"%Y/%m/%d",&strolddate);
605 605
606 fprintf(htmloldout, 606 fprintf(htmloldout,
607 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s %s %s-%s</a><br>\n", 607 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s %s %s-%s</a><br>\n",
608 configtag->configdefaults->url_prefix, 608 configtag->configdefaults->url_prefix,
609 configtag->tag, 609 configtag->tag,
610 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->name, 610 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->name,
611 strolddate, 611 strolddate,
612 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->name, 612 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->name,
613 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->version, 613 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->version,
614 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->release); 614 (configtag->stats.headersourcelistvec)[configtag->stats.headersourcecount-1-i]->release);
615 } 615 }
616 616
617 if (i < RSSSTATS_NUM) { 617 if (i < RSSSTATS_NUM) {
618 // RSS recent packages 618 // RSS recent packages
619 fprintf(rssout," <item>\n"); 619 fprintf(rssout," <item>\n");
620 fprintf(rssout," <title>%s %s %s-%s</title>\n", 620 fprintf(rssout," <title>%s %s %s-%s</title>\n",
621 strdate, 621 strdate,
622 (configtag->stats.headersourcelistvec)[i]->name, 622 (configtag->stats.headersourcelistvec)[i]->name,
623 (configtag->stats.headersourcelistvec)[i]->version, 623 (configtag->stats.headersourcelistvec)[i]->version,
624 (configtag->stats.headersourcelistvec)[i]->release); 624 (configtag->stats.headersourcelistvec)[i]->release);
625 625
626 fprintf(rssout," <link>http://%s%stag=%s&amp;pkg=%s.source</link>\n", 626 fprintf(rssout," <link>http://%s%stag=%s&amp;pkg=%s.source</link>\n",
627 configtag->configdefaults->url_address, 627 configtag->configdefaults->url_address,
628 configtag->configdefaults->url_prefix, 628 configtag->configdefaults->url_prefix,
629 configtag->tag, 629 configtag->tag,
630 (configtag->stats.headersourcelistvec)[i]->name); 630 (configtag->stats.headersourcelistvec)[i]->name);
631 fprintf(rssout," </item>\n"); 631 fprintf(rssout," </item>\n");
632 } 632 }
633 i++; 633 i++;
634 } 634 }
635 635
636 636
637 fclose(htmlout); 637 fclose(htmlout);
638 638
639 // fprintf(rssout, "</feed>\n"); 639 // fprintf(rssout, "</feed>\n");
640 640
641 fprintf(rssout, "</channel>\n"); 641 fprintf(rssout, "</channel>\n");
642 fprintf(rssout, "</rss>\n"); 642 fprintf(rssout, "</rss>\n");
643 fclose(rssout); 643 fclose(rssout);
644 644
645 /* create APT repository file */ 645 /* create APT repository file */
646 snprintf(outfile, PATH_MAX, "%s%s-%s.list", 646 snprintf(outfile, PATH_MAX, "%s%s-%s.list",
647 configtag->html_dir, 647 configtag->html_dir,
648 configtag->configdefaults->distribution_name, 648 configtag->configdefaults->distribution_name,
649 configtag->tag); 649 configtag->tag);
650 650
651 if ((htmlout = fopen(outfile, "w")) == NULL) { 651 if ((htmlout = fopen(outfile, "w")) == NULL) {
652 perror(outfile); 652 perror(outfile);
653 return 1; 653 return 1;
654 } else { 654 } else {
655 655
656 /* remove final slashes from download_prefix as required by apt */ 656 /* remove final slashes from download_prefix as required by apt */
657 strncpy(buffer, configtag->download_dir, PATH_MAX); 657 strncpy(buffer, configtag->download_dir, PATH_MAX);
658 658
659 i=strlen(buffer); 659 i=strlen(buffer);
660 while ((i > 0) && (buffer[i-1] == '/' )) { 660 while ((i > 0) && (buffer[i-1] == '/' )) {
661 buffer[i-1]='\0'; 661 buffer[i-1]='\0';
662 i--; 662 i--;
663 } 663 }
664 664
665 fprintf(htmlout, "#\n# %s %s repository sources list for APT\n#\n\n", 665 fprintf(htmlout, "#\n# %s %s repository sources list for APT\n#\n\n",
666 configtag->configdefaults->distribution_name, 666 configtag->configdefaults->distribution_name,
667 configtag->tag); 667 configtag->tag);
668 fprintf(htmlout, "#\n# %s %s repository from %s\n#\n", 668 fprintf(htmlout, "#\n# %s %s repository from %s\n#\n",
669 configtag->tag, 669 configtag->tag,
670 configtag->arch[arch], 670 configtag->arch[arch],
671 configtag->configdefaults->url_address); 671 configtag->configdefaults->url_address);
672 fprintf(htmlout, "rpm http://%s %s %s\n\n", 672 fprintf(htmlout, "rpm http://%s %s %s\n\n",
673 configtag->configdefaults->url_address, 673 configtag->configdefaults->url_address,
674 buffer, 674 buffer,
675 configtag->arch[arch]); 675 configtag->arch[arch]);
676 fprintf(htmlout, "#\n# %s sources repository from %s\n#\n", 676 fprintf(htmlout, "#\n# %s sources repository from %s\n#\n",
677 configtag->tag, 677 configtag->tag,
678 configtag->configdefaults->url_address); 678 configtag->configdefaults->url_address);
679 fprintf(htmlout, "rpm-src http://%s %s base\n\n", 679 fprintf(htmlout, "rpm-src http://%s %s base\n\n",
680 configtag->configdefaults->url_address, 680 configtag->configdefaults->url_address,
681 buffer); 681 buffer);
682 fclose(htmlout); 682 fclose(htmlout);
683 } 683 }
684 684
685 /* create Smart Package Manager channel file */ 685 /* create Smart Package Manager channel file */
686 snprintf(outfile, PATH_MAX, "%s%s-%s.smart", 686 snprintf(outfile, PATH_MAX, "%s%s-%s.smart",
687 configtag->html_dir, 687 configtag->html_dir,
688 configtag->configdefaults->distribution_name, 688 configtag->configdefaults->distribution_name,
689 configtag->tag); 689 configtag->tag);
690 690
691 if ((htmlout = fopen(outfile, "w")) == NULL) { 691 if ((htmlout = fopen(outfile, "w")) == NULL) {
692 perror(outfile); 692 perror(outfile);
693 return 1; 693 return 1;
694 } else { 694 } else {
695 /* remove final slashes from download_prefix as required by apt */ 695 /* remove final slashes from download_prefix as required by apt */
696 strncpy(buffer, configtag->download_dir, PATH_MAX); 696 strncpy(buffer, configtag->download_dir, PATH_MAX);
697 697
698 i=strlen(buffer); 698 i=strlen(buffer);
699 while ((i > 0) && (buffer[i-1] == '/' )) { 699 while ((i > 0) && (buffer[i-1] == '/' )) {
700 buffer[i-1]='\0'; 700 buffer[i-1]='\0';
701 i--; 701 i--;
702 } 702 }
703 703
704 fprintf(htmlout, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n", 704 fprintf(htmlout, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n",
705 configtag->configdefaults->distribution_name, 705 configtag->configdefaults->distribution_name,
706 configtag->tag); 706 configtag->tag);
707 fprintf(htmlout, "[%s]\ntype = apt-rpm\n", 707 fprintf(htmlout, "[%s]\ntype = apt-rpm\n",
708 configtag->tag); 708 configtag->tag);
709 fprintf(htmlout, "name = %s\n", 709 fprintf(htmlout, "name = %s\n",
710 configtag->description); 710 configtag->description);
711 fprintf(htmlout, "baseurl = http://%s%s\n", 711 fprintf(htmlout, "baseurl = http://%s%s\n",
712 configtag->configdefaults->url_address, buffer); 712 configtag->configdefaults->url_address, buffer);
713 fprintf(htmlout, "components ="); 713 fprintf(htmlout, "components =");
714 for (i = 0; i < ARCHS_MAX; i++) { 714 for (i = 0; i < ARCHS_MAX; i++) {
715 if (configtag->arch[i]) fprintf(htmlout," %s", configtag->arch[i]); 715 if (configtag->arch[i]) fprintf(htmlout," %s", configtag->arch[i]);
716 } 716 }
717 fprintf(htmlout, "\n"); 717 fprintf(htmlout, "\n");
718 fclose(htmlout); 718 fclose(htmlout);
719 } 719 }
720 720
721 /* create Changelog page */ 721 /* create Changelog page */
722 struct tm tmdate; 722 struct tm tmdate;
723 tmdate.tm_min = 0; 723 tmdate.tm_min = 0;
724 tmdate.tm_hour = 0; 724 tmdate.tm_hour = 0;
725 tmdate.tm_sec = 0; 725 tmdate.tm_sec = 0;
726 tmdate.tm_year = 90; 726 tmdate.tm_year = 90;
727 tmdate.tm_mday = 1; 727 tmdate.tm_mday = 1;
728 tmdate.tm_mon = 0; 728 tmdate.tm_mon = 0;
729 729
730 snprintf(outfile, PATH_MAX, "%s_changelog.inc", configtag->html_dir); 730 snprintf(outfile, PATH_MAX, "%s_changelog.inc", configtag->html_dir);
731 731
732 if ((htmlout = fopen(outfile, "w")) == NULL) { 732 if ((htmlout = fopen(outfile, "w")) == NULL) {
733 perror(outfile); 733 perror(outfile);
734 return 1; 734 return 1;
735 } 735 }
736 736
737 fprintf(htmlout, 737 fprintf(htmlout,
738 "<h1>Changelog for the <b>%s</b> repository (%s):</h1>\n", 738 "<h1>Changelog for the <b>%s</b> repository (%s):</h1>\n",
739 configtag->tag, 739 configtag->tag,
740 configtag->description); 740 configtag->description);
741 741
742 printChangelogSince(htmlout, configtag, &tmdate, 1); 742 printChangelogSince(htmlout, configtag, &tmdate, 1);
743 743
744 fclose(htmlout); 744 fclose(htmlout);
745 return 0; 745 return 0;
746 } 746 }
747 747
748 int 748 int
749 generateHTMLMainIndex(struct configTag *configtag) 749 generateHTMLMainIndex(struct configTag *configtag)
750 { 750 {
751 char indexfile[PATH_MAX],smartfile[PATH_MAX],buffer[PATH_MAX],smartpyfile[PATH_MAX]; 751 char indexfile[PATH_MAX],smartfile[PATH_MAX],buffer[PATH_MAX],smartpyfile[PATH_MAX];
752 FILE *fout,*fsmart,*fsmartpy; 752 FILE *fout,*fsmart,*fsmartpy;
753 int i; 753 int i;
754 754
755 if (!configtag->configdefaults->html_basedir) { 755 if (!configtag->configdefaults->html_basedir) {
756 return 2; 756 return 2;
757 } 757 }
758 758
759 strncpy(indexfile, configtag->configdefaults->html_basedir, PATH_MAX); 759 strncpy(indexfile, configtag->configdefaults->html_basedir, PATH_MAX);
760 strncat(indexfile, "_index.inc", sizeof(indexfile) - strlen(indexfile)); 760 strncat(indexfile, "_index.inc", sizeof(indexfile) - strlen(indexfile));
761 761
762 if ((fout = fopen(indexfile, "w")) == NULL) { 762 if ((fout = fopen(indexfile, "w")) == NULL) {
763 perror(indexfile); 763 perror(indexfile);
764 return 1; 764 return 1;
765 } 765 }
766 766
767 /* create Smart Package Manager channel files */ 767 /* create Smart Package Manager channel files */
768 snprintf(smartfile,PATH_MAX,"%s%s.smart", 768 snprintf(smartfile,PATH_MAX,"%s%s.smart",
769 configtag->configdefaults->html_basedir, 769 configtag->configdefaults->html_basedir,
770 configtag->configdefaults->distribution_name); 770 configtag->configdefaults->distribution_name);
771 snprintf(smartpyfile,PATH_MAX,"%s%s.smart.py", 771 snprintf(smartpyfile,PATH_MAX,"%s%s.smart.py",
772 configtag->configdefaults->html_basedir, 772 configtag->configdefaults->html_basedir,
773 configtag->configdefaults->distribution_name); 773 configtag->configdefaults->distribution_name);
774 774
775 if ((fsmart = fopen(smartfile, "w")) == NULL) { 775 if ((fsmart = fopen(smartfile, "w")) == NULL) {
776 perror(smartfile); 776 perror(smartfile);
777 return 1; 777 return 1;
778 } 778 }
779 if ((fsmartpy = fopen(smartpyfile, "w")) == NULL) { 779 if ((fsmartpy = fopen(smartpyfile, "w")) == NULL) {
780 perror(smartpyfile); 780 perror(smartpyfile);
781 return 1; 781 return 1;
782 } 782 }
783 783
784 fprintf(fout,"<b>Available repositories:</b><br><br>\n"); 784 fprintf(fout,"<b>Available repositories:</b><br><br>\n");
785 while (configtag) { 785 while (configtag) {
786 786
787 fprintf(fout, 787 fprintf(fout,
788 "<a href=\"%stag=%s\">%s</a>: %s<br>", 788 "<a href=\"%stag=%s\">%s</a>: %s<br>",
789 configtag->configdefaults->url_prefix, 789 configtag->configdefaults->url_prefix,
790 configtag->tag, 790 configtag->tag,
791 configtag->tag, 791 configtag->tag,
792 configtag->description); 792 configtag->description);
793 793
794 /* remove final slashes from download_prefix as required by apt */ 794 /* remove final slashes from download_prefix as required by apt */
795 strncpy(buffer, configtag->download_dir, PATH_MAX); 795 strncpy(buffer, configtag->download_dir, PATH_MAX);
796 i=strlen(buffer); 796 i=strlen(buffer);
797 while ((i > 0) && (buffer[i-1] == '/' )) { 797 while ((i > 0) && (buffer[i-1] == '/' )) {
798 buffer[i-1]='\0'; 798 buffer[i-1]='\0';
799 i--; 799 i--;
800 } 800 }
801 fprintf(fsmart, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n", 801 fprintf(fsmart, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n",
802 configtag->configdefaults->distribution_name, 802 configtag->configdefaults->distribution_name,
803 configtag->tag); 803 configtag->tag);
804 fprintf(fsmart, "[%s]\ntype = apt-rpm\n", 804 fprintf(fsmart, "[%s]\ntype = apt-rpm\n",
805 configtag->tag); 805 configtag->tag);
806 fprintf(fsmart, "name = %s\n", 806 fprintf(fsmart, "name = %s\n",
807 configtag->description); 807 configtag->description);
808 fprintf(fsmart, "disabled = yes\n"); 808 fprintf(fsmart, "disabled = yes\n");
809 fprintf(fsmart, "baseurl = http://%s%s\n", 809 fprintf(fsmart, "baseurl = http://%s%s\n",
810 configtag->configdefaults->url_address, buffer); 810 configtag->configdefaults->url_address, buffer);
811 fprintf(fsmart, "components = %s\n\n", 811 fprintf(fsmart, "components = %s\n\n",
812 configtag->arch[0]); 812 configtag->arch[0]);
813 fprintf(fsmartpy, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n", 813 fprintf(fsmartpy, "#\n# %s %s channel configuration for Smart Package Manager\n#\n\n",
814 configtag->configdefaults->distribution_name, 814 configtag->configdefaults->distribution_name,
815 configtag->tag); 815 configtag->tag);
816 fprintf(fsmartpy, "if not sysconf.get((\"channels\", \"%s\")):\n", 816 fprintf(fsmartpy, "if not sysconf.get((\"channels\", \"%s\")):\n",
817 configtag->tag); 817 configtag->tag);
818 fprintf(fsmartpy, "\tsysconf.set((\"channels\", \"%s\"),\n", 818 fprintf(fsmartpy, "\tsysconf.set((\"channels\", \"%s\"),\n",
819 configtag->tag); 819 configtag->tag);
820 fprintf(fsmartpy, "\t\t\t{\"alias\": \"%s\",\n", 820 fprintf(fsmartpy, "\t\t\t{\"alias\": \"%s\",\n",
821 configtag->tag); 821 configtag->tag);
822 fprintf(fsmartpy, "\t\t\t\"type\": \"apt-rpm\",\n"); 822 fprintf(fsmartpy, "\t\t\t\"type\": \"apt-rpm\",\n");
823 fprintf(fsmartpy, "\t\t\t\"name\": \"%s\",\n", 823 fprintf(fsmartpy, "\t\t\t\"name\": \"%s\",\n",
824 configtag->description); 824 configtag->description);
825 fprintf(fsmartpy, "\t\t\t\"disabled\": \"yes\",\n"); 825 fprintf(fsmartpy, "\t\t\t\"disabled\": \"yes\",\n");
826 fprintf(fsmartpy, "\t\t\t\"baseurl\": \"http://%s%s\",\n", 826 fprintf(fsmartpy, "\t\t\t\"baseurl\": \"http://%s%s\",\n",
827 configtag->configdefaults->url_address, buffer); 827 configtag->configdefaults->url_address, buffer);
828 fprintf(fsmartpy, "\t\t\t\"components\": \"%s\"})\n\n", 828 fprintf(fsmartpy, "\t\t\t\"components\": \"%s\"})\n\n",
829 configtag->arch[0]); 829 configtag->arch[0]);
830 830
831 configtag = configtag->next; 831 configtag = configtag->next;
832 832
833 } 833 }
834 fclose(fout); 834 fclose(fout);
835 fclose(fsmart); 835 fclose(fsmart);
836 fclose(fsmartpy); 836 fclose(fsmartpy);
837 837
838 return 0; 838 return 0;
839 } 839 }
840 840
841 int 841 int
842 generateHTML_SRPMSFiles(struct configTag *configtag) 842 generateHTML_SRPMSFiles(struct configTag *configtag)
843 { 843 {
844 844
845 humanDate strdate; 845 humanDate strdate;
846 char indexfile[PATH_MAX]; 846 char indexfile[PATH_MAX];
847 char htmlfile[PATH_MAX]; 847 char htmlfile[PATH_MAX];
848 char warningsdir[PATH_MAX]; 848 char warningsdir[PATH_MAX];
849 char buffer[PATH_MAX],buffer2[PATH_MAX]; 849 char buffer[PATH_MAX],buffer2[PATH_MAX];
850 int c,i,j,arch,idx; 850 int c,i,j,arch,idx;
851 char *st; 851 char *st;
852 char curr_letter,curr_anchor ='a'-1; 852 char curr_letter,curr_anchor ='a'-1;
853 FILE *findexout[ARCHS_MAX+1], *fout; 853 FILE *findexout[ARCHS_MAX+1], *fout;
854 struct changeLog *currchangelog; 854 struct changeLog *currchangelog;
855 struct headerSourceList *currheadersourcelist; 855 struct headerSourceList *currheadersourcelist;
856 struct headerList *currchild; 856 struct headerList *currchild;
857 struct stat buf; 857 struct stat buf;
858 sizeString strsize; 858 sizeString strsize;
859 859
860 snprintf(buffer,PATH_MAX,"%spackages",configtag->html_dir); 860 snprintf(buffer,PATH_MAX,"%spackages",configtag->html_dir);
861 if (stat(buffer,&buf)) { 861 if (stat(buffer,&buf)) {
862 if (mkdir(buffer,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { 862 if (mkdir(buffer,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
863 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",buffer); 863 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",buffer);
864 exit(1); 864 exit(1);
865 } 865 }
866 } else { 866 } else {
867 if (!S_ISDIR(buf.st_mode)) { 867 if (!S_ISDIR(buf.st_mode)) {
868 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",buffer); 868 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",buffer);
869 exit(1); 869 exit(1);
870 } 870 }
871 } 871 }
872 872
873 // write an empty index.html file to avoid directory files browsing 873 // write an empty index.html file to avoid directory files browsing
874 snprintf(indexfile,PATH_MAX,"%sindex.html",configtag->html_dir); 874 snprintf(indexfile,PATH_MAX,"%sindex.html",configtag->html_dir);
875 875
876 if ((fout = fopen(indexfile, "w")) == NULL) { 876 if ((fout = fopen(indexfile, "w")) == NULL) {
877 perror(indexfile); 877 perror(indexfile);
878 return 1; 878 return 1;
879 } 879 }
880 fclose(fout); 880 fclose(fout);
881 881
882 // create warnings directory 882 // create warnings directory
883 snprintf(warningsdir,PATH_MAX,"%swarnings",configtag->html_dir); 883 snprintf(warningsdir,PATH_MAX,"%swarnings",configtag->html_dir);
884 if (stat(warningsdir,&buf)) { 884 if (stat(warningsdir,&buf)) {
885 if (mkdir(warningsdir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { 885 if (mkdir(warningsdir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
886 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",warningsdir); 886 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",warningsdir);
887 exit(1); 887 exit(1);
888 } 888 }
889 } else { 889 } else {
890 if (!S_ISDIR(buf.st_mode)) { 890 if (!S_ISDIR(buf.st_mode)) {
891 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",warningsdir); 891 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",warningsdir);
892 exit(1); 892 exit(1);
893 } 893 }
894 } 894 }
895 895
896 /* open full SRPM index file */ 896 /* open full SRPM index file */
897 snprintf(indexfile,PATH_MAX,"%s_index.inc",configtag->html_dir); 897 snprintf(indexfile,PATH_MAX,"%s_index.inc",configtag->html_dir);
898 if ((findexout[0] = fopen(indexfile, "w")) == NULL) { 898 if ((findexout[0] = fopen(indexfile, "w")) == NULL) {
899 perror(indexfile); 899 perror(indexfile);
900 return 1; 900 return 1;
901 } 901 }
902 902
903 /* open arch specific SRPM index files */ 903 /* open arch specific SRPM index files */
904 for (arch = 0; arch < ARCHS_MAX; arch++) { 904 for (arch = 0; arch < ARCHS_MAX; arch++) {
905 if (configtag->arch[arch]) { 905 if (configtag->arch[arch]) {
906 snprintf(indexfile,PATH_MAX,"%s_index-%s.inc",configtag->html_dir,configtag->arch[arch]); 906 snprintf(indexfile,PATH_MAX,"%s_index-%s.inc",configtag->html_dir,configtag->arch[arch]);
907 if ((findexout[arch+1] = fopen(indexfile, "w")) == NULL) { 907 if ((findexout[arch+1] = fopen(indexfile, "w")) == NULL) {
908 perror(indexfile); 908 perror(indexfile);
909 return 1; 909 return 1;
910 } 910 }
911 } else { 911 } else {
912 findexout[arch+1] = NULL; 912 findexout[arch+1] = NULL;
913 } 913 }
914 } 914 }
915 915
916 for (arch = 0; arch < ARCHS_MAX + 1 && findexout[arch]; arch++) { 916 for (arch = 0; arch < ARCHS_MAX + 1 && findexout[arch]; arch++) {
917 fprintf(findexout[arch], 917 fprintf(findexout[arch],
918 "<h1><b>%s</b> - %s</h1>\n", 918 "<h1><b>%s</b> - %s</h1>\n",
919 configtag->tag, 919 configtag->tag,
920 configtag->description); 920 configtag->description);
921 if (configtag->repository_level > 0) { 921 if (configtag->repository_level > 0) {
922 fprintf(findexout[arch],"<h2>Depends on:</h2> "); 922 fprintf(findexout[arch],"<h2>Depends on:</h2> ");
923 for (c=0; c < configtag->repository_level; c++) { 923 for (c=0; c < configtag->repository_level; c++) {
924 fprintf(findexout[arch],"<a href=\"%stag=%s\">%s</a>&nbsp;- %s<br>", 924 fprintf(findexout[arch],"<a href=\"%stag=%s\">%s</a>&nbsp;- %s<br>",
925 configtag->configdefaults->url_prefix, 925 configtag->configdefaults->url_prefix,
926 configtag->repository[c]->tag, 926 configtag->repository[c]->tag,
927 configtag->repository[c]->tag, 927 configtag->repository[c]->tag,
928 configtag->repository[c]->description); 928 configtag->repository[c]->description);
929 } 929 }
930 fprintf(findexout[arch],"\n"); 930 fprintf(findexout[arch],"\n");
931 } 931 }
932 fprintf(findexout[arch], 932 fprintf(findexout[arch],
933 "<br><h2>List of packages:</h2>\n[ "); 933 "<br><h2>List of packages:</h2>\n[ ");
934 // <th width=18></th><th nowrap align=left><b>Source</b></th><th nowrap align=left><b>Release</b></th><th width=100%% nowrap align=left><b>Builds</b></th></tr>\n"); 934 // <th width=18></th><th nowrap align=left><b>Source</b></th><th nowrap align=left><b>Release</b></th><th width=100%% nowrap align=left><b>Builds</b></th></tr>\n");
935 935
936 for (c='a'; c <= 'z'; c++) { 936 for (c='a'; c <= 'z'; c++) {
937 fprintf(findexout[arch],"<a href=\"#%c\">%c</a>&nbsp;&nbsp;",c,c); 937 fprintf(findexout[arch],"<a href=\"#%c\">%c</a>&nbsp;&nbsp;",c,c);
938 } 938 }
939 fprintf(findexout[arch]," ]<br><br><table>\n"); 939 fprintf(findexout[arch]," ]<br><br><table>\n");
940 } 940 }
941 941
942 currheadersourcelist = configtag->headersourcelist; 942 currheadersourcelist = configtag->headersourcelist;
943 943
944 while (currheadersourcelist) { 944 while (currheadersourcelist) {
945 if ((configtag->repository_level == 0) || 945 if ((configtag->repository_level == 0) ||
946 (currheadersourcelist->altrepository == configtag->repository_level)) { 946 (currheadersourcelist->altrepository == configtag->repository_level)) {
947 947
948 curr_letter=currheadersourcelist->name[0]; 948 curr_letter=currheadersourcelist->name[0];
949 if (curr_letter >= 'A' && curr_letter <= 'Z') curr_letter=curr_letter+'a'-'A'; 949 if (curr_letter >= 'A' && curr_letter <= 'Z') curr_letter=curr_letter+'a'-'A';
950 950
951 snprintf(htmlfile,PATH_MAX,"%spackages/%s.source.inc",configtag->html_dir,currheadersourcelist->name); 951 snprintf(htmlfile,PATH_MAX,"%spackages/%s.source.inc",configtag->html_dir,currheadersourcelist->name);
952 952
953 if ((fout = fopen(htmlfile, "w")) == NULL) { 953 if ((fout = fopen(htmlfile, "w")) == NULL) {
954 perror(htmlfile); 954 perror(htmlfile);
955 return 1; 955 return 1;
956 } 956 }
957 957
958 get_favicon_from_url(currheadersourcelist->url, buffer2, PATH_MAX); 958 get_favicon_from_url(currheadersourcelist->url, buffer2, PATH_MAX);
959 959
960 fprintf(fout, 960 fprintf(fout,
961 "<h1><img src=\"%s\" width=\"16\" height=\"16\">" 961 "<h1><img src=\"%s\" width=\"16\" height=\"16\">"
962 "&nbsp;%s: %s (source)</h1><table class=\"pkgpage\" width=\"100%%\">\n", 962 "&nbsp;%s: %s (source)</h1><table class=\"pkgpage\" width=\"100%%\">\n",
963 buffer2, 963 buffer2,
964 currheadersourcelist->name, 964 currheadersourcelist->name,
965 htmlclean(currheadersourcelist->summary,buffer,PATH_MAX)); 965 htmlclean(currheadersourcelist->summary,buffer,PATH_MAX));
966 966
967 fprintf(fout,"<p>"); 967 fprintf(fout,"<p>");
968 printHTMLWarnings(fout,configtag,currheadersourcelist,1); 968 printHTMLWarnings(fout,configtag,currheadersourcelist,1);
969 969
970 fprintf(fout, 970 fprintf(fout,
971 "<tr><td width=\"25%%\">Name:</td><td><b>%s</b></td></tr>\n", 971 "<tr><td width=\"25%%\">Name:</td><td><b>%s</b></td></tr>\n",
972 currheadersourcelist->name); 972 currheadersourcelist->name);
973 if (currheadersourcelist->epoch > 0) { 973 if (currheadersourcelist->epoch > 0) {
974 fprintf(fout, 974 fprintf(fout,
975 "<tr><td>Release:</td><td><b>%ld:%s-%s</b></td></tr>\n", 975 "<tr><td>Release:</td><td><b>%ld:%s-%s</b></td></tr>\n",
976 currheadersourcelist->epoch, 976 currheadersourcelist->epoch,
977 currheadersourcelist->version, 977 currheadersourcelist->version,
978 currheadersourcelist->release); 978 currheadersourcelist->release);
979 } else { 979 } else {
980 fprintf(fout, 980 fprintf(fout,
981 "<tr><td>Release:</td><td><b>%s-%s</b></td></tr>\n", 981 "<tr><td>Release:</td><td><b>%s-%s</b></td></tr>\n",
982 currheadersourcelist->version, 982 currheadersourcelist->version,
983 currheadersourcelist->release); 983 currheadersourcelist->release);
984 } 984 }
985 /* fprintf(fout, 985 /* fprintf(fout,
986 "<tr><td>Summary:</td><td><b>%s</b></td></tr>\n", 986 "<tr><td>Summary:</td><td><b>%s</b></td></tr>\n",
987 htmlclean(currheadersourcelist->summary,buffer,PATH_MAX));*/ 987 htmlclean(currheadersourcelist->summary,buffer,PATH_MAX));*/
988 fprintf(fout, 988 fprintf(fout,
989 "<tr><td>Group:</td><td><a href=\"%stag=%s&amp;group=%s\">%s</a></td></tr>\n", 989 "<tr><td>Group:</td><td><a href=\"%stag=%s&amp;group=%s\">%s</a></td></tr>\n",
990 configtag->configdefaults->url_prefix, 990 configtag->configdefaults->url_prefix,
991 configtag->tag, 991 configtag->tag,
992 groupdirname(currheadersourcelist->group, buffer2, PATH_MAX), 992 groupdirname(currheadersourcelist->group, buffer2, PATH_MAX),
993 htmlclean(currheadersourcelist->group,buffer,PATH_MAX)); 993 htmlclean(currheadersourcelist->group,buffer,PATH_MAX));
994 994
995 fprintf(fout, 995 fprintf(fout,
996 "<tr><td>Maintainer:</td><td>"); 996 "<tr><td>Maintainer:</td><td>");
997 997
998 if (currheadersourcelist->packager && 998 if (currheadersourcelist->packager &&
999 (currheadersourcelist->packager->role & PACKAGER_ROLE_MAINTAINER)) { 999 (currheadersourcelist->packager->role & PACKAGER_ROLE_MAINTAINER)) {
1000 fprintf(fout, 1000 fprintf(fout,
1001 "<a href=\"%stag=%s&amp;maintainer=%s\">%s</a></td></tr>\n", 1001 "<a href=\"%stag=%s&amp;maintainer=%s\">%s</a></td></tr>\n",
1002 configtag->configdefaults->url_prefix, 1002 configtag->configdefaults->url_prefix,
1003 configtag->tag, 1003 configtag->tag,
1004 currheadersourcelist->packager->name, 1004 currheadersourcelist->packager->name,
1005 currheadersourcelist->packager->name); 1005 currheadersourcelist->packager->name);
1006 // currheadersourcelist->packager->packages_count++; 1006 // currheadersourcelist->packager->packages_count++;
1007 } else 1007 } else
1008 fprintf(fout, 1008 fprintf(fout,
1009 "<a href=\"%stag=%s&amp;maintainer=unmaintained\"><b>unmaintained</b></a></td></tr>\n", 1009 "<a href=\"%stag=%s&amp;maintainer=unmaintained\"><b>unmaintained</b></a></td></tr>\n",
1010 configtag->configdefaults->url_prefix, 1010 configtag->configdefaults->url_prefix,
1011 configtag->tag); 1011 configtag->tag);
1012 1012
1013 fprintf(fout, 1013 fprintf(fout,
1014 "<tr><td>Description:</td><td><font size=\"-1\">%s</font></td></tr>\n", 1014 "<tr><td>Description:</td><td><font size=\"-1\">%s</font></td></tr>\n",
1015 htmlclean(currheadersourcelist->description,buffer,PATH_MAX)); 1015 htmlclean(currheadersourcelist->description,buffer,PATH_MAX));
1016 fprintf(fout, 1016 fprintf(fout,
1017 "<tr><td>License:</td><td><font size=\"-1\">%s</font></td></tr>\n", 1017 "<tr><td>License:</td><td><font size=\"-1\">%s</font></td></tr>\n",
1018 currheadersourcelist->license); 1018 currheadersourcelist->license);
1019 fprintf(fout, 1019 fprintf(fout,
1020 "<tr><td>Size:</td><td><font size=\"-1\">%s</font></td></tr>\n", 1020 "<tr><td>Size:</td><td><font size=\"-1\">%s</font></td></tr>\n",
1021 humanSize(currheadersourcelist->size, &strsize)); 1021 humanSize(currheadersourcelist->size, &strsize));
1022 1022
1023 if (configtag->download_prefix) { 1023 if (configtag->download_prefix) {
1024 1024
1025 fprintf(fout,"<tr><td>Download:</td><td><font size=\"-1\">"); 1025 fprintf(fout,"<tr><td>Download:</td><td><font size=\"-1\">");
1026 1026
1027 fprintf(fout,"<a href=\"%s%s/SRPMS.base/%s-%s-%s.src.rpm\">%s-%s-%s.src.rpm</a>", 1027 fprintf(fout,"<a href=\"%s%s/SRPMS.base/%s-%s-%s.src.rpm\">%s-%s-%s.src.rpm</a>",
1028 configtag->download_prefix, 1028 configtag->download_prefix,
1029 configtag->download_dir, 1029 configtag->download_dir,
1030 currheadersourcelist->name, 1030 currheadersourcelist->name,
1031 currheadersourcelist->version, 1031 currheadersourcelist->version,
1032 currheadersourcelist->release, 1032 currheadersourcelist->release,
1033 currheadersourcelist->name, 1033 currheadersourcelist->name,
1034 currheadersourcelist->version, 1034 currheadersourcelist->version,
1035 currheadersourcelist->release); 1035 currheadersourcelist->release);
1036 fprintf(fout,"</font></td></tr>\n"); 1036 fprintf(fout,"</font></td></tr>\n");
1037 } 1037 }
1038 1038
1039 if (currheadersourcelist->url) 1039 if (currheadersourcelist->url)
1040 fprintf(fout, 1040 fprintf(fout,
1041 "<tr><td>URL:</td><td><font size=\"-1\"><a href=\"%s\" target=\"_new\">%s</a></font></td></tr>\n", 1041 "<tr><td>URL:</td><td><font size=\"-1\"><a href=\"%s\" target=\"_new\">%s</a></font></td></tr>\n",
1042 currheadersourcelist->url, 1042 currheadersourcelist->url,
1043 currheadersourcelist->url); 1043 currheadersourcelist->url);
1044 1044
1045 fprintf(fout, 1045 fprintf(fout,
1046 "<tr><td>Specfile:</td><td><font size=\"-1\"><a href=\"%s%s/specs/%s.spec\">%s.spec</a>", 1046 "<tr><td>Specfile:</td><td><font size=\"-1\"><a href=\"%s%s/specs/%s.spec\">%s.spec</a>",
1047 configtag->showfile_prefix, 1047 configtag->showfile_prefix,
1048 configtag->download_dir, 1048 configtag->download_dir,
1049 currheadersourcelist->name, 1049 currheadersourcelist->name,
1050 currheadersourcelist->name); 1050 currheadersourcelist->name);
1051 1051
1052 if (currheadersourcelist->source) { 1052 if (currheadersourcelist->source) {
1053 fprintf(fout,"<tr><td>Sources:</td><td><font size=\"-1\">"); 1053 fprintf(fout,"<tr><td>Sources:</td><td><font size=\"-1\">");
1054 1054
1055 i=0; 1055 i=0;
1056 while (currheadersourcelist->source[i+1]) i++; 1056 while (currheadersourcelist->source[i+1]) i++;
1057 1057
1058 for (; i>=0; i--) 1058 for (; i>=0; i--)
1059 fprintf(fout,"%s ",currheadersourcelist->source[i]); 1059 fprintf(fout,"%s ",currheadersourcelist->source[i]);
1060 1060
1061 fprintf(fout,"</font></td></tr>\n"); 1061 fprintf(fout,"</font></td></tr>\n");
1062 } 1062 }
1063 1063
1064 if (currheadersourcelist->patch) { 1064 if (currheadersourcelist->patch) {
1065 fprintf(fout,"<tr><td>Patches:</td><td><font size=\"-1\">"); 1065 fprintf(fout,"<tr><td>Patches:</td><td><font size=\"-1\">");
1066 1066
1067 i=0; 1067 i=0;
1068 while (currheadersourcelist->patch[i+1]) i++; 1068 while (currheadersourcelist->patch[i+1]) i++;
1069 1069
1070 for (; i>=0; i--) 1070 for (; i>=0; i--)
1071 // fprintf(fout,"%s ",currheadersourcelist->patch[i]); 1071 // fprintf(fout,"%s ",currheadersourcelist->patch[i]);
1072 fprintf(fout,"<a href=\"%s%s/patches/%s\">%s</a>&nbsp;", 1072 fprintf(fout,"<a href=\"%s%s/patches/%s\">%s</a>&nbsp;",
1073 configtag->showfile_prefix, 1073 configtag->showfile_prefix,
1074 configtag->download_dir, 1074 configtag->download_dir,
1075 currheadersourcelist->patch[i], 1075 currheadersourcelist->patch[i],
1076 currheadersourcelist->patch[i]); 1076 currheadersourcelist->patch[i]);
1077 1077
1078 fprintf(fout,"</font></td></tr>\n"); 1078 fprintf(fout,"</font></td></tr>\n");
1079 } 1079 }
1080 1080
1081 fprintf(fout, 1081 fprintf(fout,
1082 "<tr><td>Build time:</td><td><font size=\"-1\">%s</font></td></tr>\n", 1082 "<tr><td>Build time:</td><td><font size=\"-1\">%s</font></td></tr>\n",
1083 *simpleTimeToHuman(currheadersourcelist->buildtime, 1083 *simpleTimeToHuman(currheadersourcelist->buildtime,
1084 & strdate)); 1084 & strdate));
1085 1085
1086 for (idx = 0; idx < ARCHS_MAX + 1; idx++) { 1086 for (idx = 0; idx < ARCHS_MAX + 1; idx++) {
1087 if ((idx > 0) && ((!configtag->arch[idx-1]) || (!currheadersourcelist->firstchild[idx-1]))) continue; 1087 if ((idx > 0) && ((!configtag->arch[idx-1]) || (!currheadersourcelist->firstchild[idx-1]))) continue;
1088 if (curr_anchor < curr_letter) { 1088 if (curr_anchor < curr_letter) {
1089 fprintf(findexout[idx],"<tr><td>"); 1089 fprintf(findexout[idx],"<tr><td>");
1090 while (curr_anchor < curr_letter) { 1090 while (curr_anchor < curr_letter) {
1091 curr_anchor += 1; 1091 curr_anchor += 1;
1092 fprintf(findexout[idx],"<a name=\"%c\"></a>",curr_anchor); 1092 fprintf(findexout[idx],"<a name=\"%c\"></a>",curr_anchor);
1093 } 1093 }
1094 fprintf(findexout[idx],"</td></tr>"); 1094 fprintf(findexout[idx],"</td></tr>");
1095 } 1095 }
1096 fprintf(findexout[idx],"<tr><td>"); 1096 fprintf(findexout[idx],"<tr><td>");
1097 printpkgicon(findexout[idx], configtag, currheadersourcelist); 1097 printpkgicon(findexout[idx], configtag, currheadersourcelist);
1098 fprintf(findexout[idx],"</td><td><b>%s</b>: <i>%s</i>",currheadersourcelist->name,htmlclean(currheadersourcelist->summary,buffer,PATH_MAX)); 1098 fprintf(findexout[idx],"</td><td><b>%s</b>: <i>%s</i>",currheadersourcelist->name,htmlclean(currheadersourcelist->summary,buffer,PATH_MAX));
1099 st=strstr(currheadersourcelist->url,"://"); 1099 st=strstr(currheadersourcelist->url,"://");
1100 if (st) { 1100 if (st) {
1101 strncpy(buffer,st+3,PATH_MAX); 1101 strncpy(buffer,st+3,PATH_MAX);
1102 st=strchr(buffer,'/'); 1102 st=strchr(buffer,'/');
1103 if (st) st[0]='\0'; 1103 if (st) st[0]='\0';
1104 fprintf(findexout[idx], 1104 fprintf(findexout[idx],
1105 " <a href=\"%s\" target=\"_new\"><img src=\"%s/external.png\" title=\"%s\" ></a>", 1105 " <a href=\"%s\" target=\"_new\"><img src=\"%s/external.png\" title=\"%s\" ></a>",
1106 currheadersourcelist->url, 1106 currheadersourcelist->url,
1107 configtag->configdefaults->url_dir, 1107 configtag->configdefaults->url_dir,
1108 buffer); 1108 buffer);
1109 } 1109 }
1110 fprintf(findexout[idx],"</td></tr><tr><td></td><td><i>"); 1110 fprintf(findexout[idx],"</td></tr><tr><td></td><td><i>");
1111 1111
1112 if (currheadersourcelist->epoch) { 1112 if (currheadersourcelist->epoch) {
1113 fprintf(findexout[idx],"%ld:%s-%s", 1113 fprintf(findexout[idx],"%ld:%s-%s",
1114 currheadersourcelist->epoch, 1114 currheadersourcelist->epoch,
1115 currheadersourcelist->version, 1115 currheadersourcelist->version,
1116 currheadersourcelist->release); 1116 currheadersourcelist->release);
1117 1117
1118 } else { 1118 } else {
1119 fprintf(findexout[idx], 1119 fprintf(findexout[idx],
1120 "%s-%s", 1120 "%s-%s",
1121 currheadersourcelist->version, 1121 currheadersourcelist->version,
1122 currheadersourcelist->release); 1122 currheadersourcelist->release);
1123 } 1123 }
1124 1124
1125 fprintf(findexout[idx]," - "); 1125 fprintf(findexout[idx]," - ");
1126 } 1126 }
1127 1127
1128 fprintf(fout,"<tr><td>Built RPMS:</td><td><font size=\"-1\">"); 1128 fprintf(fout,"<tr><td>Built RPMS:</td><td><font size=\"-1\">");
1129 for (arch = 0; arch < ARCHS_MAX && configtag->arch[arch]; arch++) { 1129 for (arch = 0; arch < ARCHS_MAX && configtag->arch[arch]; arch++) {
1130 /* write children to both fout and findexout */ 1130 /* write children to both fout and findexout */
1131 currchild = currheadersourcelist->firstchild[arch]; 1131 currchild = currheadersourcelist->firstchild[arch];
1132 1132
1133 c = 0; 1133 c = 0;
1134 while (currchild) { 1134 while (currchild) {
1135 for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) { 1135 for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) {
1136 if ((idx > 0) && ((!configtag->arch[idx-1]) || (arch != idx -1))) continue; 1136 if ((idx > 0) && ((!configtag->arch[idx-1]) || (arch != idx -1))) continue;
1137 fprintf(findexout[idx], 1137 fprintf(findexout[idx],
1138 "<a href=\"%stag=%s&amp;pkg=%s.%s\">%s(%s)</a><a href=\"apt:%s\"><img src=\"%s/pkg.png\" title=\"Install\" ></a> ", 1138 "<a href=\"%stag=%s&amp;pkg=%s.%s\">%s(%s)</a><a href=\"apt:%s\"><img src=\"%s/pkg.png\" title=\"Install\" ></a> ",
1139 configtag->configdefaults->url_prefix, 1139 configtag->configdefaults->url_prefix,
1140 configtag->tag, currchild->name, configtag->arch[arch], 1140 configtag->tag, currchild->name, configtag->arch[arch],
1141 currchild->name, configtag->arch[arch], 1141 currchild->name, configtag->arch[arch],
1142 currchild->name, 1142 currchild->name,
1143 configtag->configdefaults->url_dir); 1143 configtag->configdefaults->url_dir);
1144 } 1144 }
1145 fprintf(fout, 1145 fprintf(fout,
1146 "<a href=\"%stag=%s&amp;pkg=%s.%s\">%s(%s)</a> ", 1146 "<a href=\"%stag=%s&amp;pkg=%s.%s\">%s(%s)</a> ",
1147 configtag->configdefaults->url_prefix, 1147 configtag->configdefaults->url_prefix,
1148 configtag->tag, currchild->name, configtag->arch[arch], 1148 configtag->tag, currchild->name, configtag->arch[arch],
1149 currchild->name, configtag->arch[arch]); 1149 currchild->name, configtag->arch[arch]);
1150 1150
1151 currchild = currchild->nextbrother; 1151 currchild = currchild->nextbrother;
1152 c++; 1152 c++;
1153 } 1153 }
1154 } 1154 }
1155 fprintf(fout, "</font></td></tr>\n"); 1155 fprintf(fout, "</font></td></tr>\n");
1156 1156
1157 for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) { 1157 for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) {
1158 if ((idx > 0) && ((!configtag->arch[idx-1]) || (!currheadersourcelist->firstchild[idx-1]))) continue; 1158 if ((idx > 0) && ((!configtag->arch[idx-1]) || (!currheadersourcelist->firstchild[idx-1]))) continue;
1159 fprintf(findexout[idx], 1159 fprintf(findexout[idx],
1160 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s(source)</a></td></tr><tr><td colspan=2><hr></td></tr>\n", 1160 "<a href=\"%stag=%s&amp;pkg=%s.source\">%s(source)</a></td></tr><tr><td colspan=2><hr></td></tr>\n",
1161 configtag->configdefaults->url_prefix, 1161 configtag->configdefaults->url_prefix,
1162 configtag->tag, 1162 configtag->tag,
1163 currheadersourcelist->name, 1163 currheadersourcelist->name,
1164 currheadersourcelist->name); 1164 currheadersourcelist->name);
1165 } 1165 }
1166 1166
1167 /* list build requirements */ 1167 /* list build requirements */
1168 fprintf(fout, "<tr><td nowrap>Build requirements:</td><td><font size=\"-1\">"); 1168 fprintf(fout, "<tr><td nowrap>Build requirements:</td><td><font size=\"-1\">");
1169 1169
1170 for (i = 0; i < currheadersourcelist->requirecount; i++) { 1170 for (i = 0; i < currheadersourcelist->requirecount; i++) {
1171 if (currheadersourcelist->require[i]->resolved) { 1171 if (currheadersourcelist->require[i]->resolved) {
1172 if (currheadersourcelist->require[i]->resolved->numbuildproviders == 0) { 1172 if (currheadersourcelist->require[i]->resolved->numbuildproviders == 0) {
1173 // missing provider 1173 // missing provider
1174 fprintf(fout,"<b>%s(unresolved)</b>",currheadersourcelist->require[i]->resolved->name); 1174 fprintf(fout,"<b>%s(unresolved)</b>",currheadersourcelist->require[i]->resolved->name);
1175 } else if (currheadersourcelist->require[i]->resolved->numbuildproviders == 1) { 1175 } else if (currheadersourcelist->require[i]->resolved->numbuildproviders == 1) {
1176 // single provider 1176 // single provider
1177 if ((i == 0 || 1177 if ((i == 0 ||
1178 strcmp(currheadersourcelist->require[i-1]->name, 1178 strcmp(currheadersourcelist->require[i-1]->name,
1179 currheadersourcelist->require[i]->name)) && 1179 currheadersourcelist->require[i]->name)) &&
1180 strcmp(currheadersourcelist->name, 1180 strcmp(currheadersourcelist->name,
1181 currheadersourcelist->require[i]->name)) { 1181 currheadersourcelist->require[i]->name)) {
1182 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>", 1182 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>",
1183 configtag->configdefaults->url_prefix, 1183 configtag->configdefaults->url_prefix,
1184 configtag->repository[currheadersourcelist->require[i]->resolved->buildprovider[0]->altrepository]->tag, 1184 configtag->repository[currheadersourcelist->require[i]->resolved->buildprovider[0]->altrepository]->tag,
1185 currheadersourcelist->require[i]->resolved->name, 1185 currheadersourcelist->require[i]->resolved->name,
1186 configtag->arch[0], 1186 configtag->arch[0],
1187 currheadersourcelist->require[i]->resolved->name); 1187 currheadersourcelist->require[i]->resolved->name);
1188 if ((configtag->repository_level > 0) && 1188 if ((configtag->repository_level > 0) &&
1189 currheadersourcelist->require[i]->resolved->buildprovider[0]->sourceheader && 1189 currheadersourcelist->require[i]->resolved->buildprovider[0]->sourceheader &&
1190 (currheadersourcelist->require[i]->resolved->buildprovider[0]->altrepository == configtag->repository_level)) { 1190 (currheadersourcelist->require[i]->resolved->buildprovider[0]->altrepository == configtag->repository_level)) {
1191 snprintf(buffer, PATH_MAX, "has build requirement %s which is only provided in this repository", 1191 snprintf(buffer, PATH_MAX, "has build requirement %s which is only provided in this repository",
1192 currheadersourcelist->require[i]->resolved->name); 1192 currheadersourcelist->require[i]->resolved->name);
1193 addWarning(currheadersourcelist, buffer); 1193 addWarning(currheadersourcelist, buffer);
1194 } 1194 }
1195 } 1195 }
1196 } else { 1196 } else {
1197 // multiple providers 1197 // multiple providers
1198 if (i == 0 || 1198 if (i == 0 ||
1199 strcmp(currheadersourcelist->require[i-1]->resolved->name, 1199 strcmp(currheadersourcelist->require[i-1]->resolved->name,
1200 currheadersourcelist->require[i]->resolved->name)) 1200 currheadersourcelist->require[i]->resolved->name))
1201 fprintf(fout,"<i>%s</i>(",currheadersourcelist->require[i]->resolved->name); 1201 fprintf(fout,"<i>%s</i>(",currheadersourcelist->require[i]->resolved->name);
1202 for (j = 0; j < currheadersourcelist->require[i]->resolved->numbuildproviders; j++) { 1202 for (j = 0; j < currheadersourcelist->require[i]->resolved->numbuildproviders; j++) {
1203 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>", 1203 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>",
1204 configtag->configdefaults->url_prefix, 1204 configtag->configdefaults->url_prefix,
1205 configtag->repository[currheadersourcelist->require[i]->resolved->buildprovider[j]->altrepository]->tag, 1205 configtag->repository[currheadersourcelist->require[i]->resolved->buildprovider[j]->altrepository]->tag,
1206 currheadersourcelist->require[i]->resolved->buildprovider[j]->name, 1206 currheadersourcelist->require[i]->resolved->buildprovider[j]->name,
1207 configtag->arch[0], 1207 configtag->arch[0],
1208 currheadersourcelist->require[i]->resolved->buildprovider[j]->name); 1208 currheadersourcelist->require[i]->resolved->buildprovider[j]->name);
1209 if (j+1 < currheadersourcelist->require[i]->resolved->numbuildproviders) fprintf(fout,"|"); 1209 if (j+1 < currheadersourcelist->require[i]->resolved->numbuildproviders) fprintf(fout,"|");
1210 } 1210 }
1211 fprintf(fout,")"); 1211 fprintf(fout,")");
1212 } // if numproviders 1212 } // if numproviders
1213 if (currheadersourcelist->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { 1213 if (currheadersourcelist->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) {
1214 fprintf(fout,"["); 1214 fprintf(fout,"[");
1215 if (currheadersourcelist->require[i]->flags & RPMSENSE_LESS) fprintf(fout, "<"); 1215 if (currheadersourcelist->require[i]->flags & RPMSENSE_LESS) fprintf(fout, "<");
1216 if (currheadersourcelist->require[i]->flags & RPMSENSE_GREATER) fprintf(fout, ">"); 1216 if (currheadersourcelist->require[i]->flags & RPMSENSE_GREATER) fprintf(fout, ">");
1217 if (currheadersourcelist->require[i]->flags & RPMSENSE_EQUAL) fprintf(fout, "="); 1217 if (currheadersourcelist->require[i]->flags & RPMSENSE_EQUAL) fprintf(fout, "=");
1218 fprintf(fout, "%s", currheadersourcelist->require[i]->version); 1218 fprintf(fout, "%s", currheadersourcelist->require[i]->version);
1219 fprintf(fout,"]"); 1219 fprintf(fout,"]");
1220 } 1220 }
1221 fprintf(fout," "); 1221 fprintf(fout," ");
1222 } // if required 1222 } // if required
1223 } // for 1223 } // for
1224 fprintf(fout, "</font></td></tr>\n"); 1224 fprintf(fout, "</font></td></tr>\n");
1225 1225
1226 /* print changelog to fout */ 1226 /* print changelog to fout */
1227 fprintf(fout, 1227 fprintf(fout,
1228 "<tr><td>Changelog:</td><td><font size=\"-1\" face=\"Courier,Courier New,monospace\">"); 1228 "<tr><td>Changelog:</td><td><font size=\"-1\" face=\"Courier,Courier New,monospace\">");
1229 1229
1230 currchangelog = currheadersourcelist->changelog; 1230 currchangelog = currheadersourcelist->changelog;
1231 1231
1232 while (currchangelog) { 1232 while (currchangelog) {
1233 // changelog_total++; 1233 // changelog_total++;
1234 simpleTimeToHuman(currchangelog->time, 1234 simpleTimeToHuman(currchangelog->time,
1235 (humanDate *) & strdate); 1235 (humanDate *) & strdate);
1236 1236
1237 if (currchangelog->pkg) { 1237 if (currchangelog->pkg) {
1238 if ((currchangelog->pkg->role & PACKAGER_ROLE_MAINTAINER) && 1238 if ((currchangelog->pkg->role & PACKAGER_ROLE_MAINTAINER) &&
1239 (currchangelog->pkg->packages_count)) { 1239 (currchangelog->pkg->packages_count)) {
1240 fprintf(fout, "%s - <a href=\"%stag=%s&amp;maintainer=%s\">%s</a> (%s)<br>%s<br>", 1240 fprintf(fout, "%s - <a href=\"%stag=%s&amp;maintainer=%s\">%s</a> (%s)<br>%s<br>",
1241 &strdate[0], 1241 &strdate[0],
1242 configtag->configdefaults->url_prefix, 1242 configtag->configdefaults->url_prefix,
1243 configtag->tag, 1243 configtag->tag,
1244 currchangelog->pkg->name, 1244 currchangelog->pkg->name,
1245 currchangelog->pkg->name, 1245 currchangelog->pkg->name,
1246 currchangelog->release, 1246 currchangelog->release,
1247 htmlclean(currchangelog->text,buffer,PATH_MAX)); 1247 htmlclean(currchangelog->text,buffer,PATH_MAX));
1248 // currchangelog->pkg->changes_count++; 1248 // currchangelog->pkg->changes_count++;
1249 } else { 1249 } else {
1250 fprintf(fout, "%s - %s (%s)<br>%s<br>", 1250 fprintf(fout, "%s - %s (%s)<br>%s<br>",
1251 &strdate[0], 1251 &strdate[0],
1252 currchangelog->pkg->name, 1252 currchangelog->pkg->name,
1253 currchangelog->release, 1253 currchangelog->release,
1254 htmlclean(currchangelog->text,buffer,PATH_MAX)); 1254 htmlclean(currchangelog->text,buffer,PATH_MAX));
1255 // currchangelog->pkg->changes_count++; 1255 // currchangelog->pkg->changes_count++;
1256 } 1256 }
1257 } else 1257 } else
1258 fprintf(fout, "%s - (noname) (%s)<br>%s<br>", 1258 fprintf(fout, "%s - (noname) (%s)<br>%s<br>",
1259 &strdate[0], 1259 &strdate[0],
1260 currchangelog->release, 1260 currchangelog->release,
1261 htmlclean(currchangelog->text,buffer,PATH_MAX)); 1261 htmlclean(currchangelog->text,buffer,PATH_MAX));
1262 1262
1263 currchangelog = currchangelog->next; 1263 currchangelog = currchangelog->next;
1264 } 1264 }
1265 1265
1266 /* close fout */ 1266 /* close fout */
1267 fprintf(fout, "</font></td></tr></table>"); 1267 fprintf(fout, "</font></td></tr></table>");
1268 fclose(fout); 1268 fclose(fout);
1269 } 1269 }
1270 currheadersourcelist = currheadersourcelist->next; 1270 currheadersourcelist = currheadersourcelist->next;
1271 } 1271 }
1272 for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) { 1272 for (idx = 0; idx < ARCHS_MAX + 1 && findexout[idx]; idx++) {
1273 fprintf(findexout[idx], "</table>\n"); 1273 fprintf(findexout[idx], "</table>\n");
1274 fclose(findexout[idx]); 1274 fclose(findexout[idx]);
1275 } 1275 }
1276 return 0; 1276 return 0;
1277 } 1277 }
1278 1278
1279 static int 1279 static int
1280 htmlincselector(const struct dirent *entry) 1280 htmlincselector(const struct dirent *entry)
1281 { 1281 {
1282 char *ptr; 1282 char *ptr;
1283 1283
1284 ptr = strstr(entry->d_name, ".inc"); 1284 ptr = strstr(entry->d_name, ".inc");
1285 if (entry->d_type != DT_REG) return 0; /* skip if not a file */ 1285 if (entry->d_type != DT_REG) return 0; /* skip if not a file */
1286 if (ptr == NULL) { 1286 if (ptr == NULL) {
1287 return 0; 1287 return 0;
1288 } 1288 }
1289 return 1; 1289 return 1;
1290 } 1290 }
1291 1291
1292 int 1292 int
1293 cleanHTMLFilesInc(char* dir) 1293 cleanHTMLFilesInc(char* dir)
1294 { 1294 {
1295 int n,cnt,r; 1295 int n,cnt,r;
1296 struct dirent **namelist; 1296 struct dirent **namelist;
1297 const char* errstr; 1297 const char* errstr;
1298 char uf[PATH_MAX]; 1298 char uf[PATH_MAX];
1299 1299
1300 n = scansdir(dir, &namelist, htmlincselector, NULL); 1300 n = scansdir(dir, &namelist, htmlincselector, NULL);
1301 if (n < 0) { 1301 if (n < 0) {
1302 errstr = strerror(errno); 1302 errstr = strerror(errno);
1303 logmsg(LOG_ERROR, "cannot scan directory '%s' (%s)", dir, errstr); 1303 logmsg(LOG_ERROR, "cannot scan directory '%s' (%s)", dir, errstr);
1304 return 1; 1304 return 1;
1305 } 1305 }
1306 1306
1307 for (cnt = 0; cnt < n; ++cnt) { 1307 for (cnt = 0; cnt < n; ++cnt) {
1308 snprintf(uf,PATH_MAX,"%s/%s",dir,namelist[cnt]->d_name); 1308 snprintf(uf,PATH_MAX,"%s/%s",dir,namelist[cnt]->d_name);
1309 logmsg(LOG_DEBUG,"unlinking %s",uf); 1309 logmsg(LOG_DEBUG,"unlinking %s",uf);
1310 r=unlink(uf); 1310 r=unlink(uf);
1311 if (r < 0) { 1311 if (r < 0) {
1312 errstr = strerror(errno); 1312 errstr = strerror(errno);
1313 logmsg(LOG_WARNING, "cannot remove file '%s' (%s)", uf, errstr); 1313 logmsg(LOG_WARNING, "cannot remove file '%s' (%s)", uf, errstr);
1314 } 1314 }
1315 } 1315 }
1316 return 0; 1316 return 0;
1317 } 1317 }
1318 1318
1319 int 1319 int
1320 cleanHTMLPackagesFiles(struct configTag *ct) 1320 cleanHTMLPackagesFiles(struct configTag *ct)
1321 { 1321 {
1322 char dir[PATH_MAX]; 1322 char dir[PATH_MAX];
1323 1323
1324 snprintf(dir,PATH_MAX,"%spackages",ct->html_dir); 1324 snprintf(dir,PATH_MAX,"%spackages",ct->html_dir);
1325 if (cleanHTMLFilesInc(dir)) { 1325 if (cleanHTMLFilesInc(dir)) {
1326 logmsg(LOG_WARNING,"cannot clean %s directory",dir); 1326 logmsg(LOG_WARNING,"cannot clean %s directory",dir);
1327 } 1327 }
1328 return 0; 1328 return 0;
1329 } 1329 }
1330 1330
1331 int 1331 int
1332 cleanHTMLFiles(struct configTag *ct) 1332 cleanHTMLFiles(struct configTag *ct)
1333 { 1333 {
1334 int s; 1334 int s;
1335 char uf[PATH_MAX],dir[PATH_MAX]; 1335 char uf[PATH_MAX],dir[PATH_MAX];
1336 const char* clean_subdir[] = { "", "maintainers" }; 1336 const char* clean_subdir[] = { "", "maintainers" };
1337 struct headerSourceList *currheadersourcelist; 1337 struct headerSourceList *currheadersourcelist;
1338 struct stat buf; 1338 struct stat buf;
1339 1339
1340 for (s = 0; s < 2; s++) { 1340 for (s = 0; s < 2; s++) {
1341 snprintf(dir,PATH_MAX,"%s%s",ct->html_dir,clean_subdir[s]); 1341 snprintf(dir,PATH_MAX,"%s%s",ct->html_dir,clean_subdir[s]);
1342 if (cleanHTMLFilesInc(dir)) { 1342 if (cleanHTMLFilesInc(dir)) {
1343 logmsg(LOG_WARNING,"cannot clean %s directory",dir); 1343 logmsg(LOG_WARNING,"cannot clean %s directory",dir);
1344 } 1344 }
1345 } 1345 }
1346 1346
1347 currheadersourcelist = ct->headersourcelist; 1347 currheadersourcelist = ct->headersourcelist;
1348 while (currheadersourcelist) { 1348 while (currheadersourcelist) {
1349 snprintf(dir, PATH_MAX, "%sgroups/%s", 1349 snprintf(dir, PATH_MAX, "%sgroups/%s",
1350 ct->html_dir, 1350 ct->html_dir,
1351 groupdirname(currheadersourcelist->group,uf,PATH_MAX)); 1351 groupdirname(currheadersourcelist->group,uf,PATH_MAX));
1352 1352
1353 if (!stat(dir,&buf)) { 1353 if (!stat(dir,&buf)) {
1354 logmsg(LOG_DEBUG,"removing directory %s",dir); 1354 logmsg(LOG_DEBUG,"removing directory %s",dir);
1355 if (cleanHTMLFilesInc(dir)) { 1355 if (cleanHTMLFilesInc(dir)) {
1356 logmsg(LOG_ERROR,"cannot clean %s directory; aborting",dir); 1356 logmsg(LOG_ERROR,"cannot clean %s directory; aborting",dir);
1357 exit(1); 1357 exit(1);
1358 } 1358 }
1359 if (rmdir(dir)) { 1359 if (rmdir(dir)) {
1360 logmsg(LOG_ERROR,"cannot remove %s directory; aborting.",dir); 1360 logmsg(LOG_ERROR,"cannot remove %s directory; aborting.",dir);
1361 exit(1); 1361 exit(1);
1362 } 1362 }
1363 } 1363 }
1364 1364
1365 /* legacy: clean old group dirs */ 1365 /* legacy: clean old group dirs */
1366 snprintf(dir, PATH_MAX, "%s%s", 1366 snprintf(dir, PATH_MAX, "%s%s",
1367 ct->html_dir, 1367 ct->html_dir,
1368 groupdirname(currheadersourcelist->group,uf,PATH_MAX)); 1368 groupdirname(currheadersourcelist->group,uf,PATH_MAX));
1369 1369
1370 if (!stat(dir,&buf)) { 1370 if (!stat(dir,&buf)) {
1371 logmsg(LOG_DEBUG,"removing legacy directory %s",dir); 1371 logmsg(LOG_DEBUG,"removing legacy directory %s",dir);
1372 if (cleanHTMLFilesInc(dir)) { 1372 if (cleanHTMLFilesInc(dir)) {
1373 logmsg(LOG_ERROR,"cannot clean %s directory; aborting.",dir); 1373 logmsg(LOG_ERROR,"cannot clean %s directory; aborting.",dir);
1374 exit(1); 1374 exit(1);
1375 } 1375 }
1376 if (rmdir(dir)) { 1376 if (rmdir(dir)) {
1377 logmsg(LOG_ERROR,"cannot remove %s directory; aborting.",dir); 1377 logmsg(LOG_ERROR,"cannot remove %s directory; aborting.",dir);
1378 exit(1); 1378 exit(1);
1379 } 1379 }
1380 } 1380 }
1381 currheadersourcelist = currheadersourcelist->next; 1381 currheadersourcelist = currheadersourcelist->next;
1382 } 1382 }
1383 1383
1384 return 0; 1384 return 0;
1385 } 1385 }
1386 1386
1387 1387
1388 int 1388 int
1389 generateHTMLFiles(struct configTag *ct, int arch) 1389 generateHTMLFiles(struct configTag *ct, int arch)
1390 { 1390 {
1391 1391
1392 char buffer[PATH_MAX]; 1392 char buffer[PATH_MAX];
1393 char htmlfile[PATH_MAX]; 1393 char htmlfile[PATH_MAX];
1394 int i,j; 1394 int i,j;
1395 sizeString strsize; 1395 sizeString strsize;
1396 FILE *fout; 1396 FILE *fout;
1397 struct headerList *currheaderlist, *auxheaderlist; 1397 struct headerList *currheaderlist, *auxheaderlist;
1398 struct headerSourceList *auxheadersourcelist; 1398 struct headerSourceList *auxheadersourcelist;
1399 int found; 1399 int found;
1400 struct stat buf; 1400 struct stat buf;
1401 1401
1402 snprintf(buffer,PATH_MAX,"%spackages",ct->html_dir); 1402 snprintf(buffer,PATH_MAX,"%spackages",ct->html_dir);
1403 if (stat(buffer,&buf)) { 1403 if (stat(buffer,&buf)) {
1404 if (mkdir(buffer,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { 1404 if (mkdir(buffer,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1405 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",buffer); 1405 logmsg(LOG_ERROR,"cannot create %s directory; aborting.",buffer);
1406 exit(1); 1406 exit(1);
1407 } 1407 }
1408 } else { 1408 } else {
1409 if (!S_ISDIR(buf.st_mode)) { 1409 if (!S_ISDIR(buf.st_mode)) {
1410 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",buffer); 1410 logmsg(LOG_ERROR,"cannot create %s directory, a file with this name already exists; aborting.",buffer);
1411 exit(1); 1411 exit(1);
1412 } 1412 }
1413 } 1413 }
1414 1414
1415 currheaderlist = ct->headerlist[arch]; 1415 currheaderlist = ct->headerlist[arch];
1416 1416
1417 while (currheaderlist) { 1417 while (currheaderlist) {
1418 if ((ct->repository_level == 0) || 1418 if ((ct->repository_level == 0) ||
1419 ((currheaderlist->sourceheader) && 1419 ((currheaderlist->sourceheader) &&
1420 (currheaderlist->altrepository == ct->repository_level))) { 1420 (currheaderlist->altrepository == ct->repository_level))) {
1421 1421
1422 logmsg(LOG_DEBUG,"generating HTML pages for %s",currheaderlist->name); 1422 logmsg(LOG_DEBUG,"generating HTML pages for %s",currheaderlist->name);
1423 snprintf(htmlfile,PATH_MAX,"%spackages/%s.%s.inc",ct->html_dir,currheaderlist->name,ct->arch[arch]); 1423 snprintf(htmlfile,PATH_MAX,"%spackages/%s.%s.inc",ct->html_dir,currheaderlist->name,ct->arch[arch]);
1424 1424
1425 if ((fout = fopen(htmlfile, "w")) == NULL) { 1425 if ((fout = fopen(htmlfile, "w")) == NULL) {
1426 perror(htmlfile); 1426 perror(htmlfile);
1427 return 1; 1427 return 1;
1428 } 1428 }
1429 get_favicon_from_url(currheaderlist->sourceheader->url, buffer, PATH_MAX); 1429 get_favicon_from_url(currheaderlist->sourceheader->url, buffer, PATH_MAX);
1430 1430
1431 fprintf(fout, 1431 fprintf(fout,
1432 "<h1><img src=\"%s\" width=\"16\" height=\"16\">" 1432 "<h1><img src=\"%s\" width=\"16\" height=\"16\">"
1433 "&nbsp;%s: %s</h1><table class=\"pkgpage\" width=\"100%%\">", 1433 "&nbsp;%s: %s</h1><table class=\"pkgpage\" width=\"100%%\">",
1434 buffer, 1434 buffer,
1435 currheaderlist->name, 1435 currheaderlist->name,
1436 currheaderlist->summary); 1436 currheaderlist->summary);
1437 fprintf(fout, 1437 fprintf(fout,
1438 "<tr><td width=\"15%%\">Name:</td><td><b>%s</b></td></tr>\n", 1438 "<tr><td width=\"15%%\">Name:</td><td><b>%s</b></td></tr>\n",
1439 currheaderlist->name); 1439 currheaderlist->name);
1440 fprintf(fout, 1440 fprintf(fout,
1441 "<tr><td>Release:</td><td><b>%s-%s</b></td></tr>\n", 1441 "<tr><td>Release:</td><td><b>%s-%s</b></td></tr>\n",
1442 currheaderlist->version, currheaderlist->release); 1442 currheaderlist->version, currheaderlist->release);
1443 fprintf(fout, 1443 fprintf(fout,
1444 "<tr><td>Architecture:</td><td>%s</td></tr>\n", 1444 "<tr><td>Architecture:</td><td>%s</td></tr>\n",
1445 currheaderlist->arch); 1445 currheaderlist->arch);
1446 /* fprintf(fout, 1446 /* fprintf(fout,
1447 "<tr><td>Summary:</td><td><b>%s</b></td></tr>\n", 1447 "<tr><td>Summary:</td><td><b>%s</b></td></tr>\n",
1448 htmlclean(currheaderlist->summary,buffer,PATH_MAX));*/ 1448 htmlclean(currheaderlist->summary,buffer,PATH_MAX));*/
1449 fprintf(fout, 1449 fprintf(fout,
1450 "<tr><td>Group:</td><td>%s</td></tr>\n", 1450 "<tr><td>Group:</td><td>%s</td></tr>\n",
1451 htmlclean(currheaderlist->group,buffer,PATH_MAX)); 1451 htmlclean(currheaderlist->group,buffer,PATH_MAX));
1452 fprintf(fout, "<tr><td>Description:</td><td>%s</td></tr>\n", 1452 fprintf(fout, "<tr><td>Description:</td><td>%s</td></tr>\n",
1453 htmlclean(currheaderlist->description,buffer,PATH_MAX)); 1453 htmlclean(currheaderlist->description,buffer,PATH_MAX));
1454 fprintf(fout, 1454 fprintf(fout,
1455 "<tr><td>Size:</td><td><font size=\"-1\">%s</font></td></tr>\n", 1455 "<tr><td>Size:</td><td><font size=\"-1\">%s</font></td></tr>\n",
1456 humanSize(currheaderlist->size, &strsize)); 1456 humanSize(currheaderlist->size, &strsize));
1457 1457
1458 /* fprintf(fout, 1458 /* fprintf(fout,
1459 "<tr><td>Arch:</td><td><font size=\"-1\">%s</font></td></tr>\n", 1459 "<tr><td>Arch:</td><td><font size=\"-1\">%s</font></td></tr>\n",
1460 currheaderlist->arch);*/ 1460 currheaderlist->arch);*/
1461 1461
1462 if (ct->download_prefix) { 1462 if (ct->download_prefix) {
1463 1463
1464 fprintf(fout,"<tr><td>Download:</td><td><font size=\"-1\">"); 1464 fprintf(fout,"<tr><td>Download:</td><td><font size=\"-1\">");
1465 1465
1466 fprintf(fout,"<a href=\"%s%s/RPMS.%s/%s-%s-%s.%s.rpm\">%s-%s-%s.%s.rpm</a>", 1466 fprintf(fout,"<a href=\"%s%s/RPMS.%s/%s-%s-%s.%s.rpm\">%s-%s-%s.%s.rpm</a>",
1467 ct->download_prefix, 1467 ct->download_prefix,
1468 ct->download_dir, 1468 ct->download_dir,
1469 ct->arch[arch], 1469 ct->arch[arch],
1470 currheaderlist->name, 1470 currheaderlist->name,
1471 currheaderlist->version, 1471 currheaderlist->version,
1472 currheaderlist->release, 1472 currheaderlist->release,
1473 currheaderlist->arch, 1473 currheaderlist->arch,
1474 currheaderlist->name, 1474 currheaderlist->name,
1475 currheaderlist->version, 1475 currheaderlist->version,
1476 currheaderlist->release, 1476 currheaderlist->release,
1477 currheaderlist->arch); 1477 currheaderlist->arch);
1478 1478
1479 fprintf(fout,"</font></td></tr>\n"); 1479 fprintf(fout,"</font></td></tr>\n");
1480 } 1480 }
1481 1481
1482 if (currheaderlist->sourcename 1482 if (currheaderlist->sourcename
1483 && currheaderlist->sourceheader) { 1483 && currheaderlist->sourceheader) {
1484 fprintf(fout, 1484 fprintf(fout,
1485 "<tr><td>Source RPM:</td><td><font size=\"-1\"><a href=\"%stag=%s&amp;pkg=%s.source\">%s</a></font></td></tr>\n", 1485 "<tr><td>Source RPM:</td><td><font size=\"-1\"><a href=\"%stag=%s&amp;pkg=%s.source\">%s</a></font></td></tr>\n",
1486 ct->configdefaults->url_prefix, 1486 ct->configdefaults->url_prefix,
1487 ct->tag, 1487 ct->tag,
1488 currheaderlist->sourceheader->name, 1488 currheaderlist->sourceheader->name,
1489 currheaderlist->sourcename); 1489 currheaderlist->sourcename);
1490 } 1490 }
1491 1491
1492 /* list obsoletes */ 1492 /* list obsoletes */
1493 if (currheaderlist->obsoletecount > 0) { 1493 if (currheaderlist->obsoletecount > 0) {
1494 fprintf(fout, 1494 fprintf(fout,
1495 "<tr><td>Obsoletes:</td><td><font size=\"-1\">"); 1495 "<tr><td>Obsoletes:</td><td><font size=\"-1\">");
1496 for (i = 0; i < currheaderlist->obsoletecount; i++) { 1496 for (i = 0; i < currheaderlist->obsoletecount; i++) {
1497 fprintf(fout, "%s", currheaderlist->obsoletename[i]); 1497 fprintf(fout, "%s", currheaderlist->obsoletename[i]);
1498 if (currheaderlist->obsoleteflags[i] & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { 1498 if (currheaderlist->obsoleteflags[i] & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) {
1499 fprintf(fout, "["); 1499 fprintf(fout, "[");
1500 if (currheaderlist->obsoleteflags[i] & RPMSENSE_LESS) fprintf(fout, "<"); 1500 if (currheaderlist->obsoleteflags[i] & RPMSENSE_LESS) fprintf(fout, "<");
1501 if (currheaderlist->obsoleteflags[i] & RPMSENSE_GREATER) fprintf(fout, ">"); 1501 if (currheaderlist->obsoleteflags[i] & RPMSENSE_GREATER) fprintf(fout, ">");
1502 if (currheaderlist->obsoleteflags[i] & RPMSENSE_EQUAL) fprintf(fout, "="); 1502 if (currheaderlist->obsoleteflags[i] & RPMSENSE_EQUAL) fprintf(fout, "=");
1503 fprintf(fout, "%s]", currheaderlist->obsoleteversion[i]); 1503 fprintf(fout, "%s]", currheaderlist->obsoleteversion[i]);
1504 } 1504 }
1505 fprintf(fout," "); 1505 fprintf(fout," ");
1506 } 1506 }
1507 fprintf(fout, "</font></td></tr>\n"); 1507 fprintf(fout, "</font></td></tr>\n");
1508 } 1508 }
1509 1509
1510 /* list provides */ 1510 /* list provides */
1511 fprintf(fout, 1511 fprintf(fout,
1512 "<tr><td>Provides:</td><td><font size=\"-1\">"); 1512 "<tr><td>Provides:</td><td><font size=\"-1\">");
1513 for (i = 0; i < currheaderlist->providecount; i++) { 1513 for (i = 0; i < currheaderlist->providecount; i++) {
1514 fprintf(fout, "%s", currheaderlist->providename[i]); 1514 fprintf(fout, "%s", currheaderlist->providename[i]);
1515 if (currheaderlist->provideflags[i] & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { 1515 if (currheaderlist->provideflags[i] & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) {
1516 fprintf(fout, "["); 1516 fprintf(fout, "[");
1517 if (currheaderlist->provideflags[i] & RPMSENSE_LESS) fprintf(fout, "<"); 1517 if (currheaderlist->provideflags[i] & RPMSENSE_LESS) fprintf(fout, "<");
1518 if (currheaderlist->provideflags[i] & RPMSENSE_GREATER) fprintf(fout, ">"); 1518 if (currheaderlist->provideflags[i] & RPMSENSE_GREATER) fprintf(fout, ">");
1519 if (currheaderlist->provideflags[i] & RPMSENSE_EQUAL) fprintf(fout, "="); 1519 if (currheaderlist->provideflags[i] & RPMSENSE_EQUAL) fprintf(fout, "=");
1520 fprintf(fout, "%s]", currheaderlist->provideversion[i]); 1520 fprintf(fout, "%s]", currheaderlist->provideversion[i]);
1521 } 1521 }
1522 fprintf(fout," "); 1522 fprintf(fout," ");
1523 } 1523 }
1524 fprintf(fout, "</font></td></tr>\n"); 1524 fprintf(fout, "</font></td></tr>\n");
1525 1525
1526 /* list requires */ 1526 /* list requires */
1527 fprintf(fout, 1527 fprintf(fout,
1528 "<tr><td>Requires:</td><td><font size=\"-1\">"); 1528 "<tr><td>Requires:</td><td><font size=\"-1\">");
1529 for (i = 0; i < currheaderlist->requirecount; i++) { 1529 for (i = 0; i < currheaderlist->requirecount; i++) {
1530 if (currheaderlist->require[i]->resolved) { 1530 if (currheaderlist->require[i]->resolved) {
1531 if (currheaderlist->require[i]->resolved->numproviders == 0) { 1531 if (currheaderlist->require[i]->resolved->numproviders == 0) {
1532 // no provider 1532 // no provider
1533 fprintf(fout,"%s",currheaderlist->require[i]->resolved->name); 1533 fprintf(fout,"%s",currheaderlist->require[i]->resolved->name);
1534 } else if (currheaderlist->require[i]->resolved->numproviders == 1) { 1534 } else if (currheaderlist->require[i]->resolved->numproviders == 1) {
1535 // single provider 1535 // single provider
1536 if (currheaderlist->require[i]->resolved->provider[0]->sourceheader) { 1536 if (currheaderlist->require[i]->resolved->provider[0]->sourceheader) {
1537 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>", 1537 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>",
1538 ct->configdefaults->url_prefix, 1538 ct->configdefaults->url_prefix,
1539 ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag, 1539 ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag,
1540 currheaderlist->require[i]->resolved->provider[0]->name, 1540 currheaderlist->require[i]->resolved->provider[0]->name,
1541 ct->arch[arch], 1541 ct->arch[arch],
1542 currheaderlist->require[i]->resolved->name); 1542 currheaderlist->require[i]->resolved->name);
1543 } else { 1543 } else {
1544 fprintf(fout,"%s",currheaderlist->require[i]->resolved->name); 1544 fprintf(fout,"%s",currheaderlist->require[i]->resolved->name);
1545 } 1545 }
1546 } else { 1546 } else {
1547 // multiple providers 1547 // multiple providers
1548 logmsg(LOG_DEBUG,"Requirement %s has multiple providers",currheaderlist->require[i]->resolved->name); 1548 logmsg(LOG_DEBUG,"Requirement %s has multiple providers",currheaderlist->require[i]->resolved->name);
1549 fprintf(fout,"<i>%s</i>(",currheaderlist->require[i]->resolved->name); 1549 fprintf(fout,"<i>%s</i>(",currheaderlist->require[i]->resolved->name);
1550 for (j = 0; j < currheaderlist->require[i]->resolved->numproviders; j++) { 1550 for (j = 0; j < currheaderlist->require[i]->resolved->numproviders; j++) {
1551 if (currheaderlist->require[i]->resolved->provider[j]->sourceheader) 1551 if (currheaderlist->require[i]->resolved->provider[j]->sourceheader)
1552 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>", 1552 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>",
1553 ct->configdefaults->url_prefix, 1553 ct->configdefaults->url_prefix,
1554 ct->repository[currheaderlist->require[i]->resolved->provider[j]->altrepository]->tag, 1554 ct->repository[currheaderlist->require[i]->resolved->provider[j]->altrepository]->tag,
1555 currheaderlist->require[i]->resolved->provider[j]->name, 1555 currheaderlist->require[i]->resolved->provider[j]->name,
1556 ct->arch[arch], 1556 ct->arch[arch],
1557 currheaderlist->require[i]->resolved->provider[j]->name); 1557 currheaderlist->require[i]->resolved->provider[j]->name);
1558 else 1558 else
1559 fprintf(fout,"%s",currheaderlist->require[i]->resolved->provider[j]->name); 1559 fprintf(fout,"%s",currheaderlist->require[i]->resolved->provider[j]->name);
1560 if (j+1 < currheaderlist->require[i]->resolved->numproviders) fprintf(fout,"|"); 1560 if (j+1 < currheaderlist->require[i]->resolved->numproviders) fprintf(fout,"|");
1561 } 1561 }
1562 fprintf(fout,")"); 1562 fprintf(fout,")");
1563 } // if numproviders 1563 } // if numproviders
1564 if (currheaderlist->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) { 1564 if (currheaderlist->require[i]->flags & (RPMSENSE_LESS|RPMSENSE_GREATER|RPMSENSE_EQUAL)) {
1565 fprintf(fout,"["); 1565 fprintf(fout,"[");
1566 if (currheaderlist->require[i]->flags & RPMSENSE_LESS) fprintf(fout, "<"); 1566 if (currheaderlist->require[i]->flags & RPMSENSE_LESS) fprintf(fout, "<");
1567 if (currheaderlist->require[i]->flags & RPMSENSE_GREATER) fprintf(fout, ">"); 1567 if (currheaderlist->require[i]->flags & RPMSENSE_GREATER) fprintf(fout, ">");
1568 if (currheaderlist->require[i]->flags & RPMSENSE_EQUAL) fprintf(fout, "="); 1568 if (currheaderlist->require[i]->flags & RPMSENSE_EQUAL) fprintf(fout, "=");
1569 fprintf(fout, "%s", currheaderlist->require[i]->version); 1569 fprintf(fout, "%s", currheaderlist->require[i]->version);
1570 fprintf(fout,"]"); 1570 fprintf(fout,"]");
1571 } 1571 }
1572 fprintf(fout," "); 1572 fprintf(fout," ");
1573 } // if required 1573 } // if required
1574 } // for 1574 } // for
1575 fprintf(fout, "</font></td></tr>\n"); 1575 fprintf(fout, "</font></td></tr>\n");
1576 1576
1577 /* list RPM requirements */ 1577 /* list RPM requirements */
1578 fprintf(fout, "<tr><td>RPM requirements:</td><td><font size=\"-1\">"); 1578 fprintf(fout, "<tr><td>RPM requirements:</td><td><font size=\"-1\">");
1579 1579
1580 for (i = 0; i < currheaderlist->requirecount; i++) { 1580 for (i = 0; i < currheaderlist->requirecount; i++) {
1581 if (currheaderlist->require[i]->resolved) { 1581 if (currheaderlist->require[i]->resolved) {
1582 if (currheaderlist->require[i]->resolved->numproviders == 0) { 1582 if (currheaderlist->require[i]->resolved->numproviders == 0) {
1583 // missing provider 1583 // missing provider
1584 fprintf(fout,"<b>%s(unresolved)</b> ",currheaderlist->require[i]->resolved->name); 1584 fprintf(fout,"<b>%s(unresolved)</b> ",currheaderlist->require[i]->resolved->name);
1585 } else if (currheaderlist->require[i]->resolved->numproviders == 1) { 1585 } else if (currheaderlist->require[i]->resolved->numproviders == 1) {
1586 // single provider 1586 // single provider
1587 if ((i == 0 || 1587 if ((i == 0 ||
1588 !currheaderlist->require[i-1]->resolved || 1588 !currheaderlist->require[i-1]->resolved ||
1589 !currheaderlist->require[i-1]->resolved->numproviders || 1589 !currheaderlist->require[i-1]->resolved->numproviders ||
1590 strcmp(currheaderlist->require[i-1]->resolved->provider[0]->name, 1590 strcmp(currheaderlist->require[i-1]->resolved->provider[0]->name,
1591 currheaderlist->require[i]->resolved->provider[0]->name)) && 1591 currheaderlist->require[i]->resolved->provider[0]->name)) &&
1592 strcmp(currheaderlist->name, 1592 strcmp(currheaderlist->name,
1593 currheaderlist->require[i]->resolved->provider[0]->name)) { 1593 currheaderlist->require[i]->resolved->provider[0]->name)) {
1594 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a> ", 1594 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a> ",
1595 ct->configdefaults->url_prefix, 1595 ct->configdefaults->url_prefix,
1596 ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag, 1596 ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag,
1597 currheaderlist->require[i]->resolved->provider[0]->name, 1597 currheaderlist->require[i]->resolved->provider[0]->name,
1598 ct->arch[arch], 1598 ct->arch[arch],
1599 currheaderlist->require[i]->resolved->provider[0]->name); 1599 currheaderlist->require[i]->resolved->provider[0]->name);
1600 if ((ct->repository_level > 0) && 1600 if ((ct->repository_level > 0) &&
1601 (currheaderlist->sourceheader != currheaderlist->require[i]->resolved->provider[0]->sourceheader) && 1601 (currheaderlist->sourceheader != currheaderlist->require[i]->resolved->provider[0]->sourceheader) &&
1602 (currheaderlist->require[i]->resolved->provider[0]->altrepository == ct->repository_level)) { 1602 (currheaderlist->require[i]->resolved->provider[0]->altrepository == ct->repository_level)) {
1603 snprintf(buffer, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) which is only in this repository", 1603 snprintf(buffer, PATH_MAX, "%s(%s,%s) requires %s(%s,%s) which is only in this repository",
1604 currheaderlist->name, 1604 currheaderlist->name,
1605 ct->arch[arch], 1605 ct->arch[arch],
1606 ct->repository[currheaderlist->altrepository]->tag, 1606 ct->repository[currheaderlist->altrepository]->tag,
1607 currheaderlist->require[i]->resolved->provider[0]->name, 1607 currheaderlist->require[i]->resolved->provider[0]->name,
1608 ct->arch[arch], 1608 ct->arch[arch],
1609 ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag); 1609 ct->repository[currheaderlist->require[i]->resolved->provider[0]->altrepository]->tag);
1610 addWarning(currheaderlist->sourceheader, buffer); 1610 addWarning(currheaderlist->sourceheader, buffer);
1611 } 1611 }
1612 } 1612 }
1613 } else { 1613 } else {
1614 // multiple providers 1614 // multiple providers
1615 if (i == 0 || 1615 if (i == 0 ||
1616 !currheaderlist->require[i-1]->resolved || 1616 !currheaderlist->require[i-1]->resolved ||
1617 !currheaderlist->require[i-1]->resolved->numproviders || 1617 !currheaderlist->require[i-1]->resolved->numproviders ||
1618 strcmp(currheaderlist->require[i-1]->resolved->name, 1618 strcmp(currheaderlist->require[i-1]->resolved->name,
1619 currheaderlist->require[i]->resolved->name)) { 1619 currheaderlist->require[i]->resolved->name)) {
1620 fprintf(fout,"<i>%s</i>(",currheaderlist->require[i]->resolved->name); 1620 fprintf(fout,"<i>%s</i>(",currheaderlist->require[i]->resolved->name);
1621 for (j = 0; j < currheaderlist->require[i]->resolved->numproviders; j++) { 1621 for (j = 0; j < currheaderlist->require[i]->resolved->numproviders; j++) {
1622 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>", 1622 fprintf(fout,"<a href=\"%stag=%s&amp;pkg=%s.%s\">%s</a>",
1623 ct->configdefaults->url_prefix, 1623 ct->configdefaults->url_prefix,
1624 ct->repository[currheaderlist->require[i]->resolved->provider[j]->altrepository]->tag, 1624 ct->repository[currheaderlist->require[i]->resolved->provider[j]->altrepository]->tag,
1625 currheaderlist->require[i]->resolved->provider[j]->name, 1625 currheaderlist->require[i]->resolved->provider[j]->name,
1626 ct->arch[arch], 1626 ct->arch[arch],
1627 currheaderlist->require[i]->resolved->provider[j]->name); 1627 currheaderlist->require[i]->resolved->provider[j]->name);
1628 if (j+1 < currheaderlist->require[i]->resolved->numproviders) fprintf(fout,"|"); 1628 if (j+1 < currheaderlist->require[i]->resolved->numproviders) fprintf(fout,"|");