Project

General

Profile

Download (11.4 KB) Statistics
| Branch: | Tag: | Revision:
1 447611c4 Scott Ullrich
<?php
2 a7f908db Scott Ullrich
/*
3 6173d1f5 Colin Fleming
 * diag_edit.php
4 fd9ebcd5 Stephen Beaver
 *
5 c5d81585 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 8f585441 Luiz Souza
 * Copyright (c) 2014-2021 Rubicon Communications, LLC (Netgate)
9 c5d81585 Renato Botelho
 * All rights reserved.
10 fd9ebcd5 Stephen Beaver
 *
11 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14 fd9ebcd5 Stephen Beaver
 *
15 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
16 fd9ebcd5 Stephen Beaver
 *
17 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22 fd9ebcd5 Stephen Beaver
 */
23 a7f908db Scott Ullrich
24 9fbb3599 Ermal
##|+PRIV
25
##|*IDENT=page-diagnostics-edit
26 9599211d jim-p
##|*NAME=Diagnostics: Edit File
27 9fbb3599 Ermal
##|*DESCR=Allow access to the 'Diagnostics: Edit File' page.
28 57188e47 Phil Davis
##|*WARN=standard-warning-root
29 a09f3d8e Phil Davis
##|*MATCH=diag_edit.php*
30 c0f613e2 Ermal
##|*MATCH=browser.php*
31 18e7bc46 Stephen Beaver
##|*MATCH=vendor/filebrowser/browser.php*
32 9fbb3599 Ermal
##|-PRIV
33
34 1b910463 Steve Beaver
$lineheight = "18"; // Required by the jumpToLine() JS function
35
36 a6a6ee00 k-paulius
$pgtitle = array(gettext("Diagnostics"), gettext("Edit File"));
37 c81ef6e2 Phil Davis
require_once("guiconfig.inc");
38 859329c8 Scott Ullrich
39 41b1ff89 Phil Davis
if ($_POST['action']) {
40
	switch ($_POST['action']) {
41 0d6a185a Scott Ullrich
		case 'load':
42 288a2a0f Phil Davis
			if (strlen($_POST['file']) < 1) {
43 1bd5e62d k-paulius
				print('|5|');
44 ed98ef92 Phil Davis
				print_info_box(gettext("No file name specified."), 'danger');
45 1bd5e62d k-paulius
				print('|');
46 288a2a0f Phil Davis
			} elseif (is_dir($_POST['file'])) {
47 1bd5e62d k-paulius
				print('|4|');
48 ed98ef92 Phil Davis
				print_info_box(gettext("Loading a directory is not supported."), 'danger');
49 1bd5e62d k-paulius
				print('|');
50 288a2a0f Phil Davis
			} elseif (!is_file($_POST['file'])) {
51 1bd5e62d k-paulius
				print('|3|');
52 ed98ef92 Phil Davis
				print_info_box(gettext("File does not exist or is not a regular file."), 'danger');
53 1bd5e62d k-paulius
				print('|');
54 0d6a185a Scott Ullrich
			} else {
55 55344e2c Ermal
				$data = file_get_contents(urldecode($_POST['file']));
56 288a2a0f Phil Davis
				if ($data === false) {
57 1bd5e62d k-paulius
					print('|1|');
58 ed98ef92 Phil Davis
					print_info_box(gettext("Failed to read file."), 'danger');
59 1bd5e62d k-paulius
					print('|');
60 0d6a185a Scott Ullrich
				} else {
61 b71f0cbb Ermal
					$data = base64_encode($data);
62 45d6ada5 Sjon Hortensius
					print("|0|{$_POST['file']}|{$data}|");
63 0d6a185a Scott Ullrich
				}
64
			}
65
			exit;
66 45d6ada5 Sjon Hortensius
67 0d6a185a Scott Ullrich
		case 'save':
68 288a2a0f Phil Davis
			if (strlen($_POST['file']) < 1) {
69 1bd5e62d k-paulius
				print('|');
70 ed98ef92 Phil Davis
				print_info_box(gettext("No file name specified."), 'danger');
71 1bd5e62d k-paulius
				print('|');
72 0d6a185a Scott Ullrich
			} else {
73 55344e2c Ermal
				$_POST['data'] = str_replace("\r", "", base64_decode($_POST['data']));
74
				$ret = file_put_contents($_POST['file'], $_POST['data']);
75 41b1ff89 Phil Davis
				if ($_POST['file'] == "/conf/config.xml" || $_POST['file'] == "/cf/conf/config.xml") {
76
					if (file_exists("/tmp/config.cache")) {
77 5f05c1e8 Scott Ullrich
						unlink("/tmp/config.cache");
78 41b1ff89 Phil Davis
					}
79 0f806eca Erik Fonnesbeck
					disable_security_checks();
80
				}
81 288a2a0f Phil Davis
				if ($ret === false) {
82 1bd5e62d k-paulius
					print('|');
83 ed98ef92 Phil Davis
					print_info_box(gettext("Failed to write file."), 'danger');
84 1bd5e62d k-paulius
					print('|');
85 288a2a0f Phil Davis
				} elseif ($ret != strlen($_POST['data'])) {
86 1bd5e62d k-paulius
					print('|');
87 ed98ef92 Phil Davis
					print_info_box(gettext("Error while writing file."), 'danger');
88 1bd5e62d k-paulius
					print('|');
89 0d6a185a Scott Ullrich
				} else {
90 1bd5e62d k-paulius
					print('|');
91 ed98ef92 Phil Davis
					print_info_box(gettext("File saved successfully."), 'success');
92 1bd5e62d k-paulius
					print('|');
93 0d6a185a Scott Ullrich
				}
94
			}
95
			exit;
96 5124d619 Scott Ullrich
	}
97 0d6a185a Scott Ullrich
	exit;
98 5124d619 Scott Ullrich
}
99
100 c81ef6e2 Phil Davis
require_once("head.inc");
101 ee092d36 Jared Dillard
102
print_callout(gettext("The capabilities offered here can be dangerous. No support is available. Use them at your own risk!"), 'danger', gettext('Advanced Users Only'));
103
104 5b237745 Scott Ullrich
?>
105 45d6ada5 Sjon Hortensius
<!-- file status box -->
106
<div style="display:none; background:#eeeeee;" id="fileStatusBox">
107 1bd5e62d k-paulius
	<div id="fileStatus"></div>
108 45d6ada5 Sjon Hortensius
</div>
109
110
<div class="panel panel-default">
111 3d7a8696 k-paulius
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Save / Load a File from the Filesystem")?></h2></div>
112 45d6ada5 Sjon Hortensius
	<div class="panel-body">
113 2ca4eec2 Jared Dillard
		<div class="content">
114
			<form>
115 e5343844 Stephen Beaver
				<p><input type="text" class="form-control" id="fbTarget" placeholder="<?=gettext('Path to file to be edited')?>"/></p>
116 37676f4e jim-p
				<div class="btn-group">
117 ee092d36 Jared Dillard
					<p>
118
						<button type="button" class="btn btn-default btn-sm" onclick="loadFile();"	value="<?=gettext('Load')?>">
119
							<i class="fa fa-file-text-o"></i>
120
							<?=gettext('Load')?>
121
						</button>
122
						<button type="button" class="btn btn-default btn-sm" id="fbOpen"		value="<?=gettext('Browse')?>">
123
							<i class="fa fa-list"></i>
124
							<?=gettext('Browse')?>
125
						</button>
126
						<button type="button" class="btn btn-default btn-sm" onclick="saveFile();"	value="<?=gettext('Save')?>">
127
							<i class="fa fa-save"></i>
128
							<?=gettext('Save')?>
129
						</button>
130
					</p>
131 37676f4e jim-p
				</div>
132 ee092d36 Jared Dillard
				<p class="pull-right">
133
					<button id="btngoto" class="btn btn-default btn-sm"><i class="fa fa-forward"></i><?=gettext("GoTo Line #")?></button> <input type="number" id="gotoline" size="6" style="padding: 3px 0px;"/>
134
				</p>
135 2ca4eec2 Jared Dillard
			</form>
136 45d6ada5 Sjon Hortensius
137 ee092d36 Jared Dillard
			<div id="fbBrowser" style="display:none; border:1px dashed gray; width:98%; padding:10px"></div>
138 45d6ada5 Sjon Hortensius
139 ee092d36 Jared Dillard
			<script type="text/javascript">
140
			//<![CDATA[
141
			window.onload=function() {
142
				document.getElementById("fileContent").wrap='off';
143
			}
144
			//]]>
145
			</script>
146 1b910463 Steve Beaver
			<textarea id="fileContent" name="fileContent" class="form-control" rows="30" cols="20"  style="line-height: <?=$lineheight?>px;"></textarea>
147 45d6ada5 Sjon Hortensius
		</div>
148
	</div>
149
</div>
150
151 8fd9052f Colin Fleming
<script type="text/javascript">
152
//<![CDATA[
153 b54c2035 Stephen Beaver
	events.push(function(){
154 6935650a Steve Beaver
		// Hitting the enter key will do the same as clicking the 'Load' button
155
		$("#fbTarget").on("keyup", function (event) {
156
			if (event.keyCode == 13) {
157
				loadFile();
158
			}
159
		});
160 b54c2035 Stephen Beaver
161
		function showLine(tarea, lineNum) {
162
			lineNum--; // array starts at 0
163
			var lines = tarea.value.split("\n");
164
165
			// calculate start/end
166
			var startPos = 0, endPos = tarea.value.length;
167 9d3e8723 Phil Davis
			for (var x = 0; x < lines.length; x++) {
168
				if (x == lineNum) {
169 b54c2035 Stephen Beaver
					break;
170
				}
171
				startPos += (lines[x].length+1);
172
173
			}
174
175
			var endPos = lines[lineNum].length+startPos;
176
177
			// do selection
178
			// Chrome / Firefox
179
180 9d3e8723 Phil Davis
			if (typeof(tarea.selectionStart) != "undefined") {
181 b54c2035 Stephen Beaver
				tarea.focus();
182
				tarea.selectionStart = startPos;
183
				tarea.selectionEnd = endPos;
184 1b910463 Steve Beaver
				jumpToLine(lineNum);
185 b54c2035 Stephen Beaver
				return true;
186
			}
187
188
			// IE
189
			if (document.selection && document.selection.createRange) {
190
				tarea.focus();
191
				tarea.select();
192
				var range = document.selection.createRange();
193
				range.collapse(true);
194
				range.moveEnd("character", endPos);
195
				range.moveStart("character", startPos);
196
				range.select();
197 1b910463 Steve Beaver
				jumpToLine(lineNum);
198 b54c2035 Stephen Beaver
				return true;
199
			}
200
201
			return false;
202
		}
203
204 1b910463 Steve Beaver
		// Jump to the specified line number
205
		// This requires that the line-height CSS parameter applied to the text area is the same 
206
		// as specified in this function
207
		function jumpToLine(line) {
208
			var lineht = <?=$lineheight?>; // Line height in pixels
209
			console.log("Jumpting to line " + line);
210
			var ta = document.getElementById("fileContent");
211
			ta.scrollTop = lineht * (line - 1);
212
		}
213
214 b54c2035 Stephen Beaver
		$("#btngoto").prop('type','button');
215
216 fd778d8b Stephen Beaver
		//On clicking the GoTo button, validate the entered value
217
		// and highlight the required line
218 b54c2035 Stephen Beaver
		$('#btngoto').click(function() {
219
			var tarea = document.getElementById("fileContent");
220 fd778d8b Stephen Beaver
			var gtl = $('#gotoline').val();
221
			var lines = $("#fileContent").val().split(/\r|\r\n|\n/).length;
222
223
			if (gtl < 1) {
224
				gtl = 1;
225
			}
226
227
			if (gtl > lines) {
228
				gtl = lines;
229
			}
230
231
			showLine(tarea, gtl);
232 b54c2035 Stephen Beaver
		});
233 86e94bec Stephen Beaver
234
		// Goto the specified line on pressing the Enter key within the "Goto line" input element
235
		$('#gotoline').keyup(function(e) {
236
			if(e.keyCode == 13) {
237
				$('#btngoto').click();
238
			}
239
		});
240
241
	}); // e-o-events.push()
242 b54c2035 Stephen Beaver
243 0d6a185a Scott Ullrich
	function loadFile() {
244 3f98044a Francisco Cavalcante
		$("#fileStatus").html("");
245
		$("#fileStatusBox").show(500);
246
		$.ajax(
247 45d6ada5 Sjon Hortensius
			"<?=$_SERVER['SCRIPT_NAME']?>", {
248 e3c1ea9b Vinicius Coque
				type: "post",
249 3f98044a Francisco Cavalcante
				data: "action=load&file=" + $("#fbTarget").val(),
250 e3c1ea9b Vinicius Coque
				complete: loadComplete
251 0d6a185a Scott Ullrich
			}
252
		);
253
	}
254 5b237745 Scott Ullrich
255 0d6a185a Scott Ullrich
	function loadComplete(req) {
256 3f98044a Francisco Cavalcante
		$("#fileContent").show(1000);
257 0d6a185a Scott Ullrich
		var values = req.responseText.split("|");
258
		values.shift(); values.pop();
259
260 41b1ff89 Phil Davis
		if (values.shift() == "0") {
261 0d6a185a Scott Ullrich
			var file = values.shift();
262 557e0826 Steve Beaver
			var fileContent = window.Base64.decode(values.join("|"));
263 0d6a185a Scott Ullrich
264 3f98044a Francisco Cavalcante
			$("#fileContent").val(fileContent);
265 947141fd Phil Davis
		} else {
266 3f98044a Francisco Cavalcante
			$("#fileStatus").html(values[0]);
267
			$("#fileContent").val("");
268 0d6a185a Scott Ullrich
		}
269 45d6ada5 Sjon Hortensius
270 3f98044a Francisco Cavalcante
		$("#fileContent").show(1000);
271 0d6a185a Scott Ullrich
	}
272 5b237745 Scott Ullrich
273 0d6a185a Scott Ullrich
	function saveFile(file) {
274 3f98044a Francisco Cavalcante
		$("#fileStatus").html("");
275
		$("#fileStatusBox").show(500);
276 41b1ff89 Phil Davis
277 3f98044a Francisco Cavalcante
		var fileContent = Base64.encode($("#fileContent").val());
278 6c07db48 Phil Davis
		fileContent = fileContent.replace(/\+/g, "%2B");
279 45d6ada5 Sjon Hortensius
280 3f98044a Francisco Cavalcante
		$.ajax(
281 45d6ada5 Sjon Hortensius
			"<?=$_SERVER['SCRIPT_NAME']?>", {
282 e3c1ea9b Vinicius Coque
				type: "post",
283 3f98044a Francisco Cavalcante
				data: "action=save&file=" + $("#fbTarget").val() +
284 ee650539 Scott Ullrich
							"&data=" + fileContent,
285 e3c1ea9b Vinicius Coque
				complete: function(req) {
286 0d6a185a Scott Ullrich
					var values = req.responseText.split("|");
287 3f98044a Francisco Cavalcante
					$("#fileStatus").html(values[1]);
288 0d6a185a Scott Ullrich
				}
289
			}
290
		);
291
	}
292
293 e561ccdf Stephen Beaver
/**
294
 *
295
 *	Base64 encode / decode
296
 *	http://www.webtoolkit.info/
297
 *	http://www.webtoolkit.info/licence
298
 **/
299
300
var Base64 = {
301
302
	// private property
303
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
304
305
	// public method for encoding
306
	encode : function (input) {
307
		var output = "";
308
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
309
		var i = 0;
310
311
		input = Base64._utf8_encode(input);
312
313
		while (i < input.length) {
314
315
			chr1 = input.charCodeAt(i++);
316
			chr2 = input.charCodeAt(i++);
317
			chr3 = input.charCodeAt(i++);
318
319
			enc1 = chr1 >> 2;
320
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
321
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
322
			enc4 = chr3 & 63;
323
324
			if (isNaN(chr2)) {
325
				enc3 = enc4 = 64;
326
			} else if (isNaN(chr3)) {
327
				enc4 = 64;
328
			}
329
330
			output = output +
331
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
332
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
333
334
		}
335
336
		return output;
337
	},
338
339
	// public method for decoding
340
	decode : function (input) {
341
		var output = "";
342
		var chr1, chr2, chr3;
343
		var enc1, enc2, enc3, enc4;
344
		var i = 0;
345
346
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
347
348
		while (i < input.length) {
349
350
			enc1 = this._keyStr.indexOf(input.charAt(i++));
351
			enc2 = this._keyStr.indexOf(input.charAt(i++));
352
			enc3 = this._keyStr.indexOf(input.charAt(i++));
353
			enc4 = this._keyStr.indexOf(input.charAt(i++));
354
355
			chr1 = (enc1 << 2) | (enc2 >> 4);
356
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
357
			chr3 = ((enc3 & 3) << 6) | enc4;
358
359
			output = output + String.fromCharCode(chr1);
360
361
			if (enc3 != 64) {
362
				output = output + String.fromCharCode(chr2);
363
			}
364
			if (enc4 != 64) {
365
				output = output + String.fromCharCode(chr3);
366
			}
367
368
		}
369
370
		output = Base64._utf8_decode(output);
371
372
		return output;
373
374
	},
375
376
	// private method for UTF-8 encoding
377
	_utf8_encode : function (string) {
378
		string = string.replace(/\r\n/g,"\n");
379
		var utftext = "";
380
381
		for (var n = 0; n < string.length; n++) {
382
383
			var c = string.charCodeAt(n);
384
385
			if (c < 128) {
386
				utftext += String.fromCharCode(c);
387 947141fd Phil Davis
			} else if ((c > 127) && (c < 2048)) {
388 e561ccdf Stephen Beaver
				utftext += String.fromCharCode((c >> 6) | 192);
389
				utftext += String.fromCharCode((c & 63) | 128);
390 947141fd Phil Davis
			} else {
391 e561ccdf Stephen Beaver
				utftext += String.fromCharCode((c >> 12) | 224);
392
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
393
				utftext += String.fromCharCode((c & 63) | 128);
394
			}
395
396
		}
397
398
		return utftext;
399
	},
400
401
	// private method for UTF-8 decoding
402
	_utf8_decode : function (utftext) {
403
		var string = "";
404
		var i = 0;
405
		var c = c1 = c2 = 0;
406
407 947141fd Phil Davis
		while (i < utftext.length) {
408 e561ccdf Stephen Beaver
409
			c = utftext.charCodeAt(i);
410
411
			if (c < 128) {
412
				string += String.fromCharCode(c);
413
				i++;
414 947141fd Phil Davis
			} else if ((c > 191) && (c < 224)) {
415 e561ccdf Stephen Beaver
				c2 = utftext.charCodeAt(i+1);
416
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
417
				i += 2;
418 947141fd Phil Davis
			} else {
419 e561ccdf Stephen Beaver
				c2 = utftext.charCodeAt(i+1);
420
				c3 = utftext.charCodeAt(i+2);
421
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
422
				i += 3;
423
			}
424
425
		}
426
427
		return string;
428
	}
429
430
};
431
432 7f4268b6 Steve Beaver
	<?php if ($_POST['action'] == "load"): ?>
433 45d6ada5 Sjon Hortensius
		events.push(function() {
434 7f4268b6 Steve Beaver
			$("#fbTarget").val("<?=htmlspecialchars($_POST['path'])?>");
435 45d6ada5 Sjon Hortensius
			loadFile();
436
		});
437 0d6a185a Scott Ullrich
	<?php endif; ?>
438 86e94bec Stephen Beaver
439 8fd9052f Colin Fleming
//]]>
440 0d6a185a Scott Ullrich
</script>
441 ab541dbb Scott Ullrich
442 45d6ada5 Sjon Hortensius
<?php include("foot.inc");
443
444 18e7bc46 Stephen Beaver
outputJavaScriptFileInline("vendor/filebrowser/browser.js");