블로그 이미지
항상웃자 애바른2

카테고리

분류 전체보기 (99)
사진 (4)
비공개 (0)
업무 (1)
자동차 (6)
개발 (23)
가족 (33)
모바일 (13)
Total
Today
Yesterday

달력

« » 2025.12
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

공지사항

최근에 올라온 글


http://localhost:7402/crx/de/js/CRX/util/Util.js


/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */

/**
 * The <code>CRX.utils.Util</code> library contains utility methods for CRXDE.
 * @static
 * @class CRX.utils.Util
 */

CRX.util.Util = function() {

    var lastAuthHeader = null;

	var connectionData = null;
	
    var globalDialogs = {};
    
    // private property
    var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    // private method for UTF-8 encoding
    var _utf8_encode = function (string) {
        string = string.replace(/\\r\\n/g,'\\n');
        var utftext = '';
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            } else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            } else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
        }
        return utftext;
    };
    
    var fileMap = {};

    var eventObject = new Ext.util.Observable();
    eventObject.addEvents("reinit");

    return {
        on : function(eventName, fn, scope, o) {
            eventObject.on(eventName, fn, scope, o);
        },

        /**
         * Evaluates and returns a string.
         * @param {String} param The string
         * @return The evaluated object
         * @type Object
         */
        eval: function(json) {
            try {
                return eval("(" + json + ")");
            } catch (e) {
                return null;
            }
        },

		/**
         * Returns the anchor part of the URL.
         * @static
         * @param {String} url The URL
         * @return {String} The anchor
         */
        getAnchor: function(url) {
            if (url.indexOf("#") != -1) {
                return url.substring(url.indexOf("#") + 1);
            }
        },
        
    	getURLParams: function(url) {
    	    url = url || window.location.search;
    	    url = url.split("?");
    	    if (url.length > 1) {
    	        return Ext.urlDecode(url[1]);
    	    }
    	    return {};
    	},

        /**
         * Returns the value of the cookie with the given name.
         * @static
         * @param {String} name The name of the cookie
         * @return {String} The value of the cookie
         */
        getCookie: function(name) {
            var cname = encodeURIComponent(name) + "=";
            var dc = document.cookie;
            if (dc.length > 0) {
                var begin = dc.indexOf(cname);
                if (begin != -1) {
                    begin += cname.length;
                    var end = dc.indexOf(";", begin);
                    if (end == -1) end = dc.length;
                    return decodeURIComponent(dc.substring(begin, end));
                }
            }
            return null;
        },

        /**
         * Sets the value of the cookie with the given name.
         * @static
         * @param {String} name The name of the cookie
         * @param {String} value The value of the cookie
         * @param {String} path (Optional) The server path the cookie applies to
         * @param {int} days (Optional) The number of days the cookie will live, 
		 *                              no value creates a session cookie, 0 removes
		 *                              the cookie
         * @param {String} domain (Optional) The server domain
         * @param {boolean} secure (Optional) <code>true</code> if the
         *        connection is secure, <code>false</code> otherwise
         * @return {String} The value of the cookie
         */
        setCookie: function(name, value, path, days, domain, secure) {
            if (days && (typeof(days) != "number")) days = 7;

            var date;
            if (days > 0) {
                date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            } else if (days == 0) {
				date = new Date(1970, 0, 1);
			}
            document.cookie = encodeURIComponent(name) + "=" +
                         encodeURIComponent(value) + "; " +
                         (date ? "expires=" + date.toGMTString() + "; " : "") +
                         (domain ? "domain=" + domain + "; " : "") +
                         (path ? "path=" + path : "") +
                         (secure ? "; secure" : "");
            return value;
        },

        // public method for encoding
        base64Encode: function (input) {
            var output = '';
            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
            var i = 0;
            input = _utf8_encode(input);
            while (i < input.length) {
                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);
                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;
                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }
                output = output +
                _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
                _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
            }
            return output;
        },
        
        reinit: function() {
            Ext.Ajax.request({
                url:CRX.Util.getContextPath() + "/de/init.jsp",
                success:function(response, options) {
                    connectionData = CRX.Util.eval(response.responseText);

                    eventObject.fireEvent("reinit", this);

                    if (CRX.NodetypeRegistry) {
                        // todo: probably the wrong place, use event listener
                        // reload node types
                        CRX.NodetypeRegistry.reload(function() {
                            var tree = Ext.getCmp(CRX.ide.TREE_ID);
                            tree.setWorkspace(CRX.Util.getWorkspace());
                        });
                    }
                }
            });
        },
        
        /**
         * Creates a new dialog or returns an existing dialog if there was already a dialog
         * created with the same xtype before.
         *
         * @param {String/Object} config either an xtype string or a full dialog config object
         * @param {Object} dialogs (optional) cache for dialogs; if omitted, a global cache will be used
         **/
        getDialog: function(config, dialogs) {
            dialogs = dialogs || globalDialogs;
            var type   = typeof config === "string" ? config : config.xtype;
            config = typeof config === "string" ? {xtype: type} : config;
            
            if (!dialogs[type]) {
                dialogs[type] = Ext.ComponentMgr.create(config);
            }
            return dialogs[type];
        },

		getLocalWorkspacePath: function(path) {
			var localPath = path.substr(path.indexOf(CRX.ide.JCR_ROOT_NAME) 
									+ CRX.ide.JCR_ROOT_NAME.length);
			if (localPath == "") {
				localPath = "/"; // it the root node
			}
			return decodeURIComponent(localPath);
		},
		
		convertToTreePath: function(path) {
			// encode path
	        var labels = path.split("/");
	        for (var i=0; i<labels.length; i++) {
	            labels[i] = encodeURIComponent(labels[i]);
	        }
	        path = labels.join("/");
			return "/" + CRX.Util.getWorkspace() + "/" + CRX.ide.JCR_ROOT_NAME + path;
		},
		
		setWorkspaceFromPath: function(path) {
            connectionData.workspace = path.substr(0, path.indexOf(CRX.ide.JCR_ROOT_NAME) - 1).substr(1);
		},
		
		setConnectionData: function(data) {
            connectionData = CRX.Util.eval(data);
        },

        getWorkspace: function() {
            return connectionData.workspace;
        },

        getWorkspaces: function() {
            return connectionData.workspaces;
        },

		getLaunchpadContextPath: function() {
            return connectionData.launchpadContextPath == "/" ? "" : connectionData.launchpadContextPath;
        },
        
		getSpiBaseUrl: function() {
			return CRX.Util.getContextPath() + "/server";
		},
		
		getSpiRootUrl: function() {
			return CRX.Util.getSpiBaseUrl() 
			        + "/" + CRX.Util.getWorkspace() 
			        + "/" + CRX.ide.JCR_ROOT_NAME;
		},
		
		getJcrVersion: function() {
			return connectionData.jcrVersion;
		},
		
		getContextPath: function() {
			return connectionData.contextPath;
		},

		getUserID: function() {
			return connectionData.userID;
		},
		
		getFileExtension: function(name) {
			name = name.replace(/^\s|\s$/g, ""); //trims string

			if (/\.\w+$/.test(name)) {
				if (name.match(/([^\/\\]+)\.(\w+)$/)) {
					return RegExp.$2;
				} 
			}
		},
		
		getDateAsISO8601: function(date) {
			return date.format("Y-m-d") + "T" + date.format("H:i:s.uP");
		},

		isFormatISO8601: function(date) {
			return Date.parseDate(date,"Y-m-dTH:i:s.uP") != undefined;
		},
		
		getErrorMsgFromXML: function(response) {
			var msgs, xmlDoc = response.responseXML;
			
			if (xmlDoc) {
				if (Ext.isGecko) {
					msgs = xmlDoc.getElementsByTagName("dcr:message");
					return msgs[0].textContent;
				} else {
					msgs = xmlDoc.getElementsByTagName("message");
					return msgs.item(0).textContent;
				}
			} else {
				return "Unknown error (Error Code: " + response.status + ")";
			}
		},
		
		openActionDialog: function() {
			var dialogId;
			var loadSelection;
			if (this.baseAction) {
				dialogId = this.baseAction.initialConfig.dialogId;
				loadSelection = this.baseAction.initialConfig.loadSelection;
			} else {
				dialogId = this.initialConfig.dialogId;
				loadSelection = this.initialConfig.loadSelection;
			}
			var tree = Ext.getCmp(CRX.ide.TREE_ID);
	    	var node = tree.getSelectionModel().getSelectedNode();
	    	if (node) {
				var dlg = CRX.Util.getDialog(dialogId);
				dlg.init(node);
				
				if (Ext.isFunction(dlg.reset)) {
					dlg.reset();
				}
				
				if (loadSelection) {
					var cb = function() {
						dlg.show();
					};
					if (!node.isLoaded()) {
						node.reload(cb);
					} else {
						cb.call();
					}
				} else {
					dlg.show();
				}
			}
		},
		
		validateNodeName: function(value) {
			var valid = true;
			
			var tree = Ext.getCmp(CRX.ide.TREE_ID);
			var selection = tree.getSelectionModel().getSelectedNode();
        	if (selection) {
				var node = selection.findChild("name", value);
				if (node) {
					if (CRX.State.isDeleted(node.getRealPath())) {
						valid = "A locally deleted node with the same name was detected. "
							+"Please save changes in order to create a new node with this name.";
					} else {
						valid = "A node with this name already exist";
					}
				}
			}
			return valid;
			
			// TODO validate name against child node definitions
		},
		
		createNode: function(name, text, type, parent, loader, atts, data) {
			var attr = loader.processAttributes({
				name:encodeURIComponent(name), text:text,
				primaryType:type
			}, type);
			
			var node = loader.createNode(attr);
			if (node) {
				parent.appendChild(node);

				var propDefs = CRX.NodetypeRegistry.getPropertyDefinitions([ 
					node.getPrimaryType() 
				]);

				if (!atts) {
					atts = {};
				}
				atts[CRX.util.JCR_PRIMARY_TYPE] = type;
				atts[":" + CRX.util.JCR_PRIMARY_TYPE] = CRX.util.NAME;

				var records = loader.createPropertyRecords(atts, propDefs);
				records.each(function(record) {
					if (record.get("name") == CRX.util.JCR_DATA) {
						record.set("type", CRX.util.BINARY);
						if (data) {
							record.set("value", data);
						}
					}
					record.markDirty(); // ugly hack to deal with property grid
				});
				node.addPropertyRecords(records);
				CRX.State.addTransientNode(node);
			}
			return node;
		},
		
		/**
		 * Recursive variant of Ext.applyIf(). The optional last param "r" is
		 * true/false (go recursive), or number (number of levels to go recursive);
		 * defaults to "true".
		 **/
        applyDefaults: function(o, c, r) {
            // default r to true
            r = (typeof r == "undefined") ? true : r;
            
            if (o && c) {
                for (var p in c) {
                    if (typeof o[p] == "undefined") {
                        o[p] = c[p];
                    } else if (typeof o[p] == "object" && r) {
                        if (typeof r == "number") {
                            r--;
                        }
                        CRX.Util.applyDefaults(o[p], c[p], r);
                    }
                }
            }
            return o;
        },
        
        /**
         * Requests the specified URL from the server using GET. The request
         * will be synchronous, unless a callback function is specified.
         * @static
         * @param {String} url The URL to request
         * @param {Function} callback (optional) The callback function which is
         *        called regardless of success or failure and is passed the following
         *        parameters:<ul>
         *        <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>
         *        <li><b>success</b> : Boolean<div class="sub-desc">True if the request succeeded.</div></li>
         *        <li><b>response</b> : Object<div class="sub-desc">The response object.</div></li>
         *        </ul>
         * @return {Mixed} The response object or, if the
         *         request is asynchronous, the transaction ID
         */
        httpGet: function(url, callback) {
            if (callback != undefined) {
                return Ext.Ajax.request({
                    url: url,
                    callback: callback
                });
            } else {
                var request = document.all ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
                try {
                    request.open("GET", url, false);
                    request.send(null);
                    return {
                        status: request.status,
                        body: request.responseText
                    };
                } catch (e) {
                    return null;
                }
            }
        },
        
        /**
         * Pre-caches file contents for {@link #loadFile()}.
         *
         * @param {String} path URL path to the file (without CRX.Util.getContentPath())
         * @param {String} content file contents to cache
         */
        storeFile: function(path, content) {
            fileMap[path] = content;
        },
        
        /**
         * Loads a server side file via Ajax and caches its contents internally.
         * To pre-populate the cache, for example in a single production js file,
         * {@link #storeFile()} can be used.
         *
         * @param {String} path URL path to the file (without CRX.Util.getContentPath(),
         *                      but with leading slash)
         * @param {Boolean} noCaching (optional) if true, the file will be fetched and not
         *                  cached; if it was pre-cached via {@link #storeFile()}
         *                  it will be removed from the cache. Useful for larger
         *                  files that are used one time only
         *
         * @return {String} the file contents or null if not found
         */
        loadFile: function(path, noCaching) {
    		if (fileMap[path] === undefined) {
    		    var response = CRX.Util.httpGet( CRX.Util.getContextPath() + path );
    		    if (response !== null && response.status == 200) {
    		        if (noCaching) {
    		            return response.body;
    		        }
    		        fileMap[path] = response.body;
    		        return fileMap[path];
    		    }
    		    return null;
    		} else {
    		    var content = fileMap[path];
    		    if (noCaching) {
    		        delete fileMap[path];
    		    }
    			return content;
    		}
    	},

        logout: function() {
            Ext.Ajax.request({
                url:CRX.Util.getContextPath() + "/de/logout.jsp",
                params: {
                },
                success:function(response, options) {
                    CRX.Util.setAuthHeader("");
                    CRX.Util.reinit();
                },
                failure:function(response, options) {
                }
            });
            return false;
        },

        isLoggedIn: function() {
            return connectionData && connectionData.userID && connectionData.userID != "anonymous";
        },

        getAuthHeader: function() {
            if (lastAuthHeader) {
                return lastAuthHeader;
            } else {
                if (window.name.indexOf("Basic ") == 0) {
                    return window.name;
                } else {
                    return null;
                }
            }
        },

        setAuthHeader: function(hdr) {
            window.name = lastAuthHeader = hdr;
        },


        login: function(username, password, workspace, opts) {
            Ext.Ajax.request({
                url:CRX.Util.getContextPath() + "/de/login.jsp",
                params: {
                    UserId: username,
                    Password: password,
                    Workspace: workspace,
                    _charset_: "utf-8",
                    ".token": ""
                },
                success:function(response, options) {
                    // TODO: check response if token-auth is supported.
                    var tokenLoginSupported = !!CRX.Util.getCookie("login-token");
                    if (!tokenLoginSupported) {
                        // store auth header
                        CRX.Util.setAuthHeader("Basic " + CRX.Util.base64Encode(username + ":" + password));
                        CRX.Util.setCookie("login-workspace", workspace, CRX.Util.getContextPath());
                    }
                    if (opts.success) {
                        opts.success(response, options);
                    }
                    CRX.Util.reinit();
                },
                failure:function(response, options) {
                    if (opts.failure) {
                        opts.failure(response, options);
                    }
                }
            });
            return false;
    	},

    	/**
    	 * Utility for updating a panel body's contents regardless whether the panel
    	 * is already rendered (ie. the body el is present) or not (ie. if called
    	 * right after the constructor).
    	 */
    	updatePanel: function(panel, html) {
    	    if (panel.body) {
    	        panel.body.update(html);
    	    } else {
    	        panel.html = html;
    	    }
    	},
    	
    	/**
    	 * Rendering bug utility that will re-set the current height of the
    	 * Ext element or component passed.
    	 */
    	updateHeight: function(el) {
    	    var h = el.getHeight();
    	    el.setHeight(h + 1);
    	    el.setHeight(h);
    	},

    	/**
    	 * Rendering bug utility that will re-set the current width of the
    	 * Ext element or component passed.
    	 */
    	updateWidth: function(el) {
    	    var w = el.getWidth();
    	    el.setWidth(w + 1);
    	    el.setWidth(w);
    	}
    };
}();


CRX.util.Mimetypes = function() {
    var mimetypes = {
		"css":"text/css",
		"html":"text/html",
		"js":"text/javascript",
		"ecma":"text/javascript",
		"txt":"text/plain",
		"xml":"text/xml",
		"json":"application/json",
		"java":"text/plain",
		"bnd":"text/plain",
		"esp":"text/plain",
		"jsp":"text/plain",
		"bmp":"image/bmp",
		"bmp":"image/bmp",
		"gif":"image/gif",
		"bmp":"image/bmp",
		"jpg":"image/jpeg",
		"jpeg":"image/jpeg",
		"bmp":"image/bmp",
		"png":"image/png",
		"tif":"image/tiff",
		"tiff":"image/tiff"
	};
    
    return {
        getMimetype: function(name) {
			var ext = CRX.Util.getFileExtension(name);
			if (mimetypes[ext]) {
				return mimetypes[ext];
			} else {
				return "application/octet-stream";
			}
		}
}; 
Posted by 애바른2
, |



출처: http://javastore.tistory.com/111

분들이 자바 웹 프로젝트를 진행할때 이클립스 IDE를 사용합니다. 물론 저도 그렇구요. 이클립스는 WTP라는 아주 훌륭한 플랫폼이 있어서 웹개발시에 작업하고 서버에 deploy하지 않고도 이클립스상에서 서버를 껐다 키고, 서버의 임시 deploy 디렉토리에 배포하여 빠르게 개발할수 있습니다.

하지만 Maven을 통해 프로젝트를 생성하면 바로 WTP를 사용할 수가 없습니다. 인터넷에 검색해보면 여러가지 적용방법이 있는데 그중 가장 간단한 방법인 이클립스의 m2eclipse plugin과 m2eclipse Extras plugin을 통해서 간단하게 WTP용 Maven 프로젝트를 생성해 보겠습니다.

전체적으로 3단계로 나눌수 있겠는데요.
첫째. 이클립스 플러그인인 m2eclipse 를 설치한다. 
(maven이 설치 되었다는 가정하에 진행하겠습니다.)
둘째. 이클립스 플러그인인 m2eclipse Extras 를 설치한다.
셋째. maven 프로젝트를 생성한다.

이정도 쯤으로 간단하게 WTP와 maven을 연동할수 있습니다.

그럼 지금부터 시작해 보도록 하겠습니다.

1. m2eclipse 플러그인을 설치합니다.
Help >> Install New Software >> Add버튼을 누르고 다음 url을 입력해 줍니다.
http://m2eclipse.sonatype.org/sites/m2e


위와 같이 Maven Integration for Eclipse를 선택하시고 Next >> Next >> I accept the terms of the license argreement 선택하시고 Finish 누르시면 설치가 시작됩니다.

2. m2eclipse Extras 플러그인을 설치합니다. 위와같이 Help >> Install New Software >> Add버튼을 누르고 다음 url을 입력해 줍니다.
http://m2eclipse.sonatype.org/sites/m2e-extras

위와 같이 Maven Integration for Eclipse Extras와 Maven Integration for Eclipse WTP를 선택하시고 설치하시면 됩니다.

위의 4개를 보두 선택하셔도 상관없지만 좀더 빠른 설치를 위해서 필요한것만 설치했습니다.

3. Maven Project를 생성합니다.
File >> New >> Other >> Maven >> Maven Project 를 선택합니다.
Use default Workspace location 을 선택하고 Next를 눌러줍니다.


다음 창에서 artifact Id가 maven-archetype-webapp를 선택합니다.

Group Id : 이 프로젝트를 구별하기 위한 일종의 ID입니다. 보통 package 와 똑같이 지정합니다.
Artifact Id : Project 이름입니다.
Package : 프로젝트에서 사용할 package이름입니다.

위와 같이 프로젝트를 생성하면 Dynamic Web Project가 생성됩니다.

지금부터 약간의 설정을 해야합니다.

새로 만들어진 프로젝트를 선택한후 오른쪽 마우스 클릭 >> Properties >> Project Facets를 선택합니다.
이곳에서 바꾸어야 할것은 3가지 입니다.

1. Dynamic Web Module의 버전
2. Dynamic Web Project의 Webroot 위치
3. Java 버전 변경
입니다.

먼저 첫번째를 수정하려면 다음과 같이 진행해야 합니다.
Dynamic Web Module의 체크를 풀어준다 >> Apply 버튼을 누른다 >> Dynamic Web Module을 Version을 알맞게 변경한다.(저는 참고로 2.5로 변경하겠습니다.) >> Dynamic WebModule의 체크를 다시 한다 

두번째 webroot의 위치를 변경하겠습니다.
위사진의 (3번)을 선택한다. >> 다음창에서 Context root는 프로젝트 이름으로(기본적으로 프로젝트 이름이고 바꾸고 싶은것으로 바꾸어도 됩니다. 하지만 전 default로 두겠습니다.) 설정하고 directory는 /src/main/webapp 로 세팅합니다.

이렇게 세팅하면 기존의 Dynamic Web Project의 webroot가 WebContent에서 /src/main/webapp로 변경됩니다.

세번째 Java Version을 변경합니다. 저는 1.6 버전을 사용할 것이기 때문에 1.6으로 선택하고 OK를 누르겠습니다.


이렇게 세팅하고 OK를 눌러 빠져나옵니다. 만약 위와같이 설정한뒤 프로젝트에 에러가 발생하면 아마 거의 대부분은 위에서 설정한 Java버전과 Build Path의 java버전과 맞지 않았을때 에러가 날것입니다. 당연히 Build Path의 자바 버전도 변경해 주면 에러는 없어집니다.

기본적인 설정은 여기 까지입니다. 하지만 메이븐을 많이 사용하신 분들이라면 뭔가 이상함을 느끼실 겁니다.

패키지 이름이 이상합니다..ㅜㅜ

보통 메이븐은 4가지 정도로 분리가 됩니다.
1) src/main/java --> back end를 구성할 java 파일을 작성합니다.
2) src/main/resources --> 프로젝트의 설정파일을 저장합니다.
3) src/test/java --> 테스트를 하기위한 테스트 케이스를 작성합니다.
4) src/test/resources --> 테스트를 하기위한 설정파일을 작성합니다.

이렇게 4가지가 있어야 하는데 지금은 src/main/resources 밖에 없습니다.
그렇다면 직접 만들어 주는 수밖에 없겠네요..

탐색기를 통해 해당 웹프로젝트 디렉토리로 이동합니다.
다음과 같은 디렉토리를 만듭니다.

1) src/main/java
2) src/test 생성후
               /java
              /resources

이런 구조로 만들어 주시면 됩니다.

그리고 이클립스로 돌아오셔서 상단의 Navigator를 선택하시면 다음과 같은 구조를 보실수 있습니다.
(Navigator가 없으시면 Window >> Show View >> Navigator 를 선택하시면 됩니다)

이중에 수정해야 할 파일은 2가지 입니다.
.settings/org.eclipse.wst.common.component

.classpath 파일입니다.

먼저 .settings/org.eclipse.wst.common.component를 열고 다음을 추가합니다.

더보기


빨간 3줄을 추가해 줍니다.

다음으로 .classpath입니다.

더보기


위의 3줄을 추가해주고 그 아래 한줄을 수정해 줍니다.

이로서 maven + WTP의 통합 과정이 끝났습니다. 이제 불편하게 maven package를 만들어서 테스트 서버에 배포할 필요없이 바로 사용할 수 있습니다.
Posted by 애바른2
, |

콩까기

카테고리 없음 / 2011. 5. 31. 17:57
Posted by 애바른2
, |

이부분이 많은분들이 궁금해하시는 부분의 해답이라고 할수있습니다.
앱들중에 수정시이 필요한 부분이 있을때 decrypt작업을 끝낸후 간단하게 한두코드만 수정하면 마무리가 됩니다.
일단 crypt되어있는 앱을 수정하기 위해서 decrypt시켜야하는것이 제일 중요한 부분이죠.
crypt되어있는 앱실행화일을 아무리 수정하여도 원하는 답을 얻지는 못합니다.
자~ 그럼 시작해 볼까요~

먼저 준비를 챙겨보겠습니다.
OSX용 HEX편집기입니다. 일반적으로 인터넷에 나와있는 강좌는 Windows용 UltraEdit를 사용하죠. ^^ 이왕이면 간편하고 다루기편한 OSX용 편집기를 다루겠습니다.
0xED.zip

그리고 전강좌에서 만들었던 dump.bin과 HancomViewer실행화일을 준비합니다.
참고로 HancomViewer를 사용하는 이윤~ 그냥 decrypt하는 방법을 설명하는 예로 들기위함입니다.
전혀 원앱의 기능상..변화와 문제를 주지는 않습니다.
오픈하기전에 화일비교를 체크하기 위해 HancomViewer를 HancomViewer.XXX 로 하나 백업해두시기 바랍니다.

두 파일을 0xED로 오픈합니다. 그냥 두개를 한꺼번에 드래그드롭 시키면 되겠죠.
그럼 다음과 같이 창이 2개 뜰껍니다.
여기서 제일 중요한것이 있습니다.
왼쪽편이 6자리의 숫자는 16진수로된 주소창이고..오른쪽편 4단으로된 2자리씩 4개는 16진수로된 데이타값입니다.
마우스로 왼쪽하단의 창조절를 드래그하여 오른쪽을 꼭 그림과 같이 4단으로 만들어주세요~ 꼭~ ^^ 그래야 편합니다.
또 중요한것은 창하단에 보시면 왼쪽에서 3번째 Overwrite가 보일껍니다. 들여쓰기 상태를 보여주는 겁니다.
Insert로 되어 있다면 마우스로 더블클릭하셔서 Overwrite로 만들어 주세요~ 중요합니다.
..
먼저 dump.bin 데이타를 몽땅 카피합니다.
카피하기전에 dump.bin의 마지막주소값을 기억해야 합니다.

오른쪽을 스크롤을 맨하단까지~ 쭈욱~ 내립니다.
그리고 왼쪽의 6자리 16진수값을 메모해 둡니다.
629FF0
메모후 Cmd + a (전체선택)을 하신후에 Cmd + c (베껴두기)를 하세요.

이젠 crypt되어있는 HancomViewer화일을 decrypt하기 위해 방금카피한 dump.bin데이타값을 덮어씌웁니다.
덮어씌우기란 Insert가 아닌 Overwrite로 해야겠죠.
하지만 정확하게 그만큼을 덮어씌우기 위해 영역을 설정해야 합니다.
영역은..
001000 ~ dump.bin(데이타길이)입니다.
dump.bin데이타 길이는 아까 메모해둔 629FF0이겠죠.
이것을 그대로 대입하면 안됩니다.
001000부터 629FF0만큼의 데이타이기 때문에 629FF0 + 1000이 정확한 dump.bin데이타가 덮어씌어질 마지막주소자리입니다.
001000의 1000은 10진수가 아닌 16진수값입니다.
자~ 그럼 저번 강좌에서 사용했던 계산기(프로그래머모드)를 사용해 볼까요?


+ 1000을 대입합니다.
0x62AFF0이란 값이 나옵니다.
crypt된 HancomViewer를 decrypt하기 위해 dump.bin를 덮어씌어야할 영역은 0x001000 ~ 0x62AFF0이 됩니다.
그럼 HancomViewer창에서 영역을 선택해 볼까요.

001000 ~ 62AFF0까지 선택부분을 편집해서 그림으로 표현했습니다.
선택하기 쉬운방법을 알려드리죠~
오른쪽 상단에 있는 Go to Offset부분에 1000값을 입력합니다.
그럼 1000주소로 커서가 이동합니다.

이동된 부분 F에서 마우스로 1까지 클릭하며 드래그를 합니다. 그럼 F1이 블록이 씌워집니다.

이상태에서 다시 오픈쪽상단의 Go to Offset에 가셔서 62AFF0값을 입력합니다.

위의 그림과 같이 이동합니다.
여기서 조심스럽게 Shift키를 누른채~ 62AFF0주소줄의 맨끝에 마우스를 클릭합니다.

62AFF0까지라면 8B에서 끝나야 하지만..여기서 0x000000까지라는것은 그 주소의 라인의 전체를 이야기하는겁니다.
이젠 dump.bin데이타가 덮어씌어질 영역이 설정이 되었습니다.
그럼 이젠 붙이기를 해야합니다.
Cmd + v 하시면됩니다.
제대로 실행이 되었다면..
다음과 같이 보일껍니다.

데이타가 정상적으로 덮어씌어졌는지를 체크하기 위해서..
일단 저장을 하세요.
그리고 처음에 백업해놓았던 화일과 비교를 해보세요.

그림과 같이 1바이트도 차이가 나지않았야 합니다.
^^
제일 중요한 고비를 넘겼습니다.
이젠 데이타값~ 하나만 고치면 끝납니다.
cryptid값을 수정하는 겁니다. 현재 1로 되어있는 상태죠.
하지만 지금까지 한 작업은 decrypt를 한것이기 때문에 cryptid값은 0으로 수정이 되어야 앱이 실행 제대로 됩니다.
이 부분이 좀 난감한데~ ^^ 해외사이트나 국내사이트에도 딱히 명확한 주소를 가리키지 못하고 있습니다.
눈대중으로 찾아야하죠.
일단 Go to Offset에 800값을 입력하여 이동합니다.

윗부분 /lib/dyld... 과 아랫부분 T.../.../System/Library.. 사이에 존재합니다.
01 00 00 00 의 형태로~ 밑에 T부분에 가까운 주소에 있습니다.

마우스로 01의 0부분에 클릭하시고 0을 입력하세요. 여기서 잊지 말아야할것은 상태가 Insert인지 Overwrite인지 입니다. Insert로 되어 있으면 데이타가 밀리기 때문에 오류가 생깁니다.
혹 실수로 Insert상에서 0을 입력하셨다면..바로 윈도우상단에 화살표 < Undo를 실행하셔서 그전 작업상태로 전환하시고..Insert를 더블클릭하여 Overwrite로 전환하신다음에..
01의 0위치에서 0을 입력하세요~

^^
자~ 이제 다 끝났습니다.
처음에 말씀드렸다시피..dump.bin를 덮어씌어 crypt상태의 화일을 decrypt로 변경한 작업입니다.
저장하시고~
마지막 마무리는 iFile로 실행될수있도록 파일속성을 만들어주는겁니다.
작업과정을 거쳐서 파일의 속성이 변경되어 있는 상태이기 때문입니다.
파일을 iPhone으로 보내는 방법은 전강좌에서 iFile로 했듯이 해당 디렉토리로 가서 /HancomViewer.app/ <- 실홰화일이 있는 디렉토리..Wifi를 실행시켜 PC에서 브로우져로 접속 파일을 업로드하면 됩니다.
아니면 DiskAid나 PhoneView나 Transmit로도 괜찮고요.
파일이 카피되었다면..
이젠 iPhone에서 iFile을 실행 시킵니다.
그리고 HancomViewer.app/ <- 디렉토리로 이동합니다.

HancomViewer 오른쪽 > 를 클릭한다.


하단부분에 보면 소유권과 접근권한 정보가 보인다.
Owner를 mobile로 변경.
User, Group, World에 Execute속성을 추가한다.

이제 오른쪽 상단에 있는 Done 버튼을 클릭하면 마무리가 된다.

한번 실행을 시켜보자.

아무문제없이~ 실행이 잘됩니다.
^^
decrypt가 완벽하게 되었습니다.

이 상태에서 데이타변경을 하면 됩니다.
만약에 인터넷에서 설명되어있는 변경 주소가..
0x5436 1D ED > 2E E2으로 변경해야 한다면..
실제로는 0x1000을 뺀 주소를 적용해야 합니다.
0x4436 같은 16진수이기 때문에 그냥 빼면되죠.
..
이상입니다.
지금의 과정을 그대로 적용시키면 다른 관련 수정도 해결이 될것이라 생각합니다.
Posted by 애바른2
, |

iPhone App의 암호화된 실행화일을 수정할 일이 생겼을때 1차적으로 해야할 작업은 iPhone App메모리 덤프화일을 만드는 작업을 해야합니다.
일단은 탈옥폰이어야 겠죠.
또한 Cydia의 GDB Debugger가 설치되어 있어야 합니다.(gdb, otool 실행이 필요합니다)
openSSH도 설치및 가동이 되어야 하고요.
beyouriphone이 사라져서 GDB Debugger를 구하기 어려우신분들은..
http://leejoshua.tistory.com/44 <- 이곳에 가시면 구하실수 있습니다.
PC에서 iPhone으로 ssh접속을 합니다.
터미널(Windows SecureCRT)
ssh -2 root@192.168.X.X
접속할때 password는 변경하신분도 계시겠지만..변경을 하지 않았다면 "alpine" 입니다.
왠만하면 변경을 하시는것이 좋을뜻합니다.
변경방법은..iPhone이 접속된 터미널에서 passwd 엔터치시면 패스워드 물어보고 새로운 패스워드 입력합니다.
root뿐만 아니라..기본 유저아이디 mobile도 변경을 해주시는것이 좋습니다.
터미널 상태에서
su mobile 엔터하시면 전환이 됩니다.
똑같이
passwd 엔터하셔서..변경후에..
exit 엔터하시면 root로 돌아옵니다.
자~ 이제 gdb유뮤확인을 해시죠. 

NUTTone:~ root# gdb <- 터미널에서 "gdb"를 실행시켜본다.
GNU gdb 6.3.50.20050815-cvs (Sat Sep 19 05:37:57 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=arm-apple-darwin9 --target=".
(gdb)...

위와같이 gdb에 shell로 들어갑니다.
빠져 나올때는 quit로~

NUTTone:~ root# otool <- "otool"를 실행시켜본다.
Usage: otool [-fahlLDtdorSTMRIHvVcXm] <object file> ...
-f print the fat headers
-a print the archive header
-h print the mach header
-l print the load commands
-L print shared libraries used
-D print shared library id name
-t print the text section (disassemble with -v)
-p <routine name>  start dissassemble from routine name
-s <segname> <sectname> print contents of section
-d print the data section
-o print the Objective-C segment
-r print the relocation entries
-S print the table of contents of a library
-T print the table of contents of a dynamic shared library
-M print the module table of a dynamic shared library
-R print the reference table of a dynamic shared library
-I print the indirect symbol table
-H print the two-level hints table
-v print verbosely (symbolicly) when possible
-V print disassembled operands symbolicly
-c print argument strings of a core file
-X print no leading addresses or headers
-m don't use archive(member) syntax
-B force Thumb disassembly (ARM objects only)

이제 덤프메모리를 만들준비는 끝났습니다.

수정할 App이 있는 디렉토리를 찾아야 합니다~
방법은 두가지가 있습니다.
SBSetting, iFile를 이용하는 방법이죠.
먼저 SBSetting을 이용한 방법입니다.

Image Hosted by ImageShack.us
설정아이콘을 클릭합니다.

Image Hosted by ImageShack.us
맨 하단에 있는 App Folders를 클릭.

Image Hosted by ImageShack.us
앱들 리스트가 뜹니다. 그중에서 덤프화일을 만들 앱을 선택하여 클릭하면.

Image Hosted by ImageShack.us
위의 그림과 같이 디렉토리 정보가 뜹니다.
뒷부분에 코드화되어있는것을 메모해 두십시요.

이번에는 iFile을 이용한 디렉토리정보를 얻어보겠습니다.
Image Hosted by ImageShack.us
먼저 왼쪽하단에 있는 설정아이콘을 클릭합니다.

Image Hosted by ImageShack.us
Application Names부분을 체크합니다.
이 부분을 체크하면 코드화되어있는 앱디렉토리로 보이지 않고 원래 앱이름으로 순차적으로 나열됩니다.

Image Hosted by ImageShack.us
이상태로도 앱디렉토리명을 볼수있고.
오른쪽 화살표아이콘을 클릭하시면. 좀더 자세한 정보를 얻을수있습니다.

Image Hosted by ImageShack.us
Name을 클릭하시면 선택하여 카피를 하실수있습니다.
절대 수정을 하시면 안됩니다.
실수를 하실수도 있으니 전단계에서 앱디렉토리정보를 메모해 두십시요.

자~ 이제 dump할 앱으로 이동해 봅시다.

NUTTone:~ root# cd /User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A/
NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# ls -l
total 32
drwxr-xr-x  4 mobile mobile   136 May  8 20:34 Documents/
drwxr-xr-x 12 mobile mobile   748 May  8 02:05 HancomViewer.app/
drwxr-xr-x  4 mobile mobile   136 May  8 02:06 Library/
-rwxr-xr-x  1 mobile mobile 22490 May  8 01:52 iTunesArtwork*
-rwxr-xr-x  1 mobile mobile  2210 May  8 01:52 iTunesMetadata.plist*
drwxr-xr-x  2 mobile mobile    68 May 10 12:25 tmp/
NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# 

HancomViewer.app/ <- 안에 HancomViewer 이란 실행화일이 있습니다.
그 안까지는 들어가지 마십시요.

NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# otool -l ./HancomViewer.app/HancomViewer | grep crypt
 cryptoff  4096
 cryptsize 6463488
 cryptid   1
NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# 

otool 명령어로 암호화된 화일크기를 구합니다.
중간에 cryptsize가 화일크기입니다. 이 값을 메모하십시요.

이제 memory dump를 본격적으로 시작해 봅니다.
이해하기 쉽게 설명을 드리자면~
화일이 암호화되어 있기때문에 화일자체로 dump를 뜨는것은 소용이 없습니다.
하지만 앱이 실행이 된후에는 memory상에 암호화가 풀려 상주하기 때문에 memory상에 있는 코드를 캡쳐해서 저장하는 방식입니다.
그래서 memory dump라고 이해하시면 되겠습니다.

먼저 아이폰에서 앱을 실행시킵니다.
제일 중요한것은 openSSH를 통해 PC와 계속 연결이 되어 있어야 합니다.
자동으로 슬림모드가 되는것을 꺼놓아야 끊기지 않고 유지가 잘됩니다.
혹시나 끊겼으면 다시 연결하시면 됩니다.

아이폰에서 앱을 실행시켰으면..
터미널에서..
다음과 같은 명령을 실행시킵니다.

NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# ps ax | grep HancomViewer

 1126   ??  Ss     0:01.32 /var/mobile/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A/HancomViewer.app/HancomViewer
NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# 

아이폰에서 실행중인 앱의 프로세스ID를 찾아주는겁니다.
1126번이 현재 아이폰에서 실행되는 앱의 프로세스ID입니다.

NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# gdb -p 1126
GNU gdb 6.3.50.20050815-cvs (Sat Sep 19 05:37:57 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=arm-apple-darwin9 --target=".
/private/var/mobile/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A/1126: No such file or directory
Attaching to process 1126.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............................................................................................ done
0x328c17f8 in mach_msg_trap ()
(gdb) 

프로세서아이디의 앱을 디버깅합니다.
메모리상에 상주하고 있는 앱을 gdb합니다.
gdb SHELL로 입장했습니다.
바로 dump하는 방법으로 넘어가겠습니다.

dump memory dump.bin 0x2000 {app total address}
memory dump해서 dump.bin이란 화일로 저장합니다. 저장되는곳은 앱폴더입니다.
메모리시작주소는 0x2000이고 제일 중요한 메모리끝주소는..아까 암호화된 앱화일크기로 계산해서 산출하면 됩니다.

계산방식은 cryptsize + 8192 = HEX전환
OSX에 기본적으로 있는 계산기를 이용해 보겠습니다.

Image Hosted by ImageShack.us
먼저 프로그래머 계산기로 전환합니다.

Image Hosted by ImageShack.us
프로그래머 16진수모드입니다.

Image Hosted by ImageShack.us
그림과 같이 8/10/16중에 10을 클릭하시면 10진수로 바뀝니다.
10진수모드가 되면~
cryptsize + 8192를 대입해서 계산하십시요.
6463488 + 8192 = 6471680
Image Hosted by ImageShack.us
위와같이 값이 나오며..10진수값을 16진수로 변환을 해야합니다.

Image Hosted by ImageShack.us
간단하게 16버튼을 클릭하면 전환이 됩니다.
0x62C000 <- 이것이 메모리덤프를 위한 끝주소입니다.
자 그럼 실행시켜보죠.

dump memory dump.bin 0x2000 0x62C000

아무런 메세지도 없습니다.

quit <- 엔터를 쳐서 빠져나옵니다.

NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# ls -l
total 6344
drwxr-xr-x  4 mobile mobile     136 May  8 20:34 Documents/
drwxr-xr-x 12 mobile mobile     748 May  8 02:05 HancomViewer.app/
drwxr-xr-x  4 mobile mobile     136 May  8 02:06 Library/
-rw-r--r--  1 root   mobile 6463488 May 31 17:46 dump.bin
-rwxr-xr-x  1 mobile mobile   22490 May  8 01:52 iTunesArtwork*
-rwxr-xr-x  1 mobile mobile    2210 May  8 01:52 iTunesMetadata.plist*
drwxr-xr-x  2 mobile mobile      68 May 10 12:25 tmp/
NUTTone:/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A root# 

빠져나와서 파일을 리스트해보면 위와같이 dump.bin이란 화일이 생성이 되었습니다.
dump.bin화일을 PC로 가져가면 memory dump 화일 생성은 끝입니다.

가져가는 방법은 여러가지 입니다.
iFile을 이용한 방법도 있고..DiskAid..PhoneView..Transmit..등등..
iFile를 이용한 방법을 설명하겠습니다.

Image Hosted by ImageShack.us
오른쪽 화일표아이콘을 클릭하지 마시고..그냥 "한컴뷰어"를 클릭하여 디렉토리로 이동합니다.

Image Hosted by ImageShack.us
이동하시면 dump.bin화일이 보일껍니다.
하단에 왼쪽편에 있는 Wifi아이콘을 클릭하세요~

Image Hosted by ImageShack.us
웹서버가 시동이 됩니다.
주소는 http://192.168.10.2:10000(집이나 회사의 사설네트워크의 주소에 따라 다르게나옴)

Image Hosted by ImageShack.us
앱디렉토리까지 이동을 한 상태입니다.
/User/Applications/249E009F-E7B4-4CCA-8F86-2A8773A3DE5A
이동하시면 리스트가 나오고..dump.bin을 그냥 클릭하시면 다운받을수 있습니다.



출처) http://samurai.tistory.com/31
Posted by 애바른2
, |

LSIⓡ1068E SAS는 centos 모든 버전에서 지원하지 않음. 별도의 드라이버를 설치해야 HDD가 인식됨.

- cmos, RAID구성을 raid 0으로 HDD설정 (이렇게 해야 드라이버 설치시 인식함)

현재 centos 5.5가 최신버전이나,
ftp://www.supermicro.com/driver/SAS/LSI/1064_1068/SR/Driver/Linux/v13.15.1218.2009/
이곳의 현재 최신버전은..
=> megasr-13.15.1218.2009-1-rhel50-u4-all.img
즉, centos 5.4까지의 드라이버만 존재한다.

* 설치방법
1. megasr-13.15.1218.2009-1-rhel50-u4-all.img => usb 에 복사
2. usb를 꼽고,설치CD 를 넣고, 설치선택 메뉴에서
   > linux dd
   라고 입력
.....
   usb꼽으면 /dev/sda 인식후, img파일을 선택하면 scsi 드라이버가 load됨
....
  이후 centos 5.4 설치하면 됨.

------------------------------------
주의사항
1. yum -y update <-를 하게되면, 커널까지 최신 5.5버전으로 바뀜, 이상태로 재부팅하면 
  hdd인식못하여 중간에 커널 오류발생!
 =>해결
  /boot/grub/grub.conf 편집, default 커널을 기존껄로 변경해주면됨^^ ex) default 1로 변경
 그외
 yum  -y update --exclude=kernel*   등으로 커널만 업데이트 제외하는 방법..
 

Posted by 애바른2
, |
Posted by 애바른2
, |

세연이

가족 / 2010. 4. 22. 15:17

Posted by 애바른2
, |

mylg070 이것저것!!

모바일 / 2010. 4. 15. 12:51


1. 진단코드 : *77* 통화
2. 기본프로파일 변경 : #*25533# 통화
3. 비밀번호초기화:
 => 다른곳에서 070번호로 전화=> 전화오면  통화 * 255340129# 통화 => 0000으로 초기화됨



 38400-N-8-1

serial cable로 연결하고, minicom 등으로 보면, booting 하는게 보입면, 전원켜도 아무키나 입력

uboot에서 다음 line을 입력하세요.

mw.l b0000090 4;mw.l 80002030 c48;setenv bootargs single ver=1.1.16-3 console=ttyS0,38400 quiet root=/dev/mtdblock4 ro rootfstype=jffs2;nand read.jffs2 400000 500000 200000;bootm;nand read.jffs2 400000 100000 200000;bootm;reset

single mode로 linux가 시작될 겁니다. prompt도 보이죠.
다음 문장들을 실행해서, runlevel 3의 상태와 같게(?) 만들고요,

$ /etc/rc.d/rc.sysinit
$ /etc/rc.d/rc.default
$ /etc/init.sh

root password를 변경합니다.

$ passwd

아. telnetd를 넣어볼까요?
/home/wlan.sh의 맨 마지막에

sleep 10; /bin/busybox telnetd &

을 넣습니다.
재부팅하면 끝.

이젠 serial cable 없이, 무선랜으로 telnet 접속 가능합니다.
아... telnet으로 접속하고 나서, Ctrl+D 함 눌러야 shell prompt가 뜰겁니다. 아마.

--------------------------------------
WPN-480,1.1.64이하, imtel 사용하기

*66546396753# + 통화 -> 1 myLG070 + 편집 -> 5 SIP 설정 + 확인
- User ID : *8xxxxxxx (imTel 가상번호) 혹은 로그인 ID
- Display Name : 임의대로 설정
- Authorrization Name : 로그인 ID
- Auth. Password : 로그인 패스워드
- SIP Domain : sip.imtel.com
- Proxy1 IP : 211.115.87.144 (ID에 따라 조금씩 틀릴 수도 있지만 문제 없을 듯)
- Proxy1 Port : 5060
- Proxy2 IP : 211.115.87.173 (ID에 따라 조금씩 틀릴 수도 있지만 문제 없을 듯)
- Proxy2 Port : 5060
- Registration Timer : 60
- Codec Preference : G.729 / PCMU / PCMA (안 만져도 별 문제 없을 지도)

=> *,#,0 3중하나는 .

1. '*77*'+통화 --- 진단 코드
2.' *66546396753#'+통화 --- 네트워크 설정
3. '*25533#'+통화 --- 시스템 설정
4. '*856178538#'+통화 --- S/W Upgrade
5. '*48325#'+통화 --- Engineer Mode

4, 5번 메뉴는 버전 1.1.64 보다 구 버전에서는 동작하지 않는다.

Posted by 애바른2
, |



httpd.conf 파일이나, .htaccess 파일을 이용해,

ErrorDocument command 로 오류 처리를 할 수 있다.

'ErrorDocument 404 /404.html'

만약, /404.html 은 동작안하고, http://도메인/404.html 은 동작할경우, 
404.html 파일 용량이 512k가 넘도록 만들어야 한다.

안그러면 성의없는 답변으로 explore 자체에서 무시해 버린다.

이 오류로 한참 찾았음....

Posted by 애바른2
, |