41
41
const char *p, *fn, *fnend;
44
assert( fileline != NULL );
45
if( *fileline == '\0' )
44
assert (fileline != NULL);
45
if (*fileline == '\0')
46
46
return RET_NOTHING;
48
48
/* the md5sums begins after the (perhaps) heading spaces ... */
50
while( *p != '\0' && (*p == ' ' || *p == '\t') )
50
while (*p != '\0' && (*p == ' ' || *p == '\t'))
53
53
return RET_NOTHING;
54
54
/* ... and ends with the following spaces. */
55
while( *p != '\0' && !(*p == ' ' || *p == '\t') )
55
while (*p != '\0' && !(*p == ' ' || *p == '\t'))
58
58
fprintf(stderr, "Expecting more data after md5sum!\n");
61
61
/* Then the size of the file is expected: */
62
while( (*p == ' ' || *p == '\t') )
64
while( *p !='\0' && !(*p == ' ' || *p == '\t') )
62
while ((*p == ' ' || *p == '\t'))
64
while (*p !='\0' && !(*p == ' ' || *p == '\t'))
67
67
fprintf(stderr, "Expecting more data after size!\n");
70
70
/* Then the filename */
72
while( (*fn == ' ' || *fn == '\t') )
72
while ((*fn == ' ' || *fn == '\t'))
75
while( *fnend != '\0' && !(*fnend == ' ' || *fnend == '\t') )
75
while (*fnend != '\0' && !(*fnend == ' ' || *fnend == '\t'))
78
78
filen = strndup(fn, fnend-fn);
79
if( FAILEDTOALLOC(filen) )
79
if (FAILEDTOALLOC(filen))
80
80
return RET_ERROR_OOM;
85
static retvalue getBasenames(const struct strlist *filelines,/*@out@*/struct strlist *basenames) {
85
static retvalue getBasenames(const struct strlist *filelines, /*@out@*/struct strlist *basenames) {
89
assert( filelines != NULL && basenames != NULL );
89
assert (filelines != NULL && basenames != NULL);
91
r = strlist_init_n(filelines->count,basenames);
92
if( RET_WAS_ERROR(r) )
91
r = strlist_init_n(filelines->count, basenames);
95
for( i = 0 ; i < filelines->count ; i++ ) {
95
for (i = 0 ; i < filelines->count ; i++) {
96
96
char *basefilename IFSTUPIDCC(=NULL);
97
97
const char *fileline = filelines->values[i];
99
99
r = calc_parsefileline(fileline, &basefilename);
100
if( r == RET_NOTHING ) {
100
if (r == RET_NOTHING) {
101
101
fprintf(stderr, "Malformed Files: line '%s'!\n",
105
if( RET_WAS_ERROR(r) )
105
if (RET_WAS_ERROR(r))
108
108
r = strlist_add(basenames, basefilename);
109
if( RET_WAS_ERROR(r) ) {
109
if (RET_WAS_ERROR(r)) {
114
if( RET_WAS_ERROR(r) ) {
114
if (RET_WAS_ERROR(r)) {
115
115
strlist_done(basenames);
117
assert( filelines->count == basenames->count );
117
assert (filelines->count == basenames->count);
122
122
retvalue sources_getversion(const char *control, char **version) {
125
r = chunk_getvalue(control,"Version",version);
126
if( RET_WAS_ERROR(r) )
125
r = chunk_getvalue(control, "Version", version);
126
if (RET_WAS_ERROR(r))
128
if( r == RET_NOTHING ) {
129
fprintf(stderr, "Missing 'Version' field in chunk:'%s'\n", control);
128
if (r == RET_NOTHING) {
129
fprintf(stderr, "Missing 'Version' field in chunk:'%s'\n",
130
131
return RET_ERROR;
145
146
struct checksumsarray files;
146
147
enum checksumtype cs;
148
assert( architecture == architecture_source );
149
assert (architecture == architecture_source);
150
for( cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++ ) {
151
assert( source_checksum_names[cs] != NULL );
151
for (cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++) {
152
assert (source_checksum_names[cs] != NULL);
152
153
r = chunk_getextralinelist(chunk, source_checksum_names[cs],
154
if( r == RET_NOTHING ) {
155
if( cs == cs_md5sum ) {
155
if (r == RET_NOTHING) {
156
if (cs == cs_md5sum) {
157
"Missing 'Files' entry in '%s'!\n", chunk);
158
"Missing 'Files' entry in '%s'!\n",
160
162
strlist_init(&filelines[cs]);
162
if( RET_WAS_ERROR(r) ) {
163
while( cs-- > cs_md5sum ) {
164
if (RET_WAS_ERROR(r)) {
165
while (cs-- > cs_md5sum) {
164
166
strlist_done(&filelines[cs]);
169
171
r = checksumsarray_parse(&files, filelines, packagename);
170
for( cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++ ) {
172
for (cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++) {
171
173
strlist_done(&filelines[cs]);
173
if( RET_WAS_ERROR(r) )
175
if (RET_WAS_ERROR(r))
176
178
r = chunk_getvalue(chunk, "Directory", &origdirectory);
177
if( r == RET_NOTHING ) {
179
if (r == RET_NOTHING) {
178
180
/* Flat repositories can come without this, TODO: add warnings in other cases
179
fprintf(stderr,"Missing 'Directory' entry in '%s'!\n",chunk);
181
fprintf(stderr, "Missing 'Directory' entry in '%s'!\n", chunk);
182
184
origdirectory = strdup(".");
183
if( FAILEDTOALLOC(origdirectory) )
185
if (FAILEDTOALLOC(origdirectory))
184
186
r = RET_ERROR_OOM;
186
if( RET_WAS_ERROR(r) ) {
188
if (RET_WAS_ERROR(r)) {
187
189
checksumsarray_done(&files);
191
193
r = propersourcename(packagename);
192
assert( r != RET_NOTHING );
194
assert (r != RET_NOTHING);
194
196
r = properfilenames(&files.names);
195
if( RET_WAS_ERROR(r) ) {
196
fprintf(stderr,"Forbidden characters in source package '%s'!\n", packagename);
197
if (RET_WAS_ERROR(r)) {
199
"Forbidden characters in source package '%s'!\n", packagename);
197
200
free(origdirectory);
198
201
checksumsarray_done(&files);
202
directory = calc_sourcedir(t->component_atom, packagename);
203
if( directory == NULL )
205
directory = calc_sourcedir(t->component, packagename);
206
if (FAILEDTOALLOC(directory))
204
207
r = RET_ERROR_OOM;
206
209
r = calc_dirconcats(directory, &files.names, &myfilekeys);
207
if( RET_WAS_ERROR(r) ) {
210
if (RET_WAS_ERROR(r)) {
209
212
free(origdirectory);
210
213
checksumsarray_done(&files);
213
216
r = calc_inplacedirconcats(origdirectory, &files.names);
214
217
free(origdirectory);
215
if( !RET_WAS_ERROR(r) ) {
218
if (!RET_WAS_ERROR(r)) {
216
219
mychunk = chunk_replacefield(chunk,
217
220
"Directory", directory, true);
218
if( mychunk == NULL )
221
if (FAILEDTOALLOC(mychunk))
219
222
r = RET_ERROR_OOM;
222
if( RET_WAS_ERROR(r) ) {
225
if (RET_WAS_ERROR(r)) {
223
226
strlist_done(&myfilekeys);
224
227
checksumsarray_done(&files);
240
243
/* Read the directory given there */
241
244
r = chunk_getvalue(chunk, "Directory", &origdirectory);
242
if( r == RET_NOTHING ) {
245
if (r == RET_NOTHING) {
243
246
//TODO: check if it is even text and do not print
244
247
//of looking binary??
245
fprintf(stderr, "Does not look like source control: '%s'\n", chunk);
248
fprintf(stderr, "Does not look like source control: '%s'\n",
246
250
return RET_ERROR;
248
if( RET_WAS_ERROR(r) )
252
if (RET_WAS_ERROR(r))
251
255
r = chunk_getextralinelist(chunk, "Files", &filelines);
252
if( r == RET_NOTHING ) {
256
if (r == RET_NOTHING) {
253
257
//TODO: check if it is even text and do not print
254
258
//of looking binary??
255
fprintf(stderr, "Does not look like source control: '%s'\n", chunk);
259
fprintf(stderr, "Does not look like source control: '%s'\n",
258
if( RET_WAS_ERROR(r) ) {
263
if (RET_WAS_ERROR(r)) {
259
264
free(origdirectory);
262
267
r = getBasenames(&filelines, &basenames);
263
268
strlist_done(&filelines);
264
if( RET_WAS_ERROR(r) ) {
269
if (RET_WAS_ERROR(r)) {
265
270
free(origdirectory);
282
287
/* Read the directory given there */
283
288
r = chunk_getvalue(chunk, "Directory", &origdirectory);
287
for( cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++ ) {
288
assert( source_checksum_names[cs] != NULL );
292
for (cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++) {
293
assert (source_checksum_names[cs] != NULL);
289
294
r = chunk_getextralinelist(chunk, source_checksum_names[cs],
291
if( r == RET_NOTHING ) {
292
if( cs == cs_md5sum ) {
296
if (r == RET_NOTHING) {
297
if (cs == cs_md5sum) {
294
"Missing 'Files' entry in '%s'!\n", chunk);
299
"Missing 'Files' entry in '%s'!\n",
297
303
strlist_init(&filelines[cs]);
299
if( RET_WAS_ERROR(r) ) {
300
while( cs-- > cs_md5sum ) {
305
if (RET_WAS_ERROR(r)) {
306
while (cs-- > cs_md5sum) {
301
307
strlist_done(&filelines[cs]);
303
309
free(origdirectory);
333
339
return RET_ERROR_INTERRUPTED;
335
341
o = override_search(target->distribution->overrides.dsc, packagename);
337
343
return RET_NOTHING;
339
345
r = override_allreplacefields(o, &fields);
342
348
newchunk = chunk_replacefields(controlchunk, fields,
343
349
"Directory", true);
344
350
addfield_free(fields);
345
if( newchunk == NULL )
351
if (FAILEDTOALLOC(newchunk))
346
352
return RET_ERROR_OOM;
347
353
*newcontrolchunk = newchunk;
351
retvalue sources_retrack(const char *sourcename, const char *chunk, trackingdb tracks, struct database *database) {
357
retvalue sources_retrack(const char *sourcename, const char *chunk, trackingdb tracks) {
353
359
char *sourceversion;
354
360
struct trackedpackage *pkg;
358
364
//TODO: elliminate duplicate code!
359
365
assert(sourcename!=NULL);
362
368
return RET_ERROR_INTERRUPTED;
364
r = chunk_getvalue(chunk,"Version",&sourceversion);
365
if( r == RET_NOTHING ) {
366
fprintf(stderr, "Missing 'Version' field in chunk:'%s'\n", chunk);
370
r = chunk_getvalue(chunk, "Version", &sourceversion);
371
if (r == RET_NOTHING) {
372
fprintf(stderr, "Missing 'Version' field in chunk:'%s'\n",
369
if( RET_WAS_ERROR(r) ) {
376
if (RET_WAS_ERROR(r)) {
373
380
r = sources_getfilekeys(chunk, &filekeys);
374
if( r == RET_NOTHING ) {
381
if (r == RET_NOTHING) {
375
382
fprintf(stderr, "Malformed source control:'%s'\n", chunk);
378
if( RET_WAS_ERROR(r) ) {
385
if (RET_WAS_ERROR(r)) {
379
386
free(sourceversion);
383
r = tracking_getornew(tracks,sourcename,sourceversion,&pkg);
390
r = tracking_getornew(tracks, sourcename, sourceversion, &pkg);
384
391
free(sourceversion);
385
if( RET_WAS_ERROR(r) ) {
392
if (RET_WAS_ERROR(r)) {
386
393
strlist_done(&filekeys);
390
397
// TODO: error handling is suboptimal here.
391
398
// is there a way to again remove old additions (esp. references)
392
399
// where something fails?
393
for( i = 0 ; i < filekeys.count ; i++ ) {
400
for (i = 0 ; i < filekeys.count ; i++) {
394
401
r = trackedpackage_addfilekey(tracks, pkg,
395
ft_SOURCE, filekeys.values[i],
402
ft_SOURCE, filekeys.values[i], true);
397
403
filekeys.values[i] = NULL;
398
if( RET_WAS_ERROR(r) ) {
404
if (RET_WAS_ERROR(r)) {
399
405
strlist_done(&filekeys);
400
406
trackedpackage_free(pkg);
413
419
//TODO: elliminate duplicate code!
414
420
assert(packagename!=NULL);
416
r = chunk_getvalue(chunk,"Version",&sourceversion);
417
if( r == RET_NOTHING ) {
418
fprintf(stderr, "Missing 'Version' field in chunk:'%s'\n", chunk);
422
r = chunk_getvalue(chunk, "Version", &sourceversion);
423
if (r == RET_NOTHING) {
424
fprintf(stderr, "Missing 'Version' field in chunk:'%s'\n",
421
if( RET_WAS_ERROR(r) ) {
428
if (RET_WAS_ERROR(r)) {
424
431
sourcename = strdup(packagename);
425
if( sourcename == NULL ) {
432
if (FAILEDTOALLOC(sourcename)) {
426
433
free(sourceversion);
427
434
return RET_ERROR_OOM;
434
441
/****************************************************************/
436
static inline retvalue getvalue(const char *filename,const char *chunk,const char *field,char **value) {
439
r = chunk_getvalue(chunk,field,value);
440
if( r == RET_NOTHING ) {
441
fprintf(stderr,"Missing '%s' field in %s!\n",field,filename);
447
static inline retvalue checkvalue(const char *filename,const char *chunk,const char *field) {
450
r = chunk_checkfield(chunk,field);
451
if( r == RET_NOTHING ) {
452
fprintf(stderr,"Cannot find '%s' field in %s!\n",field,filename);
458
static inline retvalue getvalue_n(const char *chunk,const char *field,char **value) {
461
r = chunk_getvalue(chunk,field,value);
462
if( r == RET_NOTHING ) {
443
static inline retvalue getvalue(const char *filename, const char *chunk, const char *field, char **value) {
446
r = chunk_getvalue(chunk, field, value);
447
if (r == RET_NOTHING) {
448
fprintf(stderr, "Missing '%s' field in %s!\n",
455
static inline retvalue checkvalue(const char *filename, const char *chunk, const char *field) {
458
r = chunk_checkfield(chunk, field);
459
if (r == RET_NOTHING) {
460
fprintf(stderr, "Cannot find '%s' field in %s!\n",
467
static inline retvalue getvalue_n(const char *chunk, const char *field, char **value) {
470
r = chunk_getvalue(chunk, field, value);
471
if (r == RET_NOTHING) {
483
492
/* first look for fields that should be there */
485
494
r = chunk_getname(dsc->control, "Source", &dsc->name, false);
486
if( r == RET_NOTHING ) {
487
fprintf(stderr, "Missing 'Source' field in %s!\n", filenametoshow);
495
if (r == RET_NOTHING) {
496
fprintf(stderr, "Missing 'Source' field in %s!\n",
488
498
return RET_ERROR;
490
if( RET_WAS_ERROR(r) )
500
if (RET_WAS_ERROR(r))
493
/* This is needed and cannot be ignored unless
503
/* This is needed and cannot be ignored unless
494
504
* sources_complete is changed to not need it */
495
505
r = checkvalue(filenametoshow, dsc->control, "Format");
496
if( RET_WAS_ERROR(r) )
506
if (RET_WAS_ERROR(r))
499
509
r = checkvalue(filenametoshow, dsc->control, "Maintainer");
500
if( RET_WAS_ERROR(r) )
510
if (RET_WAS_ERROR(r))
503
513
r = getvalue(filenametoshow, dsc->control, "Version", &dsc->version);
504
if( RET_WAS_ERROR(r) )
514
if (RET_WAS_ERROR(r))
507
517
r = getvalue_n(dsc->control, SECTION_FIELDNAME, &dsc->section);
508
if( RET_WAS_ERROR(r) )
518
if (RET_WAS_ERROR(r))
510
520
r = getvalue_n(dsc->control, PRIORITY_FIELDNAME, &dsc->priority);
511
if( RET_WAS_ERROR(r) )
521
if (RET_WAS_ERROR(r))
514
for( cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++ ) {
515
assert( source_checksum_names[cs] != NULL );
524
for (cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++) {
525
assert (source_checksum_names[cs] != NULL);
516
526
r = chunk_getextralinelist(dsc->control,
517
527
source_checksum_names[cs], &filelines[cs]);
518
if( r == RET_NOTHING ) {
519
if( cs == cs_md5sum ) {
528
if (r == RET_NOTHING) {
529
if (cs == cs_md5sum) {
521
"Missing 'Files' field in '%s'!\n", filenametoshow);
531
"Missing 'Files' field in '%s'!\n",
524
535
strlist_init(&filelines[cs]);
526
if( RET_WAS_ERROR(r) ) {
527
while( cs-- > cs_md5sum ) {
537
if (RET_WAS_ERROR(r)) {
538
while (cs-- > cs_md5sum) {
528
539
strlist_done(&filelines[cs]);
533
544
r = checksumsarray_parse(&dsc->files, filelines, filenametoshow);
534
for( cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++ ) {
545
for (cs = cs_md5sum ; cs < cs_hashCOUNT ; cs++) {
535
546
strlist_done(&filelines[cs]);
551
562
struct fieldtoadd *name;
552
563
struct fieldtoadd *replace;
553
char *newchunk,*newchunk2;
564
char *newchunk, *newchunk2;
554
565
char *newfilelines, *newsha1lines, *newsha256lines;
556
567
assert(section != NULL && priority != NULL);
558
569
/* first replace the "Source" with a "Package": */
559
name = addfield_new("Package",dsc->name,NULL);
570
name = addfield_new("Package", dsc->name, NULL);
571
if (FAILEDTOALLOC(name))
561
572
return RET_ERROR_OOM;
562
name = deletefield_new("Source",name);
573
name = deletefield_new("Source", name);
574
if (FAILEDTOALLOC(name))
564
575
return RET_ERROR_OOM;
565
576
newchunk2 = chunk_replacefields(dsc->control, name, "Format", true);
566
577
addfield_free(name);
567
if( newchunk2 == NULL )
578
if (FAILEDTOALLOC(newchunk2))
568
579
return RET_ERROR_OOM;
570
581
r = checksumsarray_genfilelist(&dsc->files,
571
582
&newfilelines, &newsha1lines, &newsha256lines);
572
if( RET_WAS_ERROR(r) ) {
583
if (RET_WAS_ERROR(r)) {
574
return RET_ERROR_OOM;
576
assert( newfilelines != NULL );
587
assert (newfilelines != NULL);
577
588
replace = aodfield_new("Checksums-Sha256", newsha256lines, NULL);
578
if( replace != NULL )
589
if (!FAILEDTOALLOC(replace))
579
590
replace = aodfield_new("Checksums-Sha1", newsha1lines, replace);
580
if( replace != NULL )
591
if (!FAILEDTOALLOC(replace))
581
592
replace = addfield_new("Files", newfilelines, replace);
582
if( replace != NULL )
583
replace = addfield_new("Directory",directory,replace);
584
if( replace != NULL )
585
replace = deletefield_new("Status",replace);
586
if( replace != NULL )
587
replace = addfield_new(SECTION_FIELDNAME,section,replace);
588
if( replace != NULL )
589
replace = addfield_new(PRIORITY_FIELDNAME,priority,replace);
590
if( replace != NULL )
591
replace = override_addreplacefields(override,replace);
592
if( replace == NULL ) {
593
if (!FAILEDTOALLOC(replace))
594
replace = addfield_new("Directory", directory, replace);
595
if (!FAILEDTOALLOC(replace))
596
replace = deletefield_new("Status", replace);
597
if (!FAILEDTOALLOC(replace))
598
replace = addfield_new(SECTION_FIELDNAME, section, replace);
599
if (!FAILEDTOALLOC(replace))
600
replace = addfield_new(PRIORITY_FIELDNAME, priority, replace);
601
if (!FAILEDTOALLOC(replace))
602
replace = override_addreplacefields(override, replace);
603
if (FAILEDTOALLOC(replace)) {
593
604
free(newsha256lines);
594
605
free(newsha1lines);
595
606
free(newfilelines);
624
635
/* fake a checksumarray... */
625
636
checksums.checksums = c;
626
637
checksums.names.count = filekeys->count;
627
checksums.names.values = calloc(filekeys->count, sizeof(char*));
628
if (checksums.names.values == NULL)
638
checksums.names.values = nzNEW(filekeys->count, char *);
639
if (FAILEDTOALLOC(checksums.names.values))
629
640
return RET_ERROR_OOM;
630
for( i = 0 ; i < filekeys->count ; i++ ) {
641
for (i = 0 ; i < filekeys->count ; i++) {
631
642
checksums.names.values[i] = (char*)
632
643
dirs_basename(filekeys->values[i]);
635
646
r = checksumsarray_genfilelist(&checksums,
636
647
&newfilelines, &newsha1lines, &newsha256lines);
637
648
free(checksums.names.values);
638
if( RET_WAS_ERROR(r) ) {
639
return RET_ERROR_OOM;
641
assert( newfilelines != NULL );
649
if (RET_WAS_ERROR(r))
651
assert (newfilelines != NULL);
642
652
replace = aodfield_new("Checksums-Sha256", newsha256lines, NULL);
643
if( replace != NULL )
653
if (!FAILEDTOALLOC(replace))
644
654
replace = aodfield_new("Checksums-Sha1", newsha1lines, replace);
645
if( replace != NULL )
655
if (!FAILEDTOALLOC(replace))
646
656
replace = addfield_new("Files", newfilelines, replace);
647
if( replace == NULL ) {
657
if (FAILEDTOALLOC(replace)) {
648
658
free(newsha256lines);
649
659
free(newsha1lines);
650
660
free(newfilelines);
674
684
char *calc_sourcedir(component_t component, const char *sourcename) {
676
assert( *sourcename != '\0' );
686
assert (*sourcename != '\0');
678
if( sourcename[0] == 'l' && sourcename[1] == 'i' &&
679
sourcename[2] == 'b' && sourcename[3] != '\0' )
688
if (sourcename[0] == 'l' && sourcename[1] == 'i' &&
689
sourcename[2] == 'b' && sourcename[3] != '\0')
680
690
return mprintf("pool/%s/lib%c/%s",
681
691
atoms_components[component],
682
692
sourcename[3], sourcename);
683
else if( *sourcename != '\0' )
693
else if (*sourcename != '\0')
684
694
return mprintf("pool/%s/%c/%s",
685
695
atoms_components[component],
686
696
sourcename[0], sourcename);
691
701
char *calc_filekey(component_t component, const char *sourcename, const char *filename) {
692
if( sourcename[0] == 'l' && sourcename[1] == 'i' &&
693
sourcename[2] == 'b' && sourcename[3] != '\0' )
702
if (sourcename[0] == 'l' && sourcename[1] == 'i' &&
703
sourcename[2] == 'b' && sourcename[3] != '\0')
694
704
return mprintf("pool/%s/lib%c/%s/%s",
695
705
atoms_components[component],
696
706
sourcename[3], sourcename, filename);
697
else if( *sourcename != '\0' )
707
else if (*sourcename != '\0')
698
708
return mprintf("pool/%s/%c/%s/%s",
699
709
atoms_components[component],
700
710
sourcename[0], sourcename, filename);
705
715
char *calc_byhanddir(component_t component, const char *sourcename, const char *version) {
706
if( sourcename[0] == 'l' && sourcename[1] == 'i' &&
707
sourcename[2] == 'b' && sourcename[3] != '\0' )
716
if (sourcename[0] == 'l' && sourcename[1] == 'i' &&
717
sourcename[2] == 'b' && sourcename[3] != '\0')
708
718
return mprintf("pool/%s/lib%c/%s/%s_%s_byhand",
709
719
atoms_components[component],
710
720
sourcename[3], sourcename,
711
721
sourcename, version);
712
else if( *sourcename != '\0' )
722
else if (*sourcename != '\0')
713
723
return mprintf("pool/%s/%c/%s/%s_%s_byhand",
714
724
atoms_components[component],
715
725
sourcename[0], sourcename,