Page 1 of 1

Problems with PHP + Curl on Windows

Posted: Thu Jul 19, 2007 9:44 am
by davil
Hi all,
I'm having problems here at work - I'm trying to setup a registry information reporting system that reports info on each client PCs registry back to a Web Server and into a MySQL database.
This seems to be working fine except for some info from the registry that can have spaces, i.e. longdate from the registry comes out as "dd MMMM yyyy" or similar... This is fine if you paste it into a url in firefox or whatever, like test.php?longdate=dd MMMM yyyy but command prompt / dos doesn't like this behaviour (I'm using batch files + CURL on each client PC to send the info to the server).
There's probably a quick fix to solve this problem using FOR but I can't figure it out.. I tried replacing the spaces with dashes but that will only work if the info in the registry string is as above, so as it can change I need a more flexible solution.

at the minute I'm just echoing the SQL query rather than running it but you still get the idea.


Here's go.bat that I use to start the process

Code: Select all

@ECHO OFF
cls
setlocal


\\oldat03\wupdates\NOW.EXE > %TMP%\NOW.TXT

for /F "tokens=1,2,3,4,5 delims=/ " %%i in (%TMP%\NOW.TXT) do set d=%%i %%j %%k %%m
for /F "tokens=1,2,3,4,5 delims=/ " %%i in (%TMP%\NOW.TXT) do set day=%%i
for /F "tokens=1,2,3,4,5 delims=/ " %%i in (%TMP%\NOW.TXT) do set month=%%j
for /F "tokens=1,2,3,4,5 delims=/ " %%i in (%TMP%\NOW.TXT) do set dayofmonth=%%k
for /F "tokens=1,2,3,4,5 delims=/ " %%i in (%TMP%\NOW.TXT) do set timey=%%l
for /F "tokens=1,2,3,4,5 delims=/ " %%i in (%TMP%\NOW.TXT) do set year=%%m

DEL %TMP%\NOW.TXT

if /i [%month%] == [Jan] set month=01
if /i [%month%] == [Feb] set month=02
if /i [%month%] == [Mar] set month=03
if /i [%month%] == [Apr] set month=04
if /i [%month%] == [May] set month=05
if /i [%month%] == [Jun] set month=06
if /i [%month%] == [Jul] set month=07
if /i [%month%] == [Aug] set month=08
if /i [%month%] == [Sep] set month=09
if /i [%month%] == [Oct] set month=10
if /i [%month%] == [Nov] set month=11
if /i [%month%] == [Dec] set month=12




FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKCU\Control Panel\International" /v sCountry') DO SET Country=%%B
FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKCU\Control Panel\International" /v sCurrency') DO SET Currency=%%B
FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKCU\Control Panel\International" /v sLongDate') DO SET LongDate=%%B
FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKCU\Control Panel\International" /v sShortDate') DO SET ShortDate=%%B
FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKCU\Control Panel\International" /v sTimeFormat') DO SET TimeFormat=%%B

FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKEY_CURRENT_USER\Control Panel\PowerCfg" /v CurrentPowerPolicy') DO SET PowerPolicy=%%B

FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKLM\SOFTWARE\Network Associates\TVD\Shared Components\VirusScan Engine\4.0.xx" /v "szVirDefVer"') DO SET VirusDefs=%%B
FOR /F "tokens=2* delims=	 " %%A IN ('\\oldat03\wupdates\reg.exe QUERY "HKLM\SOFTWARE\Network Associates\TVD\Shared Components\VirusScan Engine\4.0.xx" /v "szEngineVer"') DO SET VirusEngine=%%B



echo LONG DATE in batch file=%longdate%
echo SHORT DATE in batch file=%shortdate%
echo.
echo.


SET URL="http://localhost/it2/test.php?datestamp=%year%%month%%dayofmonth%&timestamp=%timey%&hostname=%computername%&username=%username%&country=%Country%&currency=%Currency%&longdate=%LongDate%&shortdate=%ShortDate%&timeformat=%TimeFormat%&powerpolicy=%PowerPolicy%&virusdefs=%VirusDefs%&virusengine=%VirusEngine%&end=1"

"\\oldat03\wupdates\curl.exe" -B -0 %URL%


:end

here's test.php

Code: Select all

<?php
require("config.php");
$tablename="reginfo";

echo "LONGDATE IN PHP=".$_REQUEST['longdate']."\n\n";
echo "SHORTDATE IN PHP=".$_REQUEST['shortdate']."\n\n";



if ( ($_REQUEST['currency'] == "€")or ($_REQUEST['currency'] == "Ç") ){$_REQUEST['currency']="€";}


echo "<PRE>\n\n";


$sqltest = "UPDATE `$tablename` SET ";
foreach ($_REQUEST as $key => $value) {$sqltest.= "`$key` = '$value'\n,";}
$sqltest= rtrim ($sqltest,",");
$sqltest.= " WHERE `macaddress` = '".$_REQUEST['macaddress']."' LIMIT 1";	


echo $sqltest;
?>

Here's the output in Firefox / IE if I just paste the url into the address bar, which works fine:

Code: Select all

LONGDATE IN PHP=dd MMMM yyyy SHORTDATE IN PHP=dd/MM/yyyy

UPDATE `reginfo` SET `datestamp` = '20070719'
,`timestamp` = '14:42:18'
,`hostname` = 'mypcname'
,`username` = 'jsmith'
,`country` = 'Ireland'
,`currency` = '€'
,`longdate` = 'dd MMMM yyyy'
,`shortdate` = 'dd/MM/yyyy'
,`timeformat` = 'HH:mm:ss'
,`powerpolicy` = '3'
,`virusdefs` = '4.0.5070'
,`virusengine` = '5.1.00'
,`end` = '1'
,`PHPSESSID` = '8l3f649g8aihsf8bleaeqloos6'
 WHERE `macaddress` = '' LIMIT 1

Here's the output in command prompt when I use go.bat

Code: Select all

LONG DATE in batch file=dd MMMM yyyy
SHORT DATE in batch file=dd/MM/yyyy


LONGDATE IN PHP=dd

SHORTDATE IN PHP=

<PRE>

UPDATE `reginfo` SET `datestamp` = '20070719'
,`timestamp` = '15:40:16'
,`hostname` = 'mypcname'
,`username` = 'jsmith'
,`country` = 'Ireland'
,`currency` = 'Ç'
,`longdate` = 'dd'
 WHERE `macaddress` = '' LIMIT 1

Now I have tried adding inverted commas around the URL, like this:

Code: Select all

"\\oldat03\wupdates\curl.exe" -B -0 "%URL%"
but that didn't work - obviously DOS doesn't like the ampersand so I tried replacing every ampersand with caret + ampersand( ^& ) but that didn't work either.
Is there any way to get the Command prompt to ignore the spaces (if there are any spaces)

If anybody can point me in the right direction, any help would be much appreciated.


I'm using curl for windows, here's the Version output

curl 7.16.0 (i586-pc-mingw32msvc) libcurl/7.16.0 zlib/1.2.2
Protocols: tftp ftp telnet dict ldap http file
Features: Largefile libz

Posted: Thu Jul 19, 2007 9:57 am
by Begby
Echo your URL in the batch file. I think that you will find it to be invalid, i.e. it has spaces in it. It appears to be cutting off at the first space, so curl.exe is only getting passed everything up to that point. You will need to properly escape the URL string by replacing special characters like ' ' with %20 etc. I have no idea how you would do that in DOS, but I am sure there is a way.

Posted: Thu Jul 19, 2007 9:59 am
by davil
Thanks for ur reply

Oh yeah, I forgot to mention I had tried replacing spaces with %20 but that didn't work either

Code: Select all

set longdate=dd%20mm%20yyyy
gives the following output:

`longdate` = 'dd0mm0yyyy'

I could write PHP to strip the zeroes but again this doesn't get my original REG string into the MySQL database, which is what I want to do.
I could write loads of checking PHP and batch but I'm sure there's a better/more efficient way to do this.

Any ideas?

Posted: Thu Jul 19, 2007 10:02 am
by davil
ahah.... maybe the best way is to replace spaces with something like £-£ or something that shouldn't already be in the text and then replacing that again in the PHP with spaces... it would work but it's not great programming - I mean what happens when some crazy fool edits their registry and puts in £-£ - stranger things have happened.

[edit]I'll probably write a quick EXE in Freebasic to do some of the replacing work but it just seems a bit messy[/edit]

Posted: Thu Jul 19, 2007 10:09 am
by Begby
Its replacing it in DOS with 0 because % is the marker for a variable, and %2 means the second variable passed through STDIN. Since there are no arguments when you run the batch file %2 just comes out blank leaving the zero behind. You need to escape the %, like \%20 maybe. I am not sure how to do that, but there has got to be a way.

Or you can put in a 'get it done' hack like you mentioned.

Posted: Thu Jul 19, 2007 10:40 am
by davil
Sorry yes %2 I should have thought of that....

anyhow at the minute I'm working on a get it done hack like so:
go.bat -> clean.exe -> curl -> phpserver

clean.exe basically just written in Freebasic and it replaces spaces with something like "(P)z6IrQfg" because I'm lazy and couldn't think of anything else.... and also because it's unlikely to be a string in registry, although it could be.... perhaps I should make it longer.... hmmmm I dunno...

then when it is submitted to the PHP server I use PHP to str_replace the above string with a space so everything is back to normal...

It's not pretty but it should do the trick.
One problem I might have is the URL for CURL could be extremely long.... perhaps too long....

Anybody have any other ideas?