Skip to content

Instantly share code, notes, and snippets.

@ecoreng
Last active August 29, 2015 14:14
Show Gist options
  • Save ecoreng/0d10d5e3a09e3f19dc20 to your computer and use it in GitHub Desktop.
Save ecoreng/0d10d5e3a09e3f19dc20 to your computer and use it in GitHub Desktop.
/etc/hosts php command
#!/usr/bin/php
<?php
namespace ecoreng;
class HostsEditor
{
// linux [run as root]
protected $hosts = '/etc/hosts';
// windows [run as administrator]
//protected $hosts = 'C:\Windows\System32\Drivers\etc\hosts';
protected $hostsEntries = [];
protected function prompt($q, $default = '', $options = [], $max = 128, $forceOptions = true)
{
if (count($options) > 0) {
$optionsStr = ' (' . implode(', ', $options) . ")";
} else {
$optionsStr = '';
}
echo $q . $optionsStr . ' [' . $default . ']: ';
$fr = fopen("php://stdin", "r");
$input = fgets($fr, $max);
$input = rtrim($input);
fclose($fr);
echo PHP_EOL;
if (count($options) > 0 && $default !== '' && $forceOptions) {
if (!in_array($input, $options)) {
$input = $default;
}
}
if ($forceOptions && $input === '') {
$input = $default;
}
return $input;
}
protected function pad($amount = 2)
{
echo str_repeat(PHP_EOL, $amount);
}
protected function heading($title, $char = '#')
{
echo str_repeat($char, 30) . PHP_EOL;
echo ' ' . PHP_EOL;
echo ' ' . $title . PHP_EOL;
echo ' ' . PHP_EOL;
echo str_repeat($char, 30) . PHP_EOL;
}
protected function checkPermissions()
{
$hosts = file_get_contents($this->hosts);
$works = @file_put_contents($this->hosts, $hosts);
if (!$works) {
$this->heading('Not enough permissions to edit ' . $this->hosts, 'X');
die();
}
// create a backup of the current file
// as /etc/hosts~
file_put_contents($this->hosts . '~', $hosts);
}
public function __construct()
{
$this->checkPermissions();
$this->pad(1);
$this->hostsEntries = file($this->hosts);
$this->heading('HOST FILE EDITOR');
$this->pad(1);
$this->mainScreen();
}
public function mainScreen()
{
$i = 1;
foreach ($this->hostsEntries as $host) {
$f = substr($host, 0, 1);
if ($f === PHP_EOL) {
continue;
}
$needles = ['#[ ]+#', '#' . PHP_EOL . '#'];
$replace = [chr(9), ''];
if (substr($host, 0, 1) == '#') {
$needles = ['#' . PHP_EOL . '#'];
$replace = [''];
}
$this->hostsEntries[$i - 1] = $host = preg_replace($needles, $replace, $host);
$il = str_pad($i, 2, 0, STR_PAD_LEFT);
echo "[$il] " . $host . PHP_EOL;
$i++;
}
$this->pad(1);
$answer = strtolower($this->prompt('Action?', 'exit', ['{n}ew', '{e}dit', '{d}isable', 'en{a}ble', 'de{l}ete', '{s}ave',
'e{x}it'], 10, false));
switch ($answer) {
case 'edit':
case 'e':
$this->handleEdit();
break;
case 'new':
case 'n':
$this->handleNew();
break;
case 'disable':
case 'd':
$this->handleDisable();
break;
case 'delete':
case 'l':
$this->handleDelete();
break;
default:
case 'exit':
case 'x':
break;
case 'save':
case 's':
$this->handleSave();
break;
case 'enable':
case 'a':
$this->handleEnable();
break;
}
}
protected function handleEdit()
{
$options = ['0 = cancel'];
$i = 1;
foreach ($this->hostsEntries as $option) {
$options[] = $i;
$i++;
}
$entryIndex = (int) $this->prompt('Edit host entry number', '0', $options);
if ($entryIndex === 0) {
$this->pad();
$this->mainScreen();
return;
}
$entry = $this->hostsEntries[$entryIndex - 1];
if (!$this->isDisabled($entry)) {
$entry = explode(chr(9), $entry);
$default = reset($entry);
$ip = str_replace('$1', $default, $this->prompt('Edit Ip:', $default));
$default = implode(' ', array_slice($entry, 1));
$hosts = str_replace('$1', $default, $this->prompt('Edit Hosts:', $default));
$newEntry = $ip . chr(9) . $hosts;
$this->hostsEntries[$entryIndex - 1] = $newEntry;
$this->heading('Host(s) edited: ' . PHP_EOL . ' ' . $newEntry, '=');
} else {
$this->heading('Host(s) is disabled or a comment', 'X');
}
$this->pad();
$this->mainScreen();
}
protected function handleSave()
{
file_put_contents($this->hosts, implode(PHP_EOL, $this->hostsEntries));
}
protected function handleNew()
{
$newIp = $this->prompt('New IP:', '127.0.0.1');
$newHosts = $this->prompt('Hosts:');
$entry = $this->hostsEntries[] = $newIp . chr(9) . $newHosts;
$this->heading('Host(s) added:' . PHP_EOL . ' ' . $entry, '=');
$this->pad();
$this->mainScreen();
}
protected function handleDisable()
{
$options = ['0 = cancel'];
$i = 1;
foreach ($this->hostsEntries as $option) {
$options[] = $i;
$i++;
}
$entryIndex = (int) $this->prompt('Disable host entry number', '0', $options);
if ($entryIndex === 0) {
$this->pad();
$this->mainScreen();
return;
}
$entry = $this->hostsEntries[$entryIndex - 1];
if (!$this->isDisabled($entry)) {
$this->hostsEntries[$entryIndex - 1] = '# ' . $entry;
$this->heading('Host(s) disabled:' . PHP_EOL . ' ' . $entry, '=');
} else {
$this->heading('Host(s) is already disabled or a comment', 'X');
}
$this->pad();
$this->mainScreen();
}
protected function isDisabled($entry)
{
return substr($entry, 0, 1) === '#';
}
protected function handleEnable()
{
$options = ['0 = cancel'];
$i = 1;
foreach ($this->hostsEntries as $option) {
$options[] = $i;
$i++;
}
$entryIndex = (int) $this->prompt('Enable host entry number', '0', $options);
if ($entryIndex === 0) {
$this->pad();
$this->mainScreen();
return;
}
$entry = $this->hostsEntries[$entryIndex - 1];
if ($this->isDisabled($entry)) {
$this->hostsEntries[$entryIndex - 1] = trim(substr($entry, 1));
$this->heading('Host(s) enabled:' . PHP_EOL . ' ' . $entry, '=');
} else {
$this->heading('Host(s) not disabled:' . PHP_EOL . ' ' . $entry, 'X');
}
$this->pad();
$this->mainScreen();
}
protected function handleDelete()
{
$options = ['0 = cancel'];
$i = 1;
foreach ($this->hostsEntries as $option) {
$options[] = $i;
$i++;
}
$entryIndex = (int) $this->prompt('Enable host entry number', '0', $options);
if ($entryIndex === 0) {
$this->pad();
$this->mainScreen();
return;
}
$entry = $this->hostsEntries[$entryIndex - 1];
if (!$this->isDisabled($entry)) {
$confirm = $this->prompt('Are you sure you want to delete "' . $entry . '"?', 'n', ['y', 'n'], 10);
if ($confirm === 'y') {
unset($this->hostsEntries[$entryIndex - 1]);
$this->heading('Host(s) deleted:' . PHP_EOL . ' ' . $entry, '=');
$this->pad();
$this->mainScreen();
}
} else {
$this->heading('Host(s) disabled', 'X');
}
}
}
$he = new \ecoreng\HostsEditor();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment