slloyd has asked for the wisdom of the Perl Monks concerning the following question:

I am using CGI to accept an upload from windows machine and write a cab file on my linux server. I then try to use cabextract to open the saved cab file but it says that the uploaded cab file has "2 Extra bytes at end of file". Does anyone have a script to remove extra bytes at end of a file? or does anyone know how to solve this problem?
#!/usr/bin/perl #use strict; use CGI qw/:standard/; use Digest::MD5 qw(md5 md5_hex md5_base64); print header(); my $file = param('file'); if (!$file) { #file does not exist print "Error: No file to upload"; return; } #Ignore all but cab files my $fname=$file; if($fname !~/\.cab$/is){ print "Error: Not a cab file"; return; } my $time=time(); my $data=''; while (<$file>) { $data .= $_; } my $md5=md5_hex($data); my $filename="ufiles/$md5\_" . $fname; if(open(FH,">$filename")){ binmode(FH); print FH $data; close(FH); #print the MD5 hash as a return value on success print $md5; } else{ print "Failed to upload file"; }

-------------------------------
Perl - Regularly Expression yourlself
http://www.basgetti.com

Replies are listed 'Best First'.
Re: Remove Extra bytes at end of file
by wojtyk (Friar) on Sep 08, 2006 at 15:41 UTC
    My best guess is that the extra bytes could be the windows line feeds (\r\n).
    Did you try running dos2unix on the file first? Is the cab file a plain text file?

    Anyways, if you want to remove the characters manually, you could just use Tie::File and then chop($tied_file[-1]) twice.
    Or slurp the thing into a scalar, chop twice, and then dump it back out to file.

Re: Remove Extra bytes at end of file
by jdtoronto (Prior) on Sep 08, 2006 at 15:55 UTC
    I would first use a binary editor to look at exactly what the two bytes are. Then you can figure out how/why they got added.

    jdtoronto

Re: Remove Extra bytes at end of file
by ikegami (Patriarch) on Sep 08, 2006 at 17:49 UTC
    Possibly unrelated, but while you set your output to binmode, you didn't do the same for your input. Also, reading a binary file a "line" at a time makes no sense. Change
    my $data=''; while (<$file>) { $data .= $_; }
    to
    binmode($file); my $data; { local $/; $data = <$file>; }
Re: Remove Extra bytes at end of file
by BrowserUk (Patriarch) on Sep 08, 2006 at 17:19 UTC

    If it is consistantly 2 bytes, and the program works if you remove them, then use truncate.

    If you know how long the file is, use it on the filehandle before you close it.

    If not, truncate $filename, -s( $filename ) - 2; after you've closed the filehandle might do the trick.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.