Project

General

Profile

Download (11.5 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 a68f7a3d Luiz Otavio O Souza
 * Copyright (c) 2014-2024 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 c1d304b3 Marcos Mendoza
							<i class="fa-regular fa-file-lines"></i>
120 ee092d36 Jared Dillard
							<?=gettext('Load')?>
121
						</button>
122
						<button type="button" class="btn btn-default btn-sm" id="fbOpen"		value="<?=gettext('Browse')?>">
123 e0cb987c Marcos Mendoza
							<i class="fa-solid fa-list"></i>
124 ee092d36 Jared Dillard
							<?=gettext('Browse')?>
125
						</button>
126
						<button type="button" class="btn btn-default btn-sm" onclick="saveFile();"	value="<?=gettext('Save')?>">
127 e0cb987c Marcos Mendoza
							<i class="fa-solid fa-save"></i>
128 ee092d36 Jared Dillard
							<?=gettext('Save')?>
129
						</button>
130
					</p>
131 37676f4e jim-p
				</div>
132 ee092d36 Jared Dillard
				<p class="pull-right">
133 e0cb987c Marcos Mendoza
					<button id="btngoto" class="btn btn-default btn-sm"><i class="fa-solid fa-forward"></i><?=gettext("GoTo Line #")?></button> <input type="number" id="gotoline" size="6" style="padding: 3px 0px;"/>
134 ee092d36 Jared Dillard
				</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 4864d7f6 Josh Soref
			console.log("Jumping to line " + line);
210 1b910463 Steve Beaver
			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
		var values = req.responseText.split("|");
257
		values.shift(); values.pop();
258
259 8c2df62b Christopher Cope
		var fbBrowserVisible = $("#fbBrowser").is(":visible");
260
261 41b1ff89 Phil Davis
		if (values.shift() == "0") {
262 0d6a185a Scott Ullrich
			var file = values.shift();
263 557e0826 Steve Beaver
			var fileContent = window.Base64.decode(values.join("|"));
264 0d6a185a Scott Ullrich
265 8c2df62b Christopher Cope
			$("#fbBrowser").fadeOut();
266
			fbBrowserVisible = false;
267 3f98044a Francisco Cavalcante
			$("#fileContent").val(fileContent);
268 947141fd Phil Davis
		} else {
269 3f98044a Francisco Cavalcante
			$("#fileStatus").html(values[0]);
270
			$("#fileContent").val("");
271 0d6a185a Scott Ullrich
		}
272 45d6ada5 Sjon Hortensius
273 8c2df62b Christopher Cope
		if (!fbBrowserVisible) {
274
			$("#fileContent").show(1000);
275
		}
276 0d6a185a Scott Ullrich
	}
277 5b237745 Scott Ullrich
278 0d6a185a Scott Ullrich
	function saveFile(file) {
279 3f98044a Francisco Cavalcante
		$("#fileStatus").html("");
280
		$("#fileStatusBox").show(500);
281 41b1ff89 Phil Davis
282 3f98044a Francisco Cavalcante
		var fileContent = Base64.encode($("#fileContent").val());
283 6c07db48 Phil Davis
		fileContent = fileContent.replace(/\+/g, "%2B");
284 45d6ada5 Sjon Hortensius
285 3f98044a Francisco Cavalcante
		$.ajax(
286 45d6ada5 Sjon Hortensius
			"<?=$_SERVER['SCRIPT_NAME']?>", {
287 e3c1ea9b Vinicius Coque
				type: "post",
288 3f98044a Francisco Cavalcante
				data: "action=save&file=" + $("#fbTarget").val() +
289 ee650539 Scott Ullrich
							"&data=" + fileContent,
290 e3c1ea9b Vinicius Coque
				complete: function(req) {
291 0d6a185a Scott Ullrich
					var values = req.responseText.split("|");
292 3f98044a Francisco Cavalcante
					$("#fileStatus").html(values[1]);
293 0d6a185a Scott Ullrich
				}
294
			}
295
		);
296
	}
297
298 e561ccdf Stephen Beaver
/**
299
 *
300
 *	Base64 encode / decode
301
 *	http://www.webtoolkit.info/
302
 *	http://www.webtoolkit.info/licence
303
 **/
304
305
var Base64 = {
306
307
	// private property
308
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
309
310
	// public method for encoding
311
	encode : function (input) {
312
		var output = "";
313
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
314
		var i = 0;
315
316
		input = Base64._utf8_encode(input);
317
318
		while (i < input.length) {
319
320
			chr1 = input.charCodeAt(i++);
321
			chr2 = input.charCodeAt(i++);
322
			chr3 = input.charCodeAt(i++);
323
324
			enc1 = chr1 >> 2;
325
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
326
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
327
			enc4 = chr3 & 63;
328
329
			if (isNaN(chr2)) {
330
				enc3 = enc4 = 64;
331
			} else if (isNaN(chr3)) {
332
				enc4 = 64;
333
			}
334
335
			output = output +
336
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
337
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
338
339
		}
340
341
		return output;
342
	},
343
344
	// public method for decoding
345
	decode : function (input) {
346
		var output = "";
347
		var chr1, chr2, chr3;
348
		var enc1, enc2, enc3, enc4;
349
		var i = 0;
350
351
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
352
353
		while (i < input.length) {
354
355
			enc1 = this._keyStr.indexOf(input.charAt(i++));
356
			enc2 = this._keyStr.indexOf(input.charAt(i++));
357
			enc3 = this._keyStr.indexOf(input.charAt(i++));
358
			enc4 = this._keyStr.indexOf(input.charAt(i++));
359
360
			chr1 = (enc1 << 2) | (enc2 >> 4);
361
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
362
			chr3 = ((enc3 & 3) << 6) | enc4;
363
364
			output = output + String.fromCharCode(chr1);
365
366
			if (enc3 != 64) {
367
				output = output + String.fromCharCode(chr2);
368
			}
369
			if (enc4 != 64) {
370
				output = output + String.fromCharCode(chr3);
371
			}
372
373
		}
374
375
		output = Base64._utf8_decode(output);
376
377
		return output;
378
379
	},
380
381
	// private method for UTF-8 encoding
382
	_utf8_encode : function (string) {
383
		string = string.replace(/\r\n/g,"\n");
384
		var utftext = "";
385
386
		for (var n = 0; n < string.length; n++) {
387
388
			var c = string.charCodeAt(n);
389
390
			if (c < 128) {
391
				utftext += String.fromCharCode(c);
392 947141fd Phil Davis
			} else if ((c > 127) && (c < 2048)) {
393 e561ccdf Stephen Beaver
				utftext += String.fromCharCode((c >> 6) | 192);
394
				utftext += String.fromCharCode((c & 63) | 128);
395 947141fd Phil Davis
			} else {
396 e561ccdf Stephen Beaver
				utftext += String.fromCharCode((c >> 12) | 224);
397
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
398
				utftext += String.fromCharCode((c & 63) | 128);
399
			}
400
401
		}
402
403
		return utftext;
404
	},
405
406
	// private method for UTF-8 decoding
407
	_utf8_decode : function (utftext) {
408
		var string = "";
409
		var i = 0;
410
		var c = c1 = c2 = 0;
411
412 947141fd Phil Davis
		while (i < utftext.length) {
413 e561ccdf Stephen Beaver
414
			c = utftext.charCodeAt(i);
415
416
			if (c < 128) {
417
				string += String.fromCharCode(c);
418
				i++;
419 947141fd Phil Davis
			} else if ((c > 191) && (c < 224)) {
420 e561ccdf Stephen Beaver
				c2 = utftext.charCodeAt(i+1);
421
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
422
				i += 2;
423 947141fd Phil Davis
			} else {
424 e561ccdf Stephen Beaver
				c2 = utftext.charCodeAt(i+1);
425
				c3 = utftext.charCodeAt(i+2);
426
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
427
				i += 3;
428
			}
429
430
		}
431
432
		return string;
433
	}
434
435
};
436
437 7f4268b6 Steve Beaver
	<?php if ($_POST['action'] == "load"): ?>
438 45d6ada5 Sjon Hortensius
		events.push(function() {
439 7f4268b6 Steve Beaver
			$("#fbTarget").val("<?=htmlspecialchars($_POST['path'])?>");
440 45d6ada5 Sjon Hortensius
			loadFile();
441
		});
442 0d6a185a Scott Ullrich
	<?php endif; ?>
443 86e94bec Stephen Beaver
444 8fd9052f Colin Fleming
//]]>
445 0d6a185a Scott Ullrich
</script>
446 ab541dbb Scott Ullrich
447 45d6ada5 Sjon Hortensius
<?php include("foot.inc");
448
449 18e7bc46 Stephen Beaver
outputJavaScriptFileInline("vendor/filebrowser/browser.js");