add rcons page
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@7513 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		
							
								
								
									
										64
									
								
								xCAT-UI/css/ajaxterm.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								xCAT-UI/css/ajaxterm.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| pre.stat { | ||||
| 	margin: 0px; | ||||
| 	padding: 4px; | ||||
| 	display: block; | ||||
| 	font-family: monospace; | ||||
| 	white-space: pre; | ||||
| 	background-color: black; | ||||
| 	border-top: 1px solid black; | ||||
| 	color: white; | ||||
| } | ||||
| pre.stat span { | ||||
| 	padding: 0px; | ||||
| } | ||||
| pre.stat .on { | ||||
| 	background-color: #080; | ||||
| 	font-weight: bold; | ||||
| 	color: white; | ||||
| 	cursor: pointer; | ||||
| } | ||||
| pre.stat .off { | ||||
| 	background-color: #888; | ||||
| 	font-weight: bold; | ||||
| 	color: white; | ||||
| 	cursor: pointer; | ||||
| } | ||||
| pre.term { | ||||
| 	margin: 0px; | ||||
| 	padding: 4px; | ||||
| 	display: block; | ||||
| 	font-family: monospace; | ||||
| 	white-space: pre; | ||||
| 	background-color: black; | ||||
| 	border-top: 1px solid white; | ||||
| 	color: #eee; | ||||
| } | ||||
| pre.term span.f0  { color: #000; } | ||||
| pre.term span.f1  { color: #b00; } | ||||
| pre.term span.f2  { color: #0b0; } | ||||
| pre.term span.f3  { color: #bb0; } | ||||
| pre.term span.f4  { color: #00b; } | ||||
| pre.term span.f5  { color: #b0b; } | ||||
| pre.term span.f6  { color: #0bb; } | ||||
| pre.term span.f7  { color: #bbb; } | ||||
| pre.term span.f8  { color: #666; } | ||||
| pre.term span.f9  { color: #f00; } | ||||
| pre.term span.f10 { color: #0f0; } | ||||
| pre.term span.f11 { color: #ff0; } | ||||
| pre.term span.f12 { color: #00f; } | ||||
| pre.term span.f13 { color: #f0f; } | ||||
| pre.term span.f14 { color: #0ff; } | ||||
| pre.term span.f15 { color: #fff; } | ||||
| pre.term span.b0  { background-color: #000; } | ||||
| pre.term span.b1  { background-color: #b00; } | ||||
| pre.term span.b2  { background-color: #0b0; } | ||||
| pre.term span.b3  { background-color: #bb0; } | ||||
| pre.term span.b4  { background-color: #00b; } | ||||
| pre.term span.b5  { background-color: #b0b; } | ||||
| pre.term span.b6  { background-color: #0bb; } | ||||
| pre.term span.b7  { background-color: #bbb; } | ||||
|  | ||||
| body { background-color: #888; } | ||||
| #term { | ||||
| 	float: left; | ||||
| } | ||||
| @@ -374,6 +374,17 @@ function loadNodes(data) { | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	/* | ||||
| 	 * Open the Rcons page | ||||
| 	 */ | ||||
| 	var rcons = $('<a href="#">Open Rcons</a>'); | ||||
| 	rcons.bind('click', function(event){ | ||||
| 		var tgtNodes = getNodesChecked('nodesDataTable'); | ||||
| 		if (tgtNodes) { | ||||
| 			loadRoncsPage(tgtNodes); | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	/* | ||||
| 	 * Advanced | ||||
| 	 */ | ||||
| @@ -384,7 +395,14 @@ function loadNodes(data) { | ||||
| 	var powerActionMenu = createMenu(powerActions); | ||||
|  | ||||
| 	// Advanced actions | ||||
| 	var advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk ]; | ||||
| 	var advancedActions; | ||||
| 	if ('compute' == group){ | ||||
| 		advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk, rcons ]; | ||||
| 	} | ||||
| 	else{ | ||||
| 		advancedActions = [ boot2NetworkLnk, scriptLnk, setBootStateLnk, updateLnk ]; | ||||
| 	} | ||||
|  | ||||
| 	var advancedActionMenu = createMenu(advancedActions); | ||||
|  | ||||
| 	/** | ||||
| @@ -1337,4 +1355,24 @@ function selectAllCheckbox(event, obj) { | ||||
| 	var status = obj.attr('checked'); | ||||
| 	$('#' + datatableId + ' :checkbox').attr('checked', status); | ||||
| 	event.stopPropagation(); | ||||
| } | ||||
|  | ||||
| function loadRoncsPage(tgtNodes){ | ||||
| 	var hostName = window.location.host; | ||||
| 	var urlPath = window.location.pathname; | ||||
| 	var redirectUrl = 'https://'; | ||||
| 	var pos = 0; | ||||
| 	//we only support one node | ||||
| 	if (-1 != tgtNodes.indexOf(',')){ | ||||
| 		alert("Sorry, the Rcons Page only support one node."); | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	redirectUrl += hostName; | ||||
| 	pos = urlPath.lastIndexOf('/'); | ||||
| 	redirectUrl += urlPath.substring(0, pos + 1); | ||||
| 	redirectUrl += 'rconsShow.php'; | ||||
| 	 | ||||
| 	//open the rcons page | ||||
| 	window.open(redirectUrl + "?rconsnd=" + tgtNodes, '', "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=670,height=436"); | ||||
| } | ||||
							
								
								
									
										226
									
								
								xCAT-UI/js/rcons/rcons.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								xCAT-UI/js/rcons/rcons.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,226 @@ | ||||
| rconsTerm = function(nodeName, height, width){ | ||||
| 	var sid=nodeName; | ||||
| 	var keyBuf = []; | ||||
| 	var receivingFlag = false; | ||||
| 	var sendTimeout; | ||||
| 	var errorTimeout; | ||||
| 	var queryStable = 's=' + sid + '&w=' + height + '&h=' + width + '&c=1&k='; | ||||
| 	var maxDelay = 200; | ||||
| 	var firstFlag = true; | ||||
| 	 | ||||
| 	var workingStatus; | ||||
| 	var termArea; | ||||
| 	var errorArea; | ||||
| 	 | ||||
| 	var ie=0; | ||||
| 	if(window.ActiveXObject){ | ||||
| 		ie=1; | ||||
| 	} | ||||
| 	 | ||||
| 	rconsInit(); | ||||
| 	//init  | ||||
| 	function rconsInit(){ | ||||
| 		//create status, configure the css | ||||
| 		workingStatus = $('<span>.</span>'); | ||||
| 		workingStatus.attr('class', 'off'); | ||||
| 		 | ||||
| 		//create the disconnect button | ||||
| 		var disconnectButton = $('<a class="off">Disconnect</a>'); | ||||
| 		disconnectButton.bind('click', function(){ | ||||
| 			window.close(); | ||||
| 		}); | ||||
| 		 | ||||
| 		//create the control panel,  add to the rcons div | ||||
| 		var controlPanel = $('<pre class="stat"></pre>'); | ||||
| 		$('#term').append(controlPanel); | ||||
| 		 | ||||
| 		//create the error erea | ||||
| 		errorArea = $('<span></span>'); | ||||
| 		 | ||||
| 		//add all item to controlPanel | ||||
| 		controlPanel.append(workingStatus); | ||||
| 		controlPanel.append(disconnectButton); | ||||
| 		controlPanel.append(errorArea); | ||||
| 		 | ||||
| 		//create the termArea | ||||
| 		termArea = $('<div></div>'); | ||||
| 		$('#term').append(termArea); | ||||
| 		 | ||||
| 		//bind keypress event | ||||
| 		document.onkeypress=rconsKeypress; | ||||
| 		document.onkeydown=rconsKeydown; | ||||
| 		window.onbeforeunload = function(){ | ||||
| 			rconsDisconnect(); | ||||
| 			alert("This rcons page is closed."); | ||||
| 		}; | ||||
| 		 | ||||
| 		rconsSend(); | ||||
| 	} | ||||
| 	 | ||||
| 	//close the connection | ||||
| 	function rconsDisconnect(){ | ||||
| 		window.clearTimeout(sendTimeout); | ||||
| 		window.clearTimeout(errorTimeout); | ||||
| 		 | ||||
| 		$.ajax({ | ||||
| 			type : "POST", | ||||
| 			url : "lib/rcons.php", | ||||
| 			data : queryStable + '&q=1', | ||||
| 			dataType : 'json' | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	//translate the key press | ||||
| 	function rconsKeypress(event){ | ||||
| 		if (!event) var event=window.event; | ||||
| 		var kc; | ||||
| 		var k=""; | ||||
| 		if (event.keyCode) | ||||
| 			kc=event.keyCode; | ||||
| 		if (event.which) | ||||
| 			kc=event.which; | ||||
| 		if (event.altKey) { | ||||
| 			if (kc>=65 && kc<=90) | ||||
| 				kc+=32; | ||||
| 			if (kc>=97 && kc<=122) { | ||||
| 				k=String.fromCharCode(27)+String.fromCharCode(kc); | ||||
| 			} | ||||
| 		} else if (event.ctrlKey) { | ||||
| 			if (kc>=65 && kc<=90) k=String.fromCharCode(kc-64); // Ctrl-A..Z | ||||
| 			else if (kc>=97 && kc<=122) k=String.fromCharCode(kc-96); // Ctrl-A..Z | ||||
| 			else if (kc==54)  k=String.fromCharCode(30); // Ctrl-^ | ||||
| 			else if (kc==109) k=String.fromCharCode(31); // Ctrl-_ | ||||
| 			else if (kc==219) k=String.fromCharCode(27); // Ctrl-[ | ||||
| 			else if (kc==220) k=String.fromCharCode(28); // Ctrl-\ | ||||
| 			else if (kc==221) k=String.fromCharCode(29); // Ctrl-] | ||||
| 			else if (kc==219) k=String.fromCharCode(29); // Ctrl-] | ||||
| 			else if (kc==219) k=String.fromCharCode(0);  // Ctrl-@ | ||||
| 		} else if (event.which==0) { | ||||
| 			if (kc==9) k=String.fromCharCode(9);  // Tab | ||||
| 			else if (kc==8) k=String.fromCharCode(127);  // Backspace | ||||
| 			else if (kc==27) k=String.fromCharCode(27); // Escape | ||||
| 			else { | ||||
| 				if (kc==33) k="[5~";        // PgUp | ||||
| 				else if (kc==34) k="[6~";   // PgDn | ||||
| 				else if (kc==35) k="[4~";   // End | ||||
| 				else if (kc==36) k="[1~";   // Home | ||||
| 				else if (kc==37) k="[D";    // Left | ||||
| 				else if (kc==38) k="[A";    // Up | ||||
| 				else if (kc==39) k="[C";    // Right | ||||
| 				else if (kc==40) k="[B";    // Down | ||||
| 				else if (kc==45) k="[2~";   // Ins | ||||
| 				else if (kc==46) k="[3~";   // Del | ||||
| 				else if (kc==112) k="[[A";  // F1 | ||||
| 				else if (kc==113) k="[[B";  // F2 | ||||
| 				else if (kc==114) k="[[C";  // F3 | ||||
| 				else if (kc==115) k="[[D";  // F4 | ||||
| 				else if (kc==116) k="[[E";  // F5 | ||||
| 				else if (kc==117) k="[17~"; // F6 | ||||
| 				else if (kc==118) k="[18~"; // F7 | ||||
| 				else if (kc==119) k="[19~"; // F8 | ||||
| 				else if (kc==120) k="[20~"; // F9 | ||||
| 				else if (kc==121) k="[21~"; // F10 | ||||
| 				else if (kc==122) k="[23~"; // F11 | ||||
| 				else if (kc==123) k="[24~"; // F12 | ||||
| 				if (k.length) { | ||||
| 					k=String.fromCharCode(27)+k; | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (kc==8) | ||||
| 				k=String.fromCharCode(127);  // Backspace | ||||
| 			else | ||||
| 				k=String.fromCharCode(kc); | ||||
| 		} | ||||
| 		if(k.length) { | ||||
| 			if(k=="+") { | ||||
| 				rconsQueue("%2B"); | ||||
| 			} else { | ||||
| 				rconsQueue(escape(k)); | ||||
| 			} | ||||
| 		} | ||||
| 		event.cancelBubble=true; | ||||
| 		if (event.stopPropagation) event.stopPropagation(); | ||||
| 		if (event.preventDefault)  event.preventDefault(); | ||||
| 		return false;	 | ||||
| 	} | ||||
| 	 | ||||
| 	//translate the key press, same with rconsKeypress | ||||
| 	function rconsKeydown(event){ | ||||
| 		if (!event) var event=window.event; | ||||
| 		if (ie) { | ||||
| 			o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1, 113:1,114:1,115:1,116:1,117:1,118:1,119:1,120:1,121:1,122:1,123:1}; | ||||
| 			if (o[event.keyCode] || event.ctrlKey || event.altKey) { | ||||
| 				event.which=0; | ||||
| 				return keypress(event); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	//send the command and request to server | ||||
| 	function rconsSend(){ | ||||
| 		var keyPressList = ''; | ||||
| 		var requireString = ''; | ||||
| 		if(receivingFlag){ | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		receivingFlag = true; | ||||
| 		workingStatus.attr('class', 'on'); | ||||
| 		 | ||||
| 		while(keyBuf.length > 0){ | ||||
| 			keyPressList += keyBuf.pop();  | ||||
| 		} | ||||
| 		 | ||||
| 		if (firstFlag){ | ||||
| 			requireString = queryStable + keyPressList + '&f=1'; | ||||
| 			firstFlag = false; | ||||
| 		} | ||||
| 		else{ | ||||
| 			requireString = queryStable + keyPressList; | ||||
| 		} | ||||
| 		 | ||||
| 		$.ajax({ | ||||
| 			type : "POST", | ||||
| 			url : "lib/rcons.php", | ||||
| 			data : requireString, | ||||
| 			dataType : 'json', | ||||
| 			success : function(data){ | ||||
| 					      rconsUpdate(data); | ||||
| 					  } | ||||
| 		}); | ||||
| 		 | ||||
| 		errorTimeout = window.setTimeout(rconsSendError, 15000); | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	//when receive the response, update the term area | ||||
| 	function rconsUpdate(data){ | ||||
| 		window.clearTimeout(errorTimeout); | ||||
| 		errorArea.empty(); | ||||
| 		if (data.term){ | ||||
| 			termArea.empty().append(data.term); | ||||
| 			maxDelay = 200; | ||||
| 		} | ||||
| 		else{ | ||||
| 			maxDelay = 2000; | ||||
| 		} | ||||
| 		 | ||||
| 		receivingFlag = false; | ||||
| 		workingStatus.attr('class', 'off'); | ||||
| 		sendTimeout = window.setTimeout(rconsSend, maxDelay); | ||||
| 	} | ||||
| 	 | ||||
| 	function rconsSendError(){ | ||||
| 		workingStatus.attr('class', 'off'); | ||||
| 		errorArea.empty().append('Send require error.'); | ||||
| 	} | ||||
| 	 | ||||
| 	function rconsQueue(kc){ | ||||
| 		keyBuf.unshift(kc); | ||||
| 		if (false == receivingFlag){ | ||||
| 			window.clearTimeout(sendTimeout); | ||||
| 			sendTimeout = window.setTimeout(rconsSend, 1); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
							
								
								
									
										19
									
								
								xCAT-UI/lib/AJAXTERM/ajaxterm.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								xCAT-UI/lib/AJAXTERM/ajaxterm.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||||
| <html> | ||||
| <head> | ||||
| 	<title>Ajaxterm</title> | ||||
| 	<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> | ||||
| 	<link rel="stylesheet" type="text/css" href="ajaxterm.css"/> | ||||
| 	<script type="text/javascript" src="sarissa.js"></script> | ||||
| 	<script type="text/javascript" src="sarissa_dhtml.js"></script> | ||||
| 	<script type="text/javascript" src="ajaxterm.js"></script> | ||||
| 	<script type="text/javascript"> | ||||
| 	window.onload=function() { | ||||
| 		t=ajaxterm.Terminal("term",80,25); | ||||
| 	}; | ||||
| 	</script> | ||||
| </head> | ||||
| <body> | ||||
| <div id="term"></div> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										572
									
								
								xCAT-UI/lib/AJAXTERM/ajaxterm.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										572
									
								
								xCAT-UI/lib/AJAXTERM/ajaxterm.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,572 @@ | ||||
| #!/usr/bin/env python | ||||
|  | ||||
| """ Ajaxterm """ | ||||
|  | ||||
| import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd | ||||
|  | ||||
| os.chdir(os.path.normpath(os.path.dirname(__file__))) | ||||
| # Optional: Add QWeb in sys path | ||||
| sys.path[0:0]=glob.glob('../../python') | ||||
|  | ||||
| import qweb | ||||
|  | ||||
| class Terminal: | ||||
| 	def __init__(self,width=80,height=24): | ||||
| 		self.width=width | ||||
| 		self.height=height | ||||
| 		self.init() | ||||
| 		self.reset() | ||||
| 	def init(self): | ||||
| 		self.esc_seq={ | ||||
| 			"\x00": None, | ||||
| 			"\x05": self.esc_da, | ||||
| 			"\x07": None, | ||||
| 			"\x08": self.esc_0x08, | ||||
| 			"\x09": self.esc_0x09, | ||||
| 			"\x0a": self.esc_0x0a, | ||||
| 			"\x0b": self.esc_0x0a, | ||||
| 			"\x0c": self.esc_0x0a, | ||||
| 			"\x0d": self.esc_0x0d, | ||||
| 			"\x0e": None, | ||||
| 			"\x0f": None, | ||||
| 			"\x1b#8": None, | ||||
| 			"\x1b=": None, | ||||
| 			"\x1b>": None, | ||||
| 			"\x1b(0": None, | ||||
| 			"\x1b(A": None, | ||||
| 			"\x1b(B": None, | ||||
| 			"\x1b[c": self.esc_da, | ||||
| 			"\x1b[0c": self.esc_da, | ||||
| 			"\x1b]R": None, | ||||
| 			"\x1b7": self.esc_save, | ||||
| 			"\x1b8": self.esc_restore, | ||||
| 			"\x1bD": None, | ||||
| 			"\x1bE": None, | ||||
| 			"\x1bH": None, | ||||
| 			"\x1bM": self.esc_ri, | ||||
| 			"\x1bN": None, | ||||
| 			"\x1bO": None, | ||||
| 			"\x1bZ": self.esc_da, | ||||
| 			"\x1ba": None, | ||||
| 			"\x1bc": self.reset, | ||||
| 			"\x1bn": None, | ||||
| 			"\x1bo": None, | ||||
| 		} | ||||
| 		for k,v in self.esc_seq.items(): | ||||
| 			if v==None: | ||||
| 				self.esc_seq[k]=self.esc_ignore | ||||
| 		# regex | ||||
| 		d={ | ||||
| 			r'\[\??([0-9;]*)([@ABCDEFGHJKLMPXacdefghlmnqrstu`])' : self.csi_dispatch, | ||||
| 			r'\]([^\x07]+)\x07' : self.esc_ignore, | ||||
| 		} | ||||
| 		self.esc_re=[] | ||||
| 		for k,v in d.items(): | ||||
| 			self.esc_re.append((re.compile('\x1b'+k),v)) | ||||
| 		# define csi sequences | ||||
| 		self.csi_seq={ | ||||
| 			'@': (self.csi_at,[1]), | ||||
| 			'`': (self.csi_G,[1]), | ||||
| 			'J': (self.csi_J,[0]), | ||||
| 			'K': (self.csi_K,[0]), | ||||
| 		} | ||||
| 		for i in [i[4] for i in dir(self) if i.startswith('csi_') and len(i)==5]: | ||||
| 			if not self.csi_seq.has_key(i): | ||||
| 				self.csi_seq[i]=(getattr(self,'csi_'+i),[1]) | ||||
| 		# Init 0-256 to latin1 and html translation table | ||||
| 		self.trl1="" | ||||
| 		for i in range(256): | ||||
| 			if i<32: | ||||
| 				self.trl1+=" " | ||||
| 			elif i<127 or i>160: | ||||
| 				self.trl1+=chr(i) | ||||
| 			else: | ||||
| 				self.trl1+="?" | ||||
| 		self.trhtml="" | ||||
| 		for i in range(256): | ||||
| 			if i==0x0a or (i>32 and i<127) or i>160: | ||||
| 				self.trhtml+=chr(i) | ||||
| 			elif i<=32: | ||||
| 				self.trhtml+="\xa0" | ||||
| 			else: | ||||
| 				self.trhtml+="?" | ||||
| 	def reset(self,s=""): | ||||
| 		self.scr=array.array('i',[0x000700]*(self.width*self.height)) | ||||
| 		self.st=0 | ||||
| 		self.sb=self.height-1 | ||||
| 		self.cx_bak=self.cx=0 | ||||
| 		self.cy_bak=self.cy=0 | ||||
| 		self.cl=0 | ||||
| 		self.sgr=0x000700 | ||||
| 		self.buf="" | ||||
| 		self.outbuf="" | ||||
| 		self.last_html="" | ||||
| 	def peek(self,y1,x1,y2,x2): | ||||
| 		return self.scr[self.width*y1+x1:self.width*y2+x2] | ||||
| 	def poke(self,y,x,s): | ||||
| 		pos=self.width*y+x | ||||
| 		self.scr[pos:pos+len(s)]=s | ||||
| 	def zero(self,y1,x1,y2,x2): | ||||
| 		w=self.width*(y2-y1)+x2-x1+1 | ||||
| 		z=array.array('i',[0x000700]*w) | ||||
| 		self.scr[self.width*y1+x1:self.width*y2+x2+1]=z | ||||
| 	def scroll_up(self,y1,y2): | ||||
| 		self.poke(y1,0,self.peek(y1+1,0,y2,self.width)) | ||||
| 		self.zero(y2,0,y2,self.width-1) | ||||
| 	def scroll_down(self,y1,y2): | ||||
| 		self.poke(y1+1,0,self.peek(y1,0,y2-1,self.width)) | ||||
| 		self.zero(y1,0,y1,self.width-1) | ||||
| 	def scroll_right(self,y,x): | ||||
| 		self.poke(y,x+1,self.peek(y,x,y,self.width)) | ||||
| 		self.zero(y,x,y,x) | ||||
| 	def cursor_down(self): | ||||
| 		if self.cy>=self.st and self.cy<=self.sb: | ||||
| 			self.cl=0 | ||||
| 			q,r=divmod(self.cy+1,self.sb+1) | ||||
| 			if q: | ||||
| 				self.scroll_up(self.st,self.sb) | ||||
| 				self.cy=self.sb | ||||
| 			else: | ||||
| 				self.cy=r | ||||
| 	def cursor_right(self): | ||||
| 		q,r=divmod(self.cx+1,self.width) | ||||
| 		if q: | ||||
| 			self.cl=1 | ||||
| 		else: | ||||
| 			self.cx=r | ||||
| 	def echo(self,c): | ||||
| 		if self.cl: | ||||
| 			self.cursor_down() | ||||
| 			self.cx=0 | ||||
| 		self.scr[(self.cy*self.width)+self.cx]=self.sgr|ord(c) | ||||
| 		self.cursor_right() | ||||
| 	def esc_0x08(self,s): | ||||
| 		self.cx=max(0,self.cx-1) | ||||
| 	def esc_0x09(self,s): | ||||
| 		x=self.cx+8 | ||||
| 		q,r=divmod(x,8) | ||||
| 		self.cx=(q*8)%self.width | ||||
| 	def esc_0x0a(self,s): | ||||
| 		self.cursor_down() | ||||
| 	def esc_0x0d(self,s): | ||||
| 		self.cl=0 | ||||
| 		self.cx=0 | ||||
| 	def esc_save(self,s): | ||||
| 		self.cx_bak=self.cx | ||||
| 		self.cy_bak=self.cy | ||||
| 	def esc_restore(self,s): | ||||
| 		self.cx=self.cx_bak | ||||
| 		self.cy=self.cy_bak | ||||
| 		self.cl=0 | ||||
| 	def esc_da(self,s): | ||||
| 		self.outbuf="\x1b[?6c" | ||||
| 	def esc_ri(self,s): | ||||
| 		self.cy=max(self.st,self.cy-1) | ||||
| 		if self.cy==self.st: | ||||
| 			self.scroll_down(self.st,self.sb) | ||||
| 	def esc_ignore(self,*s): | ||||
| 		pass | ||||
| #		print "term:ignore: %s"%repr(s) | ||||
| 	def csi_dispatch(self,seq,mo): | ||||
| 	# CSI sequences | ||||
| 		s=mo.group(1) | ||||
| 		c=mo.group(2) | ||||
| 		f=self.csi_seq.get(c,None) | ||||
| 		if f: | ||||
| 			try: | ||||
| 				l=[min(int(i),1024) for i in s.split(';') if len(i)<4] | ||||
| 			except ValueError: | ||||
| 				l=[] | ||||
| 			if len(l)==0: | ||||
| 				l=f[1] | ||||
| 			f[0](l) | ||||
| #		else: | ||||
| #			print 'csi ignore',c,l | ||||
| 	def csi_at(self,l): | ||||
| 		for i in range(l[0]): | ||||
| 			self.scroll_right(self.cy,self.cx) | ||||
| 	def csi_A(self,l): | ||||
| 		self.cy=max(self.st,self.cy-l[0]) | ||||
| 	def csi_B(self,l): | ||||
| 		self.cy=min(self.sb,self.cy+l[0]) | ||||
| 	def csi_C(self,l): | ||||
| 		self.cx=min(self.width-1,self.cx+l[0]) | ||||
| 		self.cl=0 | ||||
| 	def csi_D(self,l): | ||||
| 		self.cx=max(0,self.cx-l[0]) | ||||
| 		self.cl=0 | ||||
| 	def csi_E(self,l): | ||||
| 		self.csi_B(l) | ||||
| 		self.cx=0 | ||||
| 		self.cl=0 | ||||
| 	def csi_F(self,l): | ||||
| 		self.csi_A(l) | ||||
| 		self.cx=0 | ||||
| 		self.cl=0 | ||||
| 	def csi_G(self,l): | ||||
| 		self.cx=min(self.width,l[0])-1 | ||||
| 	def csi_H(self,l): | ||||
| 		if len(l)<2: l=[1,1] | ||||
| 		self.cx=min(self.width,l[1])-1 | ||||
| 		self.cy=min(self.height,l[0])-1 | ||||
| 		self.cl=0 | ||||
| 	def csi_J(self,l): | ||||
| 		if l[0]==0: | ||||
| 			self.zero(self.cy,self.cx,self.height-1,self.width-1) | ||||
| 		elif l[0]==1: | ||||
| 			self.zero(0,0,self.cy,self.cx) | ||||
| 		elif l[0]==2: | ||||
| 			self.zero(0,0,self.height-1,self.width-1) | ||||
| 	def csi_K(self,l): | ||||
| 		if l[0]==0: | ||||
| 			self.zero(self.cy,self.cx,self.cy,self.width-1) | ||||
| 		elif l[0]==1: | ||||
| 			self.zero(self.cy,0,self.cy,self.cx) | ||||
| 		elif l[0]==2: | ||||
| 			self.zero(self.cy,0,self.cy,self.width-1) | ||||
| 	def csi_L(self,l): | ||||
| 		for i in range(l[0]): | ||||
| 			if self.cy<self.sb: | ||||
| 				self.scroll_down(self.cy,self.sb) | ||||
| 	def csi_M(self,l): | ||||
| 		if self.cy>=self.st and self.cy<=self.sb: | ||||
| 			for i in range(l[0]): | ||||
| 				self.scroll_up(self.cy,self.sb) | ||||
| 	def csi_P(self,l): | ||||
| 		w,cx,cy=self.width,self.cx,self.cy | ||||
| 		end=self.peek(cy,cx,cy,w) | ||||
| 		self.csi_K([0]) | ||||
| 		self.poke(cy,cx,end[l[0]:]) | ||||
| 	def csi_X(self,l): | ||||
| 		self.zero(self.cy,self.cx,self.cy,self.cx+l[0]) | ||||
| 	def csi_a(self,l): | ||||
| 		self.csi_C(l) | ||||
| 	def csi_c(self,l): | ||||
| 		#'\x1b[?0c' 0-8 cursor size | ||||
| 		pass | ||||
| 	def csi_d(self,l): | ||||
| 		self.cy=min(self.height,l[0])-1 | ||||
| 	def csi_e(self,l): | ||||
| 		self.csi_B(l) | ||||
| 	def csi_f(self,l): | ||||
| 		self.csi_H(l) | ||||
| 	def csi_h(self,l): | ||||
| 		if l[0]==4: | ||||
| 			pass | ||||
| #			print "insert on" | ||||
| 	def csi_l(self,l): | ||||
| 		if l[0]==4: | ||||
| 			pass | ||||
| #			print "insert off" | ||||
| 	def csi_m(self,l): | ||||
| 		for i in l: | ||||
| 			if i==0 or i==39 or i==49 or i==27: | ||||
| 				self.sgr=0x000700 | ||||
| 			elif i==1: | ||||
| 				self.sgr=(self.sgr|0x000800) | ||||
| 			elif i==7: | ||||
| 				self.sgr=0x070000 | ||||
| 			elif i>=30 and i<=37: | ||||
| 				c=i-30 | ||||
| 				self.sgr=(self.sgr&0xff08ff)|(c<<8) | ||||
| 			elif i>=40 and i<=47: | ||||
| 				c=i-40 | ||||
| 				self.sgr=(self.sgr&0x00ffff)|(c<<16) | ||||
| #			else: | ||||
| #				print "CSI sgr ignore",l,i | ||||
| #		print 'sgr: %r %x'%(l,self.sgr) | ||||
| 	def csi_r(self,l): | ||||
| 		if len(l)<2: l=[0,self.height] | ||||
| 		self.st=min(self.height-1,l[0]-1) | ||||
| 		self.sb=min(self.height-1,l[1]-1) | ||||
| 		self.sb=max(self.st,self.sb) | ||||
| 	def csi_s(self,l): | ||||
| 		self.esc_save(0) | ||||
| 	def csi_u(self,l): | ||||
| 		self.esc_restore(0) | ||||
| 	def escape(self): | ||||
| 		e=self.buf | ||||
| 		if len(e)>32: | ||||
| #			print "error %r"%e | ||||
| 			self.buf="" | ||||
| 		elif e in self.esc_seq: | ||||
| 			self.esc_seq[e](e) | ||||
| 			self.buf="" | ||||
| 		else: | ||||
| 			for r,f in self.esc_re: | ||||
| 				mo=r.match(e) | ||||
| 				if mo: | ||||
| 					f(e,mo) | ||||
| 					self.buf="" | ||||
| 					break | ||||
| #		if self.buf=='': print "ESC %r\n"%e | ||||
| 	def write(self,s): | ||||
| 		for i in s: | ||||
| 			if len(self.buf) or (i in self.esc_seq): | ||||
| 				self.buf+=i | ||||
| 				self.escape() | ||||
| 			elif i == '\x1b': | ||||
| 				self.buf+=i | ||||
| 			else: | ||||
| 				self.echo(i) | ||||
| 	def read(self): | ||||
| 		b=self.outbuf | ||||
| 		self.outbuf="" | ||||
| 		return b | ||||
| 	def dump(self): | ||||
| 		r='' | ||||
| 		for i in self.scr: | ||||
| 			r+=chr(i&255) | ||||
| 		return r | ||||
| 	def dumplatin1(self): | ||||
| 		return self.dump().translate(self.trl1) | ||||
| 	def dumphtml(self,color=1): | ||||
| 		h=self.height | ||||
| 		w=self.width | ||||
| 		r="" | ||||
| 		span="" | ||||
| 		span_bg,span_fg=-1,-1 | ||||
| 		for i in range(h*w): | ||||
| 			q,c=divmod(self.scr[i],256) | ||||
| 			if color: | ||||
| 				bg,fg=divmod(q,256) | ||||
| 			else: | ||||
| 				bg,fg=0,7 | ||||
| 			if i==self.cy*w+self.cx: | ||||
| 				bg,fg=1,7 | ||||
| 			if (bg!=span_bg or fg!=span_fg or i==h*w-1): | ||||
| 				if len(span): | ||||
| 					r+='<span class="f%d b%d">%s</span>'%(span_fg,span_bg,cgi.escape(span.translate(self.trhtml))) | ||||
| 				span="" | ||||
| 				span_bg,span_fg=bg,fg | ||||
| 			span+=chr(c) | ||||
| 			if i%w==w-1: | ||||
| 				span+='\n' | ||||
| 		r='<?xml version="1.0" encoding="ISO-8859-1"?><pre class="term">%s</pre>'%r | ||||
| 		if self.last_html==r: | ||||
| 			return '<?xml version="1.0"?><idem></idem>' | ||||
| 		else: | ||||
| 			self.last_html=r | ||||
| #			print self | ||||
| 			return r | ||||
| 	def __repr__(self): | ||||
| 		d=self.dumplatin1() | ||||
| 		r="" | ||||
| 		for i in range(self.height): | ||||
| 			r+="|%s|\n"%d[self.width*i:self.width*(i+1)] | ||||
| 		return r | ||||
|  | ||||
| class SynchronizedMethod: | ||||
| 	def __init__(self,lock,orig): | ||||
| 		self.lock=lock | ||||
| 		self.orig=orig | ||||
| 	def __call__(self,*l): | ||||
| 		self.lock.acquire() | ||||
| 		r=self.orig(*l) | ||||
| 		self.lock.release() | ||||
| 		return r | ||||
|  | ||||
| class Multiplex: | ||||
| 	def __init__(self,cmd=None): | ||||
| 		signal.signal(signal.SIGCHLD, signal.SIG_IGN) | ||||
| 		self.cmd=cmd | ||||
| 		self.proc={} | ||||
| 		self.lock=threading.RLock() | ||||
| 		self.thread=threading.Thread(target=self.loop) | ||||
| 		self.alive=1 | ||||
| 		# synchronize methods | ||||
| 		for name in ['create','fds','proc_read','proc_write','dump','die','run']: | ||||
| 			orig=getattr(self,name) | ||||
| 			setattr(self,name,SynchronizedMethod(self.lock,orig)) | ||||
| 		self.thread.start() | ||||
| 	def create(self,w=80,h=25): | ||||
| 		pid,fd=pty.fork() | ||||
| 		if pid==0: | ||||
| 			try: | ||||
| 				fdl=[int(i) for i in os.listdir('/proc/self/fd')] | ||||
| 			except OSError: | ||||
| 				fdl=range(256) | ||||
| 			for i in [i for i in fdl if i>2]: | ||||
| 				try: | ||||
| 					os.close(i) | ||||
| 				except OSError: | ||||
| 					pass | ||||
| 			if self.cmd: | ||||
| 				cmd=['/bin/sh','-c',self.cmd] | ||||
| 			elif os.getuid()==0: | ||||
| 				cmd=['/bin/login'] | ||||
| 			else: | ||||
| 				sys.stdout.write("Login: ") | ||||
| 				login=sys.stdin.readline().strip() | ||||
| 				if re.match('^[0-9A-Za-z-_. ]+$',login): | ||||
| 					cmd=['ssh'] | ||||
| 					cmd+=['-oPreferredAuthentications=keyboard-interactive,password'] | ||||
| 					cmd+=['-oNoHostAuthenticationForLocalhost=yes'] | ||||
| 					cmd+=['-oLogLevel=FATAL'] | ||||
| 					cmd+=['-F/dev/null','-l',login,'localhost'] | ||||
| 				else: | ||||
| 					os._exit(0) | ||||
| 			env={} | ||||
| 			env["COLUMNS"]=str(w) | ||||
| 			env["LINES"]=str(h) | ||||
| 			env["TERM"]="linux" | ||||
| 			env["PATH"]=os.environ['PATH'] | ||||
| 			os.execvpe(cmd[0],cmd,env) | ||||
| 		else: | ||||
| 			fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) | ||||
| 			# python bug http://python.org/sf/1112949 on amd64 | ||||
| 			fcntl.ioctl(fd, struct.unpack('i',struct.pack('I',termios.TIOCSWINSZ))[0], struct.pack("HHHH",h,w,0,0)) | ||||
| 			self.proc[fd]={'pid':pid,'term':Terminal(w,h),'buf':'','time':time.time()} | ||||
| 			return fd | ||||
| 	def die(self): | ||||
| 		self.alive=0 | ||||
| 	def run(self): | ||||
| 		return self.alive | ||||
| 	def fds(self): | ||||
| 		return self.proc.keys() | ||||
| 	def proc_kill(self,fd): | ||||
| 		if fd in self.proc: | ||||
| 			self.proc[fd]['time']=0 | ||||
| 		t=time.time() | ||||
| 		for i in self.proc.keys(): | ||||
| 			t0=self.proc[i]['time'] | ||||
| 			if (t-t0)>120: | ||||
| 				try: | ||||
| 					os.close(i) | ||||
| 					os.kill(self.proc[i]['pid'],signal.SIGTERM) | ||||
| 				except (IOError,OSError): | ||||
| 					pass | ||||
| 				del self.proc[i] | ||||
| 	def proc_read(self,fd): | ||||
| 		try: | ||||
| 			t=self.proc[fd]['term'] | ||||
| 			t.write(os.read(fd,65536)) | ||||
| 			reply=t.read() | ||||
| 			if reply: | ||||
| 				os.write(fd,reply) | ||||
| 			self.proc[fd]['time']=time.time() | ||||
| 		except (KeyError,IOError,OSError): | ||||
| 			self.proc_kill(fd) | ||||
| 	def proc_write(self,fd,s): | ||||
| 		try: | ||||
| 			os.write(fd,s) | ||||
| 		except (IOError,OSError): | ||||
| 			self.proc_kill(fd) | ||||
| 	def dump(self,fd,color=1): | ||||
| 		try: | ||||
| 			return self.proc[fd]['term'].dumphtml(color) | ||||
| 		except KeyError: | ||||
| 			return False | ||||
| 	def loop(self): | ||||
| 		while self.run(): | ||||
| 			fds=self.fds() | ||||
| 			i,o,e=select.select(fds, [], [], 1.0) | ||||
| 			for fd in i: | ||||
| 				self.proc_read(fd) | ||||
| 			if len(i): | ||||
| 				time.sleep(0.002) | ||||
| 		for i in self.proc.keys(): | ||||
| 			try: | ||||
| 				os.close(i) | ||||
| 				os.kill(self.proc[i]['pid'],signal.SIGTERM) | ||||
| 			except (IOError,OSError): | ||||
| 				pass | ||||
|  | ||||
| class AjaxTerm: | ||||
| 	def __init__(self,cmd=None,index_file='ajaxterm.html'): | ||||
| 		self.files={} | ||||
| 		for i in ['css','html','js']: | ||||
| 			for j in glob.glob('*.%s'%i): | ||||
| 				self.files[j]=file(j).read() | ||||
| 		self.files['index']=file(index_file).read() | ||||
| 		self.mime = mimetypes.types_map.copy() | ||||
| 		self.mime['.html']= 'text/html; charset=UTF-8' | ||||
| 		self.multi = Multiplex(cmd) | ||||
| 		self.session = {} | ||||
| 	def __call__(self, environ, start_response): | ||||
| 		req = qweb.QWebRequest(environ, start_response,session=None) | ||||
| 		if req.PATH_INFO.endswith('/u'): | ||||
| 			s=req.REQUEST["s"] | ||||
| 			k=req.REQUEST["k"] | ||||
| 			c=req.REQUEST["c"] | ||||
| 			w=req.REQUEST.int("w") | ||||
| 			h=req.REQUEST.int("h") | ||||
| 			q=req.REQUEST.int("q") | ||||
| 			if s in self.session: | ||||
| 				term=self.session[s] | ||||
| 			else: | ||||
| 				if not (w>2 and w<256 and h>2 and h<100): | ||||
| 					w,h=80,25 | ||||
| 				term=self.session[s]=self.multi.create(w,h) | ||||
| 			if k: | ||||
| 				self.multi.proc_write(term,k) | ||||
| 			time.sleep(0.002) | ||||
| 			dump=self.multi.dump(term,c) | ||||
| 			req.response_headers['Content-Type']='text/xml' | ||||
| 			if isinstance(dump,str): | ||||
| 				req.write(dump) | ||||
| 				req.response_gzencode=1 | ||||
| 			else: | ||||
| 				del self.session[s] | ||||
| 				req.write('<?xml version="1.0"?><idem></idem>') | ||||
| #			print "sessions %r"%self.session | ||||
| 			if (1 == q): | ||||
| 				self.multi.proc_kill(self.session[s]) | ||||
| 				time.sleep(0.002) | ||||
| 				del self.session[s] | ||||
| 		else: | ||||
| 			n=os.path.basename(req.PATH_INFO) | ||||
| 			if n in self.files: | ||||
| 				req.response_headers['Content-Type'] = self.mime.get(os.path.splitext(n)[1].lower(), 'application/octet-stream') | ||||
| 				req.write(self.files[n]) | ||||
| 			else: | ||||
| 				req.response_headers['Content-Type'] = 'text/html; charset=UTF-8' | ||||
| 				req.write(self.files['index']) | ||||
| 		return req | ||||
|  | ||||
| def main(): | ||||
| 	parser = optparse.OptionParser() | ||||
| 	parser.add_option("-p", "--port", dest="port", default="8022", help="Set the TCP port (default: 8022)") | ||||
| 	parser.add_option("-c", "--command", dest="cmd", default=None,help="set the command (default: /bin/login or ssh localhost)") | ||||
| 	parser.add_option("-l", "--log", action="store_true", dest="log",default=0,help="log requests to stderr (default: quiet mode)") | ||||
| 	parser.add_option("-d", "--daemon", action="store_true", dest="daemon", default=0, help="run as daemon in the background") | ||||
| 	parser.add_option("-P", "--pidfile",dest="pidfile",default="/var/run/ajaxterm.pid",help="set the pidfile (default: /var/run/ajaxterm.pid)") | ||||
| 	parser.add_option("-i", "--index", dest="index_file", default="ajaxterm.html",help="default index file (default: ajaxterm.html)") | ||||
| 	parser.add_option("-u", "--uid", dest="uid", help="Set the daemon's user id") | ||||
| 	(o, a) = parser.parse_args() | ||||
| 	if o.daemon: | ||||
| 		pid=os.fork() | ||||
| 		if pid == 0: | ||||
| 			#os.setsid() ? | ||||
| 			os.setpgrp() | ||||
| 			nullin = file('/dev/null', 'r') | ||||
| 			nullout = file('/dev/null', 'w') | ||||
| 			os.dup2(nullin.fileno(), sys.stdin.fileno()) | ||||
| 			os.dup2(nullout.fileno(), sys.stdout.fileno()) | ||||
| 			os.dup2(nullout.fileno(), sys.stderr.fileno()) | ||||
| 			if os.getuid()==0 and o.uid: | ||||
| 				try: | ||||
| 					os.setuid(int(o.uid)) | ||||
| 				except: | ||||
| 					os.setuid(pwd.getpwnam(o.uid).pw_uid) | ||||
| 		else: | ||||
| 			try: | ||||
| 				file(o.pidfile,'w+').write(str(pid)+'\n') | ||||
| 			except: | ||||
| 				pass | ||||
| 			print 'AjaxTerm at http://localhost:%s/ pid: %d' % (o.port,pid) | ||||
| 			sys.exit(0) | ||||
| 	else: | ||||
| 		print 'AjaxTerm at http://localhost:%s/' % o.port | ||||
| 	at=AjaxTerm(o.cmd,o.index_file) | ||||
| #	f=lambda:os.system('firefox http://localhost:%s/&'%o.port) | ||||
| #	qweb.qweb_wsgi_autorun(at,ip='localhost',port=int(o.port),threaded=0,log=o.log,callback_ready=None) | ||||
| 	try: | ||||
| 		qweb.QWebWSGIServer(at,ip='localhost',port=int(o.port),threaded=0,log=o.log).serve_forever() | ||||
| 	except KeyboardInterrupt,e: | ||||
| 		sys.excepthook(*sys.exc_info()) | ||||
| 	at.multi.die() | ||||
|  | ||||
| if __name__ == '__main__': | ||||
| 	main() | ||||
|  | ||||
							
								
								
									
										1356
									
								
								xCAT-UI/lib/AJAXTERM/qweb.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1356
									
								
								xCAT-UI/lib/AJAXTERM/qweb.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										101
									
								
								xCAT-UI/lib/rcons.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								xCAT-UI/lib/rcons.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| <?php | ||||
|  | ||||
| 	require_once "functions.php"; | ||||
| 	require_once "jsonwrapper.php"; | ||||
| 	 | ||||
| 	$query = ''; | ||||
| 	$output = ''; | ||||
| 	$temp = ''; | ||||
| 	$pythonProcess = ''; | ||||
| 	if (!isAuthenticated()){ | ||||
| 		echo ("Please log in firsr."); | ||||
| 	} | ||||
| 	 | ||||
| 	$query = 's=' . $_POST['s'] . '&w=' . $_POST['w'] . '&h=' . $_POST['h']; | ||||
| 	if (isset($_POST['q'])){ | ||||
| 		$query .= '&q=1'; | ||||
| 	} | ||||
| 	else{ | ||||
| 		$query .= '&q=0'; | ||||
| 	} | ||||
| 	 | ||||
| 	if (isset($_POST['f'])){ | ||||
| 		$pythonProcess = exec('ps -aef | grep -v grep | grep ajaxterm.py'); | ||||
| 		if ('' == $pythonProcess){ | ||||
| 			exec('nohup ' . dirname(__FILE__) . '/AJAXTERM/ajaxterm.py >/dev/null 2>&1 &'); | ||||
| 		} | ||||
| 		 | ||||
| 		sleep(1); | ||||
| 				 | ||||
| 		$temp = $query . '&k=' . urlencode($_SESSION["username"] . "\r"); | ||||
| 		$output = rconsSynchronise($temp); | ||||
| 		if (0 < substr_count($output, 'error')){ | ||||
| 			echo json_encode(array('err'=>$output)); | ||||
| 			exit; | ||||
| 		} | ||||
| 		sleep(1); | ||||
| 		 | ||||
| 		$temp = $query . '&k=' . urlencode(getpassword() . "\r"); | ||||
| 		$output = rconsSynchronise($temp); | ||||
| 		if (0 < substr_count($output, 'error')){ | ||||
| 			echo json_encode(array('err'=>$output)); | ||||
| 			exit; | ||||
| 		} | ||||
| 		sleep(1); | ||||
| 		 | ||||
| 		$temp = $query . '&c=1&k=' . urlencode('rcons ' . $_POST['s'] . "\r"); | ||||
| 	} | ||||
| 	else{ | ||||
| 		$temp = $query . '&c=1&k=' . urlencode($_POST['k']); | ||||
| 	} | ||||
|       | ||||
|     $output = rconsSynchronise($temp); | ||||
| 	if (0 < substr_count($output, 'error')){ | ||||
| 		echo (array('err'=>$output)); | ||||
| 	} | ||||
| 	else{ | ||||
| 		$xml = simplexml_load_string($output); | ||||
| 		if ('pre' == $xml->getName()){ | ||||
| 			$output = $xml->asXML(); | ||||
| 			$output = preg_replace('/'. chr(160) . '/', ' ', $output); | ||||
|  | ||||
| 			echo json_encode(array('term'=>$output)); | ||||
| 		} | ||||
| 		else{ | ||||
| 			echo json_encode(array('nc'=>'nc')); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| function rconsSynchronise($parameter){ | ||||
| 	$flag = false; | ||||
| 	$return = ""; | ||||
| 	$out = ""; | ||||
| 	$fp = fsockopen("127.0.0.1", 8022, $errno, $errstr, 30); | ||||
| 	if (!$fp) { | ||||
|     	return "<error>$errstr($errno)</error>"; | ||||
| 	} | ||||
| 	 | ||||
| 	$out = "GET /u?$parameter HTTP/1.1\r\nHost: 127.0.0.1:8022\r\nConnection: Close\r\n\r\n"; | ||||
| 	 | ||||
| 	fwrite($fp, $out); | ||||
| 	while(!feof($fp)){ | ||||
|         $line = fgets($fp,1024); | ||||
|         if (0 == strlen($line)){ | ||||
|             continue; | ||||
|         } | ||||
|         if('<' == substr($line, 0, 1)){ | ||||
|             $flag = true; | ||||
|             $return .= $line; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if ($flag){ | ||||
|         while(!feof($fp)){ | ||||
|             $return .= fgets($fp, 1024); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return ($return); | ||||
| } | ||||
| ?> | ||||
							
								
								
									
										25
									
								
								xCAT-UI/rconsShow.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								xCAT-UI/rconsShow.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <?php | ||||
| echo <<<EEE | ||||
| <html> | ||||
| 	<head> | ||||
| 	    <title>{$_GET['rconsnd']}</title> | ||||
| 	    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> | ||||
| 	    <link rel="stylesheet" type="text/css" href="css/ajaxterm.css"/> | ||||
| 	    <script type="text/javascript" src="js/jquery/jquery-1.4.2.min.js"></script> | ||||
| 	    <script type="text/javascript" src="js/rcons/rcons.js"></script> | ||||
| 	    <script type="text/javascript"> | ||||
| 	    window.onload=function() { | ||||
| 	        t=new rconsTerm("{$_GET['rconsnd']}", 80, 25); | ||||
| 	    }; | ||||
| 		window.onbeforeunload = function(){ | ||||
| 			 | ||||
| 		}; | ||||
| 	    </script> | ||||
| 	</head> | ||||
| 	<body> | ||||
| 		<div id="term"></div> | ||||
| 	</body> | ||||
| </html> | ||||
| EEE; | ||||
| ?> | ||||
|  | ||||
| @@ -38,6 +38,7 @@ mkdir -p $RPM_BUILD_ROOT%{prefix}/ui | ||||
| set +x | ||||
| cp -r * $RPM_BUILD_ROOT%{prefix}/ui | ||||
| chmod 755 $RPM_BUILD_ROOT%{prefix}/ui/* | ||||
| chmod 755 $RPM_BUILD_ROOT%{prefix}/ui/lib/AJAXTERM/*.py | ||||
| set -x | ||||
|  | ||||
| %files | ||||
|   | ||||
		Reference in New Issue
	
	Block a user