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

Hello. I am so very new to perl and cgi but am learning. Anyway I was just making this simple script so that I could run nmap remotely by using my web server. I used the system() procedure to run nmap. Everything works fine except for the fact that when it prints it to the web page the formatting does not take into account the newlines and such. Basically, what I am asking is how I can format the text to be printed to the webpage to look exactly like when I use nmap in the console. I am simply using the following to print it out.
print system("nmap", "$ip");
Any suggestions on how I could get this to work like I want would be great. Thanks. Digitalx

Replies are listed 'Best First'.
Re: Text formatting a command in CGI
by blokhead (Monsignor) on May 24, 2003 at 02:51 UTC
    As mentioned, system doesn't return the output of the program you run (only its return code). You got lucky with that line of your program: whatever you execute via system shares STDOUT with your script, so the output of nmap happened to get printed to the web page at the right time (only not via your print statement).

    You are on the right track using multi-arg system for safety. If you want to get data back from the call, you can use a magic open call. It's safer than using backticks (see above).

    open(my $fh, '-|', 'nmap', $ip); ## may not be supported in your version of Perl, so ## also consider the equivalent: ## open(my $fh, '-|') or exec 'nmap', $ip; my $data = do { local $/; <$fh> }; close $fh;
    Now you can do what you like with what's in $data -- replace newlines with <br>'s, print between <pre> tags, etc.

    Update: BTW, the <pre> HTML tag makes the browser wrap according to your whitespace (instead of ignoring whitespace), as in my example code snippet. Search for it at your favorite HTML reference site and you will see what I mean.

    Update II:Heh. Yeah, using text/plain will work too. But if you ever want to do anything with the data, get it from the program with the magic open call.

    blokhead

Re: Text formatting a command in CGI
by hacker (Priest) on May 24, 2003 at 13:49 UTC
    There's also IPC::Open3, which often goes unmentioned, but has the added benefit of being able to do reading, writing, and error handling. This means it has access to STDIN, STDOUT, and STDERR.

    Please don't use `backticks` to get system commands to return information you need. You will most-certainly find yourself bitten by that one at some point.

Re: Text formatting a command in CGI
by The Mad Hatter (Priest) on May 24, 2003 at 02:06 UTC

    Update Oops, didn't see the system call was multi-arg. I should probably get some sleep. ; )

    system won't return the text that is spit out onto STDOUT by the program it calls. You should use backticks for that, but the problem with backticks is security holes. As for formatting, just use the pre HTML tag to keep the formatting...

    BUT, you shouldn't be doing any of that, because the person running it could put anything in $ip. You haven't provided other code, so I don't know if you do filtering and escaping, but even then I wouldn't do something like that. It is almost a guaranteed security hole. What if I set $ip to "; rm -rf /"? It would run

    nmap; rm -rf /
    as whatever user the CGI is running as.
      Thanks for the help. I am very new though and do not know what the pre HTML tag is. If someone could explain to an idiot like I would appreciate. Thanks.
      Digitalx
        I am very new though and do not know what the pre HTML tag is.
        Then you'll be wanting to check out http://www.htmlhelp.com, which has the advantage of being written by people who really understand the standards. Lots of links from there to other decent sites too, not cargo-cult sites.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

        Nevermind. I figured it out. text/plain instead of text/html. Thank again for all your help.
      Thanks guys. I really do get the help when I need it here.