Adding 2 values in a Batch PHP file - php

Below code works great with getting only a bunch IP address and add it to Cacti --description='".$dev."' --ip='".$dev."', now I want to add bunch of IP with their description in cacti forexample(--description='".$hostname."' --ip='".$dev."').
I am newbie to PHP and don't know how to add 2 values instead of 1 value in PHP.
devices.txt
1.1.1.1
add_device_bulk.php
if ($handle) {
while (($line = fgets($handle)) !== false) {
$line = chop($line);
print "[".$line."] \n";
createHost($line);
}
} else {
die("Could not open file $filename!");
}
die;
function createHost($dev)
{
global $community;
global $hosttemplate;
print "================== Creating Node & Graph for $dev =======================\n";
$ret = cmd("/usr/bin/php add_device.php --quiet --description='".$dev."' --ip='".$dev."' --template=$hosttemplate --community='".$community."' --avail=snmp ");
//Get host id from: [RET] Success - new device-id: (20)
if (preg_match("/\((\d+)\)/", $ret, $matches))
{
$deviceID = $matches[1];
print "Device ID: $deviceID \n";
//We got a device - create graphs for device
$ret = cmd("/usr/bin/php add_graphs.php --graph-type=ds --graph-template-id=5 --host-id=".$deviceID." --snmp-query-id=1 --snmp-query-type-id=10 --snmp-field=ifOperStatus --snmp-value-regex=Up --snmp-field=ifDescr --snmp-value-regex='GigabitEthernet'");
//RET: Graph Added - graph-id: (34) - data-source-ids: (37, 37)
if (preg_match("/\((\d+)\)/", $ret, $matches)) {
$graphID = $matches[1];
//We got a graph - add it to default tree
# cmd("/usr/bin/php /cacti/appl/cacti/cli/add_tree.php --type=node --node-type=graph --tree-id=1 --graph-id=".$graphID);
}
}
}
function cmd($cmd)
{
print "[CMD] $cmd\n";
$ret = exec($cmd)."\n";
print "[RET] $ret\n";
return $ret;
}
Now I want to add description instead of IP and have a text file as below:
devices.txt
Link1, 1.1.1.1

Related

PHP file_get_contents check source online or not before do the execution

I'm using PHP file_get_contents to read text file data.
Assuming I have 2 IP Address, 1 online and 1 offline:
192.168.180.181 - Online
192.168.180.182 - Offline
And the PHP
$fileAccept = file_get_contents("\\\\192.168.180.181\\Reports\\".$dModel['MODEL_NAME'].$source."\\Accept\\Accept_".$dDtl['MODEL_CODE']."_".$dateCode."_".$dDtl['TS_CODE'].".txt");
As We Know IP Address 192.168.180.182 is offline, then I tried to run the code. And result the page always loading.
My question, how can I prevent it maybe first need to check the IP is alive or not, if alive then can continue to next step.
Maybe something like this:
if(IP IS OFFLINE)
{
echo "do not do anything";
}
else
{
echo "do something";
}
you can try something like that
$scc = stream_context_create(array('http'=>
array(
'timeout' => 120, //120 seconds
)
));
$url = "http://192.168.180.181/....";
$handle = file_get_contents('$url, false, $scc);
you can create two handles and check whether is ok with if statement, of course you can change the timeout to suites you
Update:
if accessing file locally you can check this stream_set_timeout() function , the documentation is here
This solution is based on pinging the IP you need to check
class IPChecker{
public static function isIPOnline($ip){
switch (SELF::currentOS()){
case "windows":
$arg = "n";
break;
case "linux":
$arg = "c";
break;
default: throw new \Exception('unknown OS');
}
$result = "";
$output = [];
// to debug errors add 2>&1 to the command to fill $output
// https://stackoverflow.com/questions/16665041/php-why-isnt-exec-returning-output
exec("ping -$arg 2 $ip " , $output, $result);
// if 0 then the there is no errors like "Destination Host Unreachable"
if ($result === 0) return true;
return false;
}
public static function currentOS(){
if(strpos(strtolower(PHP_OS), "win") !== false) return 'windows';
elseif (strpos(strtolower(PHP_OS), "linux") !== false) return 'linux';
//TODO: extend other OSs here
else return 'unknown';
}
}
usage example
var_dump( IPChecker::isIPOnline("192.168.180.181") );// should outputs bool(true)
var_dump( IPChecker::isIPOnline("192.168.180.182") );// should outputs bool(false)
I have used these answers (1, 2) in my answer

How use multi-threading with this

I've been reading up on multi-threading with PHP, but I'm having a tough time integrating it into my command line php script.
I read multithreading
and multithread foreach.
But I'm really not sure. Any thoughts how to apply multi-threading here? The reason I need multi-threading here is that Telnet takes forever (see shell script). But I can't write to my DB concurrently ($stmt2). I'm looping through my list of devices with $stmt->fetch.
Maybe I should do something like run task specifically, with just the telnet/shell script call in the task, like that example:
$task = new class extends Thread {
private $response;
public function run()
{
$content = file_get_contents("http://google.com");
preg_match("~<title>(.+)</title>~", $content, $matches);
$this->response = $matches[1];
}
};
$task->start() && $task->join();
var_dump($task->response); // string(6) "Google"
But, I'm getting the error when I try to add this to my code below:
PHP Parse error: syntax error, unexpected T_CLASS in /opt/IBM/custom/NAC_Dslam/calix_swVerThreaded.php on line 100
this is the line:
$task = new class ...
My script looks like this:
$stmt =$mysqli->prepare("SELECT ip, model FROM TableD WHERE vendor = 'Calix' AND model in ('C7','E7') AND sw_ver IS NULL LIMIT 6000"); //AND ping_reply IS NULL AND software_version IS NULL
$stmt->bind_result($ip, $model); //list of ip's
if(!$stmt->execute())
{
//err
}
$stmt2 = $mysqli2->prepare("UPDATE TableD SET sw_ver = ?
WHERE vendor = 'Calix'
AND ip = ? ");
$stmt2->bind_param("ss", $software, $ip);
while($stmt->fetch()) {
//initializing var's
if(pingAddress($ip)=="alive") { //Ones that don't ping are dead to us.
///////this is the part that takes forever and should be multi-threaded/////
//Call shell script to telnet to calix dslam and get version for that ip
if($model == "C7"){
$task = new class extends Thread {
private $itsOutput;
public function run()
{
exec ("./calix_C7_swVer.sh $ip", $itsOutput);//takes forever/telnet
//in shell script. Can't
//be fixed. Each time I
//call this script it's a
//different ip
}
};
$task->start() && $task->join();
var_dump($task->itsOutput); //should be returned output above //takes forever to telnet
//$output = $task->itsOutput;
$output2=array_reverse($output,true);
if (!(preg_grep("/DENY/", $output2))){
$found = preg_grep("/COMPLD/", $output2);
$ind = key($found);
$version = explode(",", $output[$ind+1]);
if(strlen($version[3])>=1) { //if sw ver came back in an acceptable size
$software = $version[3];
$software = trim($software,'"'); //trim double quote (usually is there)
print "sw ver after trim: " . $software . "\n";
if(!$stmt2->execute()) { //write sw version to netcool db
$tempErr = "Failed to insert into dslam_elements_nac: " . $stmt2->error;
printf($tempErr . "\n"); //show mysql execute error if exists
$err->logThis($tempErr);
}
if(!$stmtX->execute()) { //commit it
$tempErr = "Failed to commit dslam_elements_nac: " . $stmtX->error;
printf($tempErr . "\n"); //show mysql execute error if exists
$err->logThis($tempErr);
}
} //we got a version back
else { //version not retrieved
//error processing
} //didn't get sw ver
} //not deny
} //c7
else if($model == "E7") {
exec ("./calix_E7_swVer.sh $ip", $output);
$output2=array_reverse($output,true);
if (!(preg_grep("/DENY/", $output2))){
$found = preg_grep("/yes/", $output2);
$ind = key($found);
$version = explode(" ", $output[$ind]);
if(strlen($version[5])>=1) { //if sw ver came back in an acceptable size
$software = $version[5];
print "sw ver after trim: " . $software . "\n";
if(!$stmt2->execute()) { //write sw version to netcool db
$tempErr = "Failed to insert into dslam_elements_nac: " . $stmt2->error;
printf($tempErr . "\n"); //show mysql execute error if exists
$err->logThis($tempErr);
}
if(!$stmtX->execute()) { //commit it
//err processing
}
} //we got a version back
else { //version not retrieved
//handle it
} //didn't get sw ver
} //not deny
}
} //while
update
I'm trying this (pcntl_fork), but it doesn't seem to be quite what I need because when I sleep(30), which I think is similar to my shell script call, other processes don't continue and do the next one.
<?php
declare(ticks = 1);
$max=10;
$child=0;
$res = array("aabc", "bcd", "cde", "eft", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "aabc", "bcd", "cde", "eft", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq");
function sig_handler($signo) {
global $child;
switch ($signo) {
case SIGCHLD:
//echo "SIGCHLD receivedn";
// clean up zombies
$pid = pcntl_waitpid(-1, $status, WNOHANG);
$child -= 1;
//exit;
}
}
pcntl_signal(SIGCHLD, "sig_handler");
//$website_scraper = new scraper();
foreach($res as $r){
while ($child >= $max) {
sleep(5); //echo " - sleep $child n";
//pcntl_waitpid(0,$status);
}
$child++;
$pid=pcntl_fork();
if ($pid==-1) {
die("Could not fork:n");
}
elseif ($pid) {
// we're in the parent fork, dont do anything
}
else {
//example of what a child process could do:
print "child process stuff \n";
sleep(30);
//$website_scraper -> scraper("http://foo.com");
exit;
}
while(pcntl_waitpid(0, $status) != -1) { //////???
$status = pcntl_wexitstatus($status);
echo "child $status completed \n";
}
print "did stuff \n";
}
?>
I've been reading up on multi-threading with PHP
Don't. PHP threading has very limited utility, as it cannot be used in a web server environment. It can only be used in command-line scripts.
The author of the PHP pthreads extension has written:
pthreads v3 is restricted to operating in CLI only: I have spent many years trying to explain that threads in a web server just don't make sense, after 1,111 commits to pthreads I have realised that, my advice is going unheeded.
So I'm promoting the advice to hard and fast fact: you can't use pthreads safely and sensibly anywhere but CLI.
If you need to communicate with multiple network devices in parallel, consider using stream_select to perform asynchronous I/O, or running multiple PHP processes as part of a worker queue to manage the connections.

php split data from socket_receive at carriage return and then pipe

i have somme data coming from php socket_receive function and it;s like this :
ZC* |000195000000B5D0|0000|PTv1.11|ZE20S|ProBee-ZE ZR |000195000000920A|A4C0|PTv1.11|ZE20S|ProBee-ZE OK
From this i only need the mac addresses witch are like this form:"000195000000B5D0"
i want to explode the whole message at carriage return \r\n and then for every row to split again at | and insert the address into database row.
i am trying to use this code:
<?php
$out = socket_recv($socket, $buf, 2048, MSG_WAITALL);
echo "<br>MESAJ=".$buf;
$row=preg_split('#(\r\n|[\|])#', $buf);
print_r($row);
?>
in vb.net on a previous desktop application i was using this code.
Private Sub SalveazaData()
Dim list As String() = rtbComData.Text.Split(Environment.NewLine.ToCharArray())
For Each Row As String In list
If Not (Row = "AT+DSCAN=10,2" Or Row = "OK" Or Row = "") Then
Dim s As String() = Split(Row, "|")
Dim aRow As smdDataDataSet1.smdTableRow = SmdDataDataSet1.smdTable.NewsmdTableRow()
aRow.Model = "SCL-50"
aRow.AdresaUnica = s(1)
aRow.StatusModul = "ACTIVE"
Try
SmdDataDataSet1.SearchAdrese.Rows.Add(s(1))
SmdDataDataSet1.smdTable.Rows.Add(aRow)
Catch ex As Exception
Dim u As String
u = SmdTableTableAdapter.UpdateInactivActiv()
End Try
End If
Next
End Sub
Can you please help me with this? thank you
the data is long with hundreds of addresses but using this code i mannaged to split at carriage return \n\r :
MESAJ FROM=".$buf;
$row=explode("\r\n", $buf);
echo "ROW=".$row[0];
echo "ROW=".$row[1];
?>
and i get the message like this:
ROW=ZC* |000195000000B5D0|0000|PTv1.11|ZE20S|ProBee-ZE
ROW=ZR |000195000000920A|A4C0|PTv1.11|ZE20S|ProBee-ZE
Now i only need to save the |000195000000B5D0|(address) from every row in database. how can i do that?
i used this code to answer my question
// connect to server
$result = socket_connect($socket, $host, $port) or die("Could not connect to IP\n");
//send data to connected socket
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
echo "<br>MESAJ TO :".$message;
// get server response
$out='';
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>10, "usec"=>0));
$out = socket_recv($socket, $buf, 2048, MSG_WAITALL);
echo "<br>MESAJ FROM=".$buf;
$row=explode("\r\n", $buf);
echo "<br>ROW=".$row[0];
echo "<br>ROW=".$row[1];
foreach ($row as &$s) {
$s = explode("|",$s);
echo $s[0];
echo $s[1];
echo $s[2];
$adresaUnica=$s[1];
if(mysql_query("INSERT INTO `griddata`(`adresaUnica`, `status`, `model`) VALUES ('$adresaUnica','Activ','SCL-50')"))
{
}
}
socket_close($socket);
}
?>

Create a log of users country from their IP

I am using this function to get the two-letter country code:
$ipaddress = $_SERVER['REMOTE_ADDR'];
function ip_details($ip) {
$json = file_get_contents("http://ipinfo.io/{$ip}");
$details = json_decode($json);
return $details;
}
$details = ip_details($ipaddress);
echo $details->country;
Output:
US // Two-letter Country Code
And to make a log in a file, I was thinking of using something like this:
$file = 'visitors.txt';
file_put_contents($file, $ipaddress . PHP_EOL, FILE_APPEND);
Output:
xxx.xxx.xxx.xx // with a line break after
I want to loop through the country codes and display them with the number of visitors from each country. For example:
If two IP Addresses from US and 1 IP Address from Canada went on the page... I want to display:
US: 2
CA: 1
Any help will be appreciated.
Although I don't like the idea of working with text files here - here is an easy solution for that task (untested):
<?php
// Setup.
$pathVisitorsFile = 'visitors.txt';
// Execution.
if(!file_exists($pathVisitorsFile)) {
die('File "'. $pathVisitorsFile .'" not found');
}
// Read entries.
$visitorsCountry = file($pathVisitorsFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Count entries.
$foundCountries = array();
foreach($visitorsCountry as $visitorCountry) {
if(!isset($foundCountries[$visitorCountry])) {
$foundCountries[$visitorCountry] = 1;
} else {
$foundCountries[$visitorCountry]++;
}
}
// Display entries.
echo('<ul>');
foreach($foundCountries as $countryCode => $visitors) {
echo('<li>'. $countryCode .': '. $visitors .'</li>');
}
echo('</ul>');
?>
I assumed that you already have a file with contents like:
US
US
US
DE
DE
IR
AT
US

How to mimic a command line run with arguements inside a PHP script?

How can you mimic a command line run of a script with arguements inside a PHP script? Or is that not possible?
In other words, let's say you have the following script:
#!/usr/bin/php
<?php
require "../src/php/whatsprot.class.php";
function fgets_u($pStdn) {
$pArr = array($pStdn);
if (false === ($num_changed_streams = stream_select($pArr, $write = NULL, $except = NULL, 0))) {
print("\$ 001 Socket Error : UNABLE TO WATCH STDIN.\n");
return FALSE;
} elseif ($num_changed_streams > 0) {
return trim(fgets($pStdn, 1024));
}
}
$nickname = "WhatsAPI Test";
$sender = ""; // Mobile number with country code (but without + or 00)
$imei = ""; // MAC Address for iOS IMEI for other platform (Android/etc)
$countrycode = substr($sender, 0, 2);
$phonenumber=substr($sender, 2);
if ($argc < 2) {
echo "USAGE: ".$_SERVER['argv'][0]." [-l] [-s <phone> <message>] [-i <phone>]\n";
echo "\tphone: full number including country code, without '+' or '00'\n";
echo "\t-s: send message\n";
echo "\t-l: listen for new messages\n";
echo "\t-i: interactive conversation with <phone>\n";
exit(1);
}
$dst=$_SERVER['argv'][2];
$msg = "";
for ($i=3; $i<$argc; $i++) {
$msg .= $_SERVER['argv'][$i]." ";
}
echo "[] Logging in as '$nickname' ($sender)\n";
$wa = new WhatsProt($sender, $imei, $nickname, true);
$url = "https://r.whatsapp.net/v1/exist.php?cc=".$countrycode."&in=".$phonenumber."&udid=".$wa->encryptPassword();
$content = file_get_contents($url);
if(stristr($content,'status="ok"') === false){
echo "Wrong Password\n";
exit(0);
}
$wa->Connect();
$wa->Login();
if ($_SERVER['argv'][1] == "-i") {
echo "\n[] Interactive conversation with $dst:\n";
stream_set_timeout(STDIN,1);
while(TRUE) {
$wa->PollMessages();
$buff = $wa->GetMessages();
if(!empty($buff)){
print_r($buff);
}
$line = fgets_u(STDIN);
if ($line != "") {
if (strrchr($line, " ")) {
// needs PHP >= 5.3.0
$command = trim(strstr($line, ' ', TRUE));
} else {
$command = $line;
}
switch ($command) {
case "/query":
$dst = trim(strstr($line, ' ', FALSE));
echo "[] Interactive conversation with $dst:\n";
break;
case "/accountinfo":
echo "[] Account Info: ";
$wa->accountInfo();
break;
case "/lastseen":
echo "[] Request last seen $dst: ";
$wa->RequestLastSeen("$dst");
break;
default:
echo "[] Send message to $dst: $line\n";
$wa->Message(time()."-1", $dst , $line);
break;
}
}
}
exit(0);
}
if ($_SERVER['argv'][1] == "-l") {
echo "\n[] Listen mode:\n";
while (TRUE) {
$wa->PollMessages();
$data = $wa->GetMessages();
if(!empty($data)) print_r($data);
sleep(1);
}
exit(0);
}
echo "\n[] Request last seen $dst: ";
$wa->RequestLastSeen($dst);
echo "\n[] Send message to $dst: $msg\n";
$wa->Message(time()."-1", $dst , $msg);
echo "\n";
?>
To run this script, you are meant to go to the Command Line, down to the directory the file is in, and then type in something like php -s "whatsapp.php" "Number" "Message".
But what if I wanted to bypass the Command Line altogether and do that directly inside the script so that I can run it at any time from my Web Server, how would I do that?
First off, you should be using getopt.
In PHP it supports both short and long formats.
Usage demos are documented at the page I've linked to. In your case, I suspect you'll have difficulty detecting whether a <message> was included as your -s tag's second parameter. It will probably be easier to make the message a parameter for its own option.
$options = getopt("ls:m:i:");
if (isset($options["s"] && !isset($options["m"])) {
die("-s needs -m");
}
As for running things from a web server ... well, you pass variables to a command line PHP script using getopt() and $argv, but you pass variables from a web server using $_GET and $_POST. If you can figure out a sensible way to map $_GET variables your command line options, you should be good to go.
Note that a variety of other considerations exist when taking a command line script and running it through a web server. Permission and security go hand in hand, usually as inverse functions of each other. That is, if you open up permissions so that it's allowed to do what it needs, you may expose or even create vulnerabilities on your server. I don't recommend you do this unless you'll more experienced, or you don't mind if things break or get attacked by script kiddies out to 0wn your server.
You're looking for backticks, see
http://php.net/manual/en/language.operators.execution.php
Or you can use shell_exec()
http://www.php.net/manual/en/function.shell-exec.php

Categories