diff options
Diffstat (limited to 'config/systempatches')
-rw-r--r-- | config/systempatches/patches.inc | 142 | ||||
-rw-r--r-- | config/systempatches/system_patches.php | 287 | ||||
-rw-r--r-- | config/systempatches/system_patches_edit.php | 223 | ||||
-rw-r--r-- | config/systempatches/systempatches.xml | 66 |
4 files changed, 718 insertions, 0 deletions
diff --git a/config/systempatches/patches.inc b/config/systempatches/patches.inc new file mode 100644 index 00000000..d17e3614 --- /dev/null +++ b/config/systempatches/patches.inc @@ -0,0 +1,142 @@ +<?php +/* + patches.inc + Copyright (C) 2012 Jim Pingle + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("globals.inc"); +require_once("util.inc"); + +$git_root_url = "http://github.com/bsdperimeter/pfsense/commit/"; +$patch_suffix = ".patch"; +$patch_dir = "/var/patches"; +$patch_cmd = "/usr/bin/patch"; + +function patch_commit($patch, $action, $test=false, $fulldetail=false) { + global $patch_dir, $patch_cmd, $patch_suffix; + $directory = empty($patch['basedir']) ? "/" : $patch['basedir']; + $filename = '-i ' . $patch_dir . '/' . $patch['uniqid'] . $patch_suffix; + $check = ($test) ? "--check" : ""; + $force = ($action == "revert") ? "-f" : "-t"; + $direction = ($action == "revert") ? "--reverse" : "--forward"; + $whitespace = $patch['ignorewhitespace'] ? "--ignore-whitespace" : ""; + $pathstrip = '-p' . $patch['pathstrip']; + $full_patch_command = "{$patch_cmd} --directory={$directory} {$force} {$pathstrip} {$filename} {$check} {$direction} {$whitespace}"; + patch_write($patch); + if (!$fulldetail) + $output = (mwexec($full_patch_command, true) == 0); + else + $output = $full_patch_command . "\n\n" . shell_exec($full_patch_command . ' 2>&1'); + patch_erase($patch); + return $output; +} + +/* Attempt to apply a patch */ +function patch_apply($patch) { + return patch_commit($patch, "apply", false); +} + +/* Attempt to revert a patch */ +function patch_revert($patch) { + return patch_commit($patch, "revert", false); +} + +/* Test if a patch would apply cleanly */ +function patch_test_apply($patch, $fulldetail=false) { + return patch_commit($patch, "apply", true, $fulldetail); +} + +/* Test if a patch would revert cleanly */ +function patch_test_revert($patch, $fulldetail=false) { + return patch_commit($patch, "revert", true, $fulldetail); +} + +/* Fetch a patch from a URL or github */ +function patch_fetch(& $patch) { + $url = patch_fixup_url($patch['location']); + $text = @file_get_contents($url); + if (empty($text)) { + return false; + } else { + $patch['patch'] = base64_encode($text); + write_config("Fetched patch {$patch['descr']}"); + return true; + } +} + +/* Write a patch file out to $patch_dir */ +function patch_write($patch) { + global $patch_dir, $patch_suffix; + if (!file_exists($patch_dir)) { + safe_mkdir($patch_dir); + } + if (empty($patch['patch'])) { + return false; + } else { + $text = base64_decode($patch['patch']); + $filename = $patch_dir . '/' . $patch['uniqid'] . $patch_suffix; + return (file_put_contents($filename, $text) > 0); + } +} + +function patch_erase($patch) { + global $patch_dir, $patch_suffix; + if (!file_exists($patch_dir)) { + return true; + } + $filename = $patch_dir . '/' . $patch['uniqid'] . $patch_suffix; + return @unlink($filename); +} + +/* Detect a github URL or commit ID and fix it up */ +function patch_fixup_url($url) { + global $git_root_url, $patch_suffix; + // If it's a commit id then prepend git url, and add .patch + if (is_commit_id($url)) { + $url = $git_root_url . $url . $patch_suffix; + } elseif (is_URL($url)) { + $urlbits = explode("/", $url); + if (substr($urlbits[2], -10) == "github.com") { + // If it's a github url and does not already end in .patch, add it + if (substr($url, -strlen($patch_suffix)) != $patch_suffix) { + // Make sure it's really a URL to a commit id before adding .patch + if (is_commit_id(array_pop($urlbits))) { + $url .= $patch_suffix; + } + } + } + } + return $url; +} + +function is_commit_id($str) { + return preg_match("/^[0-9a-f]{5,40}$/", $str); +} + +function is_github_url($url) { + $urlbits = explode("/", $url); + return (substr($urlbits[2], -10) == "github.com"); +} +?>
\ No newline at end of file diff --git a/config/systempatches/system_patches.php b/config/systempatches/system_patches.php new file mode 100644 index 00000000..2cb6abf9 --- /dev/null +++ b/config/systempatches/system_patches.php @@ -0,0 +1,287 @@ +<?php +/* + system_patches.php + Copyright (C) 2012 Jim Pingle + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* + pfSense_MODULE: system +*/ + +##|+PRIV +##|*IDENT=page-system-patches +##|*NAME=System: Patches +##|*DESCR=Allow access to the 'System: Patches' page. +##|*MATCH=system_patches.php* +##|-PRIV + +require("guiconfig.inc"); +require_once("functions.inc"); +require_once("itemid.inc"); +require_once("patches.inc"); + +if (!is_array($config['installedpackages']['patches']['item'])) + $config['installedpackages']['patches']['item'] = array(); + +$a_patches = &$config['installedpackages']['patches']['item']; + +/* if a custom message has been passed along, lets process it */ +if ($_GET['savemsg']) + $savemsg = $_GET['savemsg']; + +if ($_POST) { + $pconfig = $_POST; + if ($_POST['apply']) { + write_config(); + } +} + +if ($_GET['act'] == "del") { + if ($a_patches[$_GET['id']]) { + unset($a_patches[$_GET['id']]); + write_config(); + header("Location: system_patches.php"); + exit; + } +} + +if (($_GET['act'] == "fetch") && ($a_patches[$_GET['id']])) { + $savemsg = patch_fetch(& $a_patches[$_GET['id']]) ? gettext("Patch Fetched Successfully") : gettext("Patch Fetch Failed"); +} +if (($_GET['act'] == "test") && ($a_patches[$_GET['id']])) { + $savemsg = patch_test_apply($a_patches[$_GET['id']]) ? gettext("Patch can be applied cleanly") : gettext("Patch can NOT be applied cleanly"); + $savemsg .= " (<a href=\"system_patches.php?id={$_GET['id']}&fulltest=apply\">" . gettext("detail") . "</a>)"; + $savemsg .= empty($savemsg) ? "" : "<br/>"; + $savemsg .= patch_test_revert($a_patches[$_GET['id']]) ? gettext("Patch can be reverted cleanly") : gettext("Patch can NOT be reverted cleanly"); + $savemsg .= " (<a href=\"system_patches.php?id={$_GET['id']}&fulltest=revert\">" . gettext("detail") . "</a>)"; +} +if (($_GET['fulltest']) && ($a_patches[$_GET['id']])) { + if ($_GET['fulltest'] == "apply") { + $fulldetail = patch_test_apply($a_patches[$_GET['id']], true); + } elseif ($_GET['fulltest'] == "revert") { + $fulldetail = patch_test_revert($a_patches[$_GET['id']], true); + } +} +if (($_GET['act'] == "apply") && ($a_patches[$_GET['id']])) { + $savemsg = patch_apply($a_patches[$_GET['id']]) ? gettext("Patch applied successfully") : gettext("Patch could NOT be applied!"); +} +if (($_GET['act'] == "revert") && ($a_patches[$_GET['id']])) { + $savemsg = patch_revert($a_patches[$_GET['id']]) ? gettext("Patch reverted successfully") : gettext("Patch could NOT be reverted!"); +} + + +if (isset($_POST['del_x'])) { + /* delete selected patches */ + if (is_array($_POST['patch']) && count($_POST['patch'])) { + foreach ($_POST['patch'] as $patchi) { + unset($a_patches[$patchi]); + } + write_config(); + header("Location: system_patches.php"); + exit; + } +} else { + /* yuck - IE won't send value attributes for image buttons, while Mozilla does - so we use .x/.y to find move button clicks instead... */ + unset($movebtn); + foreach ($_POST as $pn => $pd) { + if (preg_match("/move_(\d+)_x/", $pn, $matches)) { + $movebtn = $matches[1]; + break; + } + } + /* move selected patches before this patch */ + if (isset($movebtn) && is_array($_POST['patch']) && count($_POST['patch'])) { + $a_patches_new = array(); + + /* copy all patches < $movebtn and not selected */ + for ($i = 0; $i < $movebtn; $i++) { + if (!in_array($i, $_POST['patch'])) + $a_patches_new[] = $a_patches[$i]; + } + + /* copy all selected patches */ + for ($i = 0; $i < count($a_patches); $i++) { + if ($i == $movebtn) + continue; + if (in_array($i, $_POST['patch'])) + $a_patches_new[] = $a_patches[$i]; + } + + /* copy $movebtn patch */ + if ($movebtn < count($a_patches)) + $a_patches_new[] = $a_patches[$movebtn]; + + /* copy all patches > $movebtn and not selected */ + for ($i = $movebtn+1; $i < count($a_patches); $i++) { + if (!in_array($i, $_POST['patch'])) + $a_patches_new[] = $a_patches[$i]; + } + $a_patches = $a_patches_new; + write_config(); + header("Location: system_patches.php"); + return; + } +} + +$pgtitle = array(gettext("System"),gettext("Patches")); +include("head.inc"); + +echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript/domTT/domLib.js\"></script>"; +echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript/domTT/domTT.js\"></script>"; +echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript/domTT/behaviour.js\"></script>"; +echo "<script type=\"text/javascript\" language=\"javascript\" src=\"/javascript/domTT/fadomatic.js\"></script>"; + +?> +<link rel="stylesheet" href="/javascript/chosen/chosen.css" /> +<body link="#000000" vlink="#000000" alink="#000000"> +<?php include("fbegin.inc"); ?> +<form action="system_patches.php" method="post" name="iform"> +<script type="text/javascript" language="javascript" src="/javascript/row_toggle.js"></script> +<?php if ($savemsg) print_info_box($savemsg); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> +<tr><td><div id="mainarea"> +<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> +<tr><td colspan="8" align="center"> +<?php echo gettext("This page allows you to add patches, either from the official code repository or ones pasted in from e-mail or other sources."); ?> +<br/><br/> +<strong><?php echo gettext("Use with caution!"); ?></strong> +<br/><br/> +<?php if (!empty($fulldetail)): ?> +</td></tr> +<tr><td></td><td colspan="7" align="left">Output of full patch <?php echo $_GET['fulltest']; ?> test: +<pre><?php echo $fulldetail; ?></pre> +<a href="system_patches.php">Close</a><br/><br/> +<?php endif; ?> +</td></tr> +<tr id="frheader"> +<td width="5%" class="list"> </td> +<td width="5%" class="listhdrr"><?=gettext("Description");?></td> +<td width="65%" class="listhdrr"><?=gettext("URL/ID");?></td> +<td width="5%" class="listhdrr"><?=gettext("Fetch");?></td> +<td width="5%" class="listhdrr"><?=gettext("Test");?></td> +<td width="5%" class="listhdrr"><?=gettext("Apply");?></td> +<td width="5%" class="listhdr"><?=gettext("Revert");?></td> +<td width="5%" class="list"> +<table border="0" cellspacing="0" cellpadding="1"> + <tr><td width="17"> + <?php if (count($a_patches) == 0): ?> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" width="17" height="17" title="<?=gettext("delete selected patches");?>" border="0"> + <?php else: ?> + <input name="del" type="image" src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" title="<?=gettext("delete selected patches"); ?>" onclick="return confirm('<?=gettext("Do you really want to delete the selected patches?");?>')"> + <?php endif; ?> + </td> + <td><a href="system_patches_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" title="<?=gettext("add new patch"); ?>"></a></td> + </tr> +</table> +</td> +</tr> + +<?php +$npatches = $i = 0; +foreach ($a_patches as $thispatch): + $can_apply = patch_test_apply($thispatch); + $can_revert = patch_test_revert($thispatch); + +?> + <tr valign="top" id="fr<?=$npatches;?>"> + <td class="listt"><input type="checkbox" id="frc<?=$npatches;?>" name="patch[]" value="<?=$i;?>" onClick="fr_bgcolor('<?=$npatches;?>')" style="margin: 0; padding: 0; width: 15px; height: 15px;"></td> + <td class="listlr" onClick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + <?=$thispatch['descr'];?> + </td> + <td class="listr" onClick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + + <?php + if (!empty($thispatch['location'])) + echo $thispatch['location']; + elseif (!empty($thispatch['patch'])) + echo gettext("Saved Patch"); + ?> + </td> + <td class="listr" onClick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + <?php if (empty($thispatch['patch'])): ?> + <a href="system_patches.php?id=<?=$i;?>&act=fetch"><?php echo gettext("Fetch"); ?></a> + <?php elseif (!empty($thispatch['location'])): ?> + <a href="system_patches.php?id=<?=$i;?>&act=fetch"><?php echo gettext("Re-Fetch"); ?></a> + <?php endif; ?> + </td> + <td class="listr" onClick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + <?php if (!empty($thispatch['patch'])): ?> + <a href="system_patches.php?id=<?=$i;?>&act=test"><?php echo gettext("Test"); ?></a> + <?php endif; ?> + </td> + <td class="listr" onClick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + <?php if ($can_apply): ?> + <a href="system_patches.php?id=<?=$i;?>&act=apply"><?php echo gettext("Apply"); ?></a> + <?php endif; ?> + </td> + <td class="listr" onClick="fr_toggle(<?=$npatches;?>)" id="frd<?=$npatches;?>" ondblclick="document.location='system_patches_edit.php?id=<?=$npatches;?>';"> + <?php if ($can_revert): ?> + <a href="system_patches.php?id=<?=$i;?>&act=revert"><?php echo gettext("Revert"); ?></a> + <?php endif; ?> + </td> + <td valign="middle" class="list" nowrap> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td><input onmouseover="fr_insline(<?=$npatches;?>, true)" onmouseout="fr_insline(<?=$npatches;?>, false)" name="move_<?=$i;?>" src="/themes/<?= $g['theme']; ?>/images/icons/icon_left.gif" title="<?=gettext("move selected patches before this patch");?>" height="17" type="image" width="17" border="0"></td> + <td><a href="system_patches_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0" title="<?=gettext("edit patch"); ?>"></a></td> + </tr> + <tr> + <td align="center" valign="middle"><a href="system_patches.php?act=del&id=<?=$i;?>" onclick="return confirm('<?=gettext("Do you really want to delete this patch?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" title="<?=gettext("delete patch");?>"></a></td> + <td></td> + </tr> + </table> + </td></tr> +<?php $i++; $npatches++; endforeach; ?> + <tr> + <td class="list" colspan="7"></td> + <td class="list" valign="middle" nowrap> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td><?php if ($npatches == 0): ?><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_left_d.gif" width="17" height="17" title="<?=gettext("move selected patches to end"); ?>" border="0"><?php else: ?><input name="move_<?=$i;?>" type="image" src="/themes/<?= $g['theme']; ?>/images/icons/icon_left.gif" width="17" height="17" title="<?=gettext("move selected patches to end");?>" border="0"><?php endif; ?></td> + </tr> + <tr> + <td width="17"> + <?php if (count($a_patches) == 0): ?> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" width="17" height="17" title="<?=gettext("delete selected patches");?>" border="0"> + <?php else: ?> + <input name="del" type="image" src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" title="<?=gettext("delete selected patches"); ?>" onclick="return confirm('<?=gettext("Do you really want to delete the selected patches?");?>')"> + <?php endif; ?> + </td> + <td><a href="system_patches_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" title="<?=gettext("add new patch"); ?>"></a></td> + </tr> + </table> + </td> + </tr> + <tr><td></td><td colspan="6"> + <?php echo gettext("NOTE: Each patch is tested, and the appropriate action is shown. If neither 'Apply' or 'Revert' shows up, the patch cannot be used (check the pathstrip and whitespace options)."); ?> + <br/><br/> + <?php echo gettext("Use the 'Test' link to see if a patch can be applied or reverted. You can reorder patches so that higher patches apply later than lower patches."); ?> + </td><td></td></tr> + </table> +</div></td></tr> +</table> +</form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/systempatches/system_patches_edit.php b/config/systempatches/system_patches_edit.php new file mode 100644 index 00000000..a4038b05 --- /dev/null +++ b/config/systempatches/system_patches_edit.php @@ -0,0 +1,223 @@ +<?php +/* + system_patches_edit.php + Copyright (C) 2012 Jim Pingle + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* + pfSense_MODULE: system +*/ + +##|+PRIV +##|*IDENT=page-system-patches-edit +##|*NAME=System: Edit Patches +##|*DESCR=Allow access to the 'System: Edit Patches' page. +##|*MATCH=system_patches_edit.php* +##|-PRIV + +require("guiconfig.inc"); +require_once("itemid.inc"); +require_once("patches.inc"); + +if (!is_array($config['installedpackages']['patches']['item'])) { + $config['installedpackages']['patches']['item'] = array(); +} +$a_patches = &$config['installedpackages']['patches']['item']; + +$id = $_GET['id']; +if (isset($_POST['id'])) + $id = $_POST['id']; + +if (isset($_GET['dup'])) { + $id = $_GET['dup']; + $after = $_GET['dup']; +} + +if (isset($id) && $a_patches[$id]) { + $pconfig['descr'] = $a_patches[$id]['descr']; + $pconfig['location'] = $a_patches[$id]['location']; + $pconfig['patch'] = $a_patches[$id]['patch']; + $pconfig['pathstrip'] = $a_patches[$id]['pathstrip']; + $pconfig['basedir'] = $a_patches[$id]['basedir']; + $pconfig['ignorewhitespace'] = isset($a_patches[$id]['ignorewhitespace']); + $pconfig['autoapply'] = isset($a_patches[$id]['autoapply']); + $pconfig['uniqid'] = $a_patches[$id]['uniqid']; +} + +if (isset($_GET['dup'])) + unset($id); + +unset($input_errors); + +if ($_POST) { + $pconfig = $_POST; + + /* input validation */ + if(empty($_POST['location'])) { + $reqdfields = explode(" ", "patch"); + $reqdfieldsn = array(gettext("Patch Contents")); + } else { + $reqdfields = explode(" ", "descr location"); + $reqdfieldsn = array(gettext("Description"),gettext("URL/Commit ID")); + } + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (!empty($_POST['location']) && !is_commit_id($_POST['location']) && !is_URL($_POST['location'])) { + $input_errors[] = gettext("The supplied commit ID/URL appears to be invalid."); + } + if (!is_numeric($_POST['pathstrip'])) { + $input_errors[] = gettext("Path Strip Count must be numeric!"); + } + if (!empty($_POST['basedir']) && (!file_exists($_POST['basedir']) || !is_dir($_POST['basedir']))) { + $input_errors[] = gettext("Base Directory must exist and be a directory!"); + } + + if (!$input_errors) { + $thispatch = array(); + + $thispatch['descr'] = $_POST['descr']; + $thispatch['location'] = patch_fixup_url($_POST['location']); + if (!empty($_POST['patch'])) { + /* Strip DOS style carriage returns from textarea input */ + $thispatch['patch'] = base64_encode(str_replace("\r", "", $_POST['patch'])); + } + if (is_github_url($thispatch['location']) && ($_POST['pathstrip'] == 0)) + $thispatch['pathstrip'] = 1; + else + $thispatch['pathstrip'] = $_POST['pathstrip']; + $thispatch['basedir'] = empty($_POST['basedir']) ? "/" : $_POST['basedir']; + $thispatch['ignorewhitespace'] = isset($_POST['ignorewhitespace']); + $thispatch['autoapply'] = isset($_POST['autoapply']); + if (empty($_POST['uniqid'])) { + $thispatch['uniqid'] = uniqid(); + } else { + $thispatch['uniqid'] = $_POST['uniqid']; + } + + // Update the patch entry now + if (isset($id) && $a_patches[$id]) + $a_patches[$id] = $thispatch; + else { + if (is_numeric($after)) + array_splice($a_patches, $after+1, 0, array($thispatch)); + else + $a_patches[] = $thispatch; + } + + write_config(); + header("Location: system_patches.php"); + return; + } +} + +$pgtitle = array(gettext("System"),gettext("Patches"), gettext("Edit")); +include("head.inc"); + +?> +<link rel="stylesheet" href="/pfCenter/javascript/chosen/chosen.css" /> +</head> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<script src="/pfCenter/javascript/chosen/chosen.proto.js" type="text/javascript"></script> + +<?php +include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<form action="system_patches_edit.php" method="post" name="iform" id="iform"> +<table width="100%" border="0" cellpadding="6" cellspacing="0"> +<tr> + <td colspan="2" valign="top" class="listtopic"><?=gettext("Edit Patch Entry"); ?></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncellreq"><strong><?=gettext("Description"); ?></strong></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("Enter a description here for your reference."); ?></span></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("URL/Commit ID"); ?></td> + <td width="78%" class="vtable"> + <input name="location" type="text" class="formfld unknown" id="location" size="40" value="<?=htmlspecialchars($pconfig['location']);?>"> + <br> <span class="vexpl"><?=gettext("Enter a URL to a patch, or a commit ID from the main github repository (NOT the tools or packages repos!)."); ?></span></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Patch Contents"); ?></td> + <td width="78%" class="vtable"> + <textarea name="patch" class="" id="patch" ROWS="15" COLS="70" wrap="off"><?=base64_decode($pconfig['patch']);?></textarea> + <br> <span class="vexpl"><?=gettext("The contents of the patch. You can paste a patch here, or enter a URL/commit ID above, it can then be fetched into here automatically."); ?></span></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Path Strip Count:"); ?></td> + <td width="78%" class="vtable"> + <select name="pathstrip" class="formselect" id="pathstrip"> +<?php for ($i = 0; $i < 20; $i++): ?> + <option value="<?=$i;?>" <?php if ($i == $pconfig['pathstrip']) echo "selected"; ?>><?=$i;?></option> +<?php endfor; ?> + </select> + </td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Base Directory"); ?></td> + <td width="78%" class="vtable"> + <input name="basedir" type="text" class="formfld unknown" id="basedir" size="40" value="<?=htmlspecialchars($pconfig['basedir']);?>"> + <br> <span class="vexpl"><?=gettext("Enter the base directory for the patch, default is /. Patches from github are all based in /. Custom patches may need a full path here such as /usr/local/www/"); ?></span></td> +</tr> +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Ignore Whitespace"); ?></td> + <td width="78%" class="vtable"> + <input name="ignorewhitespace" type="checkbox" id="ignorewhitespace" value="yes" <?php if ($pconfig['ignorewhitespace']) echo "checked"; ?>> + <strong><?=gettext("Ignore Whitespace"); ?></strong><br /> + <span class="vexpl"><?=gettext("Set this option to ignore whitespace in the patch."); ?></span> + </td> +</tr> +<!-- This isn't ready yet +<tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Auto Apply"); ?></td> + <td width="78%" class="vtable"> + <input name="autoapply" type="checkbox" id="autoapply" value="yes" <?php if ($pconfig['autoapply']) echo "checked"; ?>> + <strong><?=gettext("Auto-Apply Patch"); ?></strong><br /> + <span class="vexpl"><?=gettext("Set this option to apply the patch automatically when possible, useful for patches to survive after firmware updates."); ?></span> + </td> +</tr> +--> +<tr> + <td width="22%" valign="top"> </td> + <td width="78%">Patch id: <?php echo $pconfig['uniqid']; ?></td> +</tr> +<tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="<?=gettext("Save"); ?>"> <input type="button" class="formbtn" value="<?=gettext("Cancel"); ?>" onclick="history.back()"> + <?php if (isset($id) && $a_patches[$id]): ?> + <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>"> + <input name="uniqid" type="hidden" value="<?=htmlspecialchars($pconfig['uniqid']);?>"> + <?php endif; ?> + </td> +</tr> +</table> +</form> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/systempatches/systempatches.xml b/config/systempatches/systempatches.xml new file mode 100644 index 00000000..3730c84f --- /dev/null +++ b/config/systempatches/systempatches.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* ========================================================================== */ +/* + systempatches.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2012 Jim Pingle + All rights reserved. +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>System Patches</description> + <requirements>None</requirements> + <faq>Applies patches supplied by the user to the firewall.</faq> + <name>System Patches</name> + <version>0.5</version> + <title>System: Patches</title> + <menu> + <name>Patches</name> + <tooltiptext></tooltiptext> + <section>System</section> + <url>/system_patches.php</url> + </menu> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>644</chmod> + <item>http://www.pfsense.com/packages/config/systempatches/system_patches.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>644</chmod> + <item>http://www.pfsense.com/packages/config/systempatches/system_patches_edit.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>644</chmod> + <item>http://www.pfsense.com/packages/config/systempatches/patches.inc</item> + </additional_files_needed> +</packagegui>
\ No newline at end of file |