summaryrefslogtreecommitdiffstats
path: root/modules-available/serversetup-bwlp
diff options
context:
space:
mode:
authorSimon Rettberg2018-03-29 18:08:16 +0200
committerSimon Rettberg2018-03-29 18:08:16 +0200
commit0001d5e7c0c324b4bbd4a17ff64e2ed0b31b3eee (patch)
tree2d8c16f99c46ab2f4122d666fcdbbeb67bac6b9f /modules-available/serversetup-bwlp
parent[locationinfo] Properly check permissions when saving new panel (diff)
downloadslx-admin-0001d5e7c0c324b4bbd4a17ff64e2ed0b31b3eee.tar.gz
slx-admin-0001d5e7c0c324b4bbd4a17ff64e2ed0b31b3eee.tar.xz
slx-admin-0001d5e7c0c324b4bbd4a17ff64e2ed0b31b3eee.zip
[serversetup-bwlp] Update pxelinux menu parser
Diffstat (limited to 'modules-available/serversetup-bwlp')
-rw-r--r--modules-available/serversetup-bwlp/inc/ipxe.inc.php156
1 files changed, 139 insertions, 17 deletions
diff --git a/modules-available/serversetup-bwlp/inc/ipxe.inc.php b/modules-available/serversetup-bwlp/inc/ipxe.inc.php
index abeea748..c42de80b 100644
--- a/modules-available/serversetup-bwlp/inc/ipxe.inc.php
+++ b/modules-available/serversetup-bwlp/inc/ipxe.inc.php
@@ -4,6 +4,12 @@
class Ipxe
{
+ /**
+ * Takes a (partial) pxelinux menu and parses it into
+ * a PxeMenu object.
+ * @param string $input The pxelinux menu to parse
+ * @return PxeMenu the parsed menu
+ */
public static function parsePxeLinux($input)
{
/*
@@ -13,59 +19,151 @@ class Ipxe
INITRD http://IPADDR/boot/default/initramfs-stage31
APPEND slxbase=boot/default
IPAPPEND 3
- */
- $propMap = [
+ */
+ $menu = new PxeMenu;
+ $sectionPropMap = [
'menu label' => ['string', 'title'],
'menu default' => ['true', 'isDefault'],
'menu hide' => ['true', 'isHidden'],
+ 'menu disabled' => ['true', 'isDisabled'],
+ 'menu indent' => ['int', 'indent'],
'kernel' => ['string', 'kernel'],
'initrd' => ['string', 'initrd'],
'append' => ['string', 'append'],
'ipappend' => ['int', 'ipAppend'],
'localboot' => ['int', 'localBoot'],
];
- $sections = array();
+ $globalPropMap = [
+ 'timeout' => ['int', 'timeoutMs', 100],
+ 'totaltimeout' => ['int', 'totalTimeoutMs', 100],
+ 'menu title' => ['string', 'title'],
+ 'menu clear' => ['true', 'menuClear'],
+ 'menu immediate' => ['true', 'immediateHotkeys'],
+ 'ontimeout' => ['string', 'timeoutLabel'],
+ ];
$lines = preg_split('/[\r\n]+/', $input);
$section = null;
- foreach ($lines as $line) {
- if (!preg_match('/^\s*([^m\s]+|menu\s+\S+)\s+(.*?)\s*$/i', $line, $out))
+ $count = count($lines);
+ for ($li = 0; $li < $count; ++$li) {
+ $line =& $lines[$li];
+ if (!preg_match('/^\s*([^m]\S*|menu\s+\S+)(\s+.*?|)\s*$/i', $line, $out))
continue;
- $key = strtolower($out[1]);
+ $key = trim($out[1]);
+ $key = strtolower($key);
$key = preg_replace('/\s+/', ' ', $key);
if ($key === 'label') {
if ($section !== null) {
- $sections[] = $section;
+ $menu->sections[] = $section;
}
$section = new PxeSection($out[2]);
+ } elseif ($key === 'menu separator') {
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ $section = null;
+ }
+ $menu->sections[] = new PxeSection(null);
+ } elseif (self::handleKeyword($key, $out[2], $globalPropMap, $menu)) {
+ continue;
} elseif ($section === null) {
continue;
- } elseif (isset($propMap[$key])) {
- $opt = $propMap[$key];
- if ($opt[0] === 'true') {
- $val = true;
- } else {
- $val = $out[2];
- settype($val, $opt[0]);
+ } elseif ($key === 'text' && strtolower($out[2]) === 'help') {
+ $text = '';
+ while (++$li < $count) {
+ $line =& $lines[$li];
+ if (strtolower(trim($line)) === 'endtext')
+ break;
+ $text .= $line . "\n";
}
- $section->{$opt[1]} = $val;
+ $section->helpText = $text;
+ } elseif (self::handleKeyword($key, $out[2], $sectionPropMap, $section)) {
+ continue;
}
}
if ($section !== null) {
- $sections[] = $section;
+ $menu->sections[] = $section;
}
- return $sections;
+ return $menu;
+ }
+
+ /**
+ * Check if keyword is valid and if so, add its interpreted value
+ * to the given object. The map to look up the keyword has to be passed
+ * as well as the object to set the value in. Map and object should
+ * obviously match.
+ * @param string $key keyword of parsed line
+ * @param string $val raw value of currently parsed line (empty if not present)
+ * @param array $map Map in which $key is looked up as key
+ * @param PxeMenu|PxeSection The object to set the parsed and sanitized value in
+ * @return bool true if the value was found in the map (and set in the object), false otherwise
+ */
+ private static function handleKeyword($key, $val, $map, $object)
+ {
+ if (!isset($map[$key]))
+ return false;
+ $opt = $map[$key];
+ // opt[0] is the type the value should be cast to; special case "true" means
+ // this is a bool option that will be set as soon as the keyword is present,
+ // as it doesn't have any parameters
+ if ($opt[0] === 'true') {
+ $val = true;
+ } else {
+ settype($val, $opt[0]);
+ }
+ // If opt[2] is present it's a multiplier for the value
+ if (isset($opt[2])) {
+ $val *= $opt[2];
+ }
+ $object->{$opt[1]} = $val;
+ return true;
}
}
+/**
+ * Class representing a parsed pxelinux menu. Members
+ * will be set to their annotated type if present or
+ * be null otherwise, except for present-only boolean
+ * options, which will default to false.
+ */
class PxeMenu
{
+ /**
+ * @var string menu title, shown at the top of the menu
+ */
public $title;
+ /**
+ * @var int initial timeout after which $timeoutLabel would be executed
+ */
public $timeoutMs;
+ /**
+ * @var int if the user canceled the timeout by pressing a key, this timeout would still eventually
+ * trigger and launch the $timeoutLabel section
+ */
public $totalTimeoutMs;
+ /**
+ * @var string label of section which will execute if the timeout expires
+ */
public $timeoutLabel;
+ /**
+ * @var bool hide menu and just show background after triggering an entry
+ */
+ public $menuClear = false;
+ /**
+ * @var bool boot the associated entry directly if its corresponding hotkey is presed instead of just highlighting
+ */
+ public $immediateHotkeys = false;
+ /**
+ * @var PxeSection[] list of sections the menu contains
+ */
+ public $sections = [];
}
+/**
+ * Class representing a parsed pxelinux menu entry. Members
+ * will be set to their annotated type if present or
+ * be null otherwise, except for present-only boolean
+ * options, which will default to false.
+ */
class PxeSection
{
/**
@@ -76,13 +174,33 @@ class PxeSection
* @var string MENU LABEL of PXEMENU - title of entry displayed to the user
*/
public $title;
+ /**
+ * @var int Number of spaces to prefix the title with
+ */
+ public $indent;
+ /**
+ * @var string help text to display when the entry is highlighted
+ */
+ public $helpText;
+ /**
+ * @var string Kernel to load
+ */
public $kernel;
+ /**
+ * @var string initrd to load for the kernel
+ */
public $initrd;
+ /**
+ * @var string command line options to pass to the kernel
+ */
public $append;
/**
* @var int IPAPPEND from PXEMENU. Bitmask of valid options 1 and 2.
*/
public $ipAppend;
+ /**
+ * @var string Password protecting the entry. This is most likely in crypted form.
+ */
public $passwd;
/**
* @var bool whether this section is marked as default (booted after timeout)
@@ -93,6 +211,10 @@ class PxeSection
*/
public $isHidden = false;
/**
+ * @var bool Disable this entry, making it unselectable
+ */
+ public $isDisabled = false;
+ /**
* @var int Value of the LOCALBOOT field
*/
public $localBoot;