How to determine the target machine from a DLL? - dll

How can I determine the machine on which a given DLL can run. There are many platforms ARM, SH4, x64, x32. When I have no other information than the DLL itself how to do that?
Background: There is a set off DLLs and some of them are not appropriate. How to detect them "offline"?
SOLUTION
Thanks for the help: the solution I use is the perl script
#!/usr/bin/perl
#
# usage: DllVer <exefile>
#
use strict;
use warnings;
use diagnostics;
my $exe = $ARGV[0];
my $doshdr; my $pehdr;
my %machines = (
0x014c => "I386",
0x0162 => "R3000",
0x0166 => "R4000",
0x0168 => "R10000",
0x0169 => "WCEMIPSV2",
0x0184 => "ALPHA",
0x01a2 => "SH3",
0x01a3 => "SH3DSP",
0x01a4 => "SH3E",
0x01a6 => "SH4",
0x01c0 => "ARM",
0x01c2 => "THUMB",
0x01d3 => "AM33",
0x01f0 => "POWERPC",
0x01f1 => "POWERPCFP",
0x0200 => "IA64",
0x0266 => "MIPS16",
0x0284 => "ALPHA64",
0x0366 => "MIPSFPU",
0x0466 => "MIPSFPU16",
0x0520 => "TRICORE",
0x8664 => "AMD64",
0x9041 => "M32R",
);
open(EXE, $exe) or die "can't open $exe: $!";
binmode(EXE);
if (read(EXE, $doshdr, 68)) {
my ($magic,$skip,$offset)=unpack('a2a58l', $doshdr);
die("Not an executable") if ($magic ne 'MZ');
seek(EXE, $offset, 0);
if (read(EXE, $pehdr, 6)){
my ($sig,$skip,$machine)=unpack('a2a2v', $pehdr);
die("No a PE Executable") if ($sig ne 'PE');
if (exists $machines{$machine}) {
print $machines{$machine} . "\n";
}
else{
printf("Unknown machine type 0x%lx\n", $machine);
}
}
}
close(EXE);

Try this perl script:
#!/usr/bin/perl
#
# usage: DllVer <exefile>
#
$exe = $ARGV[0];
open(EXE, $exe) or die "can't open $exe: $!";
binmode(EXE);
if (read(EXE, $doshdr, 68)) {
($magic,$skip,$offset)=unpack('a2a58l', $doshdr);
die("Not an executable") if ($magic ne 'MZ');
seek(EXE,$offset,SEEK_SET);
if (read(EXE, $pehdr, 6)){
($sig,$skip,$machine)=unpack('a2a2v', $pehdr);
die("No a PE Executable") if ($sig ne 'PE');
if ($machine == 0x014c){
print "i386\n";
}
elsif ($machine == 0x0200){
print "IA64\n";
}
elsif ($machine == 0x8664){
print "AMD64\n";
}
else{
printf("Unknown machine type 0x%lx\n", $machine);
}
}
}
close(EXE);

One way is to use the dumpbin utility:
C:\Windows\System32>dumpbin /headers kernel32.dll
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file kernel32.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
4 number of sections
49E037DD time date stamp Sat Apr 11 08:25:33 2009
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic # (PE32)
8.00 linker version
... etc ...

Related

Selenium Perl handle shadow DOM

There are plenty examples using Selenium Python to handle shadow DOM. I'd like to do the same in Perl.
Perl's Selenium::Remote::Driver doesn't have shadow DOM support, but I should be able to do it through JavaScript. I got my inspiration from
accessing-shadow-dom-tree-with-selenium.
The following is my code in Perl
#!/usr/bin/env perl
use Selenium::Chrome;
my $driver = Selenium::Chrome->new (
startup_timeout => 60,
custom_args => "--log-path=/tmp/selenium_chromedriver",
logfile => "/tmp/selenium_chromedriver2",
debug_on => 1,
extra_capabilities => {
'goog:chromeOptions' => {
args => [
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1260,720',
'--user-data-dir=/tmp/selenium_chrome',
],
},
},
);
$driver->get("chrome-search://local-ntp/local-ntp.html"); # chrome new tab
my $shadow_host = $driver->find_element("html/body/ntp-app", "xpath");
my $shadow_root = $driver->execute_script('return arguments[0].shadowRoot', $shadow_host);
for my $e ( #{$shadow_root->find_elements(':host > *', 'css')} ) {
# error: Can't call method "find_elements" on unblessed reference
print "found\n";
}
$driver->shutdown_binary();
But I got error: Can't call method "find_elements" on unblessed reference.
How can I overcome this error?
Thank you for any help.
My environment is: ubuntu 18, Perl 5.26, Selenium:Chrome 1.46, Chrome
99, chromedriver 99.
The same mechanism is tested working with Python
3.8.5.
Why I am not using Python? because the server in my work place only has Perl, no Python 3.
the following code works
#!/usr/bin/env perl
use Selenium::Chrome;
my $driver = Selenium::Chrome->new (
startup_timeout => 60,
custom_args => "--log-path=/tmp/selenium_chromedriver",
logfile => "/tmp/selenium_chromedriver2",
debug_on => 1,
extra_capabilities => {
'goog:chromeOptions' => {
args => [
'--no-sandbox',
'--disable-dev-shm-usage',
'--window-size=1260,720',
'--user-data-dir=/tmp/selenium_chrome',
],
},
},
);
$driver->get("chrome-search://local-ntp/local-ntp.html"); # chrome new tab
my $shadow_host = $driver->find_element("html/body/ntp-app", "xpath");
package MyShadow {
sub new {
my ($class, %attrs) = #_;
my $shadow_root = $attrs{driver}->execute_script('return arguments[0].shadowRoot', $attrs{shadow_host});
return undef if ! $shadow_root;
$attrs{shadow_root} = $shadow_root;
bless \%attrs, $class;
}
sub find_element {
my ($self, $target, $scheme) = #_;
die "scheme=$scheme is not supported. Only css is supported" if $scheme ne 'css';
return $self->{driver}->execute_script(
"return arguments[0].querySelector(arguments[1])",
$self->{shadow_root},
$target
);
}
sub find_elements {
my ($self, $target, $scheme) = #_;
die "scheme=$scheme is not supported. Only css is supported" if $scheme ne 'css';
return $self->{driver}->execute_script(
"return arguments[0].querySelectorAll(arguments[1])",
$self->{shadow_root},
$target
);
}
};
my $shadow_driver = MyShadow->new(driver=>$driver, shadow_host=>$shadow_host);
if ($shadow_driver) {
for my $e ( #{$shadow_driver->find_elements(':host > *', 'css')} ) {
print "found\n";
}
}
$driver->shutdown_binary();
Key points:
For Selenium, no matter Python or Perl, they are wrappers to
javascript. As long as you get correct javascript, you can do
whatever you want.
For Shadow driver, all you need to implement is the find_element() and find_elements().
I only implemented 'css', no 'xpath', because that's what Python does as of 2022/09/19.

Informix fetch using rivet not returning end of query results

We are having an issue running Tclsql code from a web page using Rivet and Informix.
When we run the TCL code that executes the query from a command line script, it works. The Informix C library fetch sets the value of sqlca.sqlcode to 100 after it has fetch the last row of data. Then, the tclsql C library sets the result string to "", which is what the command line TCL script uses to determine that all of the results have been fetched.
When we run the same script from a browser using Rivet, the Informix C library fetch does not set the sqlca.sqlcode value to 100 after it has fetched the last row of results. Instead, it sets it to 0, indicating that there are more results, and returns the last query result to the tclsql C library, which then returns the last query result to the TCL script that we ran from the browser (instead of "").
Here is the script that we run from the command line:
#!/bin/sh
# Next line restarts using tclsh \
exec /BSG/local/bin/tclsh "$0" "$#"
package require Tclsql
sql database devncrs
set query "SELECT count(*) FROM district"
set cur [sql open $query]
while { [set result [sql fetch $cur 1]] != "" } {
puts $result
}
sql close $cur
The query should return 110 (which is the count for the table) to the TCL script above and then return a "", which it does.
Here is the script that we run from the browser:
package require Tclsql
sql database devncrs
set query "SELECT count(*) FROM district"
set cur [sql open $query]
while { [set result [sql fetch $cur 1]] != "" } {
puts "<br>result = '$result`"
}
sql close $cur
This code gets stuck in and endless while loop because it never gets "" back
from the tclsql C library.
We compiled rivet, TCL, and Informix on the same LINUX box using the same version of the OS and installed Apache with the lampp package.
Here is the environment:
OS: Linux dev-ncrs-web4 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
Apache version: 2.4.27
Rivet version: 2.3.4
TCL version: 8.6.6
Informix version: 4.10
Here are the libraries being used by libtclsql.so, libsqlinf.o, and mod_rivet.so
ldd libsqlinf.so
linux-vdso.so.1 => (0x00007ffe691e0000)
libixsql.so => /usr/informix/lib/esql/libixsql.so (0x00007f6426bab000)
libixasf.so => /usr/informix/lib/libixasf.so (0x00007f6426962000)
libixgen.so => /usr/informix/lib/esql/libixgen.so (0x00007f64266fe000)
libixos.so => /usr/informix/lib/esql/libixos.so (0x00007f64264dd000)
libixgls.so => /usr/informix/lib/esql/libixgls.so (0x00007f642628a000)
libcrypt.so.1 => /usr/lib64/libcrypt.so.1 (0x00007f6426053000)
libm.so.6 => /usr/lib64/libm.so.6 (0x00007f6425d51000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007f642598d000)
libfreebl3.so => /usr/lib64/libfreebl3.so (0x00007f642578a000)
/lib64/ld-linux-x86-64.so.2 (0x000055862238b000)
libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007f6425586000)
ldd libtclsql.so
linux-vdso.so.1 => (0x00007ffe22fc5000)
libsqlinf.so (0x00007ff9a85b0000)
libtcl8.6.so => /BSG/local/lib/libtcl8.6.so (0x00007ff9a8201000)
libixsql.so => /usr/informix/lib/esql/libixsql.so (0x00007ff9a7fad000)
libixasf.so => /usr/informix/lib/libixasf.so (0x00007ff9a7d65000)
libixgen.so => /usr/informix/lib/esql/libixgen.so (0x00007ff9a7b00000)
libixos.so => /usr/informix/lib/esql/libixos.so (0x00007ff9a78df000)
libixgls.so => /usr/informix/lib/esql/libixgls.so (0x00007ff9a768d000)
libcrypt.so.1 => /usr/lib64/libcrypt.so.1 (0x00007ff9a7455000)
libm.so.6 => /usr/lib64/libm.so.6 (0x00007ff9a7153000)
libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007ff9a6f4f000)
libz.so.1 => /usr/lib64/libz.so.1 (0x00007ff9a6d38000)
libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007ff9a6b1c000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007ff9a6759000)
libfreebl3.so => /usr/lib64/libfreebl3.so (0x00007ff9a6555000)
/lib64/ld-linux-x86-64.so.2 (0x000055873ec47000)
ldd mod_rivet.so
linux-vdso.so.1 => (0x00007ffdbfbf2000)
libtcl8.6.so => /BSG/local/lib/libtcl8.6.so (0x00007fcd949e0000)
libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007fcd947db000)
libz.so.1 => /usr/lib64/libz.so.1 (0x00007fcd945c5000)
libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007fcd943a9000)
libm.so.6 => /usr/lib64/libm.so.6 (0x00007fcd940a6000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007fcd93ce3000)
/lib64/ld-linux-x86-64.so.2 (0x000056435fdca000)
Has anyone else encountered this problem or have any idea what might be causing the fetch, as it is executed through rivet, to not set the value of sqlca.sqlcode to 100 after the last result has been fetched? We had similar results when we ran a query that returned more than one row.
I found what I am going to call a workaround for this problem. I modified the tclsql.c and sqlinf.ec files that we u
se.
The TCL SQL "sql fetch" calls a function in the isqltcl4.0 library tclsql.c file named tcl_sql_fetch.
The tcl_sql_fetch function calls a function in the isqltcl4.0 library sqlinf.ec file named sql_fetch.
The sql_fetch function executes the fetch on the Informix database server it and a row is fetched. If there are no m
ore rows to fetch, the sql server code should set the value of sqlca.sqlcode to 100. When we ran a TCL fetch from a
TCL script run from the command line, it worked fine. When we ran the same TCL code from a browser using rivet and a
pache, the value of sqlca.sqlcode was always set to 0. This caused the code in the tclsql.c tcl_sql_fetch function to
think that there were more rows to fetch and it did not return a blank result string "". Instead, it return the las
t value fetched over and over again. As a result, the TCL script while loop never stopped.
Here is the code that sets returns the value from the sqlinf.ec sql_fetch function to the tclsqlc tcl_sql_fetch funct
ion:
ret = sqlca.sqlcode;
chk_status("FETCH(OPEN)", ssql[fd].cmd);
return ret;
The sqlca.sqlcode was never set to 100 when the script was run from a browser.
To remedy this, I added wrote a new sql_fetch function in sqlinf.ec named "bnc_sql_fetch" and passed it an integer value
int bnc_sql_fetch(fd, bnc_fetch_count)
I added a static integer to the tclsql.c file named bnc_fetch_count. The bnc_fetch_count static int variable was initialized to 0 in the tcl_sql_open function in tclsql.c and incremented by 1 each time the bnc_sql_fetch function was called.
Then, in the bnc_sql_fetch function, I check the value of bnc_fetch_count against that of the first element in the integer array sqlca.sqlerrd, which contains the total number of rows to be fetched. If it was greater than the total number of rows to be fetched, then the last row had been fetch and it returns 100.
if ( bnc_fetch_count > sqlca.sqlerrd[0] ) {
ret = 100;
chk_status("FETCH(OPEN)", ssql[fd].cmd);
return ret;
}
This fixed the problem.

Perl6: How to find all installed modules whose filename matches a pattern?

Is it possible in Perl6 to find all installed modules whose file-name matches a pattern?
In Perl5 I would write it like this:
use File::Spec::Functions qw( catfile );
my %installed;
for my $dir ( #INC ) {
my $glob_pattern = catfile $dir, 'App', 'DBBrowser', 'DB', '*.pm';
map { $installed{$_}++ } glob $glob_pattern;
}
There is currently no way to get the original file name of an installed module. However it is possible to get the module names
sub list-installed {
my #curs = $*REPO.repo-chain.grep(*.?prefix.?e);
my #repo-dirs = #curs>>.prefix;
my #dist-dirs = |#repo-dirs.map(*.child('dist')).grep(*.e);
my #dist-files = |#dist-dirs.map(*.IO.dir.grep(*.IO.f).Slip);
my $dists := gather for #dist-files -> $file {
if try { Distribution.new( |%(from-json($file.IO.slurp)) ) } -> $dist {
my $cur = #curs.first: {.prefix eq $file.parent.parent}
take $_ for $dist.hash<provides>.keys;
}
}
}
.say for list-installed();
see: Zef::Client.list-installed()

Apache PerlAuthzHandler and form POST vars

I have a mod_perl PerlAuthzHandler authorizing access to directories served by Apache2. In terms of controlling access it is working well.
A side effect, though, is that it seems to be preventing POST form variables from being available to PHP apps in the protected locations. At least when I comment out the PerlAuthzHandler and reload Apache the PHP app functions again. I think either the full environment is not being inherited by Perl or Perl is sending a cleansed environment on.
Is it possible to ensure that all POST variables are available to the PHP application after authorization?
Details
User authentication is managed by simplesamlphp on this box, the SP, and ADFS, the IdP. The addition to the simplesamlphp installation is the use of PerlAuthzHandler.
Apache configuration
The Apache configuration for the location in question looks like this:
<Location /activity>
ErrorDocument 401 "/simplesaml/authmemcookie.php"
AuthName "MCLAnet"
AuthType Cookie
Require valid-user
PerlSetvar Auth_memCookie_SessionTableSize "40"
PerlAuthzHandler My::simple
PerlSetVar VALID_GROUP_EXPR "status-acad or staff-g"
</Location>
Authorization handler
The authorization handler retrieves group memberships recorded in setting up the session and compared to a VALID_GROUP_EXPRESSION in the PerlSetVar:
#! /usr/bin/perl
package My::simple;
# Version 1.0 MCLA CSS
use Apache2::Access ();
use Apache2::RequestUtil ();
# load modules that are going to be used
use Data::Dumper;
use CGI qw(:standard);
use CGI::Cookie;
use Cache::Memcached;
use PHP::Serialization qw(serialize unserialize);
# compile (or import) constants
use Apache2::Const -compile => qw(OK FORBIDDEN);
$debug=0;
$debug_file="/tmp/xxx";
dmp('prerun',('test'));
sub handler {
my $r = shift;
my $user = $r->user;
dmp('0 user',$user);
# ------------------------ get valid group(s) for this session
my $valid_group_expr=$r->dir_config("VALID_GROUP_EXPR");
dmp('1 valid group list',$valid_group_expr);
# -- get the session cooke to retrieve the session <ID>
$query = new CGI;
# fetch existing cookies
my %cookies = CGI::Cookie->fetch;
# dmp('Cookies',%cookies);
my $ID = $cookies{'SimpleSAMLSessionID'}->value;
dmp('2 SimpleSAMLSessionID value',$ID);
my $SessionID='simpleSAMLphp.session.' . $ID;
# -- use the session ID to look up the value of memcached key simpleSAMLphp.session.<ID>
my $cache = new Cache::Memcached {
'servers' => ['127.0.0.1:11211'],
'compress_threshold' => 10_000,
};
# Get the value from cache:
my $value = $cache->get($SessionID);
# dmp('mamcache value',($value));
# -- use the value data to find the groups
my $hashref = unserialize($value);
# dmp('mamcache unserialized',($hashref));
my %hash = %{ $hashref };
%hash = % { $hash {'data'}{chr(0) . 'SimpleSAML_Session' . chr(0) . 'authData'}{'default-sp'}{'Attributes'} };
my #groups = # { $hash{'groups'} };
dmp("3 Comparing $valid_group_expr to", \#groups);
my $result=evaluate($valid_group_expr,#groups);
if ($result) {
dmp("this guy oK",$result);
return Apache2::Const::HTTP_OK;
}
dmp("blowing this guy off",$result);
$r->log_reason("Not a member of group " . $valid_group_expr);
return Apache2::Const::FORBIDDEN;
# return Apache2::Const::HTTP_FORBIDDEN;
# return Apache2::Const::HTTP_OK;
# return Apache2::Const::DECLINED;
}
# ======================= utility functions
# evaluate returns the boolean value of the expression $expr
# after substituting membership information in #groups
#
# valid operators are
#
# &&, and, AND logical AND
# ||, or, OR logical OR
# !, NOT, not logical NOT
#
# expression must be infix and precidence can be indicated by ()
sub evaluate {
my ($expr,#groups)=#_;
# print "$expr\n";
# print Dumper(\%group_hash);
# operator tokens
my %token_hash = (
'(' => '(',
')' => ')',
'AND' => '&&',
'and' => '&&',
'or' => '||',
'OR' => '||',
'!' => '!',
'not' => '!',
'NOT' => '!',
) ;
# add the group array into the token hash as TRUEs
foreach $v (#groups) {
$v=~s/ /_/g;
$token_hash{$v} = 1;
}
dmp('merged hash',\%token_hash);
# merge the two hashes into %token_hash
# foreach my $tkey ( keys %group_hash) { $token_hash{$tkey} = $group_hash{$tkey}; }
# print Dumper(\%token_hash);
$expr=~s/\(/ ( /g;
$expr=~s/\)/ ) /g;
$expr=~s/\!/ ! /g;
# print "$expr\n";
my #expr_hash=split (/ /,$expr);
$expr='';
foreach my $t (#expr_hash) {
if ($t ne '') {
if (exists ($token_hash{$t})) { $t = $token_hash{$t} } else {$t = 0;}
$expr = $expr . "$t ";
}
}
dmp("expression",$expr);
my $result=0;
my $assignment="\$result = $expr;";
dmp("assignment",$assignment);
eval($assignment);
dmp("result",$result);
return $result;
}
# debug dump structure funcion
sub dmp {
if ($debug == 1) {
my ($label,#value) = #_;
my $temp = Dumper(#value);
open (T, ">>$debug_file"); # || die "Can't open $debug_file: $!\n";
print T "$label: $temp\n";
close (T);
}
}
1;
Failing PHP script
The simple PHP form below displays no value when the Perl authorization is enabled. If I comment out the PerlAuthzHandler line both $_POST'[submit'] and $_POST['in1'] are set.
<?php
if (isset($_POST['submit'])) { print_r($_POST); }
$form=<<<EOT
<form name="test" action="y.php" method="post">
<input name="in1">
<input type="submit" name="submit">
</form>
EOT;
print $form;
?>
Again, authentication (simplesamlphp/ADFS) and authorization both work as expected. The exception is that when authorization is used no $_POST variables are available.
RESOLUTION
As often happens the problem was of my own making. One of the kind monks at perlmonks.org pointed out that the Perl handler contained the line:
$query = new CGI;
Removing that did it. Since I was in fact only accessing but not changing anything there was no point to it and in fact $query was never used.

retrieve data from online database using input file

Im using Postgres 9.3 on MacOSX.
I would be very happy if anyone could point me in the right direction here. I would like to write a function which connects to an existing (online) database (e.g. this one) and retrieves data (in this case shapefiles) using an input file with appropriate strings (in this case MRGIDs). Im sorry I don't have any code, I literally don't know where to start and I don't seem to find any threads on it. Maybe SQL isn't the way to go here?
Input file example;
species,mrgids
Sp1,4279
Sp1,8366
Sp1,21899
Sp1,21834
Sp1,7130
Sp1,1905
Sp1,21900
Sp1,5679
Sp1,5696
Thanks!
This is almost certainly done best outside the database, using a script in your choice of language. I'd use Python and psycopg2, but things like Ruby + the Pg gem, Perl and DBI / DBD::Pg, or even PHP and PDO, are equally reasonable choices.
Your code can do an HTTP fetch, then (if it's CSV-like) use the COPY command to load the data into PostgreSQL. If it's a shapefile, you can feed the data to PostGIS's shp2pgsql loader, or make individual INSERTs using the GeomFromText PostGIS function.
You could do the HTTP fetch from a PL/Pythonu or PL/Perlu stored procedure, but there'd be no real benefit over just doing it from a script, and it'd be more robust as an external script.
So, really, you need to split this problem up.
You'll need code to talk to the website(s) of interest, possibly including things like HTTP POSTs to submit forms. Or, preferably, use a web API for the site(s) that's designed for automatic scripted interaction. Most simple RESTful APIs are easy to use from scripting languages using libraries like Perl's LWP, Python's httplib, etc. In the case of the site you linked to, as user623952 mentioned, there's a RESTful API.
Then you'll need code to fetch the data of interest, and code to read the fetched data and load it into PostgreSQL. You might want to download all the data then load it, or you may want to stream it into the database as it's downloaded (pipe to shp2pgsql, etc).
this a very basic example with with PHP and CURL
I used your input file exactly and saved it as input.txt
species,mrgids
Sp1,4279
Sp1,8366
Sp1,21899
Sp1,21834
Sp1,7130
Sp1,1905
Sp1,21900
Sp1,5679
Sp1,5696
and this is the PHP and CURL doing its stuff:
<?php
$base_url = "http://www.marineregions.org/rest/getGazetteerRecordByMRGID.json/%s/";
// just get the input file into an array to use
$csv = read_file("input.txt");
// if you want to see the format of $csv
print "<pre>".print_r($csv,true)."</pre>";
// go through each csv item and run a curl request on it
foreach($csv as $i => $data)
{
$mrgids = $data['mrgids'];
$url = sprintf($base_url,$mrgids);
$response = run_curl_request($url);
if ($response!==false)
{
//http://us2.php.net/manual/en/function.json-decode.php
$json = json_decode($response,true);
if (!is_null($json))
{
// this is where you would write the code to stick this info in
// your DB or do whatever you want with it...
print "<pre>$url \n".print_r($json,true)."\n\n</pre>";
}
else
{
print "error: response was not proper JSON for $url <br/><br/>";
print $response."<br/><br/><br/>";
}
}
else
{
print "error: response was false for $url <br/><br/>";
}
}
function read_file($filename, $has_headers=true, $assoc=true)
{
$headers = array();
$row = 1;
if (($handle = fopen($filename, "r")) !== FALSE)
{
$return = array();
if ($has_headers)
{
if (($data = fgetcsv($handle, 1000, ",")) !==false)
{
$headers = $data;
}
}
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
if ($assoc)
{
$temp = array();
foreach($headers as $hi => $header)
{
$temp[$header] = (isset($data[$hi])) ? $data[$hi] : '';
}
$return[] = $temp;
}
else
{
$return[] = $data;
}
}
fclose($handle);
}
else
{
$return = false;
}
return $return;
}
// requires PHP CURL extension
// http://php.net/manual/en/function.curl-setopt.php
function run_curl_request($url)
{
// create curl resource
$ch = curl_init();
$defaults = array(
CURLOPT_POST => false,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => true,
CURLOPT_FAILONERROR => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FORBID_REUSE => true,
CURLOPT_TIMEOUT => 4
);
curl_setopt_array($ch, $defaults);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
return $output;
}
?>
And if it worked, you get a bunch of these as output:
http://www.marineregions.org/rest/getGazetteerRecordByMRGID.json/4279/
Array
(
[MRGID] => 4279
[gazetteerSource] => IHO 23-3rd: Limits of Oceans and Seas, Special Publication 23, 3rd Edition 1953, published by the International Hydrographic Organization.
[placeType] => IHO Sea Area
[latitude] => 39.749996185303
[longitude] => 5.0942182540894
[minLatitude] => 35.071937561035
[minLongitude] => -6.0326728820801
[maxLatitude] => 44.42805480957
[maxLongitude] => 16.221109390259
[precision] => 1079464.0796258
[preferredGazetteerName] => Mediterranean Sea - Western Basin
[preferredGazetteerNameLang] => English
[status] => standard
[accepted] => 4279
)
notes:
I had to do this to get CURL to work on WAMP for PHP 5.3.13
json_decde()
curl_setopt()
curl_exec()
fgetcsv()
curl_multi_exec() - look into this if you chose this route, you will want it