147
147
/* if this gets too slow, make it a balanced tree,
148
148
* but it seems fast enough even as simple tree */
150
while( *p != NULL ) {
151
151
c = strcmp(source, (*p)->name);
156
156
p = &parent->right_child;
158
158
p = &parent->left_child;
161
161
/* there is not even something with this name */
162
n = calloc(1, sizeof(struct aa_source_package));
163
if( FAILEDTOALLOC(n) ) {
162
n = zNEW(struct aa_source_package);
163
if (FAILEDTOALLOC(n)) {
164
164
free(source); free(sourceversion);
165
165
return RET_ERROR_OOM;
264
264
struct aa_package_data *package;
266
266
r = list->target->getarchitecture(chunk, &architecture);
267
if( RET_WAS_ERROR(r) )
267
if (RET_WAS_ERROR(r))
270
270
r = list->target->getsourceandversion(chunk, packagename,
271
271
&source, &sourceversion);
272
if( RET_WAS_ERROR(r) )
272
if (RET_WAS_ERROR(r))
275
275
r = find_or_add_source(list, source, sourceversion, &src);
276
276
source = NULL; sourceversion = NULL; // just to be sure
277
if( RET_WAS_ERROR(r) )
277
if (RET_WAS_ERROR(r))
280
280
r = list->target->getversion(chunk, &version);
281
if( RET_WAS_ERROR(r) )
281
if (RET_WAS_ERROR(r))
285
if( architecture != architecture_all ) {
285
if (architecture != architecture_all) {
287
287
src->has_sibling = true;
288
288
return RET_NOTHING;
291
package = calloc(1,sizeof(struct aa_package_data));
292
if( package == NULL ) {
291
package = zNEW(struct aa_package_data);
292
if (FAILEDTOALLOC(package)) {
294
294
return RET_ERROR_OOM;
297
297
package->name = strdup(packagename);
298
if( package->name == NULL ) {
298
if (FAILEDTOALLOC(package->name)) {
301
301
return RET_ERROR_OOM;
304
304
version = NULL; // just to be sure...
305
305
package->old_source = src;
307
if( list->list == NULL ) {
307
if (list->list == NULL) {
308
308
/* first chunk to add: */
309
309
list->list = package;
310
310
list->last = package;
312
if( strcmp(packagename, list->last->name) > 0 ) {
312
if (strcmp(packagename, list->last->name) > 0) {
313
313
list->last->next = package;
314
314
list->last = package;
316
316
/* this should only happen if the underlying
317
317
* database-method get changed, so just throwing
319
fprintf(stderr, "INTERNAL ERROR: Package database is not sorted!!!\n");
320
"INTERNAL ERROR: Package database is not sorted!!!\n");
321
322
exit(EXIT_FAILURE);
327
static retvalue floodlist_initialize(struct floodlist **fl, struct target *t, struct database *database) {
328
static retvalue floodlist_initialize(struct floodlist **fl, struct target *t) {
328
329
struct floodlist *list;
330
331
const char *packagename, *controlchunk;
331
332
struct target_cursor iterator;
333
list = calloc(1,sizeof(struct floodlist));
334
list = zNEW(struct floodlist);
335
if (FAILEDTOALLOC(list))
335
336
return RET_ERROR_OOM;
337
338
list->target = t;
339
340
/* Begin with the packages currently in the archive */
341
r = target_openiterator(t, database, READONLY, &iterator);
342
if( RET_WAS_ERROR(r) ) {
342
r = target_openiterator(t, READONLY, &iterator);
343
if (RET_WAS_ERROR(r)) {
343
344
floodlist_free(list);
346
while( target_nextpackage(&iterator, &packagename, &controlchunk) ) {
347
while (target_nextpackage(&iterator, &packagename, &controlchunk)) {
347
348
r2 = save_package_version(list, packagename, controlchunk);
348
349
RET_UPDATE(r, r2);
349
if( RET_WAS_ERROR(r2) )
350
if (RET_WAS_ERROR(r2))
352
353
r2 = target_closeiterator(&iterator);
353
354
RET_UPDATE(r, r2);
355
if( RET_WAS_ERROR(r) ) {
356
if (RET_WAS_ERROR(r)) {
356
357
floodlist_free(list);
376
377
/* the algorithm assumes almost all packages are feed in
377
378
* alphabetically. */
382
assert( insertafter == NULL || insertafter->next == current );
383
assert( insertafter != NULL || current == list->list );
383
assert (insertafter == NULL || insertafter->next == current);
384
assert (insertafter != NULL || current == list->list);
385
if( current == NULL )
386
387
cmp = -1; /* every package is before the end of list */
388
389
cmp = strcmp(packagename_const, current->name);
396
if( insertafter == NULL ) {
397
if (insertafter == NULL) {
397
398
/* if we are before the first
398
399
* package, add us there...*/
402
403
precmp = strcmp(packagename_const, insertafter->name);
404
405
current = insertafter;
406
} else if( precmp < 0 ) {
407
} else if (precmp < 0) {
407
408
/* restart at the beginning: */
408
409
current = list->list;
409
410
insertafter = NULL;
416
assert( "This is not reached" == NULL );
417
assert ("This is not reached" == NULL);
418
419
/* cmp > 0 : may come later... */
419
assert( current != NULL );
420
assert (current != NULL);
420
421
insertafter = current;
421
422
current = current->next;
422
if( current == NULL ) {
423
if (current == NULL) {
423
424
/* add behind insertafter at end of list */
426
427
/* otherwise repeat until place found */
428
if( current == NULL ) {
429
if (current == NULL) {
429
430
/* adding a package not yet known */
430
431
struct aa_package_data *new;
431
432
char *source, *sourceversion;
434
435
r = list->target->getsourceandversion(chunk,
435
436
packagename_const, &source, &sourceversion);
436
if( ! RET_IS_OK(r) ) {
437
if (! RET_IS_OK(r)) {
440
441
src = find_source(list, source, sourceversion);
441
442
free(source); free(sourceversion);
442
new = calloc(1,sizeof(struct aa_package_data));
443
new = zNEW(struct aa_package_data);
444
if (FAILEDTOALLOC(new)) {
445
446
return RET_ERROR_OOM;
481
482
list->last = current;
483
if( current->new_has_sibling ) {
484
if (current->new_has_sibling) {
484
485
/* it has a new and that has a binary sibling,
485
486
* which means this becomes the new version
486
487
* exactly when it is newer than the old newest */
487
488
r = dpkgversions_cmp(version, current->new_version,
489
if( RET_WAS_ERROR(r) ) {
490
if (RET_WAS_ERROR(r)) {
493
if( versioncmp <= 0 ) {
494
if (versioncmp <= 0) {
495
496
return RET_NOTHING;
497
} else if( current->old_version != NULL ) {
498
} else if (current->old_version != NULL) {
498
499
/* if it is older than the old one, we will
499
500
* always discard it */
500
501
r = dpkgversions_cmp(version, current->old_version,
502
if( RET_WAS_ERROR(r) ) {
503
if (RET_WAS_ERROR(r)) {
506
if( versioncmp <= 0 ) {
507
if (versioncmp <= 0) {
508
509
return RET_NOTHING;
513
514
r = list->target->getsourceandversion(chunk,
514
515
packagename_const, &source, &sourceversion);
515
if( ! RET_IS_OK(r) ) {
516
if (! RET_IS_OK(r)) {
519
520
src = find_source(list, source, sourceversion);
520
521
free(source); free(sourceversion);
521
if( src == NULL || !src->has_sibling ) {
522
if (src == NULL || !src->has_sibling) {
522
523
/* the new one has no sibling, only allowed
523
524
* to override those that have: */
524
if( current->new_version == NULL ) {
525
if( current->old_source->has_sibling ) {
525
if (current->new_version == NULL) {
526
if (current->old_source->has_sibling) {
527
528
return RET_NOTHING;
529
} else if( current->new_has_sibling ) {
530
} else if (current->new_has_sibling) {
531
532
return RET_NOTHING;
533
534
/* the new one has no sibling and the old one
534
535
* has not too, take the newer one: */
535
r = dpkgversions_cmp(version, current->new_version,
536
r = dpkgversions_cmp(version,
537
current->new_version,
537
if( RET_WAS_ERROR(r) ) {
539
if (RET_WAS_ERROR(r)) {
541
if( versioncmp <= 0 ) {
543
if (versioncmp <= 0) {
543
545
return RET_NOTHING;
570
static retvalue floodlist_pull(struct floodlist *list, struct target *source, struct database *database) {
572
static retvalue floodlist_pull(struct floodlist *list, struct target *source) {
571
573
retvalue result, r;
572
574
const char *package, *control;
573
575
struct target_cursor iterator;
575
577
list->last = NULL;
576
r = target_openiterator(source, database, READONLY, &iterator);
577
if( RET_WAS_ERROR(r) )
578
r = target_openiterator(source, READONLY, &iterator);
579
if (RET_WAS_ERROR(r))
579
581
result = RET_NOTHING;
580
while( target_nextpackage(&iterator, &package, &control) ) {
582
while (target_nextpackage(&iterator, &package, &control)) {
582
584
architecture_t package_architecture;
584
r = list->target->getarchitecture(control, &package_architecture);
585
if( r == RET_NOTHING )
586
r = list->target->getarchitecture(control,
587
&package_architecture);
588
if (r == RET_NOTHING)
587
if( !RET_IS_OK(r) ) {
588
591
RET_UPDATE(result, r);
591
if( package_architecture != architecture_all )
594
if (package_architecture != architecture_all)
594
597
r = list->target->getversion(control, &version);
595
if( r == RET_NOTHING )
598
if (r == RET_NOTHING)
597
if( !RET_IS_OK(r) ) {
598
601
RET_UPDATE(result, r);
601
604
r = floodlist_trypackage(list, package, version, control);
602
605
RET_UPDATE(result, r);
603
if( RET_WAS_ERROR(r) )
606
if (RET_WAS_ERROR(r))
605
if( interrupted() ) {
606
609
result = RET_ERROR_INTERRUPTED;
610
613
r = target_closeiterator(&iterator);
611
RET_ENDUPDATE(result,r);
614
RET_ENDUPDATE(result, r);
615
static retvalue floodlist_install(struct floodlist *list, struct logger *logger, struct database *database, /*@NULL@*/struct trackingdata *td) {
618
static retvalue floodlist_install(struct floodlist *list, struct logger *logger, /*@NULL@*/struct trackingdata *td) {
616
619
struct aa_package_data *pkg;
619
if( list->list == NULL )
622
if (list->list == NULL)
620
623
return RET_NOTHING;
622
result = target_initpackagesdb(list->target, database, READWRITE);
623
if( RET_WAS_ERROR(result) )
625
result = target_initpackagesdb(list->target, READWRITE);
626
if (RET_WAS_ERROR(result))
625
628
result = RET_NOTHING;
626
for( pkg = list->list ; pkg != NULL ; pkg = pkg->next ) {
627
if( pkg->new_version != NULL ) {
628
r = files_expectfiles(database,
629
for (pkg = list->list ; pkg != NULL ; pkg = pkg->next) {
630
if (pkg->new_version != NULL) {
631
r = files_expectfiles(&pkg->new_filekeys,
630
632
pkg->new_origfiles.checksums);
631
633
RET_UPDATE(result, r);
632
if( RET_WAS_ERROR(r) )
634
if (RET_WAS_ERROR(r))
634
if( interrupted() ) {
635
637
r = RET_ERROR_INTERRUPTED;
639
if( pkg->new_source != NULL ) {
641
if (pkg->new_source != NULL) {
640
642
r = trackingdata_switch(td,
641
643
pkg->new_source->name,
642
644
pkg->new_source->version);
659
661
free(sourceversion);
661
if( RET_WAS_ERROR(r) ) {
663
if (RET_WAS_ERROR(r)) {
662
664
RET_UPDATE(result, r);
666
668
r = target_addpackage(list->target,
668
pkg->name, pkg->new_version,
669
logger, pkg->name, pkg->new_version,
669
670
pkg->new_control, &pkg->new_filekeys,
670
false, td, architecture_all,
671
false, td, architecture_all,
672
673
RET_UPDATE(result, r);
673
if( RET_WAS_ERROR(r) )
674
if (RET_WAS_ERROR(r))
682
retvalue flood(struct distribution *d, const struct atomlist *components, const struct atomlist *architectures, const struct atomlist *packagetypes, architecture_t architecture, struct database *database, trackingdb tracks) {
683
retvalue flood(struct distribution *d, const struct atomlist *components, const struct atomlist *architectures, const struct atomlist *packagetypes, architecture_t architecture, trackingdb tracks) {
683
684
struct target *t, *s;
684
685
retvalue result = RET_NOTHING, r;
685
686
struct trackingdata trackingdata;
687
if( tracks != NULL ) {
688
if (tracks != NULL) {
688
689
r = trackingdata_new(tracks, &trackingdata);
689
if( RET_WAS_ERROR(r) )
690
if (RET_WAS_ERROR(r))
693
for( t = d->targets ; t != NULL ; t = t->next ) {
694
for (t = d->targets ; t != NULL ; t = t->next) {
694
695
struct floodlist *fl = NULL;
696
if( atom_defined(architecture) ) {
697
if( architecture != t->architecture_atom )
699
} else if( limitations_missed(architectures,
700
t->architecture_atom) )
702
if( limitations_missed(components, t->component_atom) )
704
if( limitations_missed(packagetypes, t->packagetype_atom) )
706
if( t->packagetype_atom != pt_deb
707
&& t->packagetype_atom != pt_udeb )
697
if (atom_defined(architecture)) {
698
if (architecture != t->architecture)
700
} else if (limitations_missed(architectures,
703
if (limitations_missed(components, t->component))
705
if (limitations_missed(packagetypes, t->packagetype))
707
if (t->packagetype != pt_deb && t->packagetype != pt_udeb)
710
r = floodlist_initialize(&fl, t, database);
711
if( RET_WAS_ERROR(r) ) {
710
r = floodlist_initialize(&fl, t);
711
if (RET_WAS_ERROR(r)) {
713
713
trackingdata_done(&trackingdata);
717
for( s = d->targets ; s != NULL ; s = s->next ) {
718
if( s->component_atom != t->component_atom )
717
for (s = d->targets ; s != NULL ; s = s->next) {
718
if (s->component != t->component)
720
if( s->packagetype_atom != t->packagetype_atom )
720
if (s->packagetype != t->packagetype)
722
722
/* no need to copy things from myself: */
723
if( s->architecture_atom == t->architecture_atom )
725
if( limitations_missed(architectures,
726
s->architecture_atom) )
728
r = floodlist_pull(fl, s, database);
723
if (s->architecture == t->architecture)
725
if (limitations_missed(architectures,
728
r = floodlist_pull(fl, s);
729
729
RET_UPDATE(d->status, r);
730
if( RET_WAS_ERROR(r) ) {
730
if (RET_WAS_ERROR(r)) {
732
732
trackingdata_done(&trackingdata);
733
733
floodlist_free(fl);
737
r = floodlist_install(fl, d->logger, database,
737
r = floodlist_install(fl, d->logger,
738
738
(tracks != NULL)?&trackingdata:NULL);
739
739
RET_UPDATE(result, r);
740
740
floodlist_free(fl);
741
if( RET_WAS_ERROR(r) ) {
741
if (RET_WAS_ERROR(r)) {
743
743
trackingdata_done(&trackingdata);
747
if( tracks != NULL ) {
748
r = trackingdata_finish(tracks, &trackingdata, database);
747
if (tracks != NULL) {
748
r = trackingdata_finish(tracks, &trackingdata);
749
749
RET_ENDUPDATE(result, r);