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

Hi Monks, Been a long time since I have last seeked wisdom from the Perl Monks. =D
I have been working on some scripts at work, and they have me stumped! Basically, I am running a linux server, and have procmail set up to recieve email with a certain subject, and pass the attachment to a perl script. The perl script verifies the name of the attachment and puts it in the proper directory based on the name.
Here is the thing, I have a certain file overture.txt that writes properly as ASCII Text (file overture.txt). It gets sent as a 7bit Plain Text file.
The other file, Google, has no .txt extention (and cant), but it still gets sent as a 7bit Plain Text file, but it shows up as "Data" when I do a file Google from the prompt. Allow me to post my code...
#!/usr/bin/perl use MIME::Parser; open LOG, ">>/home/autotasks/.procmail/inputlog"; # Create MIME::Parser mail object my $mime = MIME::Parser->new; $mime->output_to_core(0); my $entity = $mime->parse(\*STDIN) or die "Parse failed\n"; foreach my $part ($entity->parts) { my $filename = $part->head->recommended_filename; if ($filename eq 'overture.txt') { my $sender = $part->head->get('From',0); #save file to overture directory and log printf LOG "Overture: $sender\n"; open OVERTURE, ">/home/autotasks/bidWatch/over +ture.txt"; printf OVERTURE $part->bodyhandle->as_string; close OVERTURE; } elsif ($filename eq 'Google') { my $sender = $part->head->get('From:',0); my $filepath = "/home/autotasks/pricemonitor/$ +filename"; printf LOG "$filename: $sender$filepath\n"; #open BIDWATCH, ">$filepath"; #open BIDWATCH, ">/home/autotasks/pricemonitor/Google"; open (BIDWATCH, ">:crlf", $filepath); printf BIDWATCH $part->bodyhandle->as_string; close BIDWATCH; } }
As you can see, I have tried a couple diferent methods of opening the filestream, and even tried adding the :crlf thingie. The goal here is to get the file "Google" to write as ASCII Text. =/
Any help would be greatly appreciated!

By Kzin

Replies are listed 'Best First'.
Re: Force Ascii Write
by moklevat (Priest) on Apr 05, 2006 at 19:06 UTC
    It's a little difficult for me to determine without examples of the observed and expected output, but how about

    open BIDWATCH, ">:utf8", "/home/autotasks/pricemonitor/Google";
      Thanks for your quick reply! Here is my expected output etc. Examples:
      ...What is happening... Client Machine (before script); kzin@IT-001:~$ file Google Google: ASCII text kzin@IT-001:~$ file overture.txt overture.txt: ASCII text
      Server (after script); autotasks@mail:~/pricemonitor$ file Google Google: data autotasks@mail:~/bidWatch$ file overture.txt overture.txt: ASCII text
      Note that the perl script has not written ASCII text.
      ...Expected output... autotasks@mail:~/pricemonitor$ file Google Google: ASCII text autotasks@mail:~/bidWatch$ file overture.txt overture.txt: ASCII text
      I tried the method that you posted, same problem. Note both files start as ASCII text, then they are emailed (separatley) to the server. Procmail sends them to this program. This program is the one that does the writing. Note that the MIME header is text/plain for both files.

      By Kzin
        Do you really care about the output of file, or do you think the contents of the file are bad? The best way to answer either/both questions is by having a look at the file Google. Please show us (at least a sample of) the file Google (perhaps using od) when file Google returns "Data".
Re: Force Ascii Write
by Kzin (Acolyte) on Apr 06, 2006 at 18:01 UTC
    OK SWEET! Thank you all for your help,
    The solution to this problem was swapping the "printf" with "print".
    I guess the printf command interpereted some of the data in the file as either binary or as formatting marks, not 100% sure which.
    Thanks again for all of your help!

    By Kzin

      As formatting marks. Good catch. The first argument of printf (not counting the file handle) is the format string. % is a special character in the format string. A spate of vulnerabilities that surfaced last year were caused by user text being used as a format string.

      If you do need to use printf for whatever reason, there's a couple of alternatives:

      printf BIDWATCH '%s', $part->bodyhandle->as_string;
      and
      $s = $part->bodyhandle->as_string; $s =~ s/%/%%/g; printf BIDWATCH $s;
        Thanks for those tips, I'll remember it for next time. I think I should use print on the other files I am receiving as well, just to make sure I am not exposing a vulnerability.

        By Kzin