X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?a=blobdiff_plain;f=pctb%2Fcommod-update-receiver;h=2c02c11bcb74603ada8f65b062988699d66ec00a;hb=8651c66dd983df3a05eff010cef635e641a41d8f;hp=11064cd7d9b6897f9194116690602eebb71e3e81;hpb=34c9aa9031897dada3450d014de96d68a5834039;p=ypp-sc-tools.db-live.git diff --git a/pctb/commod-update-receiver b/pctb/commod-update-receiver index 11064cd..2c02c11 100755 --- a/pctb/commod-update-receiver +++ b/pctb/commod-update-receiver @@ -34,6 +34,7 @@ # clientfixes "lastpage" [space separated list] # data filename=deduped.tsv.gz output of ypp-commodities --tsv + use strict (qw(vars)); use POSIX; use MIME::Entity; @@ -102,9 +103,6 @@ $o{'timestamp'}= must_param('timestamp', "^([1-9]\\d{1,20})\$"); my $now= time; defined $now or die $!; fail("clock skew") if $o{'timestamp'} >= $now; -die if $o{'ocean'} =~ m/\=/; -die if $o{'island'} =~ m/\=/; - my $indatafh= upload('data'); defined $indatafh or fail("data is not a file"); my $datafile= must_param('data',"^(deduped\\.tsv\\.gz)\$"); @@ -116,54 +114,56 @@ my $mcontent= MIME::Entity->build(To => 'yarrg-commod-updates', get_our_version(\%o, 'server'); foreach my $cs (qw(client server)) { - $o{"${cs}spec"}= join ' ', map { $o{$cs.$_} } qw(name version fixes); + $o{"${cs}spec"}= join "\t", map { $o{$cs.$_} } qw(name version fixes); } -foreach my $vn (sort keys %o) { - my $mpart= MIME::Entity->build(Top => 0, - Type => 'text/plain', - Charset => 'utf-8', - Disposition => 'attachment', - Filename => $vn, - Data => $o{$vn}); - $mcontent->add_part($mpart); +my $metadata= ''; + +sub ksmap ($) { + my ($v) = @_; + my $i=0; grep { return $i if $_ eq $v; $i++ } qw(ocean island timestamp); + sprintf "z %d %s", (length $v) / 8, $v; +} + +foreach my $vn (sort { ksmap($a) cmp ksmap($b) } keys %o) { + my $val= $o{$vn}; + die if $val =~ m/\n|\r/; + $metadata .= "$vn\t$o{$vn}\n"; } +my $mdpart= MIME::Entity->build(Top => 0, + Type => 'text/plain', + Charset => 'utf-8', + Disposition => 'inline', + Encoding => 'quoted-printable', + Filename => 'metadata', + Data => $metadata); +$mcontent->add_part($mdpart); + my $gunzchild= open(GZ, "-|"); defined $gunzchild or die $!; if (!$gunzchild) { open STDIN, "<&=", $indatafh or die $!; exec 'gunzip'; die $!; } -sub bad_data ($) { fail("bad data: line $.: $_[0]"); } - -our %done; +my $dedupedtsv= pipethrough_prep(); while () { - !m/\P{IsPrint}/ or die bad_data('nonprinting char(s)'); - !m/\\/ or bad_data('data contains backslashes'); - my @v= split /\t/; - @v==6 or bad_data('wrong number of fields'); - my ($commod,$stall) = @v; - defined $commods{$commod} or bad_data("unknown commodity \`$commod'"); - $stall =~ m/^\p{IsUpper}|^[0-9]/ or bad_data("stall not capitalised"); - !exists $done{$commod,$stall} or bad_data("repeated data"); - $done{$commod,$stall}= 1; - foreach my $i (2..5) { - my $f= $v[$i]; - $f =~ m/^(|0|[1-9][0-9]{0,5}|\>1000)$/ or bad_data("bad field $i"); - ($i % 2) or ($f !~ m/\>/) or bad_data("> in field $i price"); - } + my @v= check_tsv_line($_,\&fail); + print $dedupedtsv join('\t',@v),"\n" or die $!; } + GZ->error and die $!; $?=0; close GZ; $? and fail("gunzip for check failed code $?"); +my $launderedgz= pipethrough_run($dedupedtsv,undef,'gzip','gzip'); + my $mdatafile= MIME::Entity->build(Top => 0, Type => 'application/octet-stream', Disposition => 'attachment', Encoding => 'base64', Filename => 'deduped.tsv.gz', - Path => $datafile); + Data => $launderedgz); $mcontent->add_part($mdatafile); open M, "|/usr/sbin/sendmail -t -oi -oee -odb"