1 /*
2  * Created on 16 juin 2003
3  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16  *
17  */
18 package org.gudy.azureus2.core3.util;
19 
20 import java.io.InputStreamReader;
21 import java.io.LineNumberReader;
22 import java.nio.charset.Charset;
23 import java.security.AccessControlException;
24 import java.util.Locale;
25 import java.util.StringTokenizer;
26 import java.util.TimeZone;
27 import java.util.regex.Pattern;
28 
29 /**
30  *
31  * @author Olivier
32  *
33  */
34 
35 public class
36 Constants
37 {
38   public static final String EMPTY_STRING = "";
39   public static final String SF_WEB_SITE			= "http://plugins.vuze.com/";
40 
41   public static final String AELITIS_TORRENTS		= "http://cf1.vuze.com/torrent/torrents/";
42   public static final String AELITIS_FILES			= "http://cf1.vuze.com/torrent/files/";
43   public static final String AZUREUS_WIKI 			= "http://wiki.vuze.com/w/";
44 
45   public static final String  VERSION_SERVER_V4 	= "version.vuze.com";
46   public static final String  VERSION_SERVER_V6 	= "version6.vuze.com";
47 
48   public static final String DHT_SEED_ADDRESS_V4		= "dht.vuze.com";
49   public static final String DHT_SEED_ADDRESS_V6		= "dht6.vuze.com";
50   public static final String DHT_SEED_ADDRESS_V6_TUNNEL	= "dht6tunnel.vuze.com";
51 
52   public static final String NAT_TEST_SERVER		= "nettest.vuze.com";
53   public static final String NAT_TEST_SERVER_HTTP	= "http://nettest.vuze.com/";
54 
55   public static final String SPEED_TEST_SERVER		= "speedtest.vuze.com";
56 
57   public static final String PAIRING_URL			= "https://pair.vuze.com/pairing";
58 
59 
60   public static final String[] AZUREUS_DOMAINS = { "azureusplatform.com", "azureus.com", "aelitis.com", "vuze.com" };
61 
62   public static final String DEFAULT_ENCODING 	= "UTF8";
63   public static final String BYTE_ENCODING 		= "ISO-8859-1";
64   public static final Charset	BYTE_CHARSET;
65   public static final Charset	DEFAULT_CHARSET;
66 
67   public static final int	DEFAULT_INSTANCE_PORT	= 6880;
68   public static final int	INSTANCE_PORT;
69 
70   static{
71 	  String ip_str = System.getProperty( "azureus.instance.port", String.valueOf( DEFAULT_INSTANCE_PORT ));
72 
73 	  int	ip;
74 	  try{
75 		  ip = Integer.parseInt( ip_str );
76 	  }catch( Throwable e ){
77 		  ip = DEFAULT_INSTANCE_PORT;
78 	  }
79 
80 	  INSTANCE_PORT = ip;
81 
82 	  Charset	bc 	= null;
83 	  Charset	dc	= null;
84 
85 	  try{
86 	  	bc 	= Charset.forName( Constants.BYTE_ENCODING );
87 	 	dc	= Charset.forName( Constants.DEFAULT_ENCODING );
88 
89 	}catch( Throwable e ){
90 
91 		e.printStackTrace();
92 	}
93 
94   	BYTE_CHARSET 	= bc;
95   	DEFAULT_CHARSET	= dc;
96   }
97 
98   public static final Locale LOCALE_ENGLISH = new Locale("en", "");
99 
100   static{
101 	  try{
102 		  String	timezone = System.getProperty( "azureus.timezone", null );
103 
104 		  if ( timezone != null ){
105 
TimeZone.getTimeZone(timezone )106 			  TimeZone.setDefault( TimeZone.getTimeZone( timezone ));
107 		  }
108 		}catch( Throwable e ){
109 
110 				// can happen in applet
111 
112 			if ( e instanceof AccessControlException ){
113 
114 			}else{
115 
116 				e.printStackTrace();
117 			}
118 		}
119   }
120 
121   public static final String INFINITY_STRING	= "\u221E"; // "oo";pa
122   public static final int    CRAPPY_INFINITY_AS_INT  = 365*24*3600; // seconds (365days)
123   public static final long   CRAPPY_INFINITE_AS_LONG = 10000*365*24*3600; // seconds (10k years)
124 
125   public static boolean DOWNLOAD_SOURCES_PRETEND_COMPLETE	= false;
126 
127   	// keep the CVS style constant coz version checkers depend on it!
128   	// e.g. 2.0.8.3
129     //      2.0.8.3_CVS
130     //      2.0.8.3_Bnn       // incremental build
131 
132   public static final String APP_NAME 		= System.getProperty( "azureus.product.name", "Vuze" );
133   public static final String APP_PLUS_NAME	= APP_NAME + " Plus";
134 
135   public static final String AZUREUS_NAME	  					= "Azureus";
136   public static final String AZUREUS_PROTOCOL_NAME_PRE_4813	  	= "Azureus";
137   public static final String AZUREUS_PROTOCOL_NAME	  			= "Vuze";
138   public static final String AZUREUS_VERSION  = "5.7.4.0";
139   public static final String BUILD_VERSION  = "@build.version@";   //Ant replace
140   public static final String AZUREUS_SUBVER	  = "";
141   public static final byte[] VERSION_ID       = ("-" + "AZ" + "5740" + "-").getBytes();  //MUST be 8 chars long!
142 
143   private static final boolean FORCE_NON_CVS = System.getProperty( "az.force.noncvs", "0" ).equals( "1" );
144 
145   public static final boolean IS_CVS_VERSION = isCVSVersion( AZUREUS_VERSION ) && !FORCE_NON_CVS;
146 
147   public static final String  OSName = System.getProperty("os.name");
148 
149   public static final boolean isOSX				= OSName.toLowerCase().startsWith("mac os");
150   public static final boolean isLinux			= OSName.equalsIgnoreCase("Linux");
151   public static final boolean isSolaris			= OSName.equalsIgnoreCase("SunOS");
152   public static final boolean isFreeBSD			= OSName.equalsIgnoreCase("FreeBSD");
153   public static final boolean isWindowsXP		= OSName.equalsIgnoreCase("Windows XP");
154   public static final boolean isWindows95		= OSName.equalsIgnoreCase("Windows 95");
155   public static final boolean isWindows98		= OSName.equalsIgnoreCase("Windows 98");
156   public static final boolean isWindows2000		= OSName.equalsIgnoreCase("Windows 2000");
157   public static final boolean isWindowsME		= OSName.equalsIgnoreCase("Windows ME");
158   public static final boolean isWindows9598ME	= isWindows95 || isWindows98 || isWindowsME;
159 
160   public static boolean isSafeMode = false;
161 
162   public static final boolean isWindows	= OSName.toLowerCase().startsWith("windows");
163   // If it isn't windows or osx, it's most likely an unix flavor
164   public static final boolean isUnix = !isWindows && !isOSX;
165 
166   public static final boolean isWindowsVista;
167   public static final boolean isWindowsVistaSP2OrHigher;
168   public static final boolean isWindowsVistaOrHigher;
169   public static final boolean isWindows7OrHigher;
170   public static final boolean isWindows8OrHigher;
171 
172 
173   // Common Patterns
174 	public static final Pattern PAT_SPLIT_COMMAWORDS = Pattern.compile("\\s*,\\s*");
175 	public static final Pattern PAT_SPLIT_COMMA = Pattern.compile(",");
176 	public static final Pattern PAT_SPLIT_DOT = Pattern.compile("\\.");
177 	public static final Pattern PAT_SPLIT_SPACE = Pattern.compile(" ");
178 	public static final Pattern PAT_SPLIT_SLASH_N = Pattern.compile("\n");
179 
180 
181   public static final boolean is64Bit;
182   public static final boolean isJava64Bit;
183 
184   static{
185 	  boolean _is64Bit;
186 
187 	  try{
188 		  _is64Bit = System.getProperty( "os.arch" ).contains( "64" );
189 
190 	  }catch( Throwable e ){
191 
192 		  _is64Bit = false;
193 	  }
194 
195 	  is64Bit = _is64Bit;
196 
197 	  	// extended test which is supposedly better than the above
198 
199       boolean _isJava64Bit = "64".equals(System.getProperty("sun.arch.data.model")) || System.getProperty("os.arch").contains("64");
200 
201       if ( isWindows && !_isJava64Bit ){
202 
203     	  try{
204     		  String pa 	= System.getenv("PROCESSOR_ARCHITECTURE");
205 	    	  String wow_pa = System.getenv("PROCESSOR_ARCHITEW6432");
206 
207 	    	  _isJava64Bit = ( pa != null && pa.endsWith( "64" )) || ( wow_pa != null && wow_pa.endsWith( "64" ));
208 
209     	  }catch( Throwable e ){
210     	  }
211       }
212 
213       isJava64Bit = _isJava64Bit;
214 
215 	  if ( isWindows ){
216 
217 		  Float ver = null;
218 
219 		  try{
220 			  ver = new Float( System.getProperty( "os.version" ));
221 
222 		  }catch (Throwable e){
223 		  }
224 
225 		  boolean vista_sp2_or_higher	= false;
226 
227 		  if ( ver == null ){
228 
229 			  isWindowsVista			= false;
230 			  isWindowsVistaOrHigher 	= false;
231 			  isWindows7OrHigher		= false;
232 			  isWindows8OrHigher		= false;
233 
234 		  }else{
235 			  float f_ver = ver.floatValue();
236 
237 			  isWindowsVista			= f_ver == 6;
238 			  isWindowsVistaOrHigher 	= f_ver >= 6;
239 			  isWindows7OrHigher	 	= f_ver >= 6.1f;
240 			  isWindows8OrHigher	 	= f_ver >= 6.2f;
241 
242 			  if ( isWindowsVista ){
243 
244 		            LineNumberReader lnr = null;
245 
246 		    	    try{
247 		    	        Process p =
248 		    	        	Runtime.getRuntime().exec(
249 		    	        		new String[]{
250 		    	        				"reg",
251 		    	        				"query",
252 		    	        				"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion",
253 		    	        				"/v",
254 		    	        				"CSDVersion" });
255 
256 		    	        lnr = new LineNumberReader( new InputStreamReader( p.getInputStream()));
257 
258 		    	        while( true ){
259 
260 		    	        	String	line = lnr.readLine();
261 
262 		    	        	if ( line == null ){
263 
264 		    	        		break;
265 		    	        	}
266 
267 		    	            if ( line.matches( ".*CSDVersion.*" )){
268 
269 		    	            	vista_sp2_or_higher = line.matches( ".*Service Pack [2-9]" );
270 
271 		    	                break;
272 		    	            }
273 		    	        }
274 		    	    }catch( Throwable e ){
275 
276 		    	    }finally{
277 
278 		                if ( lnr != null ){
279 
280 		                    try{
lnr.close()281 		                    	lnr.close();
282 
283 		                    }catch( Throwable e ){
284 		                    }
285 		                }
286 		            }
287 		    	}
288 		  }
289 
290 		  isWindowsVistaSP2OrHigher = vista_sp2_or_higher;
291 	  }else{
292 
293 		  isWindowsVista			= false;
294 		  isWindowsVistaSP2OrHigher	= false;
295 		  isWindowsVistaOrHigher 	= false;
296 		  isWindows7OrHigher 		= false;
297 		  isWindows8OrHigher 		= false;
298 	  }
299   }
300 
301   public static final boolean isOSX_10_5_OrHigher;
302   public static final boolean isOSX_10_6_OrHigher;
303   public static final boolean isOSX_10_7_OrHigher;
304   public static final boolean isOSX_10_8_OrHigher;
305 
306   static{
307 	  if ( isOSX ){
308 
309 		  int	first_digit 	= 0;
310 		  int	second_digit	= 0;
311 
312 		  try{
313 			  String os_version = System.getProperty( "os.version" );
314 
315 			  String[] bits = os_version.split( "\\." );
316 
317 			  first_digit = Integer.parseInt( bits[0] );
318 
319 			  if ( bits.length > 1 ){
320 
321 				  second_digit = Integer.parseInt( bits[1] );
322 			  }
323 		  }catch( Throwable e ){
324 
325 		  }
326 
327 		  isOSX_10_5_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 5 );
328 		  isOSX_10_6_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 6 );
329 		  isOSX_10_7_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 7 );
330 		  isOSX_10_8_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 8 );
331 
332 	  }else{
333 
334 		  isOSX_10_5_OrHigher = false;
335 		  isOSX_10_6_OrHigher = false;
336 		  isOSX_10_7_OrHigher = false;
337 		  isOSX_10_8_OrHigher = false;
338 	  }
339   }
340 
341   public static final boolean	isAndroid;
342 
343   static{
344 	  String vm_name = System.getProperty( "java.vm.name", "" );
345 
346 	  isAndroid = vm_name.equalsIgnoreCase( "Dalvik" );
347   }
348 
349   	// Android is roughly 1.6 (reports as 0 for java.version)
350 
351   public static final String	JAVA_VERSION;
352   public static final int		API_LEVEL;
353 
354   static{
355 	  String java_version 	= isAndroid?"1.6":System.getProperty("java.version");
356 	  int	 api_level 		= 0;
357 
358 	  if ( isAndroid ){
359 
360 		  String sdk_int = System.getProperty( "android.os.build.version.sdk_int", "0" );
361 
362 		  try{
363 			  api_level = Integer.parseInt( sdk_int );
364 
365 			  if ( api_level > 0  && api_level <= 8 ){
366 
367 				  java_version = "1.5";
368 			  }
369 		  }catch( Throwable e ){
370 		  }
371 	  }
372 
373 	  JAVA_VERSION 	= java_version;
374 	  API_LEVEL		= api_level;
375   }
376 
377   public static final boolean isJava7OrHigher;
378   public static final boolean isJava8OrHigher;
379   public static final boolean isJava9OrHigher;
380   public static final boolean isJava10OrHigher;
381 
382   static{
383 	  	// http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
384 	  	// should always start with n.n.
385 
386 	  	// unless it is Android where it is always 0
387 
388 	  	// then again, from 1.9 (9) we have http://openjdk.java.net/jeps/223
389 
390 	  boolean	_7plus;
391 	  boolean	_8plus;
392 	  boolean	_9plus;
393 	  boolean	_10plus;
394 
395 	  try{
396 		  // from Java 9 we need to drop stuff after a + or - as we can have 9-ea (well, the + case shouldn't occur in java.version but whatever)
397 
398 		  int pos = JAVA_VERSION.indexOf( '-' );
399 
400 		  if ( pos == -1 ){
401 
402 			  pos = JAVA_VERSION.indexOf( '+' );
403 		  }
404 
405 		  String version = pos==-1?JAVA_VERSION:JAVA_VERSION.substring( 0, pos );
406 
407 		  String[]	bits = version.split( "\\." );
408 
409 		  int	first	= Integer.parseInt( bits[0] );
410 		  int	second 	= bits.length==1?0:Integer.parseInt( bits[1] );
411 
412 		 _7plus = first > 1 || second >= 7;
413 		 _8plus = first > 1 || second >= 8;
414 		 _9plus = first > 1 || second >= 9;
415 
416 		 _10plus = first >= 10;
417 
418 	  }catch( Throwable e ){
419 
420 		  System.err.println( "Unparsable Java version: " + JAVA_VERSION );
421 
422 		  e.printStackTrace();
423 
424 		  _7plus = false;	// derp
425 		  _8plus = false;	// derp
426 		  _9plus = false;	// derp
427 		  _10plus = false;	// derp
428 	  }
429 
430 	  isJava7OrHigher 	= _7plus;
431 	  isJava8OrHigher	= _8plus;
432 	  isJava9OrHigher	= _9plus;
433 	  isJava10OrHigher	= _10plus;
434   }
435 
436   public static final String	FILE_WILDCARD = isWindows?"*.*":"*";
437 
438   	// use this if you want to prevent the constant getting cached in separately built objects (e.g. plugins)
439 
440   public static String
getCurrentVersion()441   getCurrentVersion()
442   {
443 	  return( AZUREUS_VERSION );
444   }
445   	/**
446   	 * Gets the current version, or if a CVS version, the one on which it is based
447   	 * @return
448   	 */
449 
450   public static String
getBaseVersion()451   getBaseVersion()
452   {
453   	return( getBaseVersion( AZUREUS_VERSION ));
454   }
455 
456   public static String
getBaseVersion( String version )457   getBaseVersion(
458   	String	version )
459   {
460   	int	p1 = version.indexOf("_");	// _CVS or _Bnn
461 
462   	if ( p1 == -1 ){
463 
464   		return( version );
465   	}
466 
467   	return( version.substring(0,p1));
468   }
469 
470   	/**
471   	 * is this a formal build or CVS/incremental
472   	 * @return
473   	 */
474 
475   public static boolean
isCVSVersion()476   isCVSVersion()
477   {
478   	return IS_CVS_VERSION;
479   }
480 
481   public static boolean
isCVSVersion( String version )482   isCVSVersion(
483   	String	version )
484   {
485   	return( version.indexOf("_") != -1 );
486   }
487 
488   	/**
489   	 * For CVS builds this returns the incremental build number. For people running their own
490   	 * builds this returns -1
491   	 * @return
492   	 */
493 
494   public static int
getIncrementalBuild()495   getIncrementalBuild()
496   {
497   	return( getIncrementalBuild( AZUREUS_VERSION ));
498   }
499 
500   public static int
getIncrementalBuild( String version )501   getIncrementalBuild(
502   	String	version )
503   {
504   	if ( !isCVSVersion(version)){
505 
506   		return( 0 );
507   	}
508 
509   	int	p1 = version.indexOf( "_B" );
510 
511   	if ( p1 == -1 ){
512 
513   		return( -1 );
514   	}
515 
516   	try{
517   		return( Integer.parseInt( version.substring(p1+2)));
518 
519   	}catch( Throwable e ){
520 
521   		System.out.println("can't parse version");
522 
523   		return( -1 );
524   	}
525   }
526 
527 	public static boolean
isCurrentVersionLT( String version )528   	isCurrentVersionLT(
529   		String	version )
530   	{
531   		return( compareVersions( AZUREUS_VERSION, version ) < 0 );
532   	}
533 
534   	public static boolean
isCurrentVersionGE( String version )535   	isCurrentVersionGE(
536   		String	version )
537   	{
538   		return( compareVersions( AZUREUS_VERSION, version ) >= 0 );
539   	}
540 
541 		/**
542 		 * compare two version strings of form n.n.n.n (e.g. 1.2.3.4)
543 		 * @param version_1
544 		 * @param version_2
545 		 * @return -ve -> version_1 lower, 0 = same, +ve -> version_1 higher
546 		 */
547 
548 	public static int
compareVersions( String version_1, String version_2 )549 	compareVersions(
550 		String		version_1,
551 		String		version_2 )
552 	{
553 		try{
554 			version_1 = version_1.replaceAll( "_CVS", "_B100" );
555 			version_2 = version_2.replaceAll( "_CVS", "_B100" );
556 
557 			if ( version_1.startsWith("." )){
558 				version_1 = "0" + version_1;
559 			}
560 			if ( version_2.startsWith("." )){
561 				version_2 = "0" + version_2;
562 			}
563 
564 			version_1 = version_1.replaceAll("[^0-9.]", ".");
565 			version_2 = version_2.replaceAll("[^0-9.]", ".");
566 
567 			StringTokenizer	tok1 = new StringTokenizer(version_1,".");
568 			StringTokenizer	tok2 = new StringTokenizer(version_2,".");
569 
570 			while( true ){
571 				if ( tok1.hasMoreTokens() && tok2.hasMoreTokens()){
572 
573 					int	i1 = Integer.parseInt(tok1.nextToken());
574 					int	i2 = Integer.parseInt(tok2.nextToken());
575 
576 					if ( i1 != i2 ){
577 
578 						return( i1 - i2 );
579 					}
580 				}else if ( tok1.hasMoreTokens()){
581 
582 					int	i1 = Integer.parseInt(tok1.nextToken());
583 
584 					if ( i1 != 0 ){
585 
586 						return( 1 );
587 					}
588 				}else if ( tok2.hasMoreTokens()){
589 
590 					int	i2 = Integer.parseInt(tok2.nextToken());
591 
592 					if ( i2 != 0 ){
593 
594 						return( -1 );
595 					}
596 				}else{
597 					return( 0 );
598 				}
599 			}
600 		}catch( Throwable e ){
601 
602 			e.printStackTrace();
603 
604 			return( 0 );
605 		}
606 	}
607 
608 	public static boolean
isValidVersionFormat( String version )609 	isValidVersionFormat(
610 		String		version )
611 	{
612 		if ( version == null || version.length() == 0 ){
613 
614 			return( false );
615 		}
616 
617 		for (int i=0;i<version.length();i++){
618 
619 			char	c = version.charAt(i);
620 
621 			if ( !( Character.isDigit( c ) || c == '.' )){
622 
623 				return( false) ;
624 			}
625 		}
626 
627 		if ( version.startsWith( "." ) || version.endsWith( "." ) || version.indexOf( ".." ) != -1 ){
628 
629 			return( false );
630 		}
631 
632 		return( true );
633 	}
634 
635 	public static boolean
isAzureusDomain( String host )636 	isAzureusDomain(
637 		String	host )
638 	{
639 		host = host.toLowerCase();
640 
641 		for (int i=0; i<AZUREUS_DOMAINS.length; i++) {
642 
643 			String domain = (String) AZUREUS_DOMAINS[i];
644 
645 			if ( domain.equals( host )){
646 
647 				return( true );
648 			}
649 
650 			if ( host.endsWith("." + domain)){
651 
652 				return( true );
653 			}
654 		}
655 
656 		return( false );
657 	}
658 
main(String[] args)659 	public static void main(String[] args) {
660 		System.out.println(compareVersions("3.0.0.1", "3.0.0.0"));
661 		System.out.println(compareVersions("3.0.0.0_B1", "3.0.0.0"));
662 		System.out.println(compareVersions("3.0.0.0", "3.0.0.0_B1"));
663 		System.out.println(compareVersions("3.0.0.0_B1", "3.0.0.0_B4"));
664 		System.out.println(compareVersions("3.0.0.0..B1", "3.0.0.0_B4"));
665 	}
666 }
667