Subversion Repositories php-qbpwcf

Rev

Rev 226 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
/*
3
 
4
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
5
    Copyright (C) 2015~2024 Min-Jhin,Chen
6
 
7
    This file is part of QBPWCF.
8
 
9
    QBPWCF is free software: you can redistribute it and/or modify
10
    it under the terms of the GNU General Public License as published by
11
    the Free Software Foundation, either version 3 of the License, or
12
    (at your option) any later version.
13
 
14
    QBPWCF is distributed in the hope that it will be useful,
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
    GNU General Public License for more details.
18
 
19
    You should have received a copy of the GNU General Public License
20
    along with QBPWCF.  If not, see <http://www.gnu.org/licenses/>.
21
 
22
*/
23
namespace qbpwcf;
24
 
25
/*
26
類別說明:
27
應用qemu的類別.
28
備註:
29
無.
30
*/
31
class qemu{
32
 
33
	/*
34
	#函式說明:
35
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
36
	#回傳結果:
37
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
38
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
39
	#$result["function"],當前執行的函式名稱.
40
	#必填參數:
41
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
42
	#$arguments,陣列,為呼叫方法時所用的參數.
43
	#參考資料:
44
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
45
	*/
46
	public function call($method,$arguments){
47
 
48
		#取得當前執行的函式
49
		$result["function"]=__FUNCTION__;
50
 
51
		#設置執行不正常
52
		$result["status"]="false";
53
 
54
		#設置執行錯誤
55
		$result["error"][]=__NAMESPACE__ ."/".$method."() 不存在!";
56
 
57
		#設置所丟入的參數
58
		$result["error"][]=$arguments;
59
 
60
		#回傳結果
61
		return $result;
62
 
63
		}#function __call end
64
 
65
	/*
66
	#函式說明:
67
	#當前類別被呼叫的靜態方法不存在時,將會執行該函數,回報該方法不存在.
68
	#回傳結果:
69
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
70
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
71
	#$result["function"],當前執行的函式名稱.
72
	#必填參數:
73
	#$method,物件,為物件實體或類別名稱,會自動置入該參數.
74
	#$arguments,陣列,為呼叫方法時所用的參數.
75
	#參考資料:
76
	#__call=>http://php.net/manual/en/language.oop5.overloading.php#object.callstatic
77
	*/
78
	public static function callStatic($method,$arguments){
79
 
80
		#取得當前執行的函式
81
		$result["function"]=__FUNCTION__;
82
 
83
		#設置執行不正常
84
		$result["status"]="false";
85
 
86
		#設置執行錯誤
87
		$result["error"][]="欲呼叫的". __NAMESPACE__ ."/".$method."() 不存在!";
88
 
89
		#設置所丟入的參數
90
		$result["error"][]=$arguments;
91
 
92
		#回傳結果
93
		return $result;
94
 
95
		}#function callStatic end
96
 
97
	/*
98
	#函數說明:
99
	#建立供qemu使用的socket檔案.
100
	#回傳結果:
101
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
102
	#$result["error"],錯誤訊息.
103
	#$result["function"],當前執行的函數名稱.
104
	#$result["argu"],所使用的參數.
105
	#$result["content"],socket檔案的位置與名稱.
106
	#$result["createdFilePath"],socket檔案的路徑.
107
	#$result["createdFileName"],socket檔案名稱.
108
	#必填參數:
109
	#無
110
	#可省略參數:
111
	#$conf["sockFolder"],字串,socket檔案要儲存在哪邊,預設為"/tmp/qbpwcf/qemu".
112
	#$conf["sockFolder"]="/tmp/qbpwcf/qemu";
113
	#$conf["sockFile"],字串,socket檔案的名稱,預設為"亂數產生的5位英數字.sock",副檔名".sock"會自動補上.
114
	#$conf["sockFile"]="";
115
	#$conf["plusSockFileName"],字串,針對亂數產生的socket檔案名稱,是否要增加一些內容,譬如:"[__name]-spice-sock",就代表要在自動產生的[__name]名稱後面加上"-spice-sock"字串.
116
	#$conf["plusSockFileName"]="[__name]";
117
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
118
	#$conf["fileArgu"]=__FILE__;
119
	#備註:
120
	#如果要在/tmp與/var/tmp底下建立socket檔案,若在apache環境下則會被作業系統特殊處理,即不等於實際上的路徑.
121
	*/
122
	function createSockFile(&$conf=array()){
123
 
124
		#初始化要回傳的結果
125
		$result=array();
126
 
127
		#取得當前執行的函數名稱
128
		$result["function"]=__FUNCTION__;
129
 
130
		#涵式說明:
131
		#判斷當前環境為web還是cmd
132
		#回傳結果:
133
		#$result,"web"或"cmd"
134
		if(csInformation::getEnv()==="web"){
135
 
136
			#設置執行失敗
137
			$result["status"]="false";
138
 
139
			#設置執行錯誤訊息
140
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
141
 
142
			#回傳結果
143
			return $result;
144
 
145
			}#if end
146
 
147
		#取得參數
148
		$result["argu"]=$conf;
149
 
150
		#如果 $conf 不為陣列
151
		if(gettype($conf)!="array"){
152
 
153
			#設置執行失敗
154
			$result["status"]="false";
155
 
156
			#設置執行錯誤訊息
157
			$result["error"][]="\$conf變數須為陣列形態";
158
 
159
			#如果傳入的參數為 null
160
			if($conf==null){
161
 
162
				#設置執行錯誤訊息
163
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
164
 
165
				}#if end
166
 
167
			#回傳結果
168
			return $result;
169
 
170
			}#if end
171
 
172
		#檢查參數
173
		#函式說明:
174
		#檢查一包含數個可省略變數的陣列變數,其型態是否正確,省略掉的陣列變數可以直接給定預設值。
175
		#回傳結果:
176
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
177
		#$result["error"],錯誤訊息陣列.
178
		#$result["function"],當前執行的函式名稱.
179
		#$result["passed"],參數是否都通過檢查,"true",代表有通過檢查,"false"代表沒有通過檢查。
180
		#必填參數:
181
		#$conf["checkedVar"],陣列,要檢查的變數陣列名稱為?
182
		$conf["variableCheck::checkSkipableVarType"]["checkedVar"]=$conf;
183
		#$conf["sikpableVarNameArray"],字串陣列,要檢查型態是否設定正確的變數名稱陣列.
184
		$conf["variableCheck::checkSkipableVarType"]["sikpableVarNameArray"]=array("sockFolder","sockFile","plusSockFileName","fileArgu");
185
		#$argu,要直接存取的陣列變數名稱,變數前面加上「&」,如果要在別的函式裡面使用本函式,請記得將變動過結果($argu)給使用該函式的設定變數(通常是$conf=$argu).
186
		$argu=&$conf;
187
		#可省略參數:
188
		#$conf["skipableVarTypeArray"],字串陣列,要檢查的每個變數,其型態應該要為何,null代表不指定變數形態.
189
		$conf["variableCheck::checkSkipableVarType"]["skipableVarTypeArray"]=array("string","string","string","string");
190
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的變數要初始化為什麼,null代表不指定.
191
		$conf["variableCheck::checkSkipableVarType"]["skipableVarDefaultValue"]=array("/tmp/qbpwcf/qemu",null,null,__FILE__);
192
		$checkSkipableVarType=variableCheck::checkSkipableVarType($conf["variableCheck::checkSkipableVarType"],$argu);
193
		unset($conf);
194
 
195
		#如果檢查參數失敗
196
		if($checkSkipableVarType["status"]==="false"){
197
 
198
			#設置執行失敗
199
			$result["status"]="false";
200
 
201
			#設置執行錯誤訊息
202
			$result["error"]=$checkSkipableVarType;
203
 
204
			#回傳結果
205
			return $result;
206
 
207
			}#if end
208
 
209
		#如果檢查參數不通過
210
		if($checkSkipableVarType["passed"]==="false"){
211
 
212
			#設置執行失敗
213
			$result["status"]="false";
214
 
215
			#設置執行錯誤訊息
216
			$result["error"]=$checkSkipableVarType;
217
 
218
			#回傳結果
219
			return $result;
220
 
221
			}#if end
222
 
223
		#取得更新後的參數
224
		$conf=$argu;
225
 
226
		#如果 socket 檔案不存在
227
		if(!isset($conf["sockFile"])){
228
 
229
			#產生亂數
230
			#涵式說明:
231
			#建立以圖片(PNG格式)呈現的驗證碼.
232
			#回傳的解果:
233
			#$result["status"],執行是否正常,"true"代表執行成功,"false"代表執行失敗.
234
			#$result["error"],錯誤訊息.
235
			#$result["function"],檔前執行的函數名稱.
236
			#$result["randNumberWord"],傳驗證碼的內容.
237
			#$result["imgAddress"],圖片的位置與名稱.
238
			#必填的參數:
239
			#$conf["imgAddressAndName"],字串,爲驗證碼圖片儲存的位置與名稱,副檔名程式會自動產生
240
			$conf["authenticate::validationCode"]["imgAddressAndName"]="no used";
241
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
242
			$conf["authenticate::validationCode"]["fileArgu"]="no used";
243
			#可省略的參數:
244
			#$conf["num"],字串,爲驗證碼的位數,請輸入阿拉伯數字,預設為"8"位數.
245
			#$conf["num"]="8";
246
			#$conf["disableImg"],字串,是否要取消驗證碼圖片的輸出,"true"為要取消,預設為"false"為不取消
247
			$conf["authenticate::validationCode"]["disableImg"]="true";
248
			#$conf["imgToData"],字串,預設為"true"代表將圖片轉存成base64圖片,並將原始圖片移除;反之為"false"
249
			#$conf["imgToData"]="true";
250
			$validationCode=authenticate::validationCode($conf["authenticate::validationCode"]);
251
			unset($conf["authenticate::validationCode"]);
252
 
253
			#產生亂數驗證碼失敗
254
			if($validationCode["status"]==="false"){
255
 
256
				#設置執行失敗
257
				$result["status"]="false";
258
 
259
				#設置執行錯誤訊息
260
				$result["error"]=$validationCode;
261
 
262
				#回傳結果
263
				return $result;
264
 
265
				}#if end
266
 
267
			#取得 socket 檔案名稱
268
			$conf["sockFile"]=$validationCode["randNumberWord"];
269
 
270
			}#if end
271
 
272
		#如果有設置 $conf["plusSockFileName"]
273
		if(isset($conf["plusSockFileName"])){
274
 
275
			#如果含有 $conf["plusSockFileName"]
276
			#函式說明:
277
			#檢查字串裡面有無指定的關鍵字
278
			#回傳的結果:
279
			#$result["status"],"true"代表執行成功,"false"代表執行失敗。
280
			#$result["error"],錯誤訊息
281
			#$result["function"],當前執行的函數名稱.
282
			#$result["founded"],是否找到關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字。
283
			#$result["keyWordCount"],找到的關鍵字數量.
284
			#必填的參數:
285
			$conf["search::findKeyWord"]["keyWord"]="[__name]";#想要搜尋的關鍵字
286
			$conf["search::findKeyWord"]["string"]=$conf["plusSockFileName"];#要被搜尋的字串內容
287
			#可省略的參數:
288
			#$conf["completeEqual"]="true";#是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合。
289
			$findKeyWord=search::findKeyWord($conf["search::findKeyWord"]);
290
			unset($conf["search::findKeyWord"]);
291
 
292
			#如果分割字串失敗
293
			if($findKeyWord["status"]==="false"){
294
 
295
				#設置執行失敗
296
				$result["status"]="false";
297
 
298
				#設置執行錯誤訊息
299
				$result["error"]=$findKeyWord;
300
 
301
				#回傳結果
302
				return $result;
303
 
304
				}#if end
305
 
306
			#如果沒有關鍵字 [__name]
307
			if($findKeyWord["founded"]==="false"){
308
 
309
				#設置執行失敗
310
				$result["status"]="false";
311
 
312
				#設置執行錯誤訊息
313
				$result["error"]=$findKeyWord;
314
 
315
				#回傳結果
316
				return $result;
317
 
318
				}#if end
319
 
320
			#產生新的socket檔案名稱
321
			#涵式說明:
322
			#處理多個字串避免網頁出錯
323
			#回傳的結果:
324
			#$result["status"],"true"代表執行成功,"false"代表執行失敗。
325
			#$result["function"],當前執行的函數.
326
			#$result["error"],錯誤訊息
327
			#$result["processedStrArray"],處理好的字串陣列
328
			#必填的參數:
329
			$conf["stringProcess::correctMutiStrCharacter"]["stringIn"]=array($conf["plusSockFileName"]);#爲要處理的字串陣列
330
			#可省略的參數:
331
			$conf["stringProcess::correctMutiStrCharacter"]["selectedCharacter"]=array("[__name]");#爲被選擇要處理的字串/字元,須爲陣列值。
332
				#若不設定則預設爲要將這些字串作替換 ("<",">","=","//","'","$","%","&","|","/*","*","#","\"").
333
				#特殊字元,「\n」代表換行,「\t」代表tab鍵的間隔
334
			$conf["stringProcess::correctMutiStrCharacter"]["changeTo"]=array($conf["sockFile"]);#爲被選擇的字元要換成什麼字串/字元,須爲陣列值。若不設定,則預設爲更換成""(空字串).
335
			$correctMutiStrCharacter=stringProcess::correctMutiStrCharacter($conf["stringProcess::correctMutiStrCharacter"]);
336
			unset($conf["stringProcess::correctMutiStrCharacter"]);
337
 
338
			#如果分割字串失敗
339
			if($correctMutiStrCharacter["status"]==="false"){
340
 
341
				#設置執行失敗
342
				$result["status"]="false";
343
 
344
				#設置執行錯誤訊息
345
				$result["error"]=$correctMutiStrCharacter;
346
 
347
				#回傳結果
348
				return $result;
349
 
350
				}#if end
351
 
352
			#取得產生好的新socket檔案名稱
353
			$conf["sockFile"]=$correctMutiStrCharacter["processedStrArray"][0];
354
 
355
			}#if end
356
 
357
		#建立socket檔案
358
		#函式說明:
359
		#檢查要建立的檔案路徑是否存在,若不存在則建立新檔案,若檔案已存在則會在原檔名後面加上從(1)開始的編號,再度嘗試建立檔案,以避免資料異常.
360
		#回傳的結果:
361
		#$result["status"],執行狀態,"true"代表執行正常,"false"代表執行失敗.
362
		#$result["error"],錯誤訊息陣列.
363
		#$result["function"],當前執行的函數名稱.
364
		#$result["argu"],使用的參數.
365
		#$result["createdFileName"],建立好的檔案名稱.
366
		#$result["createdFilePath"],檔案建立的路徑.
367
		#$result["createdFilePathAndName"].建立好的檔案名稱與路徑.
368
		#必填的參數:
369
		#$conf["checkedFileAndPath"],字串陣列,要建立的檔案路徑
370
		$conf["fileAccess::createFileAfterCheck"]["checkedFileAndPath"]=$conf["sockFolder"]."/".$conf["sockFile"].".sock";
371
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
372
		$conf["fileAccess::createFileAfterCheck"]["fileArgu"]=$conf["fileArgu"];
373
		#可省略參數:
374
		#$conf["filenameExtensionStartPoint"],字串,檔案的副檔名是從倒數第幾個小數點(dot)開始,預設為"1",最後一個小數點.
375
		#$conf["filenameExtensionStartPoint"]="";
376
		#$conf["repeatNameRule"],字串,遇到相同名稱的檔案要如何加上識別的編號,編號用「\$i」表示,預設為"(\$i)".
377
		#$conf["repeatNameRule"]="";
378
		$createFileAfterCheck=fileAccess::createFileAfterCheck($conf["fileAccess::createFileAfterCheck"]);
379
		unset($conf["fileAccess::createFileAfterCheck"]);
380
 
381
		#建立socket檔案失敗
382
		if($createFileAfterCheck["status"]==="false"){
383
 
384
			#設置執行失敗
385
			$result["status"]="false";
386
 
387
			#設置執行錯誤訊息
388
			$result["error"]=$createFileAfterCheck;
389
 
390
			#回傳結果
391
			return $result;
392
 
393
			}#if end
394
 
395
		#實際建立的檔案名稱
396
		$result["createdFileName"]=$createFileAfterCheck["createdFileName"];
397
 
398
		#取得建立好的socket路徑所在
399
		$result["createdFilePath"]=$createFileAfterCheck["createdFilePath"];
400
 
401
		#取得易讀的路徑
402
		#函式說明:
403
		#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.
404
		#回傳的結果:
405
		#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.
406
		#$result["function"],當前執行的函數.
407
		#$result["error"],錯誤訊息陣列.
408
		#$result["changedPath"],處理完後回傳的目錄字串.
409
		#$result["oriPath"],原始的路徑字串
410
		#必填的參數:
411
		#$conf["dirStr"],字串,要處理的檔案目錄字串.
412
		$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$result["createdFilePath"];
413
		$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);
414
		unset($conf["stringProcess::changeDirByDotDotSolidus"]);
415
 
416
		#如果處理路徑失敗
417
		if($changeDirByDotDotSolidus["status"]==="false"){
418
 
419
			#設置執行失敗
420
			$result["status"]="false";
421
 
422
			#設置執行錯誤訊息
423
			$result["error"]=$changeDirByDotDotSolidus;
424
 
425
			#回傳結果
426
			return $result;
427
 
428
			}#if end
429
 
430
		#取得建立好的socket路徑
431
		$result["createdFilePath"]=$createFileAfterCheck["createdFileName"];
432
 
433
		#取得建立好的socket路徑與檔案名稱
434
		$result["content"]=$createFileAfterCheck["createdFilePathAndName"];
435
 
436
		#取得易讀的路徑
437
		#函式說明:
438
		#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.
439
		#回傳的結果:
440
		#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.
441
		#$result["function"],當前執行的函數.
442
		#$result["error"],錯誤訊息陣列.
443
		#$result["changedPath"],處理完後回傳的目錄字串.
444
		#$result["oriPath"],原始的路徑字串
445
		#必填的參數:
446
		#$conf["dirStr"],字串,要處理的檔案目錄字串.
447
		$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$result["content"];
448
		$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);
449
		unset($conf["stringProcess::changeDirByDotDotSolidus"]);
450
 
451
		#如果處理路徑失敗
452
		if($changeDirByDotDotSolidus["status"]==="false"){
453
 
454
			#設置執行失敗
455
			$result["status"]="false";
456
 
457
			#設置執行錯誤訊息
458
			$result["error"]=$changeDirByDotDotSolidus;
459
 
460
			#回傳結果
461
			return $result;
462
 
463
			}#if end
464
 
465
		#處理好的路徑檔案字串
466
		$result["content"]=$changeDirByDotDotSolidus["changedPath"];
467
 
468
		#設置執行正常
469
		$result["status"]="true";
470
 
471
		#回傳結果
472
		return $result;
473
 
474
		}#function createSockFile end
475
 
476
	/*
477
	#函式說明:
478
	#在背景建立qemu虛擬機器
479
	#回傳結果:
480
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
481
	#$result["error"],錯誤訊息.
482
	#$result["function"],當前執行的函數名稱.
483
	#$result["argu"],所使用的參數.
484
	#$result["cmd"],執行的command
485
	#必填的參數:
486
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
487
	$conf["fileArgu"]=__FILE__;
488
	#可省的參數:
489
	#$conf["architecture"],字串,所使用的處理器架構,可用的有"i386","x86_64"預設為"x86_64".
490
	#$conf["architecture"]="x86_64";
491
	#$conf["configFile"],字串,使用讀設定檔的方式來執行qemu,此為設定檔的路徑.
492
	#$conf["configFile"]="";
493
	#$conf["storage"],字串陣列,$conf["storage"][$i]代表第$i+1個虛擬硬碟位置與名稱.
494
	#$conf["storage"]=array();
495
	#$conf["storageType"],字串陣列,$conf["storageType"][$i]代表第$i+1個虛擬硬碟的類型,可以為ide,sata,scsi,virtio,sd或/dev/開頭的裝置.
496
	#$conf["storageType"]=array();
497
	#$conf["memory"],字串,可以使用的記憶體大小,以G為單位,預設為"2",亦即2GB的記憶體.
498
	#$conf["memory"]="2";
499
	#$conf["vga"],字串,顯示卡類型,可用的有"cirrus","std","vmware","qxl","virtio"預設為"qxl".
500
	#$conf["vga"]="qxl";
501
	#$conf["soundhw"],字串,音效卡類型,可用的有"ac97","hda","all"預設為"all".
502
	#$conf["soundhw"]="";
503
	#$conf["kvm"],字串,是否使用kvm來加速虛擬機速度,"true"為啟用,"false"為不用kvm加速,預設為"true".
504
	#$conf["kvm"]="true";
505
	#$conf["machine"],字串,要用什麼樣的主機板,預設為"q35"(Q35 + ICH9, 2009),可用的還有傳統的"pc"(i440FX+PIIX,1996),知名的xen全虛擬化"xenfv",或半虛擬化"xenpv".
506
	#$conf["machine"]="";
507
	#$conf["spiceSock"],字串,是否要透過sock檔案的提供spice服務,此方法必須client端與server端都在同一台機器上,才能透spice協定進行連線,留空代表不使用,副檔名".sock"會自動補上.
508
	#$conf["spiceSock"]="";
509
	#$conf["spicePort"],字串,要使用spice服務來遠端遙控的port,例如"5901",請與參數$conf["spiceSock"]擇一使用.
510
	#$conf["spicePort"]="5901";
511
	#$conf["spicePassword"],字串,要使用spice服務來遠端遙控時所需的密碼,預設為不設定.
512
	#$conf["spicePassword"]="";
513
	#$conf["gl"],字串,是否要啟用opengl支援,可以讓spice可以擁有3D加速的功能,"true"為要使用,預設為"false"不啟用.
514
	#$conf["gl"]="";
515
	#$conf["userNet"][$i]["cardType"],字串,使用的網卡是什麼型號,預設為"virtio-net",可選的有e1000,e1000-82545em,ne2k_pci,rtl8139等...
516
	#$conf["userNet"][$i]["cardType"]="";
517
	#$conf["userNet"][$i]["mac"],字串,第$i+1個user網路類型的網卡mac.
518
	#$conf["userNet"][$i]["mac"]="";
519
	#$conf["userNet"][$i]["hostfwd"],二維字串陣列,第$i+1個user網路類型,指定到host::port的封包要轉到guest::port,例如array(array("8080","80"),array("8088","443")),就代表從8080port要進入host的封包會轉送到gust的80port,從8088port要進入host的封包會轉送到gust的443port.
520
	#$conf["userNet"][$i]["hostfwd"]=array()
521
	#$conf["bridgeNet"][$i]["cardType"],字串,使用的網卡是什麼型號,預設為"virtio",可選的有e1000,e1000-82545em,ne2k_pci,rtl8139等...
522
	#$conf["bridgeNet"][$i]["mac"],字串,第$i+1個bridge網路類型的網卡mac.
523
	#$conf["bridgeNet"][$i]["mac"]="";
524
	#$conf["bridgeNet"][$i]["brName"],字串,第$i+1個bridge網路類型要接到哪個bridge.
525
	#$conf["bridgeNet"][$i]["brName"]="";
526
	#$conf["socketNet"][$i]["cardType"],字串,使用的網卡是什麼型號,預設為"virtio",可選的有e1000,e1000-82545em,ne2k_pci,rtl8139等...
527
	#$conf["socketNet"][$i]["mac"],字串,第$i+1個socket網路類型的網卡mac.
528
	#$conf["socketNet"][$i]["mac"]="";
529
	#$conf["socketNet"][$i]["addr"],字串,第$i+1個socket網路類型的ip與port,預設為"230.0.0.1:1234".
530
	#$conf["socketNet"][$i]["addr"]="";
531
	#$conf["monitorLP"],字串,monitor要listen哪個port,預設為10000開始的port.
532
	#$conf["monitorLP"]="";
533
	#備註:
534
	#伺服器須有安裝qemu套件.
535
	#建議:
536
	#新增nec-usb-xhci的支援.
537
	*/
538
	function run(&$conf){
539
 
540
		#初始化要回傳的結果
541
		$result=array();
542
 
543
		#取得當前執行的函數名稱
544
		$result["function"]=__FUNCTION__;
545
 
546
		#如果沒有參數
547
		if(func_num_args()==0){
548
 
549
			#設置執行失敗
550
			$result["status"]="false";
551
 
552
			#設置執行錯誤訊息
553
			$result["error"]="函數".$result["function"]."需要參數";
554
 
555
			#回傳結果
556
			return $result;
557
 
558
			}#if end
559
 
560
		#涵式說明:
561
		#判斷當前環境為web還是cmd
562
		#回傳結果:
563
		#$result,"web"或"cmd"
564
		if(csInformation::getEnv()==="web"){
565
 
566
			#設置執行失敗
567
			$result["status"]="false";
568
 
569
			#設置執行錯誤訊息
570
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
571
 
572
			#回傳結果
573
			return $result;
574
 
575
			}#if end
576
 
577
		#取得參數
578
		$result["argu"]=$conf;
579
 
580
		#如果 $conf 不為陣列
581
		if(gettype($conf)!=="array"){
582
 
583
			#設置執行失敗
584
			$result["status"]="false";
585
 
586
			#設置執行錯誤訊息
587
			$result["error"][]="\$conf變數須為陣列形態";
588
 
589
			#如果傳入的參數為 null
590
			if($conf===null){
591
 
592
				#設置執行錯誤訊息
593
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
594
 
595
				}#if end
596
 
597
			#回傳結果
598
			return $result;
599
 
600
			}#if end
601
 
602
		#檢查參數
603
		#函式說明:
604
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
605
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
606
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
607
		#$result["function"],當前執行的函式名稱.
608
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
609
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
610
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
611
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
612
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
613
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
614
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
615
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
616
		#必填寫的參數:
617
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
618
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
619
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
620
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("fileArgu");
621
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
622
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string");
623
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
624
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
625
		#可以省略的參數:
626
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
627
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
628
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
629
		#$conf["canNotBeEmpty"]=array();
630
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
631
		#$conf["canBeEmpty"]=array();
632
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
633
		#$conf["skipableVariableCanNotBeEmpty"]=array();
634
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
635
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("architecture","configFile","storage","storageType","memory","vga","soundhw","kvm","machine","spiceSock","spicePort","spicePassword","userNet","bridgeNet","socketNet","monitorLP","monitorSock","gl");
636
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
637
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string","string","string","string","string","string","string","string","string","array","array","array","string","string","string");
638
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
639
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array("x86_64",null,null,null,"2","qxl","all","true","q35",null,null,null,null,null,null,null,null,"false");
640
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
641
		$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array("storage","storageType");
642
		#參考資料來源:
643
		#array_keys=>http://php.net/manual/en/function.array-keys.php
644
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
645
		unset($conf["variableCheck::checkArguments"]);
646
 
647
		#如果參數檢查失敗
648
		if($checkArguments["status"]==="false"){
649
 
650
			#設置執行不正常
651
			$result["status"]="false";
652
 
653
			#設置執行錯誤
654
			$result["error"]=$checkArguments;
655
 
656
			#回傳結果
657
			return $result;
658
 
659
			}#if end
660
 
661
		#如果參數檢查不通過
662
		if($checkArguments["passed"]==="false"){
663
 
664
			#設置執行不正常
665
			$result["status"]="false";
666
 
667
			#設置執行錯誤
668
			$result["error"]=$checkArguments;
669
 
670
			#回傳結果
671
			return $result;
672
 
673
			}#if end
674
 
675
		#檢查qemu的指令是否存在
676
		#函式說明:
677
		#檢查指令是否存在
678
		#回傳結果:
679
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
680
		#$result["error"],錯誤訊息.
681
		#$result["function"],當前執行的函數名稱.
682
		#$result["argu"],使用的參數.
683
		#$result["content"],新增好後的檔案內容.
684
		#必填參數:
685
		#$conf["cmd"],"字串",要查詢的指令.
686
		$conf["cmd::checkCmdExist"]["cmd"]="qemu-system-".$conf["architecture"];
687
		#$conf["fileArgu"],字串,變數__FILE__的內容.
688
		$conf["cmd::checkCmdExist"]["fileArgu"]=$conf["fileArgu"];
689
		#可省略參數:
690
		#$conf["binPath"],字串,要搜尋的路徑,預設為"/usr/bin".
691
		#$conf["binPath"]="";
692
		$checkCmdExist=cmd::checkCmdExist($conf["cmd::checkCmdExist"]);
693
		unset($conf["cmd::checkCmdExist"]);
694
 
695
		#如果檢查指令失敗
696
		if($checkCmdExist["status"]==="false"){
697
 
698
			#設置執行不正常
699
			$result["status"]="false";
700
 
701
			#設置執行錯誤
702
			$result["error"]=$checkCmdExist;
703
 
704
			#回傳結果
705
			return $result;
706
 
707
			}#if end
708
 
709
		#如果指令不存在
710
		if($checkCmdExist["founded"]==="false"){
711
 
712
			#設置執行不正常
713
			$result["status"]="false";
714
 
715
			#設置執行錯誤
716
			$result["error"]=$checkCmdExist;
717
 
718
			#回傳結果
719
			return $result;
720
 
721
			}#if end
722
 
723
		#初始化要執行的command
724
		$qemuBin="qemu-system-".$conf["architecture"];
725
 
726
		#設定 $conf["memory"] 參數
727
		$conf["memory"]=$conf["memory"]."G";
728
 
729
		#串接memory設定
730
		$paramsArray[]="-m";
731
		$paramsArray[]=$conf["memory"];
732
 
733
		#設定 $conf["vga"] 參數
734
		$conf["vga"]=" -vga ".$conf["vga"];
735
 
736
		#串接 vag 設定
737
		$paramsArray[]=$conf["vga"];
738
 
739
		#設定 $conf["soundhw"] 參數
740
		$conf["soundhw"]=" -soundhw ".$conf["soundhw"];
741
 
742
		#串接 soundhw 設定
743
		$paramsArray[]=$conf["soundhw"];
744
 
745
		#設定 usb 支援
746
		$paramsArray[]="-usb";
747
 
748
		#檢查主機有無支援 vmx 或 svm
749
 
750
		#初始化判別是否支援kvm的識別
751
		$kvmSupported="false";
752
 
753
		#設置支援的關鍵字串
754
		$kvmSuppurtKeyWord=array("vmx","svm");
755
 
756
		#有幾個支援的關鍵字串就執行幾次
757
		foreach($kvmSuppurtKeyWord as $kvmWord){
758
 
759
			#函數說明:
760
			#檢查指令的輸出是否含有關鍵字
761
			#回傳結果:
762
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
763
			#$result["error"],錯誤訊息.
764
			#$result["function"],當前執行的函數名稱.
765
			#$result["argu"],使用的參數.
766
			#$result["founded"],是否找到關鍵字,"true"代表有,"false"代表沒有.
767
			#$result["content"],關鍵字所在列的輸出.
768
			#必填參數:
769
			#$conf["cmd"],字串,要執行的指令.
770
			$conf["cmd::searchOutPut"]["cmd"]="lscpu";
771
			#$conf["keyWord"],字串,要檢查是否有關鍵字.
772
			$conf["cmd::searchOutPut"]["keyWord"]=$kvmWord;
773
			#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
774
			$conf["cmd::searchOutPut"]["fileArgu"]=$conf["fileArgu"];
775
			#可省略參數:
776
			#$conf["binPath"],字串,要搜尋的路徑,預設為"/usr/bin".
777
			#$conf["binPath"]="";
778
			$searchOutPut=cmd::searchOutPut($conf["cmd::searchOutPut"]);
779
			unset($conf["cmd::searchOutPut"]);
780
 
781
			#如果搜尋指令輸出是否有關鍵字失敗
782
			if($searchOutPut["status"]==="false"){
783
 
784
				#設置執行不正常
785
				$result["status"]="false";
786
 
787
				#設置執行錯誤
788
				$result["error"]=$searchOutPut;
789
 
790
				#回傳結果
791
				return $result;
792
 
793
				}#if end
794
 
795
			#如果有找到關鍵字
796
			if($searchOutPut["founded"]==="true"){
797
 
798
				#設置支援 kvm
799
				$kvmSupported="true";
800
 
801
				#跳出 foreach
802
				break;
803
 
804
				}#if end
805
 
806
			}#foreach end
807
 
808
		#如果不支援kvm又指定要用kvm
809
		if($kvmSupported==="false" && $conf["kvm"]==="true"){
810
 
811
			#設置不使用 kvm
812
			$conf["kvm"]="false";
813
 
814
			#設置警告訊息
815
			$conf["warning"][]="因為主機不支援kvm,因此取消 -enable-kvm 參數";
816
 
817
			}#if
818
 
819
		#如果指定要用kvm
820
		if($conf["kvm"]==="true"){
821
 
822
			#設置 kvm 參數
823
			$conf["kvm"]=" -enable-kvm";
824
 
825
			}#if end
826
 
827
		#反之
828
		else{
829
 
830
			#不啟用enable-kvm
831
			$conf["kvm"]="";
832
 
833
			}#else end
834
 
835
		#串接 kvm 設定
836
		$paramsArray[]=$conf["kvm"];
837
 
838
		#設置 machine 類型
839
		$conf["machine"]=" -machine ".$conf["machine"];
840
 
841
		#串接 machine 設定
842
		$paramsArray[]=$conf["machine"];
843
 
844
		#初始化 spice 設定字串,與壓縮的選項
845
		$spice=" -spice image-compression=auto_glz";
846
 
847
		#如果有設置 $conf["spiceSock"] 或 $conf["spicePort"]
848
		if(isset($conf["spiceSock"]) || isset($conf["spicePort"])){
849
 
850
			#如果有設置 $conf["spiceSock"]
851
			if(isset($conf["spiceSock"])){
852
 
853
				#確保socket檔案可以存在
854
				#涵式說明:
855
				#確保路徑存在.
856
				#回傳的結果:
857
				#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
858
				#$result["error"],錯誤訊息陣列.
859
				#$resutl["function"],當前執行的涵式名稱.
860
				#$result["path"],建立好的路徑字串.
861
				#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
862
				#必填的參數:
863
				#$conf["path"],要檢查的路徑
864
				$conf["fileAccess::validatePath"]["path"]=$conf["spiceSock"];
865
				#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
866
				$conf["fileAccess::validatePath"]["fileArgu"]=$conf["fileArgu"];
867
				#可省略參數:
868
				#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
869
				$conf["fileAccess::validatePath"]["haveFileName"]="true";
870
				#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人僅能存取.
871
				#$conf["dirPermission"]="";
872
				$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
873
				unset($conf["fileAccess::validatePath"]);
874
 
875
				#如果確保路徑失敗
876
				if($validatePath["status"]==="false"){
877
 
878
					#設置執行不正常
879
					$result["status"]="false";
880
 
881
					#設置執行錯誤
882
					$result["error"]=$validatePath;
883
 
884
					#回傳結果
885
					return $result;
886
 
887
					}#if end
888
 
889
				#取得socket檔案的路徑
890
				$conf["spiceSock"]=",unix,addr=".$conf["spiceSock"];
891
 
892
				#設置 socket 類型的 spice
893
				$spice=$spice.$conf["spiceSock"];
894
 
895
				}#if end
896
 
897
			#反之有設置 $conf["spicePort"]
898
			else if(isset($conf["spicePort"])){
899
 
900
				#設置spice的port
901
				$conf["spicePort"]=",port=".$conf["spicePort"];
902
 
903
				#設置 tcp/ip 類型的 spice
904
				$spice=$spice.$conf["spicePort"];
905
 
906
				}#if end
907
 
908
			#如果有設置 $conf["spicePassword"]
909
			if(isset($conf["spicePassword"])){
910
 
911
				#設置spice連線的密碼
912
				$conf["spicePassword"]=",password=".$conf["spicePassword"];
913
 
914
				#串接使用的密碼
915
				$spice=$spice.$conf["spicePassword"];
916
 
917
				}#if ned
918
 
919
			#反之不用密碼
920
			else{
921
 
922
				#設置spice連線不需要密碼
923
				$conf["spicePassword"]=",disable-ticketing";
924
 
925
				#串接不要使用密碼
926
				$spice=$spice.$conf["spicePassword"];
927
 
928
				}#else end
929
 
930
			#如果 $conf["gl"] 等於 "true"
931
			if($conf["gl"]==="true"){
932
 
933
				#設置gl
934
				$spice=$spice.",gl=on";
935
 
936
				}#if end
937
 
938
			#串接spice設置
939
			$paramsArray[]=$spice;
940
 
941
			}#if end
942
 
943
		#如果有設置硬碟
944
		if(isset($conf["storage"])){
945
 
946
			#依據每個硬碟
947
			foreach($conf["storage"] as $index=>$storage){
948
 
949
				#檢查檔案是否存在
950
				#涵式說明:檢查多個檔案與資料夾是否存在.
951
				#回傳的結果:
952
				#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
953
				#$result["error"],錯誤訊息陣列.
954
				#$resutl["function"],當前執行的涵式名稱.
955
				#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
956
				#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
957
				#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱。
958
				#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址
959
				#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
960
				#必填參數:
961
				#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
962
				$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array($storage);
963
				#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
964
				$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=$conf["fileArgu"];
965
				#可省略參數
966
				#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
967
				#$conf["disableWebSearch"]="false";
968
				#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
969
				#$conf["userDir"]="true";
970
				#參考資料來源:
971
				#http://php.net/manual/en/function.file-exists.php
972
				#http://php.net/manual/en/control-structures.foreach.php
973
				#備註:
974
				#函數file_exists檢查的路徑為檔案系統的路徑
975
				$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);
976
				unset($conf["fileAccess::checkMultiFileExist"]);
977
 
978
				#如果檢查硬碟檔案是否存在失敗
979
				if($checkMultiFileExist["status"]==="false"){
980
 
981
					#設置執行不正常
982
					$result["status"]="false";
983
 
984
					#設置執行錯誤
985
					$result["error"]=$checkMultiFileExist;
986
 
987
					#回傳結果
988
					return $result;
989
 
990
					}#if end
991
 
992
				#如果硬碟檔案不存在
993
				if($checkMultiFileExist["allExist"]==="false"){
994
 
995
					#設置執行不正常
996
					$result["status"]="false";
997
 
998
					#設置執行錯誤
999
					$result["error"]=$checkMultiFileExist;
1000
 
1001
					#回傳結果
1002
					return $result;
1003
 
1004
					}#if end
1005
 
1006
				#解析硬碟檔案資訊
1007
				#涵是說明:
1008
				#取得檔案路徑字串的路徑與檔案的名稱與檔案副檔名
1009
				#回傳的結果:
1010
				#$result["status"],執行是否正常,"true"正常,"false"代表不正常.
1011
				#$result["error"],錯誤訊息.
1012
				#$result["function"],當前執行的函式名稱.
1013
				#$result["filePath"],路徑字串.
1014
				#$result["fileName"],檔案名稱字串.
1015
				#$result["fileExtention"],檔案的副檔名.
1016
				#$result["fullFileName"],含副檔名的檔案名稱.
1017
				#$result["fullFilePathAndName"],完整的檔案路徑(含副檔名).
1018
				#必填的參數:
1019
				#$conf["fileAddressAndName"],字串,檔案名稱與其路徑.
1020
				$conf["fileAccess::getFileAddressAndNameAndFileExtention"]["fileAddressAndName"]=$checkMultiFileExist["varNameFullPath"][0];
1021
				#可省略的參數:
1022
				#無.
1023
				#備註:
1024
				#php內建的fileinfo方法無法正確解析中文路徑檔案名稱.
1025
				$getFileAddressAndNameAndFileExtention=fileAccess::getFileAddressAndNameAndFileExtention($conf["fileAccess::getFileAddressAndNameAndFileExtention"]);
1026
				unset($conf["fileAccess::getFileAddressAndNameAndFileExtention"]);
1027
 
1028
				#如果取得檔案資訊失敗
1029
				if($getFileAddressAndNameAndFileExtention["status"]==="false"){
1030
 
1031
					#設置執行不正常
1032
					$result["status"]="false";
1033
 
1034
					#設置執行錯誤
1035
					$result["error"]=$checkMultiFileExist;
1036
 
1037
					#回傳結果
1038
					return $result;
1039
 
1040
					}#if end
1041
 
1042
				#取得副檔名
1043
				$diskExtention=&$getFileAddressAndNameAndFileExtention["fileExtention"];
1044
 
1045
				#依據副檔名
1046
				switch($diskExtention){
1047
 
1048
					#如果是 "qcow2,raw,img,vdi,vmdk之一"
1049
					case "qcow2":
1050
					case "raw":
1051
					case "img":
1052
					case "vdi":
1053
					case "vmdk":
1054
 
1055
						#跳出switch
1056
						break;
1057
 
1058
					#其他副檔名
1059
					default:
1060
 
1061
						#檢查是否有關鍵字 "/dev/"
1062
						#函式說明:
1063
						#檢查字串裡面有無指定的關鍵字
1064
						#回傳的結果:
1065
						#$result["status"],"true"代表執行成功,"false"代表執行失敗。
1066
						#$result["error"],錯誤訊息
1067
						#$result["function"],當前執行的函數名稱.
1068
						#$result["founded"],是否找到關鍵字,"true"代表有找到關鍵字;"false"代表沒有找到關鍵字。
1069
						#$result["keyWordCount"],找到的關鍵字數量.
1070
						#必填的參數:
1071
						$conf["search::findKeyWord"]["keyWord"]="/dev/";#想要搜尋的關鍵字
1072
						$conf["search::findKeyWord"]["string"]=$diskExtention;#要被搜尋的字串內容
1073
						#可省略的參數:
1074
						#$conf["completeEqual"]="true";#是否內容要完全符合,不能多出任何不符合的內容,預設為不需要完全符合。
1075
						$findKeyWord=search::findKeyWord($conf["search::findKeyWord"]);
1076
						unset($conf["search::findKeyWord"]);
1077
 
1078
						#如果尋找關鍵字失敗
1079
						if($findKeyWord["status"]==="false"){
1080
 
1081
							#設置執行不正常
1082
							$result["status"]="false";
1083
 
1084
							#設置執行錯誤
1085
							$result["error"]=$findKeyWord;
1086
 
1087
							#回傳結果
1088
							return $result;
1089
 
1090
							}#if end
1091
 
1092
						#如果沒有關鍵字
1093
						if($findKeyWord["founded"]==="false"){
1094
 
1095
							#設置執行不正常
1096
							$result["status"]="false";
1097
 
1098
							#設置執行錯誤的訊息
1099
							$result["error"][]="虛擬硬碟的副檔名必須是qcow2,raw,img,vdi,vmdk或\"/dev/\"開頭的裝置之一";
1100
 
1101
							#回傳結果
1102
							return $result;
1103
 
1104
							}#if end
1105
 
1106
						#跳出 switch
1107
						break;
1108
 
1109
					}#switch end
1110
 
1111
				#另存儲存裝置的接口類型
1112
				$storageType=&$conf["storageType"][$index];
1113
 
1114
				#依據儲存裝置的接口類型
1115
				switch($storageType){
1116
 
1117
					#如果是 virtio
1118
					case "virtio":
1119
 
1120
						#建立virtio接口的儲存裝置片段						
1121
						$paramsArray[]="-drive";
1122
						$paramsArray[]="file=".$storage.",if=".$storageType.",l2-cache-size=13M,cache-clean-interval=900,cache=directsync,aio=native";
1123
 
1124
					#如果是 sata
1125
					case "sata":
1126
 
1127
						#建立sata接口的儲存裝置片段
1128
						$paramsArray[]="-device";
1129
						$paramsArray[]="ahci,id=ahci".$index;
1130
						$paramsArray[]="-drive";
1131
						$paramsArray[]="if=none,file=".$storage.",format=".$storageType.",id=drive-ide-".$index." -device ide-drive,bus=ahci".$index.".0,drive=drive-ide-".$index;
1132
 
1133
					#如果是 ide
1134
					case "ide":
1135
 
1136
						#建立ide接口的儲存裝置片段
1137
						$paramsArray[]="-drive";
1138
						$paramsArray[]="file=".$storage.",if=".$storageType;
1139
 
1140
					#如果是 scsi
1141
					case "scsi":
1142
 
1143
						#建立scsi接口的儲存裝置片段
1144
						$paramsArray[]="-drive";
1145
						$paramsArray[]="file=".$storage.",if=".$storageType;
1146
 
1147
					#如果是 sd
1148
					case "sd":
1149
 
1150
						#建立 sd 卡裝置的語法
1151
						$paramsArray[]="-device";
1152
						$paramsArray[]="usb-ehci,id=ehci".$index;
1153
						$paramsArray[]="-drive";
1154
						$paramsArray[]="if=sd,file=".$storage.",format=".$storageType.",id=sd".$index;
1155
						$paramsArray[]="-device";
1156
						$paramsArray[]="usb-storage,bus=ehci0.".$index.",drive=sd".$index;
1157
 
1158
					#如果是 usb
1159
					case "usb":
1160
 
1161
						#初始化虛擬儲存裝置的檔案類型參數
1162
						$storageTypeParam="";
1163
 
1164
						#如果是qcow2格式
1165
						if($storageType==="qcow2")
1166
						{
1167
							#設置對應的優化參數
1168
							$storageTypeParam=",l2-cache-size=13M,cache-clean-interval=900,cache=directsync,aio=native";
1169
						}
1170
 
1171
						#建立 usb-storage 裝置的語法
1172
						$paramsArray[]="-drive";
1173
						$paramsArray[]="=file='".$storage."',format=".$storageType.$storageTypeParam.",if=none,id=usbStorage-".$index;
1174
						$paramsArray[]="-device usb-storage,drive=usbStorage-".$index;
1175
 
1176
					#其他類型
1177
					default:
1178
 
1179
						#設置執行不正常
1180
						$result["status"]="false";
1181
 
1182
						#設置執行錯誤的訊息
1183
						$result["error"][]="虛擬硬碟的接口必須是virtio,sata,ide,scsi,sd之一";
1184
 
1185
						#回傳結果
1186
						return $result;
1187
 
1188
					}#switch end
1189
 
1190
				}#foreach end
1191
 
1192
			}#if end
1193
 
1194
		#如果有設定$conf["userNet"]
1195
		if(isset($conf["userNet"])){
1196
 
1197
			#有幾個 $conf["userNet"] 就執行幾次
1198
			foreach($conf["userNet"] as $userNet){
1199
 
1200
				#初始化暫存設定網路的參數
1201
				$settingStr="";
1202
 
1203
				#如果未設定 $conf["userNet"][$i]["cardType"]
1204
				if(!isset($conf["userNet"][$i]["cardType"])){
1205
 
1206
					#預設為 "virtio-net"
1207
					$conf["userNet"][$i]["cardType"]="virtio-net";
1208
 
1209
					}#if end
1210
 
1211
				#如果沒有指定mac
1212
				if(!isset($conf["userNet"][$i]["mac"])){
1213
 
1214
					#設置執行不正常
1215
					$result["status"]="false";
1216
 
1217
					#設置執行錯誤的訊息
1218
					$result["error"][]="網卡的mac需要指定";
1219
 
1220
					#回傳結果
1221
					return $result;
1222
 
1223
					}#if end
1224
 
1225
				#設置網路類型
1226
				$paramsArray[]="-netdev";
1227
				$paramsArray[]="user,id=userNet".$i;
1228
 
1229
				#如果有設定 $conf["userNet"][$i]["hostfwd"]
1230
				if(isset($conf["userNet"][$i]["hostfwd"])){
1231
 
1232
					#初始化 hostfwd 的設定
1233
					$hostfwdStr="";
1234
 
1235
					#有幾個 $conf["userNet"][$i]["hostfwd"] 就執行幾次
1236
					foreach($conf["userNet"][$i]["hostfwd"] as $hostfwd){
1237
 
1238
						#如果 $hostfwd 不為兩個元素
1239
						if(count($hostfwd)!==2){
1240
 
1241
							#設置執行不正常
1242
							$result["status"]="false";
1243
 
1244
							#設置執行錯誤的訊息
1245
							$result["error"][]="參數hostfwd須為二維陣列";
1246
 
1247
							#回傳結果
1248
							return $result;
1249
 
1250
							}#if end
1251
 
1252
						#設定轉port
1253
						$hostfwdStr=$hostfwdStr.",hostfwd=tcp::".$hostfwd[0]."-:".$hostfwd[1];
1254
 
1255
						}#foreach end
1256
 
1257
					}#if end
1258
 
1259
				#設置網卡類型與mac
1260
				$paramsArray[]="device";
1261
				$paramsArray[]=$conf["userNet"][$i]["cardType"].",mac=".$conf["userNet"][$i]["mac"].",netdev=userNet".$i.$hostfwdStr;
1262
 
1263
				}#foreache end
1264
 
1265
			}#if end
1266
 
1267
		#如果有設置 $conf["bridgeNet"]
1268
		if(isset($conf["bridgeNet"])){
1269
 
1270
			#有幾個 $conf["bridgeNet"] 就執行幾次
1271
			foreach($conf["bridgeNet"] as $bridgeNet){
1272
 
1273
				#如果未設定 $conf["bridgeNet"][$i]["cardType"]
1274
				if(!isset($conf["bridgeNet"][$i]["cardType"])){
1275
 
1276
					#預設為 "virtio-net"
1277
					$conf["bridgeNet"][$i]["cardType"]="virtio-net";
1278
 
1279
					}#if end
1280
 
1281
				#如果沒有指定mac
1282
				if(!isset($conf["bridgeNet"][$i]["mac"])){
1283
 
1284
					#設置執行不正常
1285
					$result["status"]="false";
1286
 
1287
					#設置執行錯誤的訊息
1288
					$result["error"][]="網卡的mac需要指定";
1289
 
1290
					#回傳結果
1291
					return $result;
1292
 
1293
					}#if end
1294
 
1295
				#如果沒有設定要橋接到哪個bridge
1296
				if(!isset($conf["bridgeNet"][$i]["brName"])){
1297
 
1298
					#增加socket預設的addr參數
1299
					$conf["bridgeNet"][$i]["addr"]="230.0.0.1:1234";
1300
 
1301
					#將之轉換成socketNet
1302
					$conf["socketNet"][]=$conf["bridgeNet"][$i];
1303
 
1304
					#跳到下一個 bridge net
1305
					continue;
1306
 
1307
					}#if end
1308
 
1309
				#檢查 $conf["bridgeNet"][$i]["brName"] 是否在 /etc/qemu/bridge.conf 裡面
1310
				#檢查有無 "allow ".$conf["bridgeNet"][$i]["brName"] 在裡面
1311
				#函式說明:
1312
				#尋找檔案裡面有無關鍵字存在,取得其所在列數與內容.
1313
				#回傳結果:
1314
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1315
				#$reuslt["error"],執行不正常結束的錯訊息陣列.
1316
				#$result["function"],當前執行的函式名稱.
1317
				#$result["argu"],所使用的參數.
1318
				#$result["founded"],是否有找到關鍵字,"true"代表有找到,"false"代表沒有找到.
1319
				#$result["content"],符合的列數與內容.
1320
				#$result["content"][$i]["LN"],第$i+1個符合條件的列數.
1321
				#$result["content"][$i]["LC"],第$i+1個符合條件的列內容.
1322
				#必填參數:
1323
				#$conf["fileAddr"],字串,檔案的路徑與名稱.
1324
				$conf["search::findKeyWordInFile"]["fileAddr"]="/etc/qemu/bridge.conf";
1325
				#$conf["keyWord"],字串,要搜尋的關鍵字.
1326
				$conf["search::findKeyWordInFile"]["keyWord"]="allow ".$conf["bridgeNet"][$i]["brName"];
1327
				#$conf["fileArgu"],字串,__FILE__的內容
1328
				$conf["search::findKeyWordInFile"]["fileArgu"]=$conf["fileArgu"];
1329
				$findKeyWordInFile=search::findKeyWordInFile($conf["search::findKeyWordInFile"]);
1330
				unset($conf["search::findKeyWordInFile"]);
1331
 
1332
				#如果尋找關鍵字失敗
1333
				if($findKeyWordInFile["status"]==="false"){
1334
 
1335
					#設置執行不正常
1336
					$result["status"]="false";
1337
 
1338
					#設置執行錯誤的訊息
1339
					$result["error"]=$findKeyWordInFile;
1340
 
1341
					#回傳結果
1342
					return $result;
1343
 
1344
					}#if end
1345
 
1346
				#如果有找到關鍵字
1347
				if($findKeyWordInFile["founded"]==="false"){
1348
 
1349
					#設置執行不正常
1350
					$result["status"]="false";
1351
 
1352
					#設置執行錯誤的訊息
1353
					$result["error"]=$findKeyWordInFile;
1354
 
1355
					#回傳結果
1356
					return $result;
1357
 
1358
					}#if end
1359
 
1360
				#檢查有無該bridge存在
1361
				#函式說明:
1362
				#檢查與取得net interface的資訊
1363
				#回傳結果
1364
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1365
				#$result["error"],錯誤訊息陣列.
1366
				#$result["function"],當前執行的函數名稱.
1367
				#$result["cmd"],使用的command.
1368
				#$result["argu"],使用的參數.
1369
				#$result["founded"],是否有找到目標網路界面,"true"代表有,"false"代表沒有.
1370
				#$result["content"],原始輸出的逐行內容.
1371
				#必填參數:
1372
				#$conf["netInterface"],字串,網路界面的名稱.
1373
				$conf["cmd::getNetDevInfo"]["netInterface"]=$conf["bridgeNet"][$i]["brName"];
1374
				#$conf["fileArgu"],字串,__FILE__的內容.
1375
				$conf["cmd::getNetDevInfo"]["fileArgu"]=$conf["fileArgu"];
1376
				$getNetDevInfo=cmd::getNetDevInfo($conf["cmd::getNetDevInfo"]);
1377
				unset($conf["cmd::getNetDevInfo"]);
1378
 
1379
				#如果執行失敗
1380
				if($getNetDevInfo["status"]==="false"){
1381
 
1382
					#設置執行不正常
1383
					$result["status"]="false";
1384
 
1385
					#設置執行錯誤的訊息
1386
					$result["error"]=$getNetDevInfo;
1387
 
1388
					#回傳結果
1389
					return $result;
1390
 
1391
					}#if end
1392
 
1393
				#如果尋找不到bridge的名稱
1394
				if($getNetDevInfo["founded"]==="false"){
1395
 
1396
					#設置執行不正常
1397
					$result["status"]="false";
1398
 
1399
					#設置執行錯誤的訊息
1400
					$result["error"]=$getNetDevInfo;
1401
 
1402
					#回傳結果
1403
					return $result;
1404
 
1405
					}#if end
1406
 
1407
				#設置 netdev
1408
				$paramsArray[]="-netdev";
1409
				$paramsArray[]="=bridge,name=".$conf["bridgeNet"][$i]["brName"].",id=bridgeNet".$i;
1410
 
1411
				#設置網路卡
1412
				$paramsArray[]="-device";
1413
				$paramsArray[]=$conf["bridgeNet"][$i]["cardType"].",mac=".$conf["bridgeNet"][$i]["mac"].",netdev=bridgeNet".$i;
1414
 
1415
				}#foreache end
1416
 
1417
			}#if end
1418
 
1419
		#如果有設置 $conf["socketNet"]
1420
		if(isset($conf["socketNet"])){
1421
 
1422
			#有幾個 $conf["socketNet"] 就執行幾次
1423
			foreach($conf["socketNet"] as $socketNet){
1424
 
1425
				#如果未設定 $conf["socketNet"][$i]["cardType"]
1426
				if(!isset($conf["socketNet"][$i]["cardType"])){
1427
 
1428
					#預設為 "virtio-net"
1429
					$conf["socketNet"][$i]["cardType"]="virtio-net";
1430
 
1431
					}#if end
1432
 
1433
				#如果沒有指定mac
1434
				if(!isset($conf["socketNet"][$i]["mac"])){
1435
 
1436
					#設置執行不正常
1437
					$result["status"]="false";
1438
 
1439
					#設置執行錯誤的訊息
1440
					$result["error"][]="網卡的mac需要指定";
1441
 
1442
					#回傳結果
1443
					return $result;
1444
 
1445
					}#if end
1446
 
1447
				#檢查 $conf["socketNet"][$i]["addr"] 是否有設置
1448
				if(!(isset($conf["socketNet"][$i]["addr"]))){
1449
 
1450
					#預設為 "230.0.0.1:1234"
1451
					$conf["socketNet"][$i]["addr"]="230.0.0.1:1234";
1452
 
1453
					}#if end
1454
 
1455
				#設置 netdev
1456
				$paramsArray[]="-netdev";
1457
				$paramsArray[]="socket,mcast=".$conf["socketNet"][$i]["addr"].",id=socketNet".$i;
1458
 
1459
				#設置網卡設備
1460
				$paramsArray[]="-device";
1461
				$paramsArray[]=$conf["socketNet"][$i]["cardType"].",mac=".$conf["socketNet"][$i]["mac"].",netdev=socketNet".$i;
1462
 
1463
				}#foreache end
1464
 
1465
			}#if end
1466
 
1467
		#virtio serial
1468
		$paramsArray[]="-device";
1469
		$paramsArray[]="-virtio-serial-pci";
1470
 
1471
		#qemu agest agent
1472
 
1473
		#確保socket檔案可以存在
1474
		#涵式說明:
1475
		#確保路徑存在.
1476
		#回傳的結果:
1477
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
1478
		#$result["error"],錯誤訊息陣列.
1479
		#$resutl["function"],當前執行的涵式名稱.
1480
		#$result["path"],建立好的路徑字串.
1481
		#$result["fileName"],檔案名稱,若 $conf["haveFileName"] 為 "true" 則會回傳.
1482
		#必填的參數:
1483
		#$conf["path"],要檢查的路徑
1484
		$conf["fileAccess::validatePath"]["path"]="/tmp/qbpwcf/qemu/".$_SERVER["LOGNAME"]."-".time()."-org.qemu.guest_agent.0";
1485
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
1486
		$conf["fileAccess::validatePath"]["fileArgu"]=$conf["fileArgu"];
1487
		#可省略參數:
1488
		#$conf["haveFileName"],字串,"true"代表有$conf["path"]檔案名稱,"false"代表$conf["path"]為純路徑,預設為"false".
1489
		$conf["fileAccess::validatePath"]["haveFileName"]="true";
1490
		#$conf["dirPermission"],字串,新建資料夾的權限設定,預設爲0770,亦即擁有者,同群組者可以讀,寫,存取,其他人僅能存取.
1491
		#$conf["dirPermission"]="";
1492
		$validatePath=fileAccess::validatePath($conf["fileAccess::validatePath"]);
1493
		unset($conf["fileAccess::validatePath"]);
1494
 
1495
		#如果確保路徑失敗
1496
		if($validatePath["status"]==="false"){
1497
 
1498
			#設置執行不正常
1499
			$result["status"]="false";
1500
 
1501
			#設置執行錯誤
1502
			$result["error"]=$validatePath;
1503
 
1504
			#回傳結果
1505
			return $result;
1506
 
1507
			}#if end
1508
 
1509
		#設置 qemu agest agent		
1510
		$paramsArray[]="-chardev";
1511
		$paramsArray[]="socket,id=charchannel0,path=".$validatePath["path"].".".$validatePath["fileName"].",server,nowait";
1512
		$paramsArray[]="-device";
1513
		$paramsArray[]="virtserialport,chardev=charchannel0,name=org.qemu.guest_agent.0";
1514
 
1515
		#剪貼簿共享
1516
		$paramsArray[]="-chardev";
1517
		$paramsArray[]="spicevmc,id=charchannel1,name=vdagent";
1518
		$paramsArray[]="-device";
1519
		$paramsArray[]="virtserialport,chardev=charchannel1,name=com.redhat.spice.0";
1520
 
1521
		#共享資料夾
1522
		$paramsArray[]="-chardev";
1523
		$paramsArray[]="spiceport,id=charchannel2,name=vdagent";
1524
		$paramsArray[]="-device";
1525
		$paramsArray[]="virtserialport,chardev=charchannel2,name=org.spice-space.webdav.0";
1526
 
1527
		#spice usb redir
1528
		$paramsArray[]="-chardev";
1529
		$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev1";
1530
		$paramsArray[]="-device";
1531
		$paramsArray[]="usb-redir,chardev=usbredirchardev1,id=usbredirdev1,debug=3";
1532
		$paramsArray[]="-chardev";
1533
		$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev2";
1534
		$paramsArray[]="-device";
1535
		$paramsArray[]="usb-redir,chardev=usbredirchardev2,id=usbredirdev2,debug=3";
1536
		$paramsArray[]="-chardev";
1537
		$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev3";
1538
		$paramsArray[]="-device";
1539
		$paramsArray[]="usb-redir,chardev=usbredirchardev3,id=usbredirdev3,debug=3";
1540
		$paramsArray[]="-chardev";
1541
		$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev4";
1542
		$paramsArray[]="-device";
1543
		$paramsArray[]="usb-redir,chardev=usbredirchardev4,id=usbredirdev4,debug=3";
1544
		$paramsArray[]="-chardev";
1545
		$paramsArray[]="spicevmc,name=usbredir,id=usbredirchardev5";
1546
		$paramsArray[]="-device";
1547
		$paramsArray[]="usb-redir,chardev=usbredirchardev5,id=usbredirdev5,debug=3";
1548
 
1549
		#uefi bios
1550
		#-pflash /usr/share/edk2/ovmf/OVMF_CODE.fd \
1551
 
1552
		#boot menu
1553
		$paramsArray[]="-boot";
1554
		$paramsArray[]="menu=on";
1555
 
1556
		#virtio input
1557
		$paramsArray[]="-device";
1558
		$paramsArray[]="virtio-keyboard-pci";
1559
		$paramsArray[]="-device";
1560
		$paramsArray[]="virtio-mouse-pci";
1561
		$paramsArray[]="-device";
1562
		$paramsArray[]="virtio-tablet-pci";
1563
 
1564
		#virtio balloon
1565
		$paramsArray[]="-balloon";
1566
		$paramsArray[]="virtio,deflate-on-oom=true";
1567
 
1568
		#virtio rng
1569
		$paramsArray[]="-device";
1570
		$paramsArray[]="virtio-rng-pci";
1571
 
1572
		#irq-chip, 需要 iommu 支援
1573
 
1574
		#-localtime
1575
		$paramsArray[]="-localtime";
1576
 
1577
		#-daemonize
1578
		$paramsArray[]="-daemonize";
1579
 
1580
		#檢查10000以上的port哪個沒有被使用.
1581
		#函式說明:
1582
		#掃port的程式
1583
		#回傳結果:
1584
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1585
		#$result["error"],錯誤訊息.
1586
		#$result["function"],當前執行的函數名稱.
1587
		#$result["argu"],使用的參數.
1588
		#$result["content"],掃好可能可以使用的port資訊.
1589
		#必填參數
1590
		#$conf["fileArgu"],字串,變數__FILE__的內容.
1591
		$conf["cmd::nmap"]["fileArgu"]=$conf["fileArgu"];
1592
		#可省略參數:
1593
		#$conf["target"],字串,要掃描的主機,預設為"127.0.0.1",
1594
		#$conf["target"]="127.0.0.1";
1595
		#$conf["-Pn"],字串,是否要啟用避免ping不到就會掃port失敗的功能,預設為"false".
1596
		#$conf["-Pn"]="false";
1597
		$nmap=cmd::nmap($conf["cmd::nmap"]);
1598
		unset($conf["cmd::nmap"]);
1599
 
1600
		#如果掃port失敗
1601
		if($nmap["status"]==="false"){
1602
 
1603
			#設置執行不正常
1604
			$result["status"]="false";
1605
 
1606
			#設置執行錯誤的訊息
1607
			$result["error"]=$nmap;
1608
 
1609
			#回傳結果
1610
			return $result;
1611
 
1612
			}#if end
1613
 
1614
		#如果沒有使用 $conf["monitorLP"]
1615
		if(!isset($conf["monitorLP"])){
1616
 
1617
			#從port10000開始找是否可用
1618
			for($i=10000;$i<65536;$i++){
1619
 
1620
				#如果port沒有被使用
1621
				if(!in_array($i,$nmap["content"])){
1622
 
1623
					#設定monitor的port
1624
					$conf["monitorLP"]=$i;
1625
 
1626
					#跳出迴圈
1627
					break;
1628
 
1629
					}#if end
1630
 
1631
				}#for end
1632
 
1633
			}#if end
1634
 
1635
		#反之有設定 $conf["monitorLP"]
1636
		else if(isset($conf["monitorLP"])){
1637
 
1638
			#如果port被使用了
1639
			if(in_array($conf["monitorLP"],$nmap["content"])){
1640
 
1641
				#設置執行不正常
1642
				$result["status"]="false";
1643
 
1644
				#設置執行錯誤的訊息
1645
				$result["error"][]="port ".$conf["monitorLP"]." 已經被使用了";
1646
 
1647
				#回傳結果
1648
				return $result;
1649
 
1650
				}#if end
1651
 
1652
			}#if end
1653
 
1654
		#設置監控的port
1655
		$paramsArray[]="-serial";
1656
		$paramsArray[]="mon:telnet::".$conf["monitorLP"].",server,nowait";
1657
 
1658
		#執行qemu指令
1659
		#涵式說明:
1660
		#呼叫shell執行系統命令,並取得回傳的內容.
1661
		#回傳的結果:
1662
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1663
		#$result["error"],錯誤訊息陣列.
1664
		#$result["function"],當前執行的函數名稱.
1665
		#$result["cmd"],執行的指令內容.
1666
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
1667
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
1668
		#$result["tmpFileOutput"],儲存輸出的暫村檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
1669
		#$result["running"],是否還在執行.
1670
		#$result["pid"],pid
1671
		#必填的參數
1672
		#$conf["command"],字串,要執行的指令與.
1673
		$conf["external::callShell"]["command"]=$qemuBin;
1674
		#$conf["fileArgu"],字串,變數__FILE__的內容.
1675
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
1676
		#可省略參數:
1677
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
1678
		$conf["external::callShell"]["argu"]=$paramsArray;
1679
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
1680
		#$conf["arguIsAddr"]=array();
1681
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
1682
		#$conf["enablePrintDescription"]="true";
1683
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
1684
		#$conf["printDescription"]="";
1685
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
1686
		$conf["external::callShell"]["escapeshellarg"]="true";
1687
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1688
		#$conf["username"]="";
1689
		#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1690
		#$conf["password"]="";
1691
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
1692
		#$conf["useScript"]="";
1693
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
1694
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
1695
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
1696
		$conf["external::callShell"]["inBackGround"]="true";
1697
		#備註:
1698
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
1699
		#參考資料:
1700
		#exec=>http://php.net/manual/en/function.exec.php
1701
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
1702
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
1703
		$callShell=external::callShell($conf["external::callShell"]);
1704
		unset($conf["external::callShell"]);
1705
 
1706
		#如果執行指令失敗
1707
		if($callShell["status"]==="false"){
1708
 
1709
			#設置執行不正常
1710
			$result["status"]="false";
1711
 
1712
			#設置執行錯誤的訊息
1713
			$result["error"]=$callShell;
1714
 
1715
			#回傳結果
1716
			return $result;
1717
 
1718
			}#if end
1719
 
1720
		#取得執行的指令
1721
		$result["cmd"]=$callShell["cmd"];
1722
 
1723
		#初始化找到的可能qemu pid 陣列
1724
		$possiableQemuPidsArray=array();
1725
 
1726
		#無窮迴圈
1727
		while(true){
1728
 
1729
			#避免抓到暫時的qemu pid
1730
			sleep(1);
1731
 
1732
			#由於 qemu 的 -daemonize 參數,會將qemu初始化變成常駐程式,因此需要重新尋找正確的pid
1733
			#函數說明:
1734
			#檢查指令的輸出是否含有關鍵字
1735
			#回傳結果:
1736
			#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1737
			#$result["error"],錯誤訊息.
1738
			#$result["function"],當前執行的函數名稱.
1739
			#$result["argu"],使用的參數.
1740
			#$result["founded"],是否找到關鍵字,"true"代表有,"false"代表沒有.
1741
			#$result["content"],關鍵字所在列的輸出.
1742
			#必填參數:
1743
			#$conf["cmd"],字串,要執行的指令.
1744
			$conf["cmd::searchOutPut"]["cmd"]="ps aux";
1745
			#$conf["keyWord"],字串,要檢查是否有關鍵字.
1746
			$conf["cmd::searchOutPut"]["keyWord"]=$result["cmd"];
1747
			#$conf["fileArgu"],字串,變數__FILE__的內容.
1748
			$conf["cmd::searchOutPut"]["fileArgu"]=$conf["fileArgu"];
1749
			#可省略參數:
1750
			#$conf["binPath"],字串,要搜尋的路徑,預設為"/usr/bin".
1751
			#$conf["binPath"]="";
1752
			$searchOutPut=cmd::searchOutPut($conf["cmd::searchOutPut"]);
1753
			unset($conf["cmd::searchOutPut"]);
1754
 
1755
			#如果搜尋失敗
1756
			if($searchOutPut["status"]==="false"){
1757
 
1758
				#設置執行不正常
1759
				$result["status"]="false";
1760
 
1761
				#設置執行錯誤的訊息
1762
				$result["error"]=$searchOutPut;
1763
 
1764
				#回傳結果
1765
				return $result;
1766
 
1767
				}#if end
1768
 
1769
			#如果有找到pid資訊
1770
			if($searchOutPut["founded"]==="true"){
1771
 
1772
				#如果有3個以上的結果
1773
				if(count($searchOutPut["content"])>3){
1774
 
1775
					#休息一秒
1776
					sleep(1);
1777
 
1778
					#在檢查一次
1779
					continue;
1780
 
1781
					}#if end
1782
 
1783
				#針對每個輸出
1784
				foreach($searchOutPut["content"] as $maybeTrueQemuPidStr){
1785
 
1786
					#函式說明:
1787
					#檢查一個字串裡面是否沒有多個任何篩選字存在
1788
					#回傳的結果:
1789
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1790
					#$result["function"],當前執行的函數
1791
					#$result["error"],涵式錯誤訊息,若爲""則表示沒有錯誤
1792
					#$result["filtered"],該字串是否為要過濾掉的,"true"為要過濾掉的;"false"為不用過濾掉的
1793
					#必填的參數:
1794
					$conf["search::filterString"]["inputStr"]=$maybeTrueQemuPidStr;#要過濾的字串
1795
					$conf["search::filterString"]["filterWord"]=array("ps aux"," grep ");#要過濾的字串不能含有該陣列元素之一
1796
					$filterString=search::filterString($conf["search::filterString"]);
1797
					unset($conf["search::filterString"]);
1798
 
1799
					#如果搜尋失敗
1800
					if($filterString["status"]==="false"){
1801
 
1802
						#設置執行不正常
1803
						$result["status"]="false";
1804
 
1805
						#設置執行錯誤的訊息
1806
						$result["error"]=$filterString;
1807
 
1808
						#回傳結果
1809
						return $result;
1810
 
1811
						}#if end
1812
 
1813
					#如果可能是正確的pid資訊列
1814
					if($filterString["filtered"]==="false"){
1815
 
1816
						#解析pid關鍵字
1817
						#涵式說明:
1818
						#將固定格式的字串分開,並回傳分開的結果。
1819
						#回傳結果:
1820
						#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1821
						#$result["error"],錯誤訊息陣列
1822
						#$result["function"],當前執行的函數名稱.
1823
						#$result["oriStr"],要分割的原始字串內容
1824
						#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
1825
						#$result["dataCounts"],爲總共分成幾段
1826
						#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
1827
						#必填的參數:
1828
						$conf["stringProcess::spiltString"]["stringIn"]=$maybeTrueQemuPidStr;#要處理的字串。
1829
						$conf["stringProcess::spiltString"]["spiltSymbol"]=" ";#爲以哪個符號作爲分割
1830
						#可省略參數:
1831
						#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
1832
						$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
1833
						$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
1834
						unset($conf["stringProcess::spiltString"]);
1835
 
1836
						#如果分割字串失敗
1837
						if($spiltString["status"]==="false"){
1838
 
1839
							#設置執行不正常
1840
							$result["status"]="false";
1841
 
1842
							#設置執行錯誤的訊息
1843
							$result["error"]=$spiltString;
1844
 
1845
							#回傳結果
1846
							return $result;
1847
 
1848
							}#if end
1849
 
1850
						#如果分割出來的段數小於2
1851
						if($spiltString["dataCounts"]<2){
1852
 
1853
							#設置執行不正常
1854
							$result["status"]="false";
1855
 
1856
							#設置執行錯誤的訊息
1857
							$result["error"]=$spiltString;
1858
 
1859
							#回傳結果
1860
							return $result;
1861
 
1862
							}#if end
1863
 
1864
						#如果分割出來的pid段不存在
1865
						if(!isset($spiltString["dataArray"][1])){
1866
 
1867
							#設置執行不正常
1868
							$result["status"]="false";
1869
 
1870
							#設置執行錯誤的訊息
1871
							$result["error"]=$spiltString;
1872
 
1873
							#回傳結果
1874
							return $result;
1875
 
1876
							}#if end
1877
 
1878
						#取得正確的pid
1879
						$callShell["pid"]=$spiltString["dataArray"][1];
1880
 
1881
						#如果抓到的pid數量小於1
1882
						if(count($possiableQemuPidsArray)<1){
1883
 
1884
							#取得pid
1885
							$possiableQemuPidsArray[]=$callShell["pid"];
1886
 
1887
							#繼續找可能的pid
1888
							continue 2;
1889
 
1890
							}#if end
1891
 
1892
						#納後來發現的qemu pid 跳出 while
1893
						break 2;
1894
 
1895
						}#if ned
1896
 
1897
					}#foreach end
1898
 
1899
				#設置警告的訊息
1900
				$result["warning"][]=$callShell["pid"]."不為正確的pid";
1901
 
1902
				#結束無窮迴圈
1903
				break;
1904
 
1905
				}#if end
1906
 
1907
			#反之
1908
			else{
1909
 
1910
				#設置警告的訊息
1911
				$result["warning"][]=$callShell["pid"]."不為正確的pid";
1912
 
1913
				}#else end
1914
 
1915
			}#while end
1916
 
1917
		#如果存在記錄暫存輸出的檔案
1918
		if(file_exists($callShell["tmpFileOutput"])){
1919
 
1920
			#取得檔案內容
1921
			$output=file($callShell["tmpFileOutput"]);
1922
 
1923
			#如果有內容
1924
			if(count($output)>0){
1925
 
1926
				#設置執行失敗
1927
				$result["status"]="false";
1928
 
1929
				#設置錯誤訊息
1930
				$result["error"]=$output;
1931
 
1932
				#回傳結果
1933
				return $result;
1934
 
1935
				}#if end
1936
 
1937
			}#if end
1938
 
1939
		#取得程式的pid
1940
		$result["content"]=$callShell["pid"];
1941
 
1942
		#設置執行正常
1943
		$result["status"]="true";
1944
 
1945
		#回傳結果
1946
		return $result;
1947
 
1948
		}#function run end
1949
 
1950
	/*
1951
	#涵式說明:
1952
	#使用remote-viewer指令進行遠端
1953
	#回傳結果:
1954
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
1955
	#$reuslt["error"],執行不正常結束的錯訊息陣列.
1956
	#$result["function"],當前執行的函式名稱.
1957
	#$result["argu"],所使用的參數.
1958
	#$result["cmd"],執行的指令.
1959
	#$result["config"],連線所用的config檔案內容.
1960
	#必填參數:
1961
	#$conf["type"],字串,"tcp"代表是用網路連線;"sock"代表是用unix socket進行連線,僅限於本機.
1962
	$conf["type"]="";
1963
	#$conf["addr"],字串,要連線到的位置,若$conf["type"]是tcp,則可以為IP位置或dns;若$conf["type"]是sock,則可以為socket檔案在本機上的位置.
1964
	$conf["addr"]="";
1965
	#$conf["fileArgu"],字串,__FILE__的內容.
1966
	$conf["fileArgu"]=__FILE__;
1967
	#可省略參數:
1968
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
1969
	#$conf["username"]="";
1970
	#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
1971
	#$conf["password"]="";
1972
	#$conf["spicePassword"],字串,連線用的密碼,$conf["type"]為"sock"時不適用.
1973
	#$conf["spicePassword"]="";
1974
	#$conf["port"],字串,$conf["addr"]為tcp時,連線用的port.
1975
	#$conf["port"]="";
1976
	#$conf["title"],字串,遠端視窗的標題要為什麼?預設為連線的位置.
1977
	#$conf["title"]="";
1978
	#$conf["fullScreen"],字串,是否一連線就要全螢幕,"true"代表要,"false"代表不要,預設為"false".
1979
	#$conf["fullScreen"]="";
1980
	#備註:
1981
	#僅能在命列執行.
1982
	#sock檔案的路徑有錯誤
1983
	*/
1984
	function spice(&$conf){
1985
 
1986
		#初始化要回傳的結果
1987
		$result=array();
1988
 
1989
		#取得當前執行的函數名稱
1990
		$result["function"]=__FUNCTION__;
1991
 
1992
		#如果沒有參數
1993
		if(func_num_args()==0){
1994
 
1995
			#設置執行失敗
1996
			$result["status"]="false";
1997
 
1998
			#設置執行錯誤訊息
1999
			$result["error"]="函數".$result["function"]."需要參數";
2000
 
2001
			#回傳結果
2002
			return $result;
2003
 
2004
			}#if end
2005
 
2006
		#涵式說明:
2007
		#判斷當前環境為web還是cmd
2008
		#回傳結果:
2009
		#$result,"web"或"cmd"
2010
		if(csInformation::getEnv()=="web"){
2011
 
2012
			#設置執行失敗
2013
			$result["status"]="false";
2014
 
2015
			#設置執行錯誤訊息
2016
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
2017
 
2018
			#回傳結果
2019
			return $result;
2020
 
2021
			}#if end
2022
 
2023
		#取得參數
2024
		$result["argu"]=$conf;
2025
 
2026
		#如果 $conf 不為陣列
2027
		if(gettype($conf)!="array"){
2028
 
2029
			#設置執行失敗
2030
			$result["status"]="false";
2031
 
2032
			#設置執行錯誤訊息
2033
			$result["error"][]="\$conf變數須為陣列形態";
2034
 
2035
			#如果傳入的參數為 null
2036
			if($conf==null){
2037
 
2038
				#設置執行錯誤訊息
2039
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
2040
 
2041
				}#if end
2042
 
2043
			#回傳結果
2044
			return $result;
2045
 
2046
			}#if end
2047
 
2048
		#檢查參數
2049
		#函式說明:
2050
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2051
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2052
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2053
		#$result["function"],當前執行的函式名稱.
2054
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2055
		#$result[$shouldBtCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2056
		#$result[$shouldBtCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2057
		#$result[$shouldBtCheckedVarName]["error"],每個參數設定的錯誤訊息
2058
		#必填寫的參數:
2059
		#$conf["variableCheck::checkArguments"]["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2060
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
2061
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2062
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("type","addr","fileArgu");
2063
		#$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列 例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double");
2064
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string","string");
2065
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2066
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2067
		#可以省略的參數:
2068
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"],必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true"。
2069
		#$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
2070
		#$conf["variableCheck::checkArguments"]["skipableVariableName"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
2071
		$conf["variableCheck::checkArguments"]["skipableVariableName"]=array("username","password","port","title","fullScreen","spicePassword");
2072
		#$conf["variableCheck::checkArguments"]["skipableVariableType"],爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
2073
		$conf["variableCheck::checkArguments"]["skipableVariableType"]=array("string","string","string","string","string","string");
2074
		#$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,"null"代表不指定,若預設值是必填參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
2075
		$conf["variableCheck::checkArguments"]["skipableVarDefaultValue"]=array(null,null,null,null,"false",null);
2076
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2077
		#$conf["variableCheck::checkArguments"]["arrayCountEqualCheck"][]=array();
2078
		$checkResult=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2079
		unset($conf["variableCheck::checkArguments"]);
2080
 
2081
		#如果檢查參數失敗
2082
		if($checkResult["status"]=="false"){
2083
 
2084
			#設置執行失敗
2085
			$result["status"]="false";
2086
 
2087
			#設置執行錯誤
2088
			$result["error"]=$checkResult;
2089
 
2090
			#回傳結果
2091
			return $result;
2092
 
2093
			}#if end
2094
 
2095
		#如果檢查參數不通過
2096
		if($checkResult["passed"]=="false"){
2097
 
2098
			#設置執行失敗
2099
			$result["status"]="false";
2100
 
2101
			#設置執行錯誤
2102
			$result["error"]=$checkResult;
2103
 
2104
			#回傳結果
2105
			return $result;
2106
 
2107
			}#if end
2108
 
2109
		#建立暫存的 remote-viewer 設定檔
2110
		#函數說明:
2111
		#建立暫存目錄與回傳暫存檔案名稱路徑
2112
		#回傳結果:
2113
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2114
		#$result["error"],錯誤訊息.
2115
		#$result["function"],當前執行的函數名稱.
2116
		#$result["content"],暫存檔案的路徑與名稱.
2117
		#必填參數:
2118
		#無
2119
		#可省略參數:
2120
		#$conf["tempDir"],字串,暫存目錄的名稱,預設為.fileAccess/createTempFile
2121
		$conf["fileAccess::createTempFile"]["tempDir"]="/tmp/qbpwcf/remote-viewer";
2122
		#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.
2123
		$conf["fileAccess::createTempFile"]["fileArgu"]=$conf["fileArgu"];
2124
		#$conf["createPath"],字串,是否僅要建立目錄,"true"代表要,"false"代表不要,預設為"true".
2125
		#$conf["fileAccess::createTempFile"]["createPath"]="true";
2126
		#$conf["createFile"],字串,是否要在暫存路徑建立好後建立暫存檔案,"true"代表要,"false"代表不用,預設為"true".
2127
		#$conf["fileAccess::createTempFile"]["createFile"]="true";
2128
		$createTempFile=fileAccess::createTempFile($conf["fileAccess::createTempFile"]);
2129
		unset($conf["fileAccess::createTempFile"]);
2130
 
2131
		#如果建立暫存檔案失敗
2132
		if($createTempFile["status"]==="false"){
2133
 
2134
			#設置執行失敗
2135
			$result["status"]="false";
2136
 
2137
			#設置執行錯誤
2138
			$result["error"]=$createTempFile;
2139
 
2140
			#回傳結果
2141
			return $result;
2142
 
2143
			}#if end
2144
 
2145
		#初始化要寫入到設定檔裡面的內容
2146
		$dataToWrite=array("[virt-viewer]","type=spice");
2147
 
2148
		#如果有設置標題
2149
		if(isset($conf["title"])){
2150
 
2151
			#設置標題
2152
			$dataToWrite[]="title=某人的虛擬機器";
2153
 
2154
			}#if end
2155
 
2156
		#初始化 spice 的目標
2157
		$spiceAddr="";
2158
 
2159
		#判斷 $conf["type"]
2160
		switch($conf["type"]){
2161
 
2162
			#如果是 "tcp"
2163
			case "tcp":
2164
 
2165
				#設置連線的位置
2166
				$dataToWrite[]="host=".$conf["addr"];
2167
 
2168
				#設置連線的 port
2169
				$dataToWrite[]="port=".$conf["port"];
2170
 
2171
				#跳出 switch
2172
				break;
2173
 
2174
			#如果是 "sock"
2175
			case "sock":
2176
 
2177
				#初始化執行的參數
2178
				$argu=array();
2179
 
2180
				#如果有設置標題
2181
				if(isset($conf["title"])){
2182
 
2183
					#設置標題
2184
					$argu[]="-t";
2185
					$argu[]=$conf["title"];
2186
 
2187
					}#if end
2188
 
2189
				#如果要全螢幕
2190
				if($conf["fullScreen"]==="true"){
2191
 
2192
					#設置要全螢幕
2193
					$argu[]="-f";
2194
 
2195
					}#if end
2196
 
2197
				#將 $conf["addr"] 轉換成絕對位址
2198
				#函數說明:
2199
				#將檔案的位置名稱變成網址,也可以取得檔案位於伺服器上檔案系統的絕對位置.
2200
				#回傳結果:
2201
				#$result["status"],"true"爲建立成功,"false"爲建立失敗.
2202
				#$result["error"],錯誤訊息陣列.
2203
				#$result["function"],函數名稱.
2204
				#$result["content"],網址,若是在命令列執行,則為"null".
2205
				#$result["webPathFromRoot"],相對於網頁根目錄的路徑.
2206
				#$result["fileSystemAbsoulutePosition"],針對伺服器端的絕對位置,亦即從網頁「/」目錄開始的路徑.
2207
				#$result["fileSystemRelativePosition"],針對伺服器檔案系統的相對位置.
2208
				#必填參數:
2209
				#$conf["address"],字串,檔案的相對位置,若為絕對位置則會自動轉換成相對位置.
2210
				$conf["fileAccess::getInternetAddress"]["address"]=$conf["addr"];
2211
				#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑.
2212
				$conf["fileAccess::getInternetAddress"]["fileArgu"]=$conf["fileArgu"];
2213
				#可省略參數:
2214
				#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
2215
				#$conf["userDir"]="true";
2216
				#備註:
2217
				#在命令列執行,所得的路徑是錯誤的。
2218
				$getInternetAddress=fileAccess::getInternetAddress($conf["fileAccess::getInternetAddress"]);
2219
				unset($conf["fileAccess::getInternetAddress"]);
2220
 
2221
				#如果取得位址失敗
2222
				if($getInternetAddress["status"]==="false"){
2223
 
2224
					#設置執行失敗
2225
					$result["status"]="false";
2226
 
2227
					#設置執行錯誤
2228
					$result["error"]=$getInternetAddress;
2229
 
2230
					#回傳結果
2231
					return $result;
2232
 
2233
					}#if end
2234
 
2235
				#debug
2236
				#var_dump($getInternetAddress);
2237
 
2238
				#檢查socket檔案是否存在
2239
				#函式說明:
2240
				#用shell檢查檔案是否存在,可以指定查詢時用的身份.
2241
				#回傳的結果:
2242
				#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.
2243
				#$result["function"],當前執行的函數名稱.
2244
				#$result["error"],錯誤訊息陣列.
2245
				#$result["founded"],"true"代表有找到檔案,"false"代表沒有找到檔案.
2246
				#必填的參數:
2247
				#$conf["fileName"],字串,要檢查的檔案名稱.
2248
				$conf["cmd::checkFileExist"]["fileName"]=$getInternetAddress["fileSystemAbsoulutePosition"];
2249
				#$conf["fileArgu"],字串,__FILE__的內容,預設為當前檔案的位置.
2250
				$conf["cmd::checkFileExist"]["fileArgu"]=$conf["fileArgu"];
2251
				#可省略參數:
2252
				#$conf["username"],字串,要用哪個身份來檢查檔案是否存在,預設不使用.
2253
				#$conf["username"]="";
2254
				#$conf["password"],字串,要用哪個身份來檢查檔案是否存在,預設不使用,若沒有設定好不用密碼即可登入,則在web端會直接出錯,在命令列則會提示輸入密碼.
2255
				#$conf["password"]="";
2256
				#備註:
2257
				#僅能在命令列環境下執行.
2258
				$checkFileExist=cmd::checkFileExist($conf["cmd::checkFileExist"]);
2259
				unset($conf["cmd::checkFileExist"]);
2260
 
2261
				#如果檔案檢查失敗
2262
				if($checkFileExist["status"]==="false"){
2263
 
2264
					#設置執行失敗
2265
					$result["status"]="false";
2266
 
2267
					#設置執行錯誤
2268
					$result["error"]=$checkFileExist;
2269
 
2270
					#回傳結果
2271
					return $result;
2272
 
2273
					}#if end
2274
 
2275
				#如果檔案不存在
2276
				if($checkFileExist["founded"]==="false"){
2277
 
2278
					#設置執行失敗
2279
					$result["status"]="false";
2280
 
2281
					#設置執行錯誤
2282
					$result["error"]=$checkFileExist;
2283
 
2284
					#回傳結果
2285
					return $result;
2286
 
2287
					}#if end
2288
 
2289
				#將路徑變成直觀的路徑
2290
				#函式說明:
2291
				#將檔案目錄的絕對位置中的 "../" 剔除變成直觀的路徑.
2292
				#回傳的結果:
2293
				#$result["status"],執行是否成功,"true"代表執行成功,"false"代表執行失敗.
2294
				#$result["function"],當前執行的函數.
2295
				#$result["error"],錯誤訊息陣列.
2296
				#$result["changedPath"],處理完後回傳的目錄字串.
2297
				#$result["oriPath"],原始的路徑字串
2298
				#必填的參數:
2299
				#$conf["dirStr"],字串,要處理的檔案目錄字串.
2300
				$conf["stringProcess::changeDirByDotDotSolidus"]["dirStr"]=$getInternetAddress["fileSystemAbsoulutePosition"];
2301
				$changeDirByDotDotSolidus=stringProcess::changeDirByDotDotSolidus($conf["stringProcess::changeDirByDotDotSolidus"]);
2302
				unset($conf["stringProcess::changeDirByDotDotSolidus"]);
2303
 
2304
				#如果轉換路徑失敗
2305
				if($changeDirByDotDotSolidus["status"]==="false"){
2306
 
2307
					#設置執行失敗
2308
					$result["status"]="false";
2309
 
2310
					#設置執行錯誤
2311
					$result["error"]=$changeDirByDotDotSolidus;
2312
 
2313
					#回傳結果
2314
					return $result;
2315
 
2316
					}#if end
2317
 
2318
				#設置位置參數
2319
				$argu[]=$spiceAddr."spice+unix://".$changeDirByDotDotSolidus["changedPath"];
2320
 
2321
				#執行 remote-viewer 指令
2322
				#涵式說明:
2323
				#呼叫shell執行系統命令,並取得回傳的內容.
2324
				#回傳的結果:
2325
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2326
				#$result["error"],錯誤訊息陣列.
2327
				#$result["function"],當前執行的函數名稱.
2328
				#$result["cmd"],執行的指令內容.
2329
				#$result["output"],爲執行完二元碼後的輸出陣列.
2330
				#必填的參數
2331
				#$conf["command"],字串,要執行的指令與.
2332
				$conf["external::callShell"]["command"]="remote-viewer";
2333
				#$conf["fileArgu"],字串,變數__FILE__的內容.
2334
				$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
2335
				#可省略參數:
2336
				#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2337
				$conf["external::callShell"]["argu"]=$argu;
2338
				#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
2339
				$conf["external::callShell"]["enablePrintDescription"]="true";
2340
				#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
2341
				#$conf["external::callShell"]["printDescription"]="";
2342
				#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
2343
				$conf["external::callShell"]["escapeshellarg"]="true";
2344
 
2345
				#如果有設定 $conf["username"]
2346
				if(isset($conf["username"])){
2347
 
2348
					#$conf["username"],字串,要用什麼使用者來執行,預設為執行apache的使用者,該參數不適用於apache環境.
2349
					$conf["external::callShell"]["username"]=$conf["username"];
2350
 
2351
					}#if end
2352
 
2353
				#如果有設定 $conf["password"]
2354
				if(isset($conf["password"])){
2355
 
2356
					#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
2357
					$conf["external::callShell"]["password"]=$conf["password"];
2358
 
2359
					}#if end
2360
 
2361
				#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
2362
				#$conf["external::callShell"]["useScript"]="true";
2363
				#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
2364
				#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2365
				#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2366
				$conf["external::callShell"]["inBackGround"]="true";
2367
				#備註:
2368
				#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2369
				#參考資料:
2370
				#exec=>http://php.net/manual/en/function.exec.php
2371
				#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2372
				#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2373
				$callShell=external::callShell($conf["external::callShell"]);
2374
				unset($conf["external::callShell"]);
2375
 
2376
				#如果執行 remote-viewer 指令失敗
2377
				if($callShell["status"]=="false"){
2378
 
2379
					#設置執行失敗
2380
					$result["status"]="false";
2381
 
2382
					#設置執行錯誤
2383
					$result["error"]=$callShell;
2384
 
2385
					#回傳結果
2386
					return $result;
2387
 
2388
					}#if end
2389
 
2390
				#執行的指令
2391
				$result["cmd"]=$callShell["cmd"];
2392
 
2393
				#執行的pid
2394
				$result["pid"]=$callShell["pid"];
2395
 
2396
				#設置執行正常
2397
				$result["status"]="true";
2398
 
2399
				#回傳結果
2400
				return $result;
2401
 
2402
				#跳出 switch
2403
				break;
2404
 
2405
			#如果是其他形態
2406
			default:
2407
 
2408
				#設置執行失敗
2409
				$result["status"]="false";
2410
 
2411
				#設置執行錯誤
2412
				$result["error"][]="\$conf[\"type\"] 僅能為 tcp 或 sock";
2413
 
2414
				#回傳結果
2415
				return $result;
2416
 
2417
			}#switc end
2418
 
2419
		#如果要全螢幕
2420
		if($conf["fullScreen"]==="true"){
2421
 
2422
			#設置要全螢幕
2423
			$dataToWrite[]="fullscreen=1";
2424
 
2425
			}#if end
2426
 
2427
		#如果有設置連線用的密碼
2428
		if(isset($conf["spicePassword"])){
2429
 
2430
			#設置連線用的密碼
2431
			$dataToWrite[]="password=".$conf["spicePassword"];
2432
 
2433
			}#if end
2434
 
2435
		#啟用轉usb
2436
		$dataToWrite[]="enable-usbredir=1";
2437
 
2438
		#不限制usb
2439
		$dataToWrite[]="usb-filter=-1";
2440
 
2441
		#全螢幕快捷按鍵為f11
2442
		$dataToWrite[]="toggle-fullscreen=f11";
2443
 
2444
		#螢幕被抓取時按下 ctrl+alt 即可離開
2445
		$dataToWrite[]="release-cursor=ctrl+alt";
2446
 
2447
		#將參數寫到暫存檔案裡面
2448
		#涵式說明:
2449
		#將多行字串寫入到檔案
2450
		#回傳的結果:
2451
		#$result["status"],"true"表示檔案寫入成功,"false"表示檔案寫入失敗.
2452
		#$result["error"],錯誤訊息陣列.
2453
		#$result["function"],當前執行函數的名稱.
2454
		#必填的參數:
2455
		#$conf["fileName"],字串,爲要編輯的檔案名稱
2456
		$conf["fileAccess::writeMultiLine"]["fileName"]=$createTempFile["content"];
2457
		#$conf["inputString"],字串陣列,爲要寫入到 $conf["fileName"] 裏面的內容
2458
			#$conf["inputString"][$i] 代表第 $i+1 行。
2459
		$conf["fileAccess::writeMultiLine"]["inputString"]=$dataToWrite;
2460
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
2461
		$conf["fileAccess::writeMultiLine"]["fileArgu"]=$conf["fileArgu"];
2462
		#可省略的參數:
2463
		#$conf["writeMethod"]="a";#爲檔案撰寫的方式,可省略,是複寫'a'還是,重新寫入'w',預設爲'w',重新寫入。
2464
		$writeMultiLine=fileAccess::writeMultiLine($conf["fileAccess::writeMultiLine"]);
2465
		unset($conf["fileAccess::writeMultiLine"]);
2466
 
2467
		#如果撰寫多行文字失敗
2468
		if($writeMultiLine["status"]==="false"){
2469
 
2470
			#設置執行失敗
2471
			$result["status"]="false";
2472
 
2473
			#設置執行錯誤
2474
			$result["error"]=$writeMultiLine;
2475
 
2476
			#回傳結果
2477
			return $result;
2478
 
2479
			}#if end
2480
 
2481
		#執行 remote-viewer 指令
2482
		#涵式說明:
2483
		#呼叫shell執行系統命令,並取得回傳的內容.
2484
		#回傳的結果:
2485
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2486
		#$result["error"],錯誤訊息陣列.
2487
		#$result["function"],當前執行的函數名稱.
2488
		#$result["cmd"],執行的指令內容.
2489
		#$result["output"],爲執行完二元碼後的輸出陣列.
2490
		#必填的參數
2491
		#$conf["command"],字串,要執行的指令與.
2492
		$conf["external::callShell"]["command"]="remote-viewer";
2493
		#$conf["fileArgu"],字串,變數__FILE__的內容.
2494
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
2495
		#可省略參數:
2496
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
2497
		$conf["external::callShell"]["argu"]=array($createTempFile["content"]);
2498
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
2499
		$conf["external::callShell"]["enablePrintDescription"]="true";
2500
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
2501
		#$conf["external::callShell"]["printDescription"]="";
2502
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
2503
		$conf["external::callShell"]["escapeshellarg"]="true";
2504
 
2505
		#如果有設定 $conf["username"]
2506
		if(isset($conf["username"])){
2507
 
2508
			#$conf["username"],字串,要用什麼使用者來執行,預設為執行apache的使用者,該參數不適用於apache環境.
2509
			$conf["external::callShell"]["username"]=$conf["username"];
2510
 
2511
			}#if end
2512
 
2513
		#如果有設定 $conf["password"]
2514
		if(isset($conf["password"])){
2515
 
2516
			#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
2517
			$conf["external::callShell"]["password"]=$conf["password"];
2518
 
2519
			}#if end
2520
 
2521
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要;"false"代表不要,預設為"false".
2522
		#$conf["external::callShell"]["useScript"]="true";
2523
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 ".qbpwcf_tmp/external/callShell/".
2524
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
2525
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
2526
		$conf["external::callShell"]["inBackGround"]="true";
2527
		#備註:
2528
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
2529
		#參考資料:
2530
		#exec=>http://php.net/manual/en/function.exec.php
2531
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
2532
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
2533
		$callShell=external::callShell($conf["external::callShell"]);
2534
		unset($conf["external::callShell"]);
2535
 
2536
		#如果執行 remote-viewer 指令失敗
2537
		if($callShell["status"]=="false"){
2538
 
2539
			#設置執行失敗
2540
			$result["status"]="false";
2541
 
2542
			#設置執行錯誤
2543
			$result["error"]=$callShell;
2544
 
2545
			#回傳結果
2546
			return $result;
2547
 
2548
			}#if end
2549
 
2550
		#執行的指令
2551
		$result["cmd"]=$callShell["cmd"];
2552
 
2553
		#執行的pid
2554
		$result["pid"]=$callShell["pid"];
2555
 
2556
		#休息一秒,避免設定檔被刪除
2557
		sleep(1);
2558
 
2559
		#移除暫存檔案裡面
2560
		#涵式說明:
2561
		#移除檔案
2562
		#回傳的結果:
2563
		#$result["status"],"true"代表移除成功,"false"代表移除失敗.
2564
		#$result["error"],錯誤訊息陣列
2565
		#$result["warning"],警告訊息陣列
2566
		#$result["function"],當前執行的函數名稱
2567
		#必填的參數:
2568
		#$conf["fileAddress"],字串,要移除檔案的位置.
2569
		$conf["fileAccess::delFile"]["fileAddress"]=$createTempFile["content"];
2570
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑.
2571
		$conf["fileAccess::delFile"]["fileArgu"]=$conf["fileArgu"];
2572
		#可省略參數:
2573
		#$conf["commentsArray"],字串陣列,提示的文字描述,$conf["commentsArray"][$i]代表第($+1)行的描述.
2574
		#$conf["commentsArray"]=array("");
2575
		$delFile=fileAccess::delFile($conf["fileAccess::delFile"]);
2576
		unset($conf["fileAccess::delFile"]);
2577
 
2578
		#如果移除暫存檔案失敗
2579
		if($delFile["status"]==="false"){
2580
 
2581
			#設置執行失敗
2582
			$result["status"]="false";
2583
 
2584
			#設置執行錯誤
2585
			$result["error"]=$delFile;
2586
 
2587
			#回傳結果
2588
			return $result;
2589
 
2590
			}#if end
2591
 
2592
		#設置執行正常
2593
		$result["status"]="true";
2594
 
2595
		#回傳結果
2596
		return $result;
2597
 
2598
		}#function spice end
2599
 
2600
	/*
2601
	#涵式說明:
2602
	#尋找指定路徑下的虛擬硬碟,將之重新轉換與壓縮,再取掉代原有的檔案.
2603
	#回傳結果:
2604
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2605
	#$result["error"],錯誤訊息.
2606
	#$result["function"],當前執行的函數名稱.
2607
	#$result["argu"],所使用的參數.
2608
	#$result["found"],是否有找到可以轉換的檔案,"true"代表有;"false"代表沒有.
2609
	#$result["content"],有改變的虛擬硬碟位置字串陣列.
2610
	#必填參數:
2611
	#$conf["path"],字串,虛擬硬碟檔案的搜尋路徑.
2612
	#$conf["path"]="";
2613
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
2614
	#$conf["fileArgu"]=__FILE__;
2615
	#備註:
2616
	#目前只支援qcow2格式的虛擬硬碟
2617
	*/
2618
	public static function imgConvert(&$conf=array()){
2619
 
2620
		#初始化要回傳的結果
2621
		$result=array();
2622
 
2623
		#取得當前執行的函數名稱
2624
		$result["function"]=__FUNCTION__;
2625
 
2626
		#如果沒有參數
2627
		if(func_num_args()==0){
2628
 
2629
			#設置執行失敗
2630
			$result["status"]="false";
2631
 
2632
			#設置執行錯誤訊息
2633
			$result["error"]="函數".$result["function"]."需要參數";
2634
 
2635
			#回傳結果
2636
			return $result;
2637
 
2638
			}#if end
2639
 
2640
		#涵式說明:
2641
		#判斷當前環境為web還是cmd
2642
		#回傳結果:
2643
		#$result,"web"或"cmd"
2644
		if(csInformation::getEnv()==="web"){
2645
 
2646
			#設置執行失敗
2647
			$result["status"]="false";
2648
 
2649
			#設置執行錯誤訊息
2650
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
2651
 
2652
			#回傳結果
2653
			return $result;
2654
 
2655
			}#if end
2656
 
2657
		#取得參數
2658
		$result["argu"]=$conf;
2659
 
2660
		#如果 $conf 不為陣列
2661
		if(gettype($conf)!=="array"){
2662
 
2663
			#設置執行失敗
2664
			$result["status"]="false";
2665
 
2666
			#設置執行錯誤訊息
2667
			$result["error"][]="\$conf變數須為陣列形態";
2668
 
2669
			#如果傳入的參數為 null
2670
			if($conf===null){
2671
 
2672
				#設置執行錯誤訊息
2673
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
2674
 
2675
				}#if end
2676
 
2677
			#回傳結果
2678
			return $result;
2679
 
2680
			}#if end
2681
 
2682
		#函式說明:
2683
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
2684
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2685
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
2686
		#$result["function"],當前執行的函式名稱.
2687
		#$result["argu"],設置給予的參數.
2688
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
2689
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
2690
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
2691
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
2692
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
2693
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
2694
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
2695
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
2696
		#必填寫的參數:
2697
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
2698
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
2699
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
2700
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
2701
		#可以省略的參數:
2702
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
2703
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("path","fileArgu");
2704
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
2705
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
2706
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
2707
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
2708
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
2709
		#$conf["canNotBeEmpty"]=array();
2710
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
2711
		#$conf["canBeEmpty"]=array();
2712
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
2713
		#$conf["skipableVariableCanNotBeEmpty"]=array();
2714
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
2715
		#$conf["skipableVariableName"]=array();
2716
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
2717
		#$conf["skipableVariableType"]=array();
2718
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
2719
		#$conf["skipableVarDefaultValue"]=array("");
2720
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
2721
		#$conf["disallowAllSkipableVarIsEmpty"]="";
2722
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
2723
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
2724
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
2725
		#$conf["arrayCountEqualCheck"][]=array();
2726
		#參考資料來源:
2727
		#array_keys=>http://php.net/manual/en/function.array-keys.php
2728
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
2729
		unset($conf["variableCheck::checkArguments"]);
2730
 
2731
		#如果檢查參數失敗
2732
		if($checkArguments["status"]==="false"){
2733
 
2734
			#設置執行失敗
2735
			$result["status"]="false";
2736
 
2737
			#設置執行失敗訊息
2738
			$result["error"]=$checkArguments;
2739
 
2740
			#回傳結果
2741
			return $result;
2742
 
2743
			}#if end
2744
 
2745
		#如果檢查參數不通過
2746
		if($checkArguments["passed"]==="false"){
2747
 
2748
			#設置執行失敗
2749
			$result["status"]="false";
2750
 
2751
			#設置執行失敗訊息
2752
			$result["error"]=$checkArguments;
2753
 
2754
			#回傳結果
2755
			return $result;
2756
 
2757
			}#if end
2758
 
2759
		#函數說明:
2760
		#將檔案的位置名稱變成網址,也可以取得檔案位於伺服器上檔案系統的絕對位置.
2761
		#回傳結果:
2762
		#$result["status"],"true"爲建立成功,"false"爲建立失敗.
2763
		#$result["error"],錯誤訊息陣列.
2764
		#$result["function"],函數名稱.
2765
		#$result["argu"],使用的參數.
2766
		#$result["content"],網址,若是在命令列執行,則為"null".
2767
		#$result["webPathFromRoot"],相對於網頁根目錄的路徑.
2768
		#$result["fileSystemAbsoulutePosition"],針對伺服器端的絕對位置,亦即從網頁「/」目錄開始的路徑.
2769
		#$result["fileSystemRelativePosition"],針對伺服器檔案系統的相對位置.
2770
		#必填參數:
2771
		#$conf["address"],字串,檔案的相對位置,若為絕對位置則會自動轉換成相對位置.
2772
		$conf["fileAccess::getInternetAddress"]["address"]=$conf["path"];
2773
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑.
2774
		$conf["fileAccess::getInternetAddress"]["fileArgu"]=$conf["fileArgu"];
2775
		#可省略參數:
2776
		#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
2777
		#$conf["userDir"]="true";
2778
		$getInternetAddress=fileAccess::getInternetAddress($conf["fileAccess::getInternetAddress"]);
2779
		unset($conf["fileAccess::getInternetAddress"]);
2780
 
2781
		#如果轉換失敗
2782
		if($getInternetAddress["status"]==="false"){
2783
 
2784
			#設置執行失敗
2785
			$result["status"]="false";
2786
 
2787
			#設置執行失敗訊息
2788
			$result["error"]=$getInternetAddress;
2789
 
2790
			#回傳結果
2791
			return $result;
2792
 
2793
			}#if end
2794
 
2795
		#取得轉換好的相對路徑
2796
		$conf["path"]=$getInternetAddress["fileSystemRelativePosition"];
2797
 
2798
		#如果不存在要搜尋的路徑
2799
		if(!file_exists($conf["path"]))
2800
		{
2801
			#設置執行失敗
2802
			$result["status"]="false";
2803
 
2804
			#設置執行失敗訊息
2805
			$result["error"][]="path ".$conf["path"]." not found";
2806
 
2807
			#回傳結果
2808
			return $result;
2809
		}
2810
 
2811
		#反之要搜尋的路徑存在
2812
		else{
2813
			#初始化儲存要印出的內容
2814
			$line2print=array();
2815
 
2816
			#且路徑是檔案
2817
			if(is_file($conf["path"])){
2818
 
2819
				#檢查副檔名是否為 qcow2
2820
				#涵式說明:
2821
				#取得符合特定字首與字尾的字串
2822
				#回傳的結果:
2823
				#$result["status"],若爲"true"則代表執行正常;若爲"false"則代表執行失敗。
2824
				#$result["function"],當前執行的函數名稱.
2825
				#$result["error"],錯誤訊息陣列.
2826
				#$result["founded"],若為"true"則代表有找到符合字首條件的結果;若爲"false"則代表沒有找到。
2827
				#$result["returnString"],爲符合字首條件的字串內容。
2828
				#必填參數:
2829
				#$conf["checkString"],字串,要檢查的字串.
2830
				$conf["search::getMeetConditionsString"]["checkString"]=$conf["path"];
2831
				#可省略參數:
2832
				#$conf["frontWord"],字串,用來檢查字首應該要有什麼字串,預設不指定.
2833
				#$conf["frontWord"]="";
2834
				#$conf["tailWord"],字串,用來檢查字尾應該要有什麼字串,預設不指定.
2835
				$conf["search::getMeetConditionsString"]["tailWord"]=".qcow2";
2836
				#參考資料:
2837
				#str_spilt(),可以將字串依照字母分割成一個個陣列字串。
2838
				$getMeetConditionsString=search::getMeetConditionsString($conf["search::getMeetConditionsString"]);
2839
				unset($conf["search::getMeetConditionsString"]);
2840
 
2841
				#如果搜尋失敗
2842
				if($getMeetConditionsString["status"]==="false"){
2843
 
2844
					#設置執行失敗
2845
					$result["status"]="false";
2846
 
2847
					#設置執行失敗訊息
2848
					$result["error"]=$getMeetConditionsString;
2849
 
2850
					#回傳結果
2851
					return $result;
2852
 
2853
					}#if end
2854
 
2855
				#如果副檔名不是 qcow2
2856
				if($getMeetConditionsString["founded"]==="false"){
2857
 
2858
					#設置執行失敗
2859
					$result["status"]="false";
2860
 
2861
					#設置執行失敗訊息
2862
					$result["error"]=$getMeetConditionsString;
2863
 
2864
					#回傳結果
2865
					return $result;
2866
 
2867
					}#if end
2868
 
2869
				#且副檔案為 qcow2
2870
 
2871
				#設置執行正常
2872
				$findFile["status"]="true";
2873
 
2874
				#設置有找到檔案
2875
				$findFile["found"]="true";
2876
 
2877
				#設置找到的檔案路徑
2878
				$findFile["content"][]=$conf["path"];
2879
 
2880
				}#if end
2881
 
2882
			#不是檔案
2883
			else{
2884
				#涵式說明:
2885
				#尋找檔案.
2886
				#回傳結果:
2887
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2888
				#$result["error"],錯誤訊息.
2889
				#$result["warning"],警告訊息陣列.
2890
				#$result["function"],當前執行的函數名稱.
2891
				#$result["argu"],所使用的參數.
2892
				#$result["found"],是否有找到可以轉換的檔案,"true"代表有;"false"代表沒有.
2893
				#$result["content"],找到的檔案陣列.
2894
				#必填參數:
2895
				#$conf["keyWord"],字串,要搜尋的檔案關鍵字,可用"*"符號,例如"*.qcow2",就代表檔案名成為"qcow2"結尾的檔案.
2896
				$conf["fileAccess::findFile"]["keyWord"]="*.qcow2";
2897
				#$conf["path"],字串陣列,虛擬硬碟檔案的搜尋路徑,預設為當前路徑.
2898
				$conf["fileAccess::findFile"]["path"]=array($conf["path"]);
2899
				#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
2900
				$conf["fileAccess::findFile"]["fileArgu"]=$conf["fileArgu"];
2901
				#參考資料:
2902
				#http://php.net/manual/en/function.glob.php
2903
				$findFile=fileAccess::findFile($conf["fileAccess::findFile"]);
2904
				unset($conf["fileAccess::findFile"]);
2905
 
2906
				}#else end
2907
 
2908
			}#esle end
2909
 
2910
		#如果檢查檔案失敗
2911
		if($findFile["status"]==="false"){
2912
 
2913
			#設置執行失敗
2914
			$result["status"]="false";
2915
 
2916
			#設置執行失敗訊息
2917
			$result["error"]=$findFile;
2918
 
2919
			#回傳結果
2920
			return $result;
2921
 
2922
			}#if end
2923
 
2924
		#如果有符合的檔案
2925
		if($findFile["found"]==="true"){
2926
 
2927
			#初始化儲存要印出的內容
2928
			$line2print=array();
2929
 
2930
			#提示內容標題
2931
			$line2print[]="找到以下檔案可以進行轉換:";
2932
 
2933
			#依照找到的數目
2934
			foreach($findFile["content"] as $qcow2ImgFile){
2935
 
2936
				#記錄檔案
2937
				$line2print[]=$qcow2ImgFile;
2938
 
2939
				}#foreach end
2940
 
2941
			#提示找到以下檔案可以進行整理
2942
			#函式說明:
2943
			#印出多行文字,結尾自動換行.
2944
			#回傳的結果:
2945
			#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.
2946
			#$result["function"],當前執行的函數名稱.
2947
			#$result["error"],錯誤訊息陣列.
2948
			#必填的參數:
2949
			#$conf["outputStringArray"],字串陣列,每行要印出的文字內容.
2950
			$conf["cmd::echoMultiLine"]["outputStringArray"]=$line2print;
2951
			$echoMultiLine=cmd::echoMultiLine($conf["cmd::echoMultiLine"]);
2952
			unset($conf["cmd::echoMultiLine"]);
2953
 
2954
			#如果執行失敗
2955
			if($echoMultiLine["status"]==="false"){
2956
 
2957
				#設置執行失敗
2958
				$result["status"]="false";
2959
 
2960
				#設置執行失敗訊息
2961
				$result["error"]=$echoMultiLine;
2962
 
2963
				#回傳結果
2964
				return $result;
2965
 
2966
				}#if end
2967
 
2968
			#如果符合的檔案數量為>0
2969
			if(count($findFile["content"])>0){
2970
 
2971
				#針對每個虛擬硬碟
2972
				foreach($findFile["content"] as $vdisk){
2973
 
2974
					#檢查虛擬硬碟是否有被使用
2975
					#涵式說明:
2976
					#取得虛擬硬碟的資訊與檢查是否被使用中
2977
					#回傳結果:
2978
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
2979
					#$result["error"],錯誤訊息.
2980
					#$result["function"],當前執行的函數名稱.
2981
					#$result["argu"],所使用的參數.
2982
					#$result["used"],是否被使用中,"true"代表有;"false"代表沒有.
2983
					#$result["image"],虛擬硬碟的路徑與名稱.
2984
					#$result["file format"],虛擬硬碟的格式.
2985
					#$result["virtual size"],虛擬硬碟實際可以儲存的最大容量.
2986
					#$result["disk size"],虛擬硬碟檔案所佔的大小.
2987
					#$result["cluster_size"],佔用空間的最小單位.
2988
					#必填參數:
2989
					#$conf["img"],字串,虛擬硬碟檔案的路徑與名稱.
2990
					$conf["qemu::imgInfo"]["img"]=$vdisk;
2991
					#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
2992
					$conf["qemu::imgInfo"]["fileArgu"]=$conf["fileArgu"];
2993
					$imgInfo=qemu::imgInfo($conf["qemu::imgInfo"]);
2994
					unset($conf["qemu::imgInfo"]);
2995
 
2996
					#如果運行失敗
2997
					if($imgInfo["status"]==="false"){
2998
 
2999
						#設置執行失敗
3000
						$result["status"]="false";
3001
 
3002
						#設置執行失敗訊息
3003
						$result["error"]=$imgInfo;
3004
 
3005
						#回傳結果
3006
						return $result;
3007
 
3008
						}#if end
3009
 
3010
					#如果虛擬硬碟檔案使用中
3011
					if($imgInfo["used"]==="true"){
3012
 
3013
						#設置執行失敗
3014
						$result["status"]="false";
3015
 
3016
						#設置執行失敗訊息
3017
						$result["error"]=$imgInfo;
3018
 
3019
						#回傳結果
3020
						return $result;
3021
 
3022
						}#if end
3023
 
3024
					#var_dump($imgInfo);
3025
 
3026
					#檢查檔案所在位置的分割區剩餘空間是否足夠
3027
 
3028
					#涵式說明:
3029
					#判斷檔案位於哪個分割區
3030
					#回傳結果:
3031
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3032
					#$result["error"],錯誤訊息.
3033
					#$result["function"],當前執行的函數名稱.
3034
					#$result["argu"],所使用的參數.
3035
					#$result["content"],找到的檔案所屬分割區資訊.
3036
					#必填參數:
3037
					#$conf["file"],字串,檔案的路徑與名稱.
3038
					$conf["fileAccess::addrInMountPoint"]["file"]=$vdisk;
3039
					#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3040
					$conf["fileAccess::addrInMountPoint"]["fileArgu"]=$conf["fileArgu"];
3041
					$addrInMountPoint=fileAccess::addrInMountPoint($conf["fileAccess::addrInMountPoint"]);
3042
					unset($conf["fileAccess::addrInMountPoint"]);
3043
 
3044
					#如果虛擬硬碟檔案使用中
3045
					if($addrInMountPoint["status"]==="false"){
3046
 
3047
						#設置執行失敗
3048
						$result["status"]="false";
3049
 
3050
						#設置執行失敗訊息
3051
						$result["error"]=$addrInMountPoint;
3052
 
3053
						#回傳結果
3054
						return $result;
3055
 
3056
						}#if end
3057
 
3058
					#取得虛擬硬碟檔案歸屬的掛載點
3059
					$mountPoint=$addrInMountPoint["content"];
3060
 
3061
					#函式說明:
3062
					#透過"df -h"取得伺服器上的磁碟空間用量
3063
					#回傳結果
3064
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3065
					#$result["error"],錯誤訊息陣列.
3066
					#$result["function"],當前執行的函數名稱.
3067
					#$result["argu"],使用的參數
3068
					#$result["content"],磁碟空間用量.
3069
					#$result["oriOutput"],原始輸出的逐行內容.
3070
					#必填參數:
3071
					#$conf["fileArgu"],字串,__FILE__的內容.
3072
					$conf["cmd::getStorageUsage"]["fileArgu"]=$conf["fileArgu"];
3073
					$getStorageUsage=cmd::getStorageUsage($conf["cmd::getStorageUsage"]);
3074
					unset($conf["cmd::getStorageUsage"]);
3075
 
3076
					#如果執行失敗
3077
					if($getStorageUsage["status"]==="false"){
3078
 
3079
						#設置執行失敗
3080
						$result["status"]="false";
3081
 
3082
						#設置執行失敗訊息
3083
						$result["error"]=$getStorageUsage;
3084
 
3085
						#回傳結果
3086
						return $result;
3087
 
3088
						}#if end
3089
 
3090
					#debug
3091
					#var_dump($getStorageUsage);
3092
 
3093
					#初始化該分割區可用的空間為0G
3094
					$availSize="0G";
3095
 
3096
					#根據每個儲存區
3097
					foreach($getStorageUsage["content"] as $block){
3098
 
3099
						#如果是所屬的分割區
3100
						if($block["Mounted"]===$mountPoint){
3101
 
3102
							#取得剩下的分割區空間
3103
							$availSize=$block["Avail"];
3104
 
3105
							#分割區大小單位
3106
							$availSizeUnit=$availSize[strlen($availSize)-1];
3107
 
3108
							#取得沒有單位的分割區空間
3109
							$availSize=substr($availSize,0,strlen($availSize)-1);
3110
 
3111
							#var_dump($availSize);
3112
 
3113
							#依照單位
3114
							switch($availSizeUnit){
3115
 
3116
								#如果是K
3117
								case "K":
3118
 
3119
									#處以1000000,以G為單位
3120
									$availSize=$availSize/1000/1000;
3121
 
3122
								#如果是M
3123
								case "M":
3124
 
3125
									#除以1000,以G為單位
3126
									$availSize=$availSize/1000;
3127
 
3128
									#跳出
3129
									break;
3130
 
3131
								#如果是G
3132
								case "G":
3133
 
3134
									#跳出
3135
									break;
3136
 
3137
								#如果是T
3138
								case "T";
3139
 
3140
									#乘以1000,以G為單位
3141
									$availSize=$availSize*1000;
3142
 
3143
									#跳出
3144
									break;
3145
 
3146
								#其他單位
3147
								default:
3148
 
3149
									#設置執行失敗
3150
									$result["status"]="false";
3151
 
3152
									#設置執行失敗訊息
3153
									$result["error"]=$getStorageUsage;
3154
 
3155
									#設置執行失敗訊息
3156
									$result["error"][]="not supported unit ".$availSizeUnit;
3157
 
3158
									#回傳結果
3159
									return $result;
3160
 
3161
								}#switch end
3162
 
3163
							#跳出 foreach
3164
							break;
3165
 
3166
							}#if end
3167
 
3168
						}#foreach end
3169
 
3170
					#取得虛擬硬碟的大小
3171
					$diskSize=$imgInfo["disk size"];
3172
 
3173
					#虛擬硬碟的大小單位
3174
					$diskSizeUnit=$diskSize[strlen($diskSize)-1];
3175
 
3176
					#var_dump($diskSizeUnit);
3177
 
3178
					#取得沒有單位的虛擬硬碟大小
3179
					$diskSize=substr($diskSize,0,strlen($diskSize)-1);
3180
 
3181
					#依照單位
3182
					switch($diskSizeUnit){
3183
 
3184
						#如果是K
3185
						case "K":
3186
 
3187
							#處以1000000,以G為單位
3188
							$diskSize=$diskSize/1000/1000;
3189
 
3190
						#如果是M
3191
						case "M":
3192
 
3193
							#除以1000,以G為單位
3194
							$diskSize=$diskSize/1000;
3195
 
3196
							#跳出
3197
							break;
3198
 
3199
						#如果是G
3200
						case "G":
3201
 
3202
							#跳出
3203
							break;
3204
 
3205
						#如果是T
3206
						case "T";
3207
 
3208
							#乘以1000,以G為單位
3209
							$diskSize=$diskSize*1000;
3210
 
3211
							#跳出
3212
							break;
3213
 
3214
						#其他單位
3215
						default:
3216
 
3217
							#設置執行失敗
3218
							$result["status"]="false";
3219
 
3220
							#設置執行失敗訊息
3221
							$result["error"]=$getStorageUsage;
3222
 
3223
							#設置執行失敗訊息
3224
							$result["error"][]="not supported unit ".$diskSizeUnit;
3225
 
3226
							#回傳結果
3227
							return $result;
3228
 
3229
						}#switch end
3230
 
3231
					#如果虛擬硬碟大小 大於 剩餘空間
3232
					if($diskSize>=$availSize){
3233
 
3234
						#設置執行失敗
3235
						$result["status"]="false";
3236
 
3237
						#設置執行失敗訊息
3238
						$result["error"][]="剩餘的空間(".$availSize."M)可能不夠虛擬硬碟(".$diskSize."M)轉換";
3239
 
3240
						#回傳結果
3241
						return $result;
3242
 
3243
						}#if end
3244
 
3245
					#解析檔案的副檔名與名稱
3246
					#涵式說明:
3247
					#取得檔案的副檔名
3248
					#回傳結果:
3249
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3250
					#$result["error"],錯誤訊息.
3251
					#$result["function"],當前執行的函數名稱.
3252
					#$result["argu"],所使用的參數.
3253
					#$result["content"],副檔名.
3254
					#$result["name"],不含副檔的名稱.
3255
					#$result["fullName"],含副檔的名稱.
3256
					#$result["path"],檔案所處的路徑.
3257
					#必填參數:
3258
					#$conf["file"],字串,檔案的路徑與名稱.
3259
					$conf["fileAccess::getExtension"]["file"]=$vdisk;
3260
					#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3261
					$conf["fileAccess::getExtension"]["fileArgu"]=$conf["fileArgu"];
3262
					$getExtension=fileAccess::getExtension($conf["fileAccess::getExtension"]);
3263
					unset($conf["fileAccess::getExtension"]);
3264
 
3265
					#如果執行失敗
3266
					if($getExtension["status"]==="false"){
3267
 
3268
						#設置執行失敗
3269
						$result["status"]="false";
3270
 
3271
						#設置執行失敗訊息
3272
						$result["error"]=$getExtension;
3273
 
3274
						#回傳結果
3275
						return $result;
3276
 
3277
						}#if end
3278
 
3279
					#轉換好的檔案名稱
3280
					$refreVdisk=$getExtension["path"].$getExtension["name"]."-refreshed.".$getExtension["content"];
3281
 
3282
					#轉換與壓縮虛擬硬碟
3283
					#涵式說明:
3284
					#呼叫shell執行系統命令,並取得回傳的內容.
3285
					#回傳的結果:
3286
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3287
					#$result["error"],錯誤訊息陣列.
3288
					#$result["function"],當前執行的函數名稱.
3289
					#$result["argu"],使用的參數.
3290
					#$result["cmd"],執行的指令內容.
3291
					#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
3292
					#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
3293
					#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
3294
					#$result["running"],是否還在執行.
3295
					#$result["pid"],pid
3296
					#必填的參數
3297
					#$conf["command"],字串,要執行的指令與.
3298
					$conf["external::callShell"]["command"]="qemu-img";
3299
					#$conf["fileArgu"],字串,變數__FILE__的內容.
3300
					$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
3301
					#可省略參數:
3302
					#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
3303
					$conf["external::callShell"]["argu"]=array("convert","-c","-f","qcow2","-O","qcow2",$vdisk,$refreVdisk);
3304
					#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
3305
					#$conf["arguIsAddr"]=array();
3306
					#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
3307
					#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
3308
					#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
3309
					#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
3310
					$conf["external::callShell"]["enablePrintDescription"]="true";
3311
					#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
3312
					#$conf["external::callShell"]["printDescription"]="";
3313
					#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
3314
					$conf["external::callShell"]["escapeshellarg"]="true";
3315
					#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
3316
					#$conf["username"]="";
3317
					#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
3318
					#$conf["password"]="";
3319
					#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
3320
					#$conf["useScript"]="";
3321
					#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
3322
					#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
3323
					#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
3324
					#$conf["inBackGround"]="";
3325
					#備註:
3326
					#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
3327
					#參考資料:
3328
					#exec=>http://php.net/manual/en/function.exec.php
3329
					#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
3330
					#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
3331
					$callShell=external::callShell($conf["external::callShell"]);
3332
					unset($conf["external::callShell"]);
3333
 
3334
					#如果執行失敗
3335
					if($callShell["status"]==="false"){
3336
 
3337
						#設置執行失敗
3338
						$result["status"]="false";
3339
 
3340
						#設置執行失敗訊息
3341
						$result["error"]=$callShell;
3342
 
3343
						#回傳結果
3344
						return $result;
3345
 
3346
						}#if end
3347
 
3348
					#取代舊的虛擬硬碟
3349
					#涵式說明:
3350
					#移動檔案
3351
					#回傳結果:
3352
					#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3353
					#$result["function"],當前執行的函數名稱
3354
					#$result["error"],錯誤訊息.
3355
					#$result["content"],檔案輸出後的位置與名稱.
3356
					#必填參數:
3357
					#$conf["from"],字串,要移動的檔案名稱與位置.
3358
					$conf["fileAccess::mv"]["from"]=$refreVdisk;
3359
					#$conf["to"],字串,要移動到的位置與名稱
3360
					$conf["fileAccess::mv"]["to"]=$vdisk;
3361
					#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3362
					$conf["fileAccess::mv"]["fileArgu"]=$conf["fileArgu"];
3363
					#可省略參數:
3364
					#$conf["commentsArray"],字串陣列,提示的文字描述,$conf["commentsArray"][$i]代表第($+1)行的描述.
3365
					#$conf["commentsArray"]=array("");
3366
					$mv=fileAccess::mv($conf["fileAccess::mv"]);
3367
					unset($conf["fileAccess::mv"]);
3368
 
3369
					#如果執行失敗
3370
					if($mv["status"]==="false"){
3371
 
3372
						#設置執行失敗
3373
						$result["status"]="false";
3374
 
3375
						#設置執行失敗訊息
3376
						$result["error"]=$mv;
3377
 
3378
						#回傳結果
3379
						return $result;
3380
 
3381
						}#if end
3382
 
3383
					#記錄轉換好的檔案
3384
					$result["content"][]=$vdisk;
3385
 
3386
					}#foreach end
3387
 
3388
				#初始化儲存要印出的內容
3389
				$line2print=array();
3390
 
3391
				#提示內容標題
3392
				$line2print[]="以下檔案已轉換完畢:";
3393
 
3394
				#依照找到的數目
3395
				foreach($result["content"] as $qcow2ImgFile){
3396
 
3397
					#記錄檔案
3398
					$line2print[]=$qcow2ImgFile;
3399
 
3400
					}#foreach end
3401
 
3402
				#提示找到以下檔案可以進行整理
3403
				#函式說明:
3404
				#印出多行文字,結尾自動換行.
3405
				#回傳的結果:
3406
				#$result["status"],執行是否成功,"true"代表成功,"false"代表失敗.
3407
				#$result["function"],當前執行的函數名稱.
3408
				#$result["error"],錯誤訊息陣列.
3409
				#必填的參數:
3410
				#$conf["outputStringArray"],字串陣列,每行要印出的文字內容.
3411
				$conf["cmd::echoMultiLine"]["outputStringArray"]=$line2print;
3412
				$echoMultiLine=cmd::echoMultiLine($conf["cmd::echoMultiLine"]);
3413
				unset($conf["cmd::echoMultiLine"]);
3414
 
3415
				#如果執行失敗
3416
				if($echoMultiLine["status"]==="false"){
3417
 
3418
					#設置執行失敗
3419
					$result["status"]="false";
3420
 
3421
					#設置執行失敗訊息
3422
					$result["error"]=$echoMultiLine;
3423
 
3424
					#回傳結果
3425
					return $result;
3426
 
3427
					}#if end
3428
 
3429
				}#if end
3430
 
3431
			}#if end
3432
 
3433
		#反之沒有符合的檔案
3434
		else{
3435
 
3436
			#設置執行失敗
3437
			$result["status"]="false";
3438
 
3439
			#設置執行失敗訊息
3440
			$result["error"]=$findFile;
3441
 
3442
			#回傳結果
3443
			return $result;
3444
 
3445
			}#else end
3446
 
3447
		#設置執行正常
3448
		$result["status"]="true";
3449
 
3450
		#回傳結果
3451
		return $result;
3452
 
3453
		}#function imgConvert end
3454
 
3455
	/*
3456
	#涵式說明:
3457
	#取得虛擬硬碟的資訊與檢查是否被使用中
3458
	#回傳結果:
3459
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3460
	#$result["error"],錯誤訊息.
3461
	#$result["function"],當前執行的函數名稱.
3462
	#$result["argu"],所使用的參數.
3463
	#$result["used"],是否被使用中,"true"代表有;"false"代表沒有.
3464
	#$result["image"],虛擬硬碟的路徑與名稱.
3465
	#$result["file format"],虛擬硬碟的格式.
3466
	#$result["virtual size"],虛擬硬碟實際可以儲存的最大容量.
3467
	#$result["disk size"],虛擬硬碟檔案所佔的大小.
3468
	#$result["cluster_size"],佔用空間的最小單位.
3469
	#必填參數:
3470
	#$conf["img"],字串,虛擬硬碟檔案的路徑與名稱.
3471
	#$conf["img"]="";
3472
	#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3473
	#$conf["fileArgu"]=__FILE__;
3474
	*/
3475
	public static function imgInfo(&$conf=array()){
3476
 
3477
		#初始化要回傳的結果
3478
		$result=array();
3479
 
3480
		#取得當前執行的函數名稱
3481
		$result["function"]=__FUNCTION__;
3482
 
3483
		#如果沒有參數
3484
		if(func_num_args()==0){
3485
 
3486
			#設置執行失敗
3487
			$result["status"]="false";
3488
 
3489
			#設置執行錯誤訊息
3490
			$result["error"]="函數".$result["function"]."需要參數";
3491
 
3492
			#回傳結果
3493
			return $result;
3494
 
3495
			}#if end
3496
 
3497
		#涵式說明:
3498
		#判斷當前環境為web還是cmd
3499
		#回傳結果:
3500
		#$result,"web"或"cmd"
3501
		if(csInformation::getEnv()==="web"){
3502
 
3503
			#設置執行失敗
3504
			$result["status"]="false";
3505
 
3506
			#設置執行錯誤訊息
3507
			$result["error"][]="函數 ".$result["function"]." 僅能在命令列環境下運行!";
3508
 
3509
			#回傳結果
3510
			return $result;
3511
 
3512
			}#if end
3513
 
3514
		#取得參數
3515
		$result["argu"]=$conf;
3516
 
3517
		#如果 $conf 不為陣列
3518
		if(gettype($conf)!=="array"){
3519
 
3520
			#設置執行失敗
3521
			$result["status"]="false";
3522
 
3523
			#設置執行錯誤訊息
3524
			$result["error"][]="\$conf變數須為陣列形態";
3525
 
3526
			#如果傳入的參數為 null
3527
			if($conf===null){
3528
 
3529
				#設置執行錯誤訊息
3530
				$result["error"][]="\$conf變數不得為null,請檢查函數「".$result["function"]."」的參數設置有無正確!";
3531
 
3532
				}#if end
3533
 
3534
			#回傳結果
3535
			return $result;
3536
 
3537
			}#if end
3538
 
3539
		#函式說明:
3540
		#檢查必填與可省略的參數,可省略參數可指定預設要給與什麼數值內容。
3541
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3542
		#$reuslt["error"],執行不正常結束的錯訊息陣列.
3543
		#$result["function"],當前執行的函式名稱.
3544
		#$result["argu"],設置給予的參數.
3545
		#$result["passed"],識別要檢查的全體變數是否存在以及型態是否正確的變數,"true"代表檢查全部通過;"false"代表檢查不通過
3546
		#$result[$shouldBeCheckedVarName]["varExist"],所檢查的變數是否存在,"false"代表不存在;"true"代表存在
3547
		#$result[$shouldBeCheckedVarName]["varType"],所檢查的變數型態是否正確,"false"代表錯誤;"true"代表正確
3548
		#$result[$shouldBeCheckedVarName]["error"],每個參數設定的錯誤訊息
3549
		#$result["shouldNotBeEmpty"],不應該為空字串或控陣列的變數.
3550
		#$result["argu"],字串陣列,目前輸入的參數名稱陣列.
3551
		#$result["legalVarName"],字串陣列,合法可用的參數名稱陣列.
3552
		#$result["notNeedVar"],字串陣列,多餘的參數名稱.
3553
		#必填寫的參數:
3554
		#$conf["varInput"],陣列變數,要檢查的陣列變數,請在要檢查的參數前面加上&,這樣變動的結果才能被套用。
3555
		$conf["variableCheck::checkArguments"]["varInput"]=&$conf;
3556
		#$conf["referenceVarKey"],字串,$conf參數後面的key值,用於移除不要的參考陣列.
3557
		$conf["variableCheck::checkArguments"]["referenceVarKey"]="variableCheck::checkArguments";
3558
		#可以省略的參數:
3559
		#$conf["mustBeFilledVariableName"],爲必填參數的變數名稱陣列,形態爲陣列變數,元素數量需要跟"mustBeFilledVariableType"參數的元素數量一致,例如: $conf["mustBeFilledVariableName"] = array("id","account","password");
3560
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableName"]=array("img","fileArgu");
3561
		#$conf["mustBeFilledVariableType"],爲必填參數的變數陣列應該爲何種變數形態,形態爲陣列,元素數量需要跟"mustBeFilledVariableName"參數的元素數量一致,例如: $conf["mustBeFilledVariableType"] = array("string",integer,"double","resource","object"); , null代表不指定變數形態.
3562
		$conf["variableCheck::checkArguments"]["mustBeFilledVariableType"]=array("string","string");
3563
		#$conf["canBeEmptyString"],字串,必填變數內容如果是空字串就不能算是有設置的話,請設為"false",預設爲"true",可以為空字串.
3564
		$conf["variableCheck::checkArguments"]["canBeEmptyString"]="false";
3565
		#$conf["canNotBeEmpty"],字串陣列,哪些必填參數的內容不得為空字串或空陣列,僅當$conf["canBeEmptyString"]為"true"時會生效.
3566
		#$conf["canNotBeEmpty"]=array();
3567
		#$conf["canBeEmpty"],字串陣列,哪些必填參數的內容可為空字串或空陣列,僅當$conf["canBeEmptyString"]為"false"時會生效.
3568
		#$conf["canBeEmpty"]=array();
3569
		#$conf["skipableVariableCanNotBeEmpty"],字串陣列,哪些可省略參數不可以為空字串或空陣列.
3570
		#$conf["skipableVariableCanNotBeEmpty"]=array();
3571
		#$conf["skipableVariableName"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableName"] = array("id","account","password");
3572
		#$conf["skipableVariableName"]=array();
3573
		#$conf["skipableVariableType"],陣列字串,爲可省略參數的變數名稱陣列,形態爲陣列變數,例如: $conf["skipableVariableType"] = array("string",integer,"double");
3574
		#$conf["skipableVariableType"]=array();
3575
		#$conf["skipableVarDefaultValue"],字串陣列,每個不存在的可省略變數要初始化為什麼,null與代表不指定,若預設值是參數之一,請將$conf["mustBeFilledVar"]改成"\$conf["\mustBeFilledVar\"]".
3576
		#$conf["skipableVarDefaultValue"]=array("");
3577
		#$conf["disallowAllSkipableVarIsEmpty"],字串,是否允許每個可省略參數都為空字串,預設為"true"允許,反之為"false".
3578
		#$conf["disallowAllSkipableVarIsEmpty"]="";
3579
		#$conf["disallowAllSkipableVarIsEmptyArray"],字串,是否允許每個可省略參數都為空陣列,預設為"true"允許,反之為"false".
3580
		#$conf["disallowAllSkipableVarIsEmptyArray"]="";
3581
		#$conf["arrayCountEqualCheck"],字串陣列,為檢查哪些陣列參數的元素數量要一樣,$conf["arrayCountEqualCheck"][$i]=array()為第$i組key為哪些的變數其元素數量要相等.
3582
		#$conf["arrayCountEqualCheck"][]=array();
3583
		#參考資料來源:
3584
		#array_keys=>http://php.net/manual/en/function.array-keys.php
3585
		$checkArguments=variableCheck::checkArguments($conf["variableCheck::checkArguments"]);
3586
		unset($conf["variableCheck::checkArguments"]);
3587
 
3588
		#如果檢查參數失敗
3589
		if($checkArguments["status"]==="false"){
3590
 
3591
			#設置執行失敗
3592
			$result["status"]="false";
3593
 
3594
			#設置執行失敗訊息
3595
			$result["error"]=$checkArguments;
3596
 
3597
			#回傳結果
3598
			return $result;
3599
 
3600
			}#if end
3601
 
3602
		#如果檢查參數不通過
3603
		if($checkArguments["passed"]==="false"){
3604
 
3605
			#設置執行失敗
3606
			$result["status"]="false";
3607
 
3608
			#設置執行失敗訊息
3609
			$result["error"]=$checkArguments;
3610
 
3611
			#回傳結果
3612
			return $result;
3613
 
3614
			}#if end
3615
 
3616
		#檢查檔案是否存在
3617
		#涵式說明:檢查多個檔案與資料夾是否存在.
3618
		#回傳的結果:
3619
		#$result["status"],執行正常與否,"true"代表正常,"false"代表不正常.
3620
		#$result["error"],錯誤訊息陣列.
3621
		#$resutl["function"],當前執行的涵式名稱.
3622
		#$result["argu"],使用的參數.
3623
		#$result["allExist"],所有檔案皆存在的識別,"true"代表皆存在,"false"代表沒有全部都存在.
3624
		#$result["varName"][$i],爲第$i個資料夾或檔案的路徑與名稱。
3625
		#$result["varNameFullPath"][$i],爲第$i個資料夾或檔案的完整檔案系統路徑與名稱,如果不存在則代表路徑是網址.
3626
		#$result["varNameWebPath"][$i],為第$i個資料夾或檔案的網址
3627
		#$result["varExist"][$i],爲第$i個資料夾或檔案是否存在,"true"代表存在,"false"代表不存在。
3628
		#必填參數:
3629
		#$conf["fileArray"],陣列字串,要檢查是否存在的檔案有哪些,須爲一維陣列數值。
3630
		$conf["fileAccess::checkMultiFileExist"]["fileArray"]=array($conf["img"]);
3631
		#$conf["fileArgu"],字串,php變數__FILE__的內容,亦即該檔案在檔案系統的絕對路徑
3632
		$conf["fileAccess::checkMultiFileExist"]["fileArgu"]=$conf["fileArgu"];
3633
		#可省略參數
3634
		#$conf["disableWebSearch"],"字串",是否取消「當檔案找不到時,改用catchWebContent類別的wget函數來檢查檔案是否存在於網路上」的功能,"false"不取消,若要取消該功能請設為"true",若抓到的內容為空字串則會視為檔案不存在,預設為"true".
3635
		#$conf["disableWebSearch"]="false";
3636
		#$conf["userDir"],字串,網頁是否置放於家目錄底下,"true"為是,"false"為不是,預設為"true".
3637
		#$conf["userDir"]="true";
3638
		#參考資料來源:
3639
		#http://php.net/manual/en/function.file-exists.php
3640
		#http://php.net/manual/en/control-structures.foreach.php
3641
		#備註:
3642
		#函數file_exists檢查的路徑為檔案系統的路徑
3643
		$checkMultiFileExist=fileAccess::checkMultiFileExist($conf["fileAccess::checkMultiFileExist"]);
3644
		unset($conf["fileAccess::checkMultiFileExist"]);
3645
 
3646
		#如果檢查檔案是否存在失敗
3647
		if($checkMultiFileExist["status"]==="false"){
3648
 
3649
			#設置執行失敗
3650
			$result["status"]="false";
3651
 
3652
			#設置執行失敗訊息
3653
			$result["error"]=$checkMultiFileExist;
3654
 
3655
			#回傳結果
3656
			return $result;
3657
 
3658
			}#if end
3659
 
3660
		#如果虛擬硬碟檔案不存在
3661
		if($checkMultiFileExist["allExist"]==="false"){
3662
 
3663
			#設置執行失敗
3664
			$result["status"]="false";
3665
 
3666
			#設置執行失敗訊息
3667
			$result["error"]=$checkMultiFileExist;
3668
 
3669
			#回傳結果
3670
			return $result;
3671
 
3672
			}#if end
3673
 
3674
		#用 qemu-img info 參數來檢查虛擬硬碟檔案是否被使用中
3675
		#涵式說明:
3676
		#呼叫shell執行系統命令,並取得回傳的內容.
3677
		#回傳的結果:
3678
		#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3679
		#$result["error"],錯誤訊息陣列.
3680
		#$result["function"],當前執行的函數名稱.
3681
		#$result["argu"],使用的參數.
3682
		#$result["cmd"],執行的指令內容.
3683
		#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
3684
		#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
3685
		#$result["tmpFileOutput"],儲存輸出的暫村檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
3686
		#$result["running"],是否還在執行.
3687
		#$result["pid"],pid
3688
		#必填的參數
3689
		#$conf["command"],字串,要執行的指令與.
3690
		$conf["external::callShell"]["command"]="qemu-img";
3691
		#$conf["fileArgu"],字串,變數__FILE__的內容.
3692
		$conf["external::callShell"]["fileArgu"]=$conf["fileArgu"];
3693
		#可省略參數:
3694
		#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
3695
		$conf["external::callShell"]["argu"]=array("info",$conf["img"],"2>&1");
3696
		#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
3697
		$conf["external::callShell"]["arguIsAddr"]=array("false","true","false");
3698
		#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
3699
		#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
3700
		#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
3701
		#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
3702
		#$conf["enablePrintDescription"]="true";
3703
		#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容.
3704
		#$conf["printDescription"]="";
3705
		#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
3706
		$conf["external::callShell"]["escapeshellarg"]="true";
3707
		#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
3708
		#$conf["username"]="";
3709
		#$conf["password"],字串,與$conf["username"]搭配的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
3710
		#$conf["password"]="";
3711
		#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
3712
		#$conf["useScript"]="";
3713
		#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
3714
		#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
3715
		#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
3716
		#$conf["inBackGround"]="";
3717
		#備註:
3718
		#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
3719
		#參考資料:
3720
		#exec=>http://php.net/manual/en/function.exec.php
3721
		#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
3722
		#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
3723
		$callShell=external::callShell($conf["external::callShell"]);
3724
		unset($conf["external::callShell"]);
3725
 
3726
		#設置檔案未被使用中
3727
		$result["used"]="false";
3728
 
3729
		#如果運行失敗
3730
		if($callShell["status"]==="false"){
3731
 
3732
			/*
3733
			#desc:
3734
			虛擬硬碟被使用中的範例輸入與輸出.
3735
			#input:
3736
			qemu-img info test.qocw2
3737
			#output:
3738
			qemu-img: Could not open 'test.qocw2': Failed to get shared "write" lock
3739
			Is another process using the image?
3740
			*/
3741
 
3742
			#如果輸出的內容為兩列
3743
			if(count($callShell["error"][1])===2){
3744
 
3745
				#如果輸出的內容為被使用中
3746
				if
3747
				(
3748
					strpos($callShell["error"][1][0],"qemu-img: Could not open '".$conf["img"]."': Failed to get shared \"write\" lock")===0
3749
					&&
3750
					strpos($callShell["error"][1][1],"Is another process using the image?")===0
3751
				){
3752
 
3753
					#設置檔案被使用中
3754
					$result["used"]="true";
3755
 
3756
					#設置執行正常
3757
					$result["status"]="true";
3758
 
3759
					#回傳結果
3760
					return $result;
3761
 
3762
					}#if end
3763
 
3764
				}#if end
3765
 
3766
			#設置執行失敗
3767
			$result["status"]="false";
3768
 
3769
			#設置執行失敗訊息
3770
			$result["error"]=$callShell;
3771
 
3772
			#回傳結果
3773
			return $result;
3774
 
3775
			}#if end
3776
 
3777
		/*
3778
		#desc:
3779
		虛擬硬碟沒被使用中的範例輸出.
3780
		image: win10-working-教育版.qcow2
3781
		file format: qcow2
3782
		virtual size: 100G (107374182400 bytes)
3783
		disk size: 73G
3784
		cluster_size: 65536
3785
		Format specific information:
3786
			compat: 1.1
3787
			lazy refcounts: false
3788
			refcount bits: 16
3789
			corrupt: false
3790
		*/
3791
 
3792
		#如果輸出大於6行
3793
		if( count($callShell["output"]) > 6 ){
3794
 
3795
			#針對每行輸出
3796
			foreach($callShell["output"] as $line){
3797
 
3798
				#涵式說明:
3799
				#將固定格式的字串分開,並回傳分開的結果。
3800
				#回傳結果:
3801
				#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
3802
				#$result["error"],錯誤訊息陣列
3803
				#$result["function"],當前執行的函數名稱.
3804
				#$result["oriStr"],要分割的原始字串內容
3805
				#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
3806
				#$result["dataCounts"],爲總共分成幾段
3807
				#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
3808
				#必填的參數:
3809
				$conf["stringProcess::spiltString"]["stringIn"]=$line;#要處理的字串。
3810
				$conf["stringProcess::spiltString"]["spiltSymbol"]=": ";#爲以哪個符號作爲分割
3811
				#可省略參數:
3812
				#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
3813
				$conf["stringProcess::spiltString"]["allowEmptyStr"]="false";
3814
				$spiltString=stringProcess::spiltString($conf["stringProcess::spiltString"]);
3815
				unset($conf["stringProcess::spiltString"]);
3816
 
3817
				#如果分割失敗
3818
				if($spiltString["status"]==="false"){
3819
 
3820
					#設置執行失敗
3821
					$result["status"]="false";
3822
 
3823
					#設置執行失敗訊息
3824
					$result["error"]=$spiltString;
3825
 
3826
					#回傳結果
3827
					return $result;
3828
 
3829
					}#if end
3830
 
3831
				#如果沒有找到分割的關鍵字
3832
				if($spiltString["found"]==="false" && $spiltString["dataCounts"]!==1){
3833
 
3834
					#設置執行失敗
3835
					$result["status"]="false";
3836
 
3837
					#設置執行失敗訊息
3838
					$result["error"]=$spiltString;
3839
 
3840
					#回傳結果
3841
					return $result;
3842
 
3843
					}#if end
3844
 
3845
				#如果沒有分割成兩分
3846
				if($spiltString["dataCounts"]!==2){
3847
 
3848
					#跳過
3849
					continue;
3850
 
3851
					}#if end
3852
 
3853
				#取得虛擬硬碟的資訊
3854
				$result[$spiltString["dataArray"][0]]=$spiltString["dataArray"][1];
3855
 
3856
				}#foreach end
3857
 
3858
			}#if end
3859
 
3860
		#取得虛擬硬碟的資訊
3861
		$result["content"]=$callShell["output"];
3862
 
3863
		#設置執行正常
3864
		$result["status"]="true";
3865
 
3866
		#回傳結果
3867
		return $result;
3868
 
3869
		}#function imgInfo end
3870
 
3871
	}#class qemu end
3872
 
3873
?>