Remote Control of a Raspberry Pi by PHP

This Smart Pascal program, inspired (like that on the preceding page) by James Farnsworth's remote control of the Raspberry Pi, uses PHP to create a file named command containing a Raspberry Pi command supplied by the user. James's shell script running in the background executes the command and sends the results if any to a file named commandoutput.

Depending on the crontab entry for running the shell script, this method might allow the user to change the current directory and to copy and delete files. See James's suggestions for restricting the user's privileges and for terminating the script when necessary. It is good practice to keep a copy of the contents of your SD card so that you can easily recover from malicious or accidental damage.

The code of the PHP file and the Smart Pascal and XML code of the form follow the screenshot of the program in action. To replicate this demonstration, put the HTML output file and command_to_file.php in the /var/www/remote folder of a Raspberry Pi that has been set up as a web server.

Application in Action

Application in Action

The user has the choice of selecting one of the tested commands in the combo box or typing a command into the edit box.

Code of command_to_file.php

<?php 
$f=fopen("command","w");
fwrite($f,$_GET['c']);
fclose($f);
echo "Received command: " . $_GET['c'] . "\r\n";
?>

Smart Pascal Code of Form

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button,
  SmartCL.Controls.EditBox, SmartCL.Controls.Memo, SmartCL.Time,
  SmartCL.Controls.Panel, SmartCL.Controls.ComboBox,
  SmartCL.Controls.Label, SmartCL.Inet;

type
  TForm1 = class(TW3Form)
    procedure W3EditBox1Changed(Sender: TObject);
    procedure W3Button1Click(Sender: TObject);
  private
    {$I 'Form1:intf'}
    strReceived, strPHP: String;
    FTimerCommand: TW3Timer;
    FHttp: TW3HttpRequest;
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure SendRequest;
    procedure Download(url: string);
    procedure HandleDataReady(Sender: TW3HttpRequest);
  end;

implementation

procedure TForm1.Download(url: string);
begin
  W3Memo1.Text := '';
  FHttp := TW3HttpRequest.Create;
  FHttp.OnDataReady := HandleDataReady;
  FHttp.Get('commandoutput');
end;

procedure TForm1.HandleDataReady(Sender: TW3HttpRequest);
begin
  W3Memo1.Text := FHttp.ResponseText;
end;

procedure TForm1.SendRequest;
begin
  FTimerCommand.Enabled := True;
  asm
    xmlhttp=new XMLHttpRequest();
    xmlhttp.onreadystatechange=function()
    {
      @strReceived = '';
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
      {
        @strReceived = xmlhttp.responseText;
      }
    }
    xmlhttp.open("GET",@strPHP,true);
    xmlhttp.send();
  end;
end;

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  strPHP := 'command_to_file.php?c=' + W3EditBox1.Text;
  SendRequest;
end;

procedure TForm1.W3EditBox1Changed(Sender: TObject);
begin
  W3Button1Click(Sender);
end;

procedure TForm1.InitializeForm;
begin
  inherited;
  FTimerCommand := TW3Timer.Create;
  FTimerCommand.Enabled := False;
  FTimerCommand.Delay:= 1000;
  FTimerCommand.OnTime := procedure (Sender: TObject)
    begin
      W3Memo2.Text := W3Memo2.Text + strReceived;
      Download('commandoutput');
      FTimerCommand.Enabled:= False;
    end;
  W3Combobox1.Add('echo This is fun!');
  W3Combobox1.Add('pwd');
  W3Combobox1.Add('ls');
  W3Combobox1.Add('du -h');
  W3Combobox1.Add('ps aux');
  W3Combobox1.Add('uname -a');
  W3Combobox1.Add('date');
  W3Combobox1.Add('cal 8 2015');
  W3Combobox1.Add('cd /var/www');

  W3Combobox1.OnClick := procedure(Sender: TObject)
    begin
      strPHP := 'command_to_file.php?c=' + W3Combobox1.Items[W3Combobox1.SelectedIndex];
      SendRequest;
    end;
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.

XML Code of Form

<SMART>
  <Form version="2" subversion="1">
    <Created>2015-03-01T13:33:43.698</Created>
    <Modified>2015-03-03T17:41:54.288</Modified>
    <object type="TW3Form">
      <Caption>Pi Control</Caption>
      <Name>Form1</Name>
      <object type="TW3Button">
        <Caption>Send Command</Caption>
        <Width>136</Width>
        <Top>8</Top>
        <Left>203</Left>
        <Height>32</Height>
        <Name>W3Button1</Name>
        <OnClick>W3Button1Click</OnClick>
      </object>
      <object type="TW3Memo">
        <Width>488</Width>
        <Top>160</Top>
        <Left>8</Left>
        <Height>136</Height>
        <Name>W3Memo1</Name>
      </object>
      <object type="TW3EditBox">
        <Value></Value>
        <Text>ls -lh</Text>
        <Range></Range>
        <Width>112</Width>
        <Top>8</Top>
        <Left>91</Left>
        <Height>32</Height>
        <Name>W3EditBox1</Name>
        <OnChanged>W3EditBox1Changed</OnChanged>
      </object>
      <object type="TW3ComboBox">
        <Width>128</Width>
        <Top>8</Top>
        <Left>368</Left>
        <Height>32</Height>
        <Name>W3ComboBox1</Name>
      </object>
      <object type="TW3Label">
        <Caption>Command:</Caption>
        <Width>80</Width>
        <Top>8</Top>
        <Left>8</Left>
        <Height>32</Height>
        <Name>W3Label1</Name>
      </object>
      <object type="TW3Memo">
        <Width>488</Width>
        <Top>48</Top>
        <Left>8</Left>
        <Height>96</Height>
        <Name>W3Memo2</Name>
      </object>
    </object>
  </Form>
</SMART>
Programming - a skill for life!

Using Node.js for a server that updates connected clients in real time and remote use of a Raspberry Pi's OS