001: // serverSystem.java
002: // -------------------------------------------
003: // (C) by Michael Peter Christen; mc@anomic.de
004: // first published on http://www.anomic.de
005: // Frankfurt, Germany, 2004
006: // last major change: 11.03.2004
007: //
008: // This program is free software; you can redistribute it and/or modify
009: // it under the terms of the GNU General Public License as published by
010: // the Free Software Foundation; either version 2 of the License, or
011: // (at your option) any later version.
012: //
013: // This program is distributed in the hope that it will be useful,
014: // but WITHOUT ANY WARRANTY; without even the implied warranty of
015: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: // GNU General Public License for more details.
017: //
018: // You should have received a copy of the GNU General Public License
019: // along with this program; if not, write to the Free Software
020: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: //
022: // Using this software in any meaning (reading, learning, copying, compiling,
023: // running) means that you agree that the Author(s) is (are) not responsible
024: // for cost, loss of data or any harm that may be caused directly or indirectly
025: // by usage of this softare or this documentation. The usage of this software
026: // is on your own risk. The installation and usage (starting/running) of this
027: // software may allow other people or application to access your computer and
028: // any attached devices and is highly dependent on the configuration of the
029: // software which must be done by the user of the software; the author(s) is
030: // (are) also not responsible for proper configuration and usage of the
031: // software, even if provoked by documentation provided together with
032: // the software.
033: //
034: // Any changes to this file according to the GPL as documented in the file
035: // gpl.txt aside this file in the shipment you received can be done to the
036: // lines that follows this copyright notice here, but changes must not be
037: // done inside the copyright notive above. A re-distribution must contain
038: // the intact and unchanged copyright notice.
039: // Contributions and changes to the program code must be marked as such.
040:
041: package de.anomic.server;
042:
043: import java.io.BufferedReader;
044: import java.io.File;
045: import java.io.IOException;
046: import java.io.InputStreamReader;
047: import java.lang.reflect.Constructor;
048: import java.lang.reflect.Method;
049: import java.util.Hashtable;
050: import java.util.Properties;
051: import java.util.Vector;
052:
053: import de.anomic.server.logging.serverLog;
054:
055: public final class serverSystem {
056:
057: // constants for system identification
058: public static final int systemMacOSC = 0; // 'classic' Mac OS 7.6.1/8.*/9.*
059: public static final int systemMacOSX = 1; // all Mac OS X
060: public static final int systemUnix = 2; // all Unix/Linux type systems
061: public static final int systemWindows = 3; // all Windows 95/98/NT/2K/XP
062: public static final int systemUnknown = -1; // any other system
063:
064: // constants for file type identification (Mac only)
065: public static final String blankTypeString = "____";
066:
067: // system-identification statics
068: public static int systemOS = systemUnknown;
069: public static boolean isMacArchitecture = false;
070: public static boolean isUnixFS = false;
071: public static boolean canExecUnix = false;
072:
073: // calculated system constants
074: public static int maxPathLength = 65535;
075:
076: // Macintosh-specific statics
077: private static Class<?> macMRJFileUtils = null;
078: private static Class<?> macMRJOSType = null;
079: private static Constructor<?> macMRJOSTypeConstructor = null;
080: private static Object macMRJOSNullObj = null;
081: private static Method macGetFileCreator = null;
082: private static Method macGetFileType = null;
083: private static Method macSetFileCreator = null;
084: private static Method macSetFileType = null;
085: private static Method macOpenURL = null;
086: public static Hashtable<String, String> macFSTypeCache = null;
087: public static Hashtable<String, String> macFSCreatorCache = null;
088:
089: // static initialization
090: static {
091: // check operation system type
092: Properties sysprop = System.getProperties();
093: String sysname = sysprop.getProperty("os.name", "")
094: .toLowerCase();
095: if (sysname.startsWith("mac os x"))
096: systemOS = systemMacOSX;
097: else if (sysname.startsWith("mac os"))
098: systemOS = systemMacOSC;
099: else if (sysname.startsWith("windows"))
100: systemOS = systemWindows;
101: else if ((sysname.startsWith("linux"))
102: || (sysname.startsWith("unix")))
103: systemOS = systemUnix;
104: else
105: systemOS = systemUnknown;
106:
107: isMacArchitecture = ((systemOS == systemMacOSC) || (systemOS == systemMacOSX));
108: isUnixFS = ((systemOS == systemMacOSX) || (systemOS == systemUnix));
109: canExecUnix = ((isUnixFS) || (!((systemOS == systemMacOSC) || (systemOS == systemWindows))));
110:
111: // set up the MRJ Methods through reflection
112: if (isMacArchitecture)
113: try {
114: macMRJFileUtils = Class
115: .forName("com.apple.mrj.MRJFileUtils");
116: macMRJOSType = Class.forName("com.apple.mrj.MRJOSType");
117: macGetFileType = macMRJFileUtils.getMethod(
118: "getFileType", new Class[] { Class
119: .forName("java.io.File") });
120: macGetFileCreator = macMRJFileUtils.getMethod(
121: "getFileCreator", new Class[] { Class
122: .forName("java.io.File") });
123: macSetFileType = macMRJFileUtils.getMethod(
124: "setFileType", new Class[] {
125: Class.forName("java.io.File"),
126: macMRJOSType });
127: macSetFileCreator = macMRJFileUtils.getMethod(
128: "setFileCreator", new Class[] {
129: Class.forName("java.io.File"),
130: macMRJOSType });
131: macMRJOSTypeConstructor = macMRJOSType
132: .getConstructor(new Class[] { Class
133: .forName("java.lang.String") });
134: macOpenURL = macMRJFileUtils
135: .getMethod("openURL", new Class[] { Class
136: .forName("java.lang.String") });
137: byte[] nullb = new byte[4];
138: for (int i = 0; i < 4; i++)
139: nullb[i] = 0;
140: macMRJOSNullObj = macMRJOSTypeConstructor
141: .newInstance(new Object[] { new String(nullb) });
142: macFSTypeCache = new Hashtable<String, String>();
143: macFSCreatorCache = new Hashtable<String, String>();
144: } catch (Exception e) {
145: //e.printStackTrace();
146: macMRJFileUtils = null;
147: macMRJOSType = null;
148: }
149:
150: // set up maximum path length accoring to system
151: if (systemOS == systemWindows)
152: maxPathLength = 255;
153: else
154: maxPathLength = 65535;
155: }
156:
157: public static boolean isWindows() {
158: return systemOS == systemWindows;
159: }
160:
161: public static Object getMacOSTS(String s) {
162: if ((isMacArchitecture) && (macMRJFileUtils != null))
163: try {
164: if ((s == null) || (s.equals(blankTypeString)))
165: return macMRJOSNullObj;
166: else
167: return macMRJOSTypeConstructor
168: .newInstance(new Object[] { s });
169: } catch (Exception e) {
170: return macMRJOSNullObj;
171: }
172: else
173: return null;
174: }
175:
176: public static String getMacFSType(File f) {
177: if ((isMacArchitecture) && (macMRJFileUtils != null))
178: try {
179: String s = macGetFileType.invoke(null,
180: new Object[] { f }).toString();
181: if ((s == null) || (s.charAt(0) == 0))
182: return blankTypeString;
183: else
184: return s;
185: } catch (Exception e) {
186: return null;
187: }
188: else
189: return null;
190: }
191:
192: public static String getMacFSCreator(File f) {
193: if ((isMacArchitecture) && (macMRJFileUtils != null))
194: try {
195: String s = macGetFileCreator.invoke(null,
196: new Object[] { f }).toString();
197: if ((s == null) || (s.charAt(0) == 0))
198: return blankTypeString;
199: else
200: return s;
201: } catch (Exception e) {
202: return null;
203: }
204: else
205: return null;
206: }
207:
208: public static void setMacFSType(File f, String t) {
209: if ((isMacArchitecture) && (macMRJFileUtils != null))
210: try {
211: macSetFileType.invoke(null, new Object[] { f,
212: getMacOSTS(t) });
213: } catch (Exception e) {/*System.out.println(e.getMessage()); e.printStackTrace();*/
214: }
215: }
216:
217: public static void setMacFSCreator(File f, String t) {
218: if ((isMacArchitecture) && (macMRJFileUtils != null))
219: try {
220: macSetFileCreator.invoke(null, new Object[] { f,
221: getMacOSTS(t) });
222: } catch (Exception e) {/*System.out.println(e.getMessage()); e.printStackTrace();*/
223: }
224: }
225:
226: public static boolean aquireMacFSType(File f) {
227: if ((!(isMacArchitecture)) || (macMRJFileUtils == null))
228: return false;
229: String name = f.toString();
230:
231: // check file type
232: int dot = name.lastIndexOf(".");
233: if ((dot < 0) || (dot + 1 >= name.length()))
234: return false;
235: String type = getMacFSType(f);
236: if ((type == null) || (type.equals(blankTypeString)))
237: return false;
238: String ext = name.substring(dot + 1).toLowerCase();
239: String oldType = (String) macFSTypeCache.get(ext);
240: if ((oldType != null) && (oldType.equals(type)))
241: return false;
242: macFSTypeCache.put(ext, type);
243: return true;
244: }
245:
246: public static boolean aquireMacFSCreator(File f) {
247: if ((!(isMacArchitecture)) || (macMRJFileUtils == null))
248: return false;
249: String name = f.toString();
250:
251: // check creator
252: String creator = getMacFSCreator(f);
253: if ((creator == null) || (creator.equals(blankTypeString)))
254: return false;
255: String oldCreator = (String) macFSCreatorCache.get(name);
256: if ((oldCreator != null) && (oldCreator.equals(creator)))
257: return false;
258: macFSCreatorCache.put(name, creator);
259: return true;
260: }
261:
262: public static boolean applyMacFSType(File f) {
263: if ((!(isMacArchitecture)) || (macMRJFileUtils == null))
264: return false;
265: String name = f.toString();
266:
267: // reconstruct file type
268: int dot = name.lastIndexOf(".");
269: if ((dot < 0) || (dot + 1 >= name.length()))
270: return false;
271: String type = (String) macFSTypeCache.get(name.substring(
272: dot + 1).toLowerCase());
273: if (type == null)
274: return false;
275: String oldType = getMacFSType(f);
276: if ((oldType != null) && (oldType.equals(type)))
277: return false;
278: setMacFSType(f, type);
279: return getMacFSType(f).equals(type);
280: }
281:
282: public static boolean applyMacFSCreator(File f) {
283: if ((!(isMacArchitecture)) || (macMRJFileUtils == null))
284: return false;
285: String name = f.toString();
286:
287: // reconstruct file creator
288: String creator = (String) macFSCreatorCache.get(name);
289: if (creator == null)
290: return false;
291: String oldCreator = getMacFSCreator(f);
292: if ((oldCreator != null) && (oldCreator.equals(creator)))
293: return false;
294: //System.out.println("***Setting creator for " + f.toString() + " to " + creator);
295: setMacFSCreator(f, creator);
296: return getMacFSCreator(f).equals(creator); // this is not always true! I guess it's caused by deprecation of the interface in 1.4er Apple Extensions
297: }
298:
299: public static String infoString() {
300: String s = "System=";
301: if (systemOS == systemUnknown)
302: s += "unknown";
303: else if (systemOS == systemMacOSC)
304: s += "Mac OS Classic";
305: else if (systemOS == systemMacOSX)
306: s += "Mac OS X";
307: else if (systemOS == systemUnix)
308: s += "Unix/Linux";
309: else if (systemOS == systemWindows)
310: s += "Windows";
311: else
312: s += "unknown";
313: if (isMacArchitecture)
314: s += ", Mac System Architecture";
315: if (isUnixFS)
316: s += ", has Unix-like File System";
317: if (canExecUnix)
318: s += ", can execute Unix-Shell Commands";
319: return s;
320: }
321:
322: /** generates a 2-character string containing information about the OS-type*/
323: public static String infoKey() {
324: String s = "";
325: if (systemOS == systemUnknown)
326: s += "o";
327: else if (systemOS == systemMacOSC)
328: s += "c";
329: else if (systemOS == systemMacOSX)
330: s += "x";
331: else if (systemOS == systemUnix)
332: s += "u";
333: else if (systemOS == systemWindows)
334: s += "w";
335: else
336: s += "o";
337: if (isMacArchitecture)
338: s += "m";
339: if (isUnixFS)
340: s += "f";
341: if (canExecUnix)
342: s += "e";
343: return s;
344: }
345:
346: private static String errorResponse(Process p) {
347: BufferedReader err = new BufferedReader(new InputStreamReader(p
348: .getErrorStream()));
349: String line, error = "";
350: try {
351: while ((line = err.readLine()) != null) {
352: error = line + "\n";
353: }
354: return error;
355: } catch (IOException e) {
356: return null;
357: }
358: }
359:
360: /*
361: public static void openBrowser(URL url) {
362: if (openBrowserJNLP(url)) return;
363: openBrowserExec(url.toString(), "firefox");
364: }
365:
366: private static boolean openBrowserJNLP(URL url) {
367: try {
368: // Lookup the javax.jnlp.BasicService object
369: javax.jnlp.BasicService bs = (javax.jnlp.BasicService) javax.jnlp.ServiceManager.lookup("javax.jnlp.BasicService");
370: // Invoke the showDocument method
371: return bs.showDocument(url);
372: } catch (Exception ue) {
373: // Service is not supported
374: return false;
375: }
376: }
377: */
378:
379: public static void openBrowser(String url) {
380: openBrowser(url, "firefox");
381: }
382:
383: public static void openBrowser(String url, String app) {
384: try {
385: String cmd;
386: Process p;
387: if (systemOS == systemUnknown) {
388: } else if (systemOS == systemMacOSC) {
389: if ((isMacArchitecture) && (macMRJFileUtils != null)) {
390: macOpenURL.invoke(null, new Object[] { url });
391: }
392: } else if (systemOS == systemMacOSX) {
393: p = Runtime.getRuntime().exec(
394: new String[] { "/usr/bin/osascript", "-e",
395: "open location \"" + url + "\"" });
396: p.waitFor();
397: if (p.exitValue() != 0)
398: throw new RuntimeException("EXEC ERROR: "
399: + errorResponse(p));
400: } else if (systemOS == systemUnix) {
401: cmd = app + " -remote openURL(" + url + ") &";
402: p = Runtime.getRuntime().exec(cmd);
403: p.waitFor();
404: if (p.exitValue() != 0) {
405: cmd = app + " " + url + " &";
406: p = Runtime.getRuntime().exec(cmd);
407: p.waitFor();
408: }
409: if (p.exitValue() != 0)
410: throw new RuntimeException("EXEC ERROR: "
411: + errorResponse(p));
412: } else if (systemOS == systemWindows) {
413: // see forum at http://forum.java.sun.com/thread.jsp?forum=57&thread=233364&message=838441
414: cmd = "rundll32 url.dll,FileProtocolHandler " + url;
415: //cmd = "cmd.exe /c start javascript:document.location='" + url + "'";
416: p = Runtime.getRuntime().exec(cmd);
417: p.waitFor();
418: if (p.exitValue() != 0)
419: throw new RuntimeException("EXEC ERROR: "
420: + errorResponse(p));
421: }
422: } catch (Exception e) {
423: System.out
424: .println("please start your browser and open the following location: "
425: + url);
426: }
427: }
428:
429: public static void deployScript(File scriptFile, String theScript)
430: throws IOException {
431: serverFileUtils.write(theScript.getBytes(), scriptFile);
432: try {
433: Runtime.getRuntime().exec(
434: "chmod 755 "
435: + scriptFile.getAbsolutePath().replaceAll(
436: " ", "\\ ")).waitFor();
437: } catch (InterruptedException e) {
438: serverLog.logSevere("DEPLOY",
439: "deploy of script file failed. file = "
440: + scriptFile.getAbsolutePath(), e);
441: throw new IOException(e.getMessage());
442: }
443: }
444:
445: public static void execAsynchronous(File scriptFile)
446: throws IOException {
447: // runs a unix/linux script as separate thread
448: File starterFile = new File(scriptFile.getAbsolutePath()
449: .replaceAll(" ", "\\ ")
450: + ".starter.sh");
451: //deployScript(starterFile, "touch restart.starter.startet1");
452: deployScript(starterFile, "#!/bin/sh" + serverCore.LF_STRING
453: + scriptFile.getAbsolutePath().replaceAll(" ", "\\ ")
454: + " &" + serverCore.LF_STRING);
455: try {
456: Runtime.getRuntime().exec(
457: starterFile.getAbsolutePath()
458: .replaceAll(" ", "\\ ")).waitFor();
459: } catch (InterruptedException e) {
460: throw new IOException(e.getMessage());
461: }
462: starterFile.delete();
463: }
464:
465: public static Vector<String> execSynchronous(String command)
466: throws IOException {
467: // runs a unix/linux command and returns output as Vector of Strings
468: // this method blocks until the command is executed
469: Process p = Runtime.getRuntime().exec(command);
470: BufferedReader in = new BufferedReader(new InputStreamReader(p
471: .getInputStream()));
472: String text;
473: Vector<String> output = new Vector<String>();
474: while ((text = in.readLine()) != null) {
475: output.add(text);
476: }
477: return output;
478: }
479:
480: public static void main(String[] args) {
481: //try{System.getProperties().list(new PrintStream(new FileOutputStream(new File("system.properties.txt"))));} catch (FileNotFoundException e) {}
482: //System.out.println("nullstr=" + macMRJOSNullObj.toString());
483: if (args[0].equals("-f")) {
484: File f = new File(args[1]);
485: System.out.println("File " + f.toString() + ": creator = "
486: + getMacFSCreator(f) + "; type = "
487: + getMacFSType(f));
488: }
489: if (args[0].equals("-u")) {
490: openBrowser(args[1]);
491: }
492: }
493:
494: }
495:
496: /*
497: table of common system properties
498: comparisment between different operation systems
499:
500: property |Mac OS 9.22 |Mac OSX 10.1.5 |Windows 98 |Linux Kernel 2.4.22 |
501: -------------------+----------------------+----------------------+----------------------+----------------------+
502: file.encoding |MacTEC |MacRoman |Cp1252 |ANSI_X3.4-1968 |
503: file.separator |/ |/ |\ |/ |
504: java.class.path |/hdisc/... |. |. |/usr/lib/j2se/ext |
505: java.class.version |45.3 |47.0 |48.0 |47.0 |
506: java.home |/hdisc/... |/System/Library/... |C:\PROGRAM\... |/usr/lib/j2se/1.3/jre |
507: java.vendor |Apple Computer, Inc. |Apple Computer, Inc. |Sun Microsystems Inc. |Blackdown Java-Linux |
508: java.version |1.1.8 |1.3.1 |1.4.0_02 |1.3.1 |
509: os.arch |PowerPC |ppc |x86 |i386 |
510: os.name |Mac OS |Mac OS X |Windows 98 |Linux |
511: os.version |9.2.2 |10.1.5 |4.10 |2.4.22 |
512: path.separator |: |: |; |: |
513: user.dir |/hdisc/... |/mydir/... |C:\mydir\... |/home/public |
514: user.home |/hdisc/... |/Users/myself |C:\WINDOWS |/home/public |
515: user.language |de |de |de |en |
516: user.name |Bob |myself |User |public |
517: user.timezone |ECT |Europe/Berlin |Europe/Berlin | |
518: -------------------+----------------------+----------------------+----------------------+----------------------+
519: */
520:
521: /*
522: static struct browser possible_browsers[] = {
523: {N_("Opera"), "opera"},
524: {N_("Netscape"), "netscape"},
525: {N_("Mozilla"), "mozilla"},
526: {N_("Konqueror"), "kfmclient"},
527: {N_("Galeon"), "galeon"},
528: {N_("Firebird"), "mozilla-firebird"},
529: {N_("Firefox"), "firefox"},
530: {N_("Gnome Default"), "gnome-open"}
531: };
532:
533: new:
534: command = exec("netscape -remote " "\" openURL(\"%s\",new-window) "", uri);
535: command = exec("opera -newwindow \"%s\"", uri);
536: command = exec("opera -newpage \"%s\"", uri);
537: command = exec("galeon -w \"%s\"", uri);
538: command = exec("galeon -n \"%s\"", uri);
539: command = exec("%s -remote \"openURL(\"%s\"," "new-window)\"", web_browser, uri);
540: command = exec("%s -remote \"openURL(\"%s\"," "new-tab)\"", web_browser, uri);
541:
542: current:
543: command = exec("netscape -remote " "\"openURL(\"%s\")\"", uri);
544: command = exec("opera -remote " "\"openURL(\"%s\")\"", uri);
545: command = exec("galeon \"%s\"", uri);
546: command = exec("%s -remote \"openURL(\"%s\")\"", web_browser, uri);
547:
548: no option:
549: command = exec("kfmclient openURL \"%s\"", uri);
550: command = exec("gnome-open \"%s\"", uri);
551: */
|