[bash] Een bestand binary safe splitsen.

Pagina: 1
Acties:
  • 113 views sinds 30-01-2008
  • Reageer

  • SA007
  • Registratie: Oktober 2002
  • Laatst online: 16-02 21:08

SA007

Moderator Tweaking
Topicstarter
Hoi, ik ben met een groep bezig met een website volledig in bash.

Nu moet er alleen ook een bestandupload ding komen.

Als je een bestand upload met een multipart formulier krijg je zo'n layout:
code:
1
2
3
4
5
6
7
8
9
10
------------------------------1234567890
Content-disposition: form-data; name="file" filename="pic.jpg"
Content-type: image/jpeg

<zut binary van een plaatje>
------------------------------1234567890
Content-disposition: form-data; name="submitknop"

Verzenden
------------------------------1234567890--


Nu moet dit dus gesplitst worden zonder het plaatje te verknoeien.

Ik heb het zover dat het compleet werkt met plaintext bestanden uploaden.

Maar binary's komen er met fouten uit.

Iemand een idee om dit te maken dat het wel werkt?

Mijn huidige code:

Bash:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/bash
cat > tmp.dat
nummer=`cat tmp.dat | head -n 1 | tail -c +30 | head -c -2`
mv tmp.dat tmpupload_$nummer
dir=upload_$nummer
mkdir $dir
cd $dir
num=0
cat ../tmpupload_$nummer | while read line
do
  if [ `echo $line | grep "$nummer"` ]
  then
    num=`expr $num + 1`
  else
    echo -n $line >> temp.$num
  fi
done

for file in temp.*
do
 head $file -n 1 | cut -d ':' -f 2 | while read line
 do
  numvars=`expr $(echo $line | tr ';' '\n' | wc -l) - 1`
  num=0
  echo $line | tr ';' '\n' | while read varval
  do
    if [ $varval != form-data ]
    then
      val=`echo $varval | cut -d '=' -f 2 | head -c -2`
      var=`echo $varval | cut -d '=' -f 1`
      val=${val%%\"}
      val=${val##\"}
      if [ $var = 'name' ]
      then
        name=$val
      elif [ $var = 'filename' ]
      then
        filename=$val
        cat $file | tail -n +4 | head -n -1 > tmp_$filename
      fi
    fi
    if [ $num -eq $numvars ]
    then
    then
      if [ $filename ]
      then
        echo "\$WWW_$name=$filename"
      else
        echo -n "\$WWW_$name="
        cat $file | tail -n +3
      fi
    fi
    num=`expr $num + 1`
  done
 done
done

  • smokalot
  • Registratie: Juni 2001
  • Laatst online: 15-01 22:00

smokalot

titel onder

doet split niet gewoon wat jij wilt?

It sounds like it could be either bad hardware or software


  • SA007
  • Registratie: Oktober 2002
  • Laatst online: 16-02 21:08

SA007

Moderator Tweaking
Topicstarter
smokalot schreef op 04 november 2004 @ 11:58:
doet split niet gewoon wat jij wilt?
Nee, want split maakt bestanden die altijd evengroot zijn, bijvoorbeeld 10kb enzo.

Ik doe het nu door met cat en while door alle regels te loopen, maar dit veknoeit dus de binary

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

cat is gewoon binary safe; dus je zal iets gespecificeerder uit moeten vinden wat er fout gaat. Heeft het te maken met newlines ofzo?

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


  • SA007
  • Registratie: Oktober 2002
  • Laatst online: 16-02 21:08

SA007

Moderator Tweaking
Topicstarter
Spider.007 schreef op 04 november 2004 @ 12:46:
cat is gewoon binary safe; dus je zal iets gespecificeerder uit moeten vinden wat er fout gaat. Heeft het te maken met newlines ofzo?
Het probleem is denk ik dat read (van while read line) niet binary safe is.

Met dit scriptje:
code:
1
2
3
4
cat| while read line
do
  echo -n $line >> testding.dat
done


Word het plaatje al compleet verknoeid

Verwijderd

uhhhmmm.... er staat geen binary data in een web upload, maar base64 encoded (binaire data zo gecodeerd dat ie alleen maar bestaat uit ascii-printable characters)

de encoding is aangegeven in de "content-transfer-encoding" header, die moet je eerst eventueel decoderen naar de originele binary data.

zie de RFC voor de volledige standaard

/me moet eerst zelf standaard lezen voor je iets roept ReSc 8)7

en je moet donders goed oppassen dat op precies de juiste bytegrenzen de data eruit knipt.

[ Voor 59% gewijzigd door Verwijderd op 04-11-2004 13:58 ]


  • SA007
  • Registratie: Oktober 2002
  • Laatst online: 16-02 21:08

SA007

Moderator Tweaking
Topicstarter
Verwijderd schreef op 04 november 2004 @ 13:47:
uhhhmmm.... er staat geen binary data in een web upload, maar base64 encoded (binaire data zo gecodeerd dat ie alleen maar bestaat uit ascii-printable characters) , die moet je eerst decoderen naar binary
zie de RFC voor de volledige standaard
Waarom komt er dan wel een goed plaatje uit als ik met nano de regels erboven en eronder uitknip?

Ik dacht eerst ook dat het base64 was, maar niet dus.

Verwijderd

uit de manpage van bash
code:
1
2
3
4
5
6
7
8
9
10
11
12
read [-r] [name ...]
              One  line  is read from the standard input, and the
              first word is assigned to the first name, the  sec-
              ond  word to the second name, and so on, with left-
              over words assigned to the  last  name.   Only  the
              characters  in  IFS  are  recognized as word delim-
              iters.  If no names are supplied, the line read  is
              assigned to the variable REPLY.  The return code is
              zero, unless end-of-file is encountered.  If the -r
              option  is  given,  a backslash-newline pair is not
              ignored, and the backslash is considered to be part
              of the line.

read komt een newline in de binare data tegen en leest dan niet meer verder(en gooit de newline waarschjinlijk weg, wat niet zou mogen omdat het binaire data is!), dus je moet op een andere manier je binnengekomen data splitsen

[ Voor 8% gewijzigd door Verwijderd op 04-11-2004 14:17 ]


  • QuarkuS
  • Registratie: December 1999
  • Laatst online: 16-02 16:46
Een wat onorthodoxe manier om bestanden te splitsen is ook wel 'dd' gebruiken. Dat werkt best goed, maar als je op de byte nauwkeurig werkt is het niet zo snel. Ik heb het wel gebruikt om afgebroken downloads halverwege te resumen.
Pagina: 1