views:

427

answers:

8

In a previous post, I was trying to update the encoding for a download file from php. One of the suggestions was to run the unix2dos command before sending the file to the user. This works great when I run the command on the linux box, but when I try and run the command from php I get nothing. Here is what I tried:

$cmd = "unix2dos -n $fullPath $downloadFile";

echo exec($cmd, $out, $retVal);

This displays nothing to the screen, $retVal is 0, and $out is an empty string.

echo system($cmd, $retVal);

This displays nothing to the screen, $retVal is 0.

echo shell_exec($cmd);

This displays nothing to the screen.

I have also tried escaping the command and it parameters like:

$cmd = escapeshellcmd($cmd);

and

$cmd = "unix2dos ". escapeshellarg("-n \"$fullPath\" \"$downloadFile\"");

Please let me know if you see something that I am doing wrong.

Thanks!

Edit: Here is some info that may be helpful. unix2dos version: 2.2 (1995.03.31) php version 5.2.9 Running in apache 2 on in Redhat Enterprise Linux 4

A: 

Are you using the full path to unix2dos? Perhaps the executable is in your path for your shell but not in the path that PHP is using.

Tim
A: 

My implementation of unix2dos produces no output. If the return value is 0 then the command succeeded and your file has been updated.

The only other thing I see is the -n option which my version doesn't seem to have. You should probably check your man page to see what options it supports

Cfreak
As I stated above, the exact command works from the command line.
aquillin
I have looked at the file after it teh command has completed and it does the file is empty. But when I run the command from the command line, the file converts perfectly.
aquillin
A: 

unix2dos does not display the file it converts. Therefor you must display it yourself. A very basic way to do it could be :

$cmd = "unix2dos -n $fullPath $downloadFile";

echo exec($cmd, $out, $retVal);

include "$fullPath."/".$downloadFile;

Using include is pretty dirty but quick and easy. A cleaner way would be to use fopen and read the file then display it.

You'd better create a function that enclose all the operation : conversion + display so you'll have everything at hands.

But, If I were you, I'd prefer to not use exec at all and use FileIterator with a trim on every line so you will not have to care about the carriage return nor deal with a hazardous shell binding.

e-satis
I am not actually looking to display the output of the file. exec returns the output of the command that was executed, and in the case of unix2dos it is something like "unix2dos: the file ... and ben converted to ..", which is what I want to display.
aquillin
OK, I changed your title to make it clear.
e-satis
Yeah, I changed it back (well slightly), because the issue is not that I cannot diplay the output, but that the command does not execute correctly.
aquillin
A: 

Not sure about your exact problem, but debugging suggestion:

Try first setting $cmd to ls. See if that works. Then try using /bin/ls (use the full path.)

If those don't work, then there might be a problem with your PHP configuration - there might be a safemode parameter or something which disallows the use of exec(), shell_exec(), or system() functions.

rascher
Yep already tried that and the ls command works fine. I get a list of all the files in the directory...
aquillin
+1  A: 

See which user the PHP exec command is running as:

<?php system('whoami'); ?>

If this command fails then you likely do not have permission to use exec() or system(), so check your INI files. But be sure to check the correct ones! On Debian systems there are separate Apache and CLI INI files stored at /etc/php5/apache/php.ini and /etc/php5/cli/php.ini respectively. Sorry I do not know the locations for RedHat.

If the whoami command succeeds, make sure that the unix2dos command can be run by the user that is shown, and that the same user is allowed to make changes to the files in question by using chmod or chown.

brownstone
The command works, it is running as the apache user. the unix2dos has execute provaleges to all users, and the directory in which the files are being read/written from/to are 0777. So I am still not sure why this does not work
aquillin
Try "chown www-data:www-data unix2dos" and the same for the files/folders you're writing to.
brownstone
Addendum: Oops, you said the user was "apache", so that command should be "chown apache:apache unix2dos/file/folder"
brownstone
A: 

Tried using passthru()?

Shadi Almosri
+2  A: 

Have you considered a pure PHP solution?

<?php

$unixfile = file_get_content('/location/of/file/');
$dosfile= str_replace("\n", "\r\n", $unixfile );
file_put_contents('/location/of/file/', $dosfile);

?>

Something like that should do it, although untested :)

Shadi

Shadi Almosri
A: 

I got the source code from here.

http://www.sfr-fresh.com/linux/misc/unix2dos-2.2.src.tar.gz

I compiled it and then ran the tool. This was my output:

rascher@danish:~/unix2dos$ ./a.out -n 1.txt 2.txt 
unix2dos: converting file 1.txt to file 2.txt in DOS format ...

I think the problem is this: the program writes all of its output to stderr, rather than stdout. If you look at the source code, you can see "fprintf(stderr, ...)"

As far as I know, PHP will only read the part of your program's output that is sent to STDOUT. So to overcome this, it seems like you have to redirect the output of your program (unix2dos uses stderr) to stdout. To do this, try something like:

 $cmd = "unix2dos -n $fullPath $downloadFile 2>&1"

The "2>" means "redirect stderr" and "&1" means "to stdout".

In either case, I would imagine that the file was converting properly, but since you weren't getting any of the expected output, you thought it was failing. Before making the change, check on the output file to see if it is in DOS or UNIX format.

rascher