From fed7659d35ede3178ecde7ab6ab5a26c5976fa2d Mon Sep 17 00:00:00 2001 From: Peter Quiring Date: Tue, 18 Aug 2015 19:21:09 -0400 Subject: [PATCH] release 10.0 --- build.xml | 17 +- deb/control | 22 +- javaforce.spec | 80 +- projects/jftest3d/run.sh | 4 +- readme.txt | 4 +- src/javaforce/JF.java | 2702 ++++++++++++++++---------------- src/javaforce/linux/Linux.java | 2458 ++++++++++++++--------------- whatsnew.txt | 2 + 8 files changed, 2645 insertions(+), 2644 deletions(-) diff --git a/build.xml b/build.xml index 17b0d3cc2..266afb6b1 100755 --- a/build.xml +++ b/build.xml @@ -5,7 +5,7 @@ - + @@ -53,15 +53,14 @@ - - - - - - - + + + + + + + - diff --git a/deb/control b/deb/control index 609e11696..ffdd0c41a 100755 --- a/deb/control +++ b/deb/control @@ -1,11 +1,11 @@ -Package: javaforce -Version: 9.6.0 -Architecture: amd64 -Maintainer: Peter Quiring -Installed-Size: 290 -Depends: openjdk-8-jre, libjsch-java (>= 0.1.42), libjzlib-java, libjcifs-java, fuse, libfuse2, fuseiso, libcdio13, mate-icon-theme -Components: main -Provides: -Section: java -Priority: optional -Description: JavaForce base classes. +Package: javaforce +Version: 10.0.0 +Architecture: amd64 +Maintainer: Peter Quiring +Installed-Size: 290 +Depends: openjdk-8-jre, libjsch-java (>= 0.1.42), libjzlib-java, libjcifs-java, fuse, libfuse2, fuseiso, libcdio13, mate-icon-theme +Components: main +Provides: +Section: java +Priority: optional +Description: JavaForce base classes. diff --git a/javaforce.spec b/javaforce.spec index 3d9862bff..b39401896 100755 --- a/javaforce.spec +++ b/javaforce.spec @@ -1,40 +1,40 @@ -Buildroot: /. -Name: javaforce -Version: 9.6.0 -Release: 1 -Summary: JavaForce Core Library -License: LGPL -Distribution: Fedora -Group: Applications/System -Requires: java-1.7.0-openjdk, jsch, jzlib, jcifs, fuse, fuse-libs, fuseiso, libcdio - -%define _rpmdir ../ -%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.noarch.rpm -%define _unpackaged_files_terminate_build 0 - -%description - -JavaForce Core Library - -%post -#!/bin/sh - -set -e - -if [ $1 = "1" ]; then - update-alternatives --install /usr/bin/update-desktop-database update-desktop-database /usr/bin/jf-update-desktop-database 100 -fi - -%pre -#!/bin/sh - -mkdir -p /usr/share/jhelp - -%preun -#!/bin/sh - -if [ $1 = "0" ]; then - update-alternatives --remove update-desktop-database /usr/bin/jf-update-desktop-database -fi - -%files +Buildroot: /. +Name: javaforce +Version: 10.0.0 +Release: 1 +Summary: JavaForce Core Library +License: LGPL +Distribution: Fedora +Group: Applications/System +Requires: java-1.7.0-openjdk, jsch, jzlib, jcifs, fuse, fuse-libs, fuseiso, libcdio + +%define _rpmdir ../ +%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.noarch.rpm +%define _unpackaged_files_terminate_build 0 + +%description + +JavaForce Core Library + +%post +#!/bin/sh + +set -e + +if [ $1 = "1" ]; then + update-alternatives --install /usr/bin/update-desktop-database update-desktop-database /usr/bin/jf-update-desktop-database 100 +fi + +%pre +#!/bin/sh + +mkdir -p /usr/share/jhelp + +%preun +#!/bin/sh + +if [ $1 = "0" ]; then + update-alternatives --remove update-desktop-database /usr/bin/jf-update-desktop-database +fi + +%files diff --git a/projects/jftest3d/run.sh b/projects/jftest3d/run.sh index 43294f2d7..d432f5a28 100755 --- a/projects/jftest3d/run.sh +++ b/projects/jftest3d/run.sh @@ -1,2 +1,2 @@ -java -cp javaforce.jar:lwjgl.jar:jftest3d.jar TestApp $* - +java -cp javaforce.jar:lwjgl.jar:jftest3d.jar Main $* + diff --git a/readme.txt b/readme.txt index 8ad17fac8..d6e7bb53a 100755 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,7 @@ JavaForce SDK ============= -Version 9.6.0 +Version 10.0.0 What is it? =========== @@ -90,6 +90,6 @@ Web : pquiring.github.io/javaforce Git : github.com/pquiring/javaforce -Version 9.6.0 +Version 10.0.0 Released : August 10 2015 diff --git a/src/javaforce/JF.java b/src/javaforce/JF.java index f21f44bb8..339adcabc 100755 --- a/src/javaforce/JF.java +++ b/src/javaforce/JF.java @@ -1,1351 +1,1351 @@ -package javaforce; - -import java.net.*; -import java.io.*; -import java.util.*; -import java.lang.reflect.Array; -import javax.net.ssl.*; - -//remove these for Android -import java.awt.*; -import java.awt.event.*; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import javaforce.jni.JFNative; -import javax.swing.*; - -/** - * A collection of static methods. Many methods help reduce try/catch clutter by - * returning error codes. - * - * @author Peter Quiring - */ -public class JF { - - public static String getVersion() { - return "9.6.0"; - } - - public static void sleep(int milli) { - try { - Thread.sleep(milli); - } catch (InterruptedException e) { - JFLog.log(e); - } - } - - public static void msg(String msg) { - java.lang.System.out.println(msg); - } - - public static URL createURL(String url) { - try { - return new URL(url); - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static String readURL(String url) { - String str = ""; - byte data[] = new byte[1024]; - int read; - String purl = ""; //percent URL - char ch; - for (int p = 0; p < url.length(); p++) { - ch = url.charAt(p); - switch (ch) { - case ' ': - purl += "%20"; - break; - case '%': - purl += "%25"; - break; - case '<': - purl += "%3c"; - break; - case '>': - purl += "%3e"; - break; - default: - purl += ch; - break; - } - } - try { - URL u = new URL(purl); - HttpURLConnection huc = (HttpURLConnection) u.openConnection(); - huc.setRequestMethod("GET"); - huc.connect(); - if (huc.getResponseCode() != HttpURLConnection.HTTP_OK) { - return "huc error : " + huc.getResponseCode(); //ohoh - } - InputStream is = huc.getInputStream(); - while (true) { - read = is.read(data); - if (read <= 0) { - break; - } - str += new String(data, 0, read); - } - is.close(); - huc.disconnect(); - return str; - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static int atoi(String str) { - if (str.length() == 0) { - return 0; - } - try { - if (str.charAt(0) == '+') { - return Integer.parseInt(str.substring(1)); - } - return Integer.parseInt(str); - } catch (Exception e) { - JFLog.log(e); - return -1; - } - } - - public static float atof(String str) { - if (str.length() == 0) { - return 0; - } - try { - return Float.parseFloat(str); - } catch (Exception e) { - JFLog.log(e); - return -1; - } - } - - public static int atox(String str) { - if (str.length() == 0) { - return 0; - } - try { - return Integer.parseInt(str, 16); - } catch (Exception e) { - JFLog.log(e); - return -1; - } - } - - /** Checks if system is Windows only. */ - public static boolean isWindows() { - return (File.separatorChar == '\\'); - } - - /** Checks is system is Unix based (includes : Unix, Linux, Mac, jfLinux) */ - public static boolean isUnix() { - return (File.separatorChar == '/'); - } - - /** Checks if system is Mac only. */ - public static boolean isMac() { - if (!isUnix()) return false; - String osName = System.getProperty("os.name"); - return osName.startsWith("Mac") || osName.startsWith("Darwin"); - } - - /** Checks if system is jfLinux only. */ - public static boolean isJFLinux() { - if (!isUnix()) return false; - return new File("/usr/sbin/jlogon").exists(); - } - - public static String getUserPath() { - return System.getProperty("user.home"); - } - - public static String getCurrentUser() { - return System.getProperty("user.name"); - } - private static String user_dir = null; - - public static synchronized String getCurrentPath() { - if (user_dir == null) { - user_dir = System.getProperty("user.dir"); - } - return user_dir; - } - - /** - * This just changes the internal value returned from getCurrentPath() - */ - public static void setCurrentPath(String new_dir) { - user_dir = new_dir; - } -//file IO helper functions (these are little-endian format!!!) - - public static boolean eof(InputStream f) { - try { - return (!(f.available() > 0)); - } catch (Exception e) { - JFLog.log(e); - return true; - } - } - - public static int filelength(InputStream is) { - try { - return is.available(); - } catch (Exception e) { - JFLog.log(e); - return -1; - } - } - - public static boolean fileskip(InputStream is, int length) { - try { - is.skip(length); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean fileflush(BufferedOutputStream bos) { - try { - bos.flush(); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static FileInputStream fileopen(String name) { - try { - return new FileInputStream(name); - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static FileOutputStream filecreate(String name) { - try { - return new FileOutputStream(name); - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static FileOutputStream filecreateappend(String name) { - try { - return new FileOutputStream(name, true); - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static boolean fileclose(InputStream is) { - try { - is.close(); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean fileclose(OutputStream os) { - try { - os.close(); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static byte[] read(InputStream in, int max) { - byte ret[] = new byte[max]; - try { - int read = in.read(ret); - if (read == max) { - return ret; - } - if (read == 0) { - return null; - } - byte ret2[] = new byte[read]; - System.arraycopy(ret, 0, ret2, 0, read); - return ret2; - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static byte[] readAll(InputStream in) { - try { - int len = in.available(); - byte ret[] = new byte[len]; - int pos = 0; - while (pos < len) { - int read = in.read(ret, pos, len - pos); - if (read <= 0) { - return null; - } - pos += read; - } - return ret; - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static byte[] readAll(InputStream in, int len) { - try { - byte ret[] = new byte[len]; - int pos = 0; - while (pos < len) { - int read = in.read(ret, pos, len - pos); - if (read <= 0) { - return null; - } - pos += read; - } - return ret; - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static boolean readAll(InputStream in, byte buf[], int pos, int len) { - int end = pos + len; - try { - while (pos < end) { - int read = in.read(buf, pos, len); - if (read <= 0) { - return false; - } - pos += read; - len -= read; - } - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean readAll(RandomAccessFile in, byte buf[], int pos, int len) { - int end = pos + len; - try { - while (pos < end) { - int read = in.read(buf, pos, len); - if (read <= 0) { - return false; - } - pos += read; - len -= read; - } - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static byte[] readAll(InputStream in, Socket s) { - try { - byte tmp[] = new byte[1500]; - byte ret[] = new byte[0]; - while (in.available() > 0 || s.isConnected()) { - int read = in.read(tmp); - if (read <= 0) { - return ret; - } - int pos = ret.length; - ret = Arrays.copyOf(ret, pos + read); - System.arraycopy(tmp, 0, ret, pos, read); - } - return ret; - } catch (Exception e) { - JFLog.log(e); - return null; - } - } - - public static int read(InputStream in, byte[] buf, int pos, int len) { - try { - return in.read(buf, pos, len); - } catch (Exception e) { - JFLog.log(e); - return 0; - } - } - - public static int read(InputStream in) { - try { - return in.read(); - } catch (Exception e) { - JFLog.log(e); - return 0; - } - } - - public static char readchar(InputStream in) { - try { - return (char) in.read(); - } catch (Exception e) { - JFLog.log(e); - return 0; - } - } - - public static int readuint8(InputStream in) { - byte data[] = new byte[1]; - try { - if (in.read(data) != 1) { - return -1; - } - } catch (Exception e) { - JFLog.log(e); - return -1; - } - return (int) data[0] & 0xff; - } - - public static int readuint16(InputStream in) { - byte data[] = new byte[2]; - try { - if (in.read(data) != 2) { - return -1; - } - } catch (Exception e) { - JFLog.log(e); - return -1; - } - int ret; - ret = (int) data[0] & 0xff; - ret += ((int) data[1] & 0xff) << 8; - return ret; - } - - public static int readuint32(InputStream in) { - byte data[] = new byte[4]; - try { - if (in.read(data) != 4) { - return -1; - } - } catch (Exception e) { - JFLog.log(e); - return -1; - } - int ret; - ret = (int) data[0] & 0xff; - ret += ((int) data[1] & 0xff) << 8; - ret += ((int) data[2] & 0xff) << 16; - ret += ((int) data[3] & 0xff) << 24; - return ret; - } - - public static long readuint64(InputStream in) { - byte data[] = new byte[8]; - try { - if (in.read(data) != 8) { - return -1; - } - } catch (Exception e) { - JFLog.log(e); - return -1; - } - long ret; - ret = (long) data[0] & 0xff; - ret += ((long) data[1] & 0xff) << 8; - ret += ((long) data[2] & 0xff) << 16; - ret += ((long) data[3] & 0xff) << 24; - ret += ((long) data[4] & 0xff) << 32; - ret += ((long) data[5] & 0xff) << 40; - ret += ((long) data[6] & 0xff) << 48; - ret += ((long) data[7] & 0xff) << 56; - return ret; - } - - public static float readfloat(InputStream in) { - int bits = JF.readuint32(in); - return Float.intBitsToFloat(bits); - } - - public static double readdouble(InputStream in) { - long bits = JF.readuint64(in); - return Double.longBitsToDouble(bits); - } - - public static boolean write(OutputStream out, byte data[]) { - try { - out.write(data); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean write(OutputStream out, String str) { - return write(out, str.getBytes()); - } - - public static boolean write(OutputStream out, byte data[], int offset, int length) { - try { - out.write(data, offset, length); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean writeuint8(OutputStream out, int data) { - try { - out.write(data); - } catch (Exception e) { - JFLog.log(e); - return false; - } - return true; - } - - public static boolean writeuint16(OutputStream out, int data) { - try { - out.write(data & 0xff); - data >>= 8; - out.write(data & 0xff); - } catch (Exception e) { - JFLog.log(e); - return false; - } - return true; - } - - public static boolean writeuint32(OutputStream out, int data) { - try { - out.write(data & 0xff); - data >>= 8; - out.write(data & 0xff); - data >>= 8; - out.write(data & 0xff); - data >>= 8; - out.write(data & 0xff); - } catch (Exception e) { - JFLog.log(e); - return false; - } - return true; - } - - public static boolean writeuint64(OutputStream out, long data) { - try { - for (int a = 0; a < 8; a++) { - out.write((int) (data & 0xff)); - data >>= 8; - } - } catch (Exception e) { - JFLog.log(e); - return false; - } - return true; - } - - public static boolean writefloat(OutputStream out, float data) { - int bits = Float.floatToIntBits(data); - return writeuint32(out, bits); - } - - public static boolean writedouble(OutputStream out, double data) { - long bits = Double.doubleToLongBits(data); - return writeuint64(out, bits); - } - - public static boolean copyAll(InputStream is, OutputStream os) { - try { - int len = is.available(); - byte buf[] = new byte[1024]; - int copied = 0; - while (copied < len) { - int read = is.read(buf); - if (read == 0) { - continue; - } - if (read == -1) { - return false; - } - os.write(buf, 0, read); - copied += read; - } - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean copyAll(String src, String dst) { - try { - FileInputStream fis = new FileInputStream(src); - FileOutputStream fos = new FileOutputStream(dst); - boolean success = copyAll(fis, fos); - fis.close(); - fos.close(); - return success; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean copyAll(InputStream is, OutputStream os, long length) { - try { - byte buf[] = new byte[1024]; - int copied = 0; - while (copied < length) { - int read = is.read(buf); - if (read == 0) { - continue; - } - if (read == -1) { - return false; - } - os.write(buf, 0, read); - copied += read; - } - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static boolean isWildcard(String wcstr) { - if (wcstr.indexOf("*") != -1) return true; - if (wcstr.indexOf("?") != -1) return true; - return false; - } - - public static boolean wildcardCompare(String fnstr, String wcstr, boolean caseSensitive) { - //wc = "*.txt" - //fn = "filename.txt" - char fn[] = fnstr.toCharArray(); - char wc[] = wcstr.toCharArray(); - int fnp = 0, wcp = 0; - char wcc, fnc; - int sl, a; - while ((fnp < fn.length) && (wcp < wc.length)) { - if (wc[wcp] == '*') { - sl = fn.length - fnp; - //try 0-sl chars of fn - wcp++; - for (a = 0; a <= sl; a++) { - if (wildcardCompare( - new String(fn, fnp, fn.length - fnp), - new String(fn, fnp, a) + new String(wc, wcp, wc.length - wcp), - caseSensitive)) { - return true; - } - } - return false; - } - if (wc[wcp] == '?') { - //try 0-1 chars of fn - wcp++; - for (a = 0; a <= 1; a++) { - if (wildcardCompare( - new String(fn, fnp, fn.length - fnp), - new String(fn, fnp, a) + new String(wc, wcp, wc.length - wcp), - caseSensitive)) { - return true; - } - } - return false; - } - if (caseSensitive) { - fnc = fn[fnp]; - wcc = wc[wcp]; - } else { - fnc = Character.toUpperCase(fn[fnp]); - wcc = Character.toUpperCase(wc[wcp]); - } - if (fnc != wcc) { - break; //no match - } - fnp++; - wcp++; - }; - while ((wcp < wc.length) && ((wc[wcp] == '*') || (wc[wcp] == '?'))) { - wcp++; - } - if (wcp < wc.length) { - return false; //wc not used up - } - if (fnp < fn.length) { - return false; //fn not used up - } - return true; - } -//String char[] functions (StringBuffer is awkward) (these are NOT null terminating) - - public static char[] createstr(String str) { - return str.toCharArray(); - } - - public static char[] truncstr(char str[], int newlength) { - if (newlength == 0) { - return null; - } - char ret[] = new char[newlength]; - if (newlength <= str.length) { - System.arraycopy(str, 0, ret, 0, ret.length); - } else { - System.arraycopy(str, 0, ret, 0, str.length); - for (int a = str.length; a < ret.length; a++) { - ret[a] = 0; - } - } - return ret; - } - - public static char[] strcpy(char str[]) { - char ret[] = new char[str.length]; - System.arraycopy(str, 0, ret, 0, str.length); - return ret; - } - - public static char[] strcat(char s1[], char s2[]) { - if (s1 == null) { - s1 = new char[0]; - } - char ret[] = new char[s1.length + s2.length]; - System.arraycopy(s1, 0, ret, 0, s1.length); - System.arraycopy(s2, 0, ret, s1.length, s2.length); - return ret; - } - - public static char[] strcat(char str[], char ch) { - char ret[]; - if (str == null) { - ret = new char[1]; - ret[0] = ch; - return ret; - } - ret = new char[str.length + 1]; - System.arraycopy(str, 0, ret, 0, str.length); - ret[str.length] = ch; - return ret; - } - - public static String createString(char str[]) { - return new String(str); - } - - public static boolean strcmp(String s1, String s2) { - return s1.equals(s2); - } - - public static boolean stricmp(String s1, String s2) { - return s1.equalsIgnoreCase(s2); - } - - public static boolean strcmp(char s1[], char s2[]) { - return strcmp(new String(s1), new String(s2)); - } - - public static boolean stricmp(char s1[], char s2[]) { - return stricmp(new String(s1), new String(s2)); - } - - public static void memcpy(Object src[], int srcpos, Object dest[], int destpos, int len) { - System.arraycopy(src, srcpos, dest, destpos, len); - } - - public static boolean memcmp(byte m1[], int m1pos, byte[] m2, int m2pos, int len) { - for (int a = 0; a < len; a++) { - if (m1[m1pos + a] != m2[m2pos + a]) { - return false; - } - } - return true; - } - - public static boolean memicmp(byte m1[], int m1pos, byte[] m2, int m2pos, int len) { - char c1, c2; - for (int a = 0; a < len; a++) { - c1 = Character.toUpperCase((char) m1[m1pos + a]); - c2 = Character.toUpperCase((char) m2[m2pos + a]); - if (c1 != c2) { - return false; - } - } - return true; - } - -//executable JAR functions - - public static String getJARPath() { - //this will equal your executable JAR filename (like argv[0] in C++) - return System.getProperty("java.class.path"); - } - -//GUI functions (remove for Android) - - public static JFrame createJFrame(String title, int x, int y, int w, int h, LayoutManager lm) { - //NOTE : When you add components, you must validate() the frame - JFrame frame = new JFrame(title); - frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - frame.setVisible(true); - frame.setLocation(x, y); - //JAVA BUG : getInsets() doesn't work until the Window is visible - Insets insets = frame.getInsets(); - frame.setSize(w + insets.left + insets.right, h + insets.top + insets.bottom); - Container mainpane = frame.getContentPane(); - mainpane.setLayout(lm); - return frame; - } - - public static JPanel createJPanel(LayoutManager lm, Container parent) { - JPanel ret = new JPanel(); - ret.setLayout(lm); - if (parent != null) { - ret.setBounds(0, 0, parent.getWidth(), parent.getHeight()); - } - ret.setVisible(false); - if (parent != null) { - parent.add(ret); - } - return ret; - } - - public static JPanel createJPanel(int x, int y, int w, int h, LayoutManager lm, Container parent) { - JPanel ret = new JPanel(); - ret.setLayout(lm); - ret.setBounds(x, y, w, h); - ret.setVisible(false); - if (parent != null) { - parent.add(ret); - } - return ret; - } - - public static JFImage createJFImage(Container parent) { - JFImage ret = new JFImage(); - if (parent != null) { - ret.setBounds(0, 0, parent.getWidth(), parent.getHeight()); - parent.add(ret); - } - return ret; - } - - public static JFImage createJFImage(int x, int y, int w, int h, Container parent) { - JFImage ret = new JFImage(); - ret.setBounds(x, y, w, h); - if (parent != null) { - parent.add(ret); - } - return ret; - } - - /** Returns font metrics for a "monospaced" font. - * - * [0] = width - * [1] = ascent - * [2] = descent - * - * height = [1] + [2] - */ - public static int[] getFontMetrics(Font fnt) { - //after doing extensive testing none of the Java font metrics are correct - //so I just draw a char and "measure" it for myself - //return : [0]=width [1]=ascent [2]=descent (total height = ascent + descent) - //Note : add ascent with y coordinate of print() to start printing below your coordinates - //on Mac I noticed the draw square is 1 pixel higher than specified - JFImage tmp = new JFImage(128, 128); - Graphics g = tmp.getGraphics(); - g.setFont(fnt); - g.setColor(Color.white); - g.drawString("\u2588", 0, 64); - int ascent = 1; - for(int y=63;y>=0;y--,ascent++) { - if (tmp.getPixel(0, y) == 0) break; - } - int descent = 0; - for(int y=65;y<128;y++,descent++) { - if (tmp.getPixel(0, y) == 0) break; - } - int width = 0; - for(int x=0;x<128;x++,width++) { - if (tmp.getPixel(x, 63) == 0) break; - } - int ret[] = new int[3]; - ret[0] = width; - ret[1] = ascent; - ret[2] = descent; - return ret; - } - - /** Returns font metrics for regular fonts. - * - * [0] = width - * [1] = ascent - * [2] = descent - * - * height = [1] + [2] - */ - public static int[] getFontMetrics(Font font, String txt) { - JFImage tmp = new JFImage(1,1); - FontMetrics fm = tmp.getGraphics().getFontMetrics(font); - int ret[] = new int[3]; - char ca[] = txt.toCharArray(); - ret[0] = fm.charsWidth(ca, 0, ca.length); - ret[1] = fm.getAscent(); - ret[2] = fm.getDescent(); - return ret; - } - -//JOptionPane quickies (remove for Android) - - public static void showMessage(String title, String msg) { - JOptionPane.showMessageDialog(null, msg, title, JOptionPane.INFORMATION_MESSAGE); - } - - public static void showError(String title, String msg) { - JOptionPane.showMessageDialog(null, msg, title, JOptionPane.ERROR_MESSAGE); - } - - public static String getString(String msg, String str) { - return JOptionPane.showInputDialog(null, msg, str); - } - - public static boolean showConfirm(String title, String msg) { - return JOptionPane.showConfirmDialog(null, msg, title, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION; - } - public static final int YES = JOptionPane.YES_OPTION; - public static final int NO = JOptionPane.NO_OPTION; - public static final int CANCEL = JOptionPane.CANCEL_OPTION; - - public static final int showConfirm3(String title, String msg) { - return JOptionPane.showConfirmDialog(null, msg, title, JOptionPane.YES_NO_CANCEL_OPTION); - } -//misc functions - - public static void randomize(Random random) { - random.setSeed(System.currentTimeMillis()); - } -//flip endian functions - - public static short endian(short x) { - short ret = (short) (x << 8); - ret += x >>> 8; - return ret; - } - - public static int endian(int x) { - return (x << 24) - | ((x << 8) & 0xff0000) - | ((x >> 8) & 0xff00) - | (x >>> 24); - } - - public static long endian(long x) { - return (x << 56) - | ((x << 40) & 0xff000000000000L) - | ((x << 24) & 0xff0000000000L) - | ((x << 8) & 0xff00000000L) - | ((x >> 8) & 0xff000000L) - | ((x >> 24) & 0xff0000L) - | ((x >> 40) & 0xff00L) - | (x >>> 56); - } - - public static int getPID() { - String pidstr = java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); - int idx = pidstr.indexOf("@"); - if (idx == -1) { - return -1; - } - return JF.atoi(pidstr.substring(0, idx)); - } - - //copies arrays excluding one element (something Arrays is missing) - - public static Object[] copyOfExcluding(Object[] array, int idx) { - Class cls = array.getClass().getComponentType(); - Object newArray[] = (Object[]) Array.newInstance(cls, array.length - 1); - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static boolean[] copyOfExcluding(boolean[] array, int idx) { - boolean newArray[] = new boolean[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static byte[] copyOfExcluding(byte[] array, int idx) { - byte newArray[] = new byte[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static short[] copyOfExcluding(short[] array, int idx) { - short newArray[] = new short[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static int[] copyOfExcluding(int[] array, int idx) { - int newArray[] = new int[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static float[] copyOfExcluding(float[] array, int idx) { - float newArray[] = new float[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static double[] copyOfExcluding(double[] array, int idx) { - double newArray[] = new double[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - public static char[] copyOfExcluding(char[] array, int idx) { - char newArray[] = new char[array.length - 1]; - System.arraycopy(array, 0, newArray, 0, idx); - System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); - return newArray; - } - - //java5 doesn't provide this function (required for Android) - - public static byte[] copyOf(byte data[], int newLength) { - byte array[] = new byte[newLength]; - System.arraycopy(data, 0, array, 0, newLength < data.length ? newLength : data.length); - return array; - } - - /** This allows connections to untrusted hosts when using https:// with URLConnection. */ - public static void initHttps() { - TrustManager[] trustAllCerts = new TrustManager[] { - new X509TrustManager() { - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; - } - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {} - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {} - } - }; - // Let us create the factory where we can set some parameters for the connection - try { - SSLContext sc = SSLContext.getInstance("SSL"); - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - SSLSocketFactory sslsocketfactory = (SSLSocketFactory) sc.getSocketFactory(); //this method will work with untrusted certs - HttpsURLConnection.setDefaultSSLSocketFactory(sslsocketfactory); - } catch (Exception e) { - JFLog.log(e); - } - //trust any hostname - HostnameVerifier hv = new HostnameVerifier() { - public boolean verify(String urlHostName, SSLSession session) { - if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) { - System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'."); - } - return true; - } - }; - HttpsURLConnection.setDefaultHostnameVerifier(hv); - } - - /** Opens a URL in default web browser */ - public static void openURL(String url) { - try { - java.awt.Desktop.getDesktop().browse(new java.net.URI(url)); - } catch (Exception e) { - JFLog.log(e); - } - } - - /** Loads the JavaForce Certs into system. */ - public static boolean loadCerts(InputStream root, InputStream applet, String domain) { - byte rootData[] = JF.readAll(root); - byte appletData[] = JF.readAll(applet); - if (isWindows()) { - KeyMgmt keys = new KeyMgmt(); - try { - File file1 = new File(System.getenv("USERPROFILE") - + "\\AppData\\LocalLow\\Sun\\Java\\Deployment\\security\\trusted.cacerts"); - if (!file1.exists()) throw new Exception("trusted.cacerts not found"); - keys.open(new FileInputStream(file1), new char[0]); - if (!keys.hasCRT(new ByteArrayInputStream(rootData))) { - String alias = "usercacert" + Math.abs(new Random().nextLong()); - keys.loadCRT(alias, new ByteArrayInputStream(rootData)); - keys.save(new FileOutputStream(file1), new char[0]); - } - - File file2 = new File(System.getenv("USERPROFILE") - + "\\AppData\\LocalLow\\Sun\\Java\\Deployment\\security\\trusted.certs"); - if (!file2.exists()) throw new Exception("trusted.certs not found"); - keys.open(new FileInputStream(file2), new char[0]); - if (!keys.hasCRT(new ByteArrayInputStream(appletData))) { - String alias = "deploymentusercert$tsflag$loc=http//" + domain; - keys.loadCRT(alias, new ByteArrayInputStream(appletData)); - keys.save(new FileOutputStream(file2), new char[0]); - } - } catch (Exception e) { - JFLog.log(e); - return false; - } - return true; - } else { - //TODO : Linux : need to find keystore paths - return false; - } - } - - /** Assigns a single hot key to activate button. - * Use mnemonics for key combos. - */ - public static void assignHotKey(JDialog dialog, final JButton button, int vk) { - String name = "Action" + vk; - Action event = new AbstractAction() { - public void actionPerformed(ActionEvent event) { - button.doClick(); - } - }; - JRootPane root = dialog.getRootPane(); - root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(vk, 0), name); - root.getActionMap().put(name, event); - } - - /** Due to JVM bugs finding a monospaced font is not that easy... - * See : Java Bug # 9009891 @ bugs.sun.com - */ - public static Font getMonospacedFont(int style, int size) { - int width; - Font fnt; - JFImage tmp = new JFImage(1,1); - Graphics g = tmp.getGraphics(); - FontMetrics fm; - - fnt = new Font("monospaced", style, size); - g.setFont(fnt); - fm = g.getFontMetrics(); - try { - width = fm.charWidth('.'); - if (fm.charWidth('w') != width) throw new Exception("nope"); - if (fm.charWidth('\u2588') != width) throw new Exception("nope"); - return fnt; //as of 1.7.0_u51 works on linux but not windows - } catch (Exception e) {} - fnt = new Font("Lucida Console", style, size); - g.setFont(fnt); - fm = g.getFontMetrics(); - try { - width = fm.charWidth('.'); - if (fm.charWidth('w') != width) throw new Exception("nope"); - if (fm.charWidth('\u2588') != width) throw new Exception("nope"); - return fnt; //as of 1.7.0_u51 works on windows but not linux - } catch (Exception e) {} - JFLog.log("JF.getMonospacedFont():Unable to find a fixed width font"); - return null; //die! - } - - /** Same as java.awt.GraphicsEnvironment.getMaximumWindowBounds() except works after a screen mode change. - * - * See : http://stackoverflow.com/questions/22467544/java-awt-graphicsenvironment-getmaximumwindowbounds-does-not-change-after-scre - */ - public static Rectangle getMaximumBounds() { - Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()); - DisplayMode mode = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); - Rectangle bounds = new Rectangle(); - bounds.x = insets.left; - bounds.y = insets.top; - bounds.width = mode.getWidth() - (insets.left + insets.right); - bounds.height = mode.getHeight() - (insets.top + insets.bottom); - return bounds; - } - - /** Returns line # of calling method. - * See http://stackoverflow.com/questions/115008/how-can-we-print-line-numbers-to-the-log-in-java - */ - public static int getLineNumber() { - return Thread.currentThread().getStackTrace()[2].getLineNumber(); - } - - /** Joins array of strings placing a delimit inbetween each string. - * Used in .NET apps then introduced in Java8. - * This is my version for Java6+ apps. - */ - public static String join(String delimit, String strings[]) { - StringBuilder sb = new StringBuilder(); - for(int a=0;a 0) sb.append(delimit); - sb.append(strings[a]); - } - return sb.toString(); - } - - /** Centers a window on screen (works with java.awt.Window/Frame javax.swing.JWindow/JFrame/JDialog */ - public static void centerWindow(java.awt.Window window) { - Dimension d = window.getSize(); - Rectangle s = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); - window.setLocation(s.width/2 - d.width/2, s.height/2 - d.height/2); - } - - //taken from JOGL GLCanvas.java - //NOTE : should place this in addNotify() and call it before super on X11 and after for Windows. - private static boolean disableBackgroundEraseInitialized; - private static Method disableBackgroundEraseMethod; - public static void disableBackgroundErase(Component comp) { - final Component _comp = comp; - if (!disableBackgroundEraseInitialized) { - try { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Object run() { - try { - Class clazz = _comp.getToolkit().getClass(); - while (clazz != null && disableBackgroundEraseMethod == null) { - try { - disableBackgroundEraseMethod = - clazz.getDeclaredMethod("disableBackgroundErase", - new Class[] { Canvas.class }); - disableBackgroundEraseMethod.setAccessible(true); - } catch (Exception e) { - clazz = clazz.getSuperclass(); - } - } - } catch (Exception e) { - } - return null; - } - }); - } catch (Exception e) { - } - disableBackgroundEraseInitialized = true; - } - if (disableBackgroundEraseMethod != null) { - Throwable t=null; - try { - disableBackgroundEraseMethod.invoke(comp.getToolkit(), new Object[] { comp }); - } catch (Exception e) { - t = e; - } - } - } - - /** Creates a field list used for JNA Structures. */ - public static java.util.List makeFieldList(Class cls) { - //This "assumes" compiler places fields in order as defined (some don't) - ArrayList list = new ArrayList(); - Field fields[] = cls.getFields(); - for(int a=0;a list = new ArrayList(); - - boolean caseSensitive = !isWindows(); - - for(int a=0;a 0 && args[a].charAt(0) != '\"' && (args[a].indexOf('*') != -1 || args[a].indexOf('?') != -1)) { - File x = new File(args[a]); - File parent = x.getParentFile(); - String glob = x.getName(); - if (parent == null) { - parent = new File("."); - } - String parentPath = args[a].substring(0, args[a].length() - glob.length()); - if (parentPath.indexOf('*') != -1 || parentPath.indexOf('?') != -1) { - list.add(args[a]); - continue; - } - File files[] = parent.listFiles(); - if (files == null) { - list.add(args[a]); - continue; - } - int cnt = 0; - for(int f=0;f': + purl += "%3e"; + break; + default: + purl += ch; + break; + } + } + try { + URL u = new URL(purl); + HttpURLConnection huc = (HttpURLConnection) u.openConnection(); + huc.setRequestMethod("GET"); + huc.connect(); + if (huc.getResponseCode() != HttpURLConnection.HTTP_OK) { + return "huc error : " + huc.getResponseCode(); //ohoh + } + InputStream is = huc.getInputStream(); + while (true) { + read = is.read(data); + if (read <= 0) { + break; + } + str += new String(data, 0, read); + } + is.close(); + huc.disconnect(); + return str; + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static int atoi(String str) { + if (str.length() == 0) { + return 0; + } + try { + if (str.charAt(0) == '+') { + return Integer.parseInt(str.substring(1)); + } + return Integer.parseInt(str); + } catch (Exception e) { + JFLog.log(e); + return -1; + } + } + + public static float atof(String str) { + if (str.length() == 0) { + return 0; + } + try { + return Float.parseFloat(str); + } catch (Exception e) { + JFLog.log(e); + return -1; + } + } + + public static int atox(String str) { + if (str.length() == 0) { + return 0; + } + try { + return Integer.parseInt(str, 16); + } catch (Exception e) { + JFLog.log(e); + return -1; + } + } + + /** Checks if system is Windows only. */ + public static boolean isWindows() { + return (File.separatorChar == '\\'); + } + + /** Checks is system is Unix based (includes : Unix, Linux, Mac, jfLinux) */ + public static boolean isUnix() { + return (File.separatorChar == '/'); + } + + /** Checks if system is Mac only. */ + public static boolean isMac() { + if (!isUnix()) return false; + String osName = System.getProperty("os.name"); + return osName.startsWith("Mac") || osName.startsWith("Darwin"); + } + + /** Checks if system is jfLinux only. */ + public static boolean isJFLinux() { + if (!isUnix()) return false; + return new File("/usr/sbin/jlogon").exists(); + } + + public static String getUserPath() { + return System.getProperty("user.home"); + } + + public static String getCurrentUser() { + return System.getProperty("user.name"); + } + private static String user_dir = null; + + public static synchronized String getCurrentPath() { + if (user_dir == null) { + user_dir = System.getProperty("user.dir"); + } + return user_dir; + } + + /** + * This just changes the internal value returned from getCurrentPath() + */ + public static void setCurrentPath(String new_dir) { + user_dir = new_dir; + } +//file IO helper functions (these are little-endian format!!!) + + public static boolean eof(InputStream f) { + try { + return (!(f.available() > 0)); + } catch (Exception e) { + JFLog.log(e); + return true; + } + } + + public static int filelength(InputStream is) { + try { + return is.available(); + } catch (Exception e) { + JFLog.log(e); + return -1; + } + } + + public static boolean fileskip(InputStream is, int length) { + try { + is.skip(length); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean fileflush(BufferedOutputStream bos) { + try { + bos.flush(); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static FileInputStream fileopen(String name) { + try { + return new FileInputStream(name); + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static FileOutputStream filecreate(String name) { + try { + return new FileOutputStream(name); + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static FileOutputStream filecreateappend(String name) { + try { + return new FileOutputStream(name, true); + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static boolean fileclose(InputStream is) { + try { + is.close(); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean fileclose(OutputStream os) { + try { + os.close(); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static byte[] read(InputStream in, int max) { + byte ret[] = new byte[max]; + try { + int read = in.read(ret); + if (read == max) { + return ret; + } + if (read == 0) { + return null; + } + byte ret2[] = new byte[read]; + System.arraycopy(ret, 0, ret2, 0, read); + return ret2; + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static byte[] readAll(InputStream in) { + try { + int len = in.available(); + byte ret[] = new byte[len]; + int pos = 0; + while (pos < len) { + int read = in.read(ret, pos, len - pos); + if (read <= 0) { + return null; + } + pos += read; + } + return ret; + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static byte[] readAll(InputStream in, int len) { + try { + byte ret[] = new byte[len]; + int pos = 0; + while (pos < len) { + int read = in.read(ret, pos, len - pos); + if (read <= 0) { + return null; + } + pos += read; + } + return ret; + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static boolean readAll(InputStream in, byte buf[], int pos, int len) { + int end = pos + len; + try { + while (pos < end) { + int read = in.read(buf, pos, len); + if (read <= 0) { + return false; + } + pos += read; + len -= read; + } + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean readAll(RandomAccessFile in, byte buf[], int pos, int len) { + int end = pos + len; + try { + while (pos < end) { + int read = in.read(buf, pos, len); + if (read <= 0) { + return false; + } + pos += read; + len -= read; + } + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static byte[] readAll(InputStream in, Socket s) { + try { + byte tmp[] = new byte[1500]; + byte ret[] = new byte[0]; + while (in.available() > 0 || s.isConnected()) { + int read = in.read(tmp); + if (read <= 0) { + return ret; + } + int pos = ret.length; + ret = Arrays.copyOf(ret, pos + read); + System.arraycopy(tmp, 0, ret, pos, read); + } + return ret; + } catch (Exception e) { + JFLog.log(e); + return null; + } + } + + public static int read(InputStream in, byte[] buf, int pos, int len) { + try { + return in.read(buf, pos, len); + } catch (Exception e) { + JFLog.log(e); + return 0; + } + } + + public static int read(InputStream in) { + try { + return in.read(); + } catch (Exception e) { + JFLog.log(e); + return 0; + } + } + + public static char readchar(InputStream in) { + try { + return (char) in.read(); + } catch (Exception e) { + JFLog.log(e); + return 0; + } + } + + public static int readuint8(InputStream in) { + byte data[] = new byte[1]; + try { + if (in.read(data) != 1) { + return -1; + } + } catch (Exception e) { + JFLog.log(e); + return -1; + } + return (int) data[0] & 0xff; + } + + public static int readuint16(InputStream in) { + byte data[] = new byte[2]; + try { + if (in.read(data) != 2) { + return -1; + } + } catch (Exception e) { + JFLog.log(e); + return -1; + } + int ret; + ret = (int) data[0] & 0xff; + ret += ((int) data[1] & 0xff) << 8; + return ret; + } + + public static int readuint32(InputStream in) { + byte data[] = new byte[4]; + try { + if (in.read(data) != 4) { + return -1; + } + } catch (Exception e) { + JFLog.log(e); + return -1; + } + int ret; + ret = (int) data[0] & 0xff; + ret += ((int) data[1] & 0xff) << 8; + ret += ((int) data[2] & 0xff) << 16; + ret += ((int) data[3] & 0xff) << 24; + return ret; + } + + public static long readuint64(InputStream in) { + byte data[] = new byte[8]; + try { + if (in.read(data) != 8) { + return -1; + } + } catch (Exception e) { + JFLog.log(e); + return -1; + } + long ret; + ret = (long) data[0] & 0xff; + ret += ((long) data[1] & 0xff) << 8; + ret += ((long) data[2] & 0xff) << 16; + ret += ((long) data[3] & 0xff) << 24; + ret += ((long) data[4] & 0xff) << 32; + ret += ((long) data[5] & 0xff) << 40; + ret += ((long) data[6] & 0xff) << 48; + ret += ((long) data[7] & 0xff) << 56; + return ret; + } + + public static float readfloat(InputStream in) { + int bits = JF.readuint32(in); + return Float.intBitsToFloat(bits); + } + + public static double readdouble(InputStream in) { + long bits = JF.readuint64(in); + return Double.longBitsToDouble(bits); + } + + public static boolean write(OutputStream out, byte data[]) { + try { + out.write(data); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean write(OutputStream out, String str) { + return write(out, str.getBytes()); + } + + public static boolean write(OutputStream out, byte data[], int offset, int length) { + try { + out.write(data, offset, length); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean writeuint8(OutputStream out, int data) { + try { + out.write(data); + } catch (Exception e) { + JFLog.log(e); + return false; + } + return true; + } + + public static boolean writeuint16(OutputStream out, int data) { + try { + out.write(data & 0xff); + data >>= 8; + out.write(data & 0xff); + } catch (Exception e) { + JFLog.log(e); + return false; + } + return true; + } + + public static boolean writeuint32(OutputStream out, int data) { + try { + out.write(data & 0xff); + data >>= 8; + out.write(data & 0xff); + data >>= 8; + out.write(data & 0xff); + data >>= 8; + out.write(data & 0xff); + } catch (Exception e) { + JFLog.log(e); + return false; + } + return true; + } + + public static boolean writeuint64(OutputStream out, long data) { + try { + for (int a = 0; a < 8; a++) { + out.write((int) (data & 0xff)); + data >>= 8; + } + } catch (Exception e) { + JFLog.log(e); + return false; + } + return true; + } + + public static boolean writefloat(OutputStream out, float data) { + int bits = Float.floatToIntBits(data); + return writeuint32(out, bits); + } + + public static boolean writedouble(OutputStream out, double data) { + long bits = Double.doubleToLongBits(data); + return writeuint64(out, bits); + } + + public static boolean copyAll(InputStream is, OutputStream os) { + try { + int len = is.available(); + byte buf[] = new byte[1024]; + int copied = 0; + while (copied < len) { + int read = is.read(buf); + if (read == 0) { + continue; + } + if (read == -1) { + return false; + } + os.write(buf, 0, read); + copied += read; + } + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean copyAll(String src, String dst) { + try { + FileInputStream fis = new FileInputStream(src); + FileOutputStream fos = new FileOutputStream(dst); + boolean success = copyAll(fis, fos); + fis.close(); + fos.close(); + return success; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean copyAll(InputStream is, OutputStream os, long length) { + try { + byte buf[] = new byte[1024]; + int copied = 0; + while (copied < length) { + int read = is.read(buf); + if (read == 0) { + continue; + } + if (read == -1) { + return false; + } + os.write(buf, 0, read); + copied += read; + } + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static boolean isWildcard(String wcstr) { + if (wcstr.indexOf("*") != -1) return true; + if (wcstr.indexOf("?") != -1) return true; + return false; + } + + public static boolean wildcardCompare(String fnstr, String wcstr, boolean caseSensitive) { + //wc = "*.txt" + //fn = "filename.txt" + char fn[] = fnstr.toCharArray(); + char wc[] = wcstr.toCharArray(); + int fnp = 0, wcp = 0; + char wcc, fnc; + int sl, a; + while ((fnp < fn.length) && (wcp < wc.length)) { + if (wc[wcp] == '*') { + sl = fn.length - fnp; + //try 0-sl chars of fn + wcp++; + for (a = 0; a <= sl; a++) { + if (wildcardCompare( + new String(fn, fnp, fn.length - fnp), + new String(fn, fnp, a) + new String(wc, wcp, wc.length - wcp), + caseSensitive)) { + return true; + } + } + return false; + } + if (wc[wcp] == '?') { + //try 0-1 chars of fn + wcp++; + for (a = 0; a <= 1; a++) { + if (wildcardCompare( + new String(fn, fnp, fn.length - fnp), + new String(fn, fnp, a) + new String(wc, wcp, wc.length - wcp), + caseSensitive)) { + return true; + } + } + return false; + } + if (caseSensitive) { + fnc = fn[fnp]; + wcc = wc[wcp]; + } else { + fnc = Character.toUpperCase(fn[fnp]); + wcc = Character.toUpperCase(wc[wcp]); + } + if (fnc != wcc) { + break; //no match + } + fnp++; + wcp++; + }; + while ((wcp < wc.length) && ((wc[wcp] == '*') || (wc[wcp] == '?'))) { + wcp++; + } + if (wcp < wc.length) { + return false; //wc not used up + } + if (fnp < fn.length) { + return false; //fn not used up + } + return true; + } +//String char[] functions (StringBuffer is awkward) (these are NOT null terminating) + + public static char[] createstr(String str) { + return str.toCharArray(); + } + + public static char[] truncstr(char str[], int newlength) { + if (newlength == 0) { + return null; + } + char ret[] = new char[newlength]; + if (newlength <= str.length) { + System.arraycopy(str, 0, ret, 0, ret.length); + } else { + System.arraycopy(str, 0, ret, 0, str.length); + for (int a = str.length; a < ret.length; a++) { + ret[a] = 0; + } + } + return ret; + } + + public static char[] strcpy(char str[]) { + char ret[] = new char[str.length]; + System.arraycopy(str, 0, ret, 0, str.length); + return ret; + } + + public static char[] strcat(char s1[], char s2[]) { + if (s1 == null) { + s1 = new char[0]; + } + char ret[] = new char[s1.length + s2.length]; + System.arraycopy(s1, 0, ret, 0, s1.length); + System.arraycopy(s2, 0, ret, s1.length, s2.length); + return ret; + } + + public static char[] strcat(char str[], char ch) { + char ret[]; + if (str == null) { + ret = new char[1]; + ret[0] = ch; + return ret; + } + ret = new char[str.length + 1]; + System.arraycopy(str, 0, ret, 0, str.length); + ret[str.length] = ch; + return ret; + } + + public static String createString(char str[]) { + return new String(str); + } + + public static boolean strcmp(String s1, String s2) { + return s1.equals(s2); + } + + public static boolean stricmp(String s1, String s2) { + return s1.equalsIgnoreCase(s2); + } + + public static boolean strcmp(char s1[], char s2[]) { + return strcmp(new String(s1), new String(s2)); + } + + public static boolean stricmp(char s1[], char s2[]) { + return stricmp(new String(s1), new String(s2)); + } + + public static void memcpy(Object src[], int srcpos, Object dest[], int destpos, int len) { + System.arraycopy(src, srcpos, dest, destpos, len); + } + + public static boolean memcmp(byte m1[], int m1pos, byte[] m2, int m2pos, int len) { + for (int a = 0; a < len; a++) { + if (m1[m1pos + a] != m2[m2pos + a]) { + return false; + } + } + return true; + } + + public static boolean memicmp(byte m1[], int m1pos, byte[] m2, int m2pos, int len) { + char c1, c2; + for (int a = 0; a < len; a++) { + c1 = Character.toUpperCase((char) m1[m1pos + a]); + c2 = Character.toUpperCase((char) m2[m2pos + a]); + if (c1 != c2) { + return false; + } + } + return true; + } + +//executable JAR functions + + public static String getJARPath() { + //this will equal your executable JAR filename (like argv[0] in C++) + return System.getProperty("java.class.path"); + } + +//GUI functions (remove for Android) + + public static JFrame createJFrame(String title, int x, int y, int w, int h, LayoutManager lm) { + //NOTE : When you add components, you must validate() the frame + JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + frame.setVisible(true); + frame.setLocation(x, y); + //JAVA BUG : getInsets() doesn't work until the Window is visible + Insets insets = frame.getInsets(); + frame.setSize(w + insets.left + insets.right, h + insets.top + insets.bottom); + Container mainpane = frame.getContentPane(); + mainpane.setLayout(lm); + return frame; + } + + public static JPanel createJPanel(LayoutManager lm, Container parent) { + JPanel ret = new JPanel(); + ret.setLayout(lm); + if (parent != null) { + ret.setBounds(0, 0, parent.getWidth(), parent.getHeight()); + } + ret.setVisible(false); + if (parent != null) { + parent.add(ret); + } + return ret; + } + + public static JPanel createJPanel(int x, int y, int w, int h, LayoutManager lm, Container parent) { + JPanel ret = new JPanel(); + ret.setLayout(lm); + ret.setBounds(x, y, w, h); + ret.setVisible(false); + if (parent != null) { + parent.add(ret); + } + return ret; + } + + public static JFImage createJFImage(Container parent) { + JFImage ret = new JFImage(); + if (parent != null) { + ret.setBounds(0, 0, parent.getWidth(), parent.getHeight()); + parent.add(ret); + } + return ret; + } + + public static JFImage createJFImage(int x, int y, int w, int h, Container parent) { + JFImage ret = new JFImage(); + ret.setBounds(x, y, w, h); + if (parent != null) { + parent.add(ret); + } + return ret; + } + + /** Returns font metrics for a "monospaced" font. + * + * [0] = width + * [1] = ascent + * [2] = descent + * + * height = [1] + [2] + */ + public static int[] getFontMetrics(Font fnt) { + //after doing extensive testing none of the Java font metrics are correct + //so I just draw a char and "measure" it for myself + //return : [0]=width [1]=ascent [2]=descent (total height = ascent + descent) + //Note : add ascent with y coordinate of print() to start printing below your coordinates + //on Mac I noticed the draw square is 1 pixel higher than specified + JFImage tmp = new JFImage(128, 128); + Graphics g = tmp.getGraphics(); + g.setFont(fnt); + g.setColor(Color.white); + g.drawString("\u2588", 0, 64); + int ascent = 1; + for(int y=63;y>=0;y--,ascent++) { + if (tmp.getPixel(0, y) == 0) break; + } + int descent = 0; + for(int y=65;y<128;y++,descent++) { + if (tmp.getPixel(0, y) == 0) break; + } + int width = 0; + for(int x=0;x<128;x++,width++) { + if (tmp.getPixel(x, 63) == 0) break; + } + int ret[] = new int[3]; + ret[0] = width; + ret[1] = ascent; + ret[2] = descent; + return ret; + } + + /** Returns font metrics for regular fonts. + * + * [0] = width + * [1] = ascent + * [2] = descent + * + * height = [1] + [2] + */ + public static int[] getFontMetrics(Font font, String txt) { + JFImage tmp = new JFImage(1,1); + FontMetrics fm = tmp.getGraphics().getFontMetrics(font); + int ret[] = new int[3]; + char ca[] = txt.toCharArray(); + ret[0] = fm.charsWidth(ca, 0, ca.length); + ret[1] = fm.getAscent(); + ret[2] = fm.getDescent(); + return ret; + } + +//JOptionPane quickies (remove for Android) + + public static void showMessage(String title, String msg) { + JOptionPane.showMessageDialog(null, msg, title, JOptionPane.INFORMATION_MESSAGE); + } + + public static void showError(String title, String msg) { + JOptionPane.showMessageDialog(null, msg, title, JOptionPane.ERROR_MESSAGE); + } + + public static String getString(String msg, String str) { + return JOptionPane.showInputDialog(null, msg, str); + } + + public static boolean showConfirm(String title, String msg) { + return JOptionPane.showConfirmDialog(null, msg, title, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION; + } + public static final int YES = JOptionPane.YES_OPTION; + public static final int NO = JOptionPane.NO_OPTION; + public static final int CANCEL = JOptionPane.CANCEL_OPTION; + + public static final int showConfirm3(String title, String msg) { + return JOptionPane.showConfirmDialog(null, msg, title, JOptionPane.YES_NO_CANCEL_OPTION); + } +//misc functions + + public static void randomize(Random random) { + random.setSeed(System.currentTimeMillis()); + } +//flip endian functions + + public static short endian(short x) { + short ret = (short) (x << 8); + ret += x >>> 8; + return ret; + } + + public static int endian(int x) { + return (x << 24) + | ((x << 8) & 0xff0000) + | ((x >> 8) & 0xff00) + | (x >>> 24); + } + + public static long endian(long x) { + return (x << 56) + | ((x << 40) & 0xff000000000000L) + | ((x << 24) & 0xff0000000000L) + | ((x << 8) & 0xff00000000L) + | ((x >> 8) & 0xff000000L) + | ((x >> 24) & 0xff0000L) + | ((x >> 40) & 0xff00L) + | (x >>> 56); + } + + public static int getPID() { + String pidstr = java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); + int idx = pidstr.indexOf("@"); + if (idx == -1) { + return -1; + } + return JF.atoi(pidstr.substring(0, idx)); + } + + //copies arrays excluding one element (something Arrays is missing) + + public static Object[] copyOfExcluding(Object[] array, int idx) { + Class cls = array.getClass().getComponentType(); + Object newArray[] = (Object[]) Array.newInstance(cls, array.length - 1); + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static boolean[] copyOfExcluding(boolean[] array, int idx) { + boolean newArray[] = new boolean[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static byte[] copyOfExcluding(byte[] array, int idx) { + byte newArray[] = new byte[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static short[] copyOfExcluding(short[] array, int idx) { + short newArray[] = new short[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static int[] copyOfExcluding(int[] array, int idx) { + int newArray[] = new int[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static float[] copyOfExcluding(float[] array, int idx) { + float newArray[] = new float[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static double[] copyOfExcluding(double[] array, int idx) { + double newArray[] = new double[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + public static char[] copyOfExcluding(char[] array, int idx) { + char newArray[] = new char[array.length - 1]; + System.arraycopy(array, 0, newArray, 0, idx); + System.arraycopy(array, idx + 1, newArray, idx, array.length - idx - 1); + return newArray; + } + + //java5 doesn't provide this function (required for Android) + + public static byte[] copyOf(byte data[], int newLength) { + byte array[] = new byte[newLength]; + System.arraycopy(data, 0, array, 0, newLength < data.length ? newLength : data.length); + return array; + } + + /** This allows connections to untrusted hosts when using https:// with URLConnection. */ + public static void initHttps() { + TrustManager[] trustAllCerts = new TrustManager[] { + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + } + }; + // Let us create the factory where we can set some parameters for the connection + try { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + SSLSocketFactory sslsocketfactory = (SSLSocketFactory) sc.getSocketFactory(); //this method will work with untrusted certs + HttpsURLConnection.setDefaultSSLSocketFactory(sslsocketfactory); + } catch (Exception e) { + JFLog.log(e); + } + //trust any hostname + HostnameVerifier hv = new HostnameVerifier() { + public boolean verify(String urlHostName, SSLSession session) { + if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) { + System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'."); + } + return true; + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(hv); + } + + /** Opens a URL in default web browser */ + public static void openURL(String url) { + try { + java.awt.Desktop.getDesktop().browse(new java.net.URI(url)); + } catch (Exception e) { + JFLog.log(e); + } + } + + /** Loads the JavaForce Certs into system. */ + public static boolean loadCerts(InputStream root, InputStream applet, String domain) { + byte rootData[] = JF.readAll(root); + byte appletData[] = JF.readAll(applet); + if (isWindows()) { + KeyMgmt keys = new KeyMgmt(); + try { + File file1 = new File(System.getenv("USERPROFILE") + + "\\AppData\\LocalLow\\Sun\\Java\\Deployment\\security\\trusted.cacerts"); + if (!file1.exists()) throw new Exception("trusted.cacerts not found"); + keys.open(new FileInputStream(file1), new char[0]); + if (!keys.hasCRT(new ByteArrayInputStream(rootData))) { + String alias = "usercacert" + Math.abs(new Random().nextLong()); + keys.loadCRT(alias, new ByteArrayInputStream(rootData)); + keys.save(new FileOutputStream(file1), new char[0]); + } + + File file2 = new File(System.getenv("USERPROFILE") + + "\\AppData\\LocalLow\\Sun\\Java\\Deployment\\security\\trusted.certs"); + if (!file2.exists()) throw new Exception("trusted.certs not found"); + keys.open(new FileInputStream(file2), new char[0]); + if (!keys.hasCRT(new ByteArrayInputStream(appletData))) { + String alias = "deploymentusercert$tsflag$loc=http//" + domain; + keys.loadCRT(alias, new ByteArrayInputStream(appletData)); + keys.save(new FileOutputStream(file2), new char[0]); + } + } catch (Exception e) { + JFLog.log(e); + return false; + } + return true; + } else { + //TODO : Linux : need to find keystore paths + return false; + } + } + + /** Assigns a single hot key to activate button. + * Use mnemonics for key combos. + */ + public static void assignHotKey(JDialog dialog, final JButton button, int vk) { + String name = "Action" + vk; + Action event = new AbstractAction() { + public void actionPerformed(ActionEvent event) { + button.doClick(); + } + }; + JRootPane root = dialog.getRootPane(); + root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(vk, 0), name); + root.getActionMap().put(name, event); + } + + /** Due to JVM bugs finding a monospaced font is not that easy... + * See : Java Bug # 9009891 @ bugs.sun.com + */ + public static Font getMonospacedFont(int style, int size) { + int width; + Font fnt; + JFImage tmp = new JFImage(1,1); + Graphics g = tmp.getGraphics(); + FontMetrics fm; + + fnt = new Font("monospaced", style, size); + g.setFont(fnt); + fm = g.getFontMetrics(); + try { + width = fm.charWidth('.'); + if (fm.charWidth('w') != width) throw new Exception("nope"); + if (fm.charWidth('\u2588') != width) throw new Exception("nope"); + return fnt; //as of 1.7.0_u51 works on linux but not windows + } catch (Exception e) {} + fnt = new Font("Lucida Console", style, size); + g.setFont(fnt); + fm = g.getFontMetrics(); + try { + width = fm.charWidth('.'); + if (fm.charWidth('w') != width) throw new Exception("nope"); + if (fm.charWidth('\u2588') != width) throw new Exception("nope"); + return fnt; //as of 1.7.0_u51 works on windows but not linux + } catch (Exception e) {} + JFLog.log("JF.getMonospacedFont():Unable to find a fixed width font"); + return null; //die! + } + + /** Same as java.awt.GraphicsEnvironment.getMaximumWindowBounds() except works after a screen mode change. + * + * See : http://stackoverflow.com/questions/22467544/java-awt-graphicsenvironment-getmaximumwindowbounds-does-not-change-after-scre + */ + public static Rectangle getMaximumBounds() { + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()); + DisplayMode mode = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); + Rectangle bounds = new Rectangle(); + bounds.x = insets.left; + bounds.y = insets.top; + bounds.width = mode.getWidth() - (insets.left + insets.right); + bounds.height = mode.getHeight() - (insets.top + insets.bottom); + return bounds; + } + + /** Returns line # of calling method. + * See http://stackoverflow.com/questions/115008/how-can-we-print-line-numbers-to-the-log-in-java + */ + public static int getLineNumber() { + return Thread.currentThread().getStackTrace()[2].getLineNumber(); + } + + /** Joins array of strings placing a delimit inbetween each string. + * Used in .NET apps then introduced in Java8. + * This is my version for Java6+ apps. + */ + public static String join(String delimit, String strings[]) { + StringBuilder sb = new StringBuilder(); + for(int a=0;a 0) sb.append(delimit); + sb.append(strings[a]); + } + return sb.toString(); + } + + /** Centers a window on screen (works with java.awt.Window/Frame javax.swing.JWindow/JFrame/JDialog */ + public static void centerWindow(java.awt.Window window) { + Dimension d = window.getSize(); + Rectangle s = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); + window.setLocation(s.width/2 - d.width/2, s.height/2 - d.height/2); + } + + //taken from JOGL GLCanvas.java + //NOTE : should place this in addNotify() and call it before super on X11 and after for Windows. + private static boolean disableBackgroundEraseInitialized; + private static Method disableBackgroundEraseMethod; + public static void disableBackgroundErase(Component comp) { + final Component _comp = comp; + if (!disableBackgroundEraseInitialized) { + try { + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Object run() { + try { + Class clazz = _comp.getToolkit().getClass(); + while (clazz != null && disableBackgroundEraseMethod == null) { + try { + disableBackgroundEraseMethod = + clazz.getDeclaredMethod("disableBackgroundErase", + new Class[] { Canvas.class }); + disableBackgroundEraseMethod.setAccessible(true); + } catch (Exception e) { + clazz = clazz.getSuperclass(); + } + } + } catch (Exception e) { + } + return null; + } + }); + } catch (Exception e) { + } + disableBackgroundEraseInitialized = true; + } + if (disableBackgroundEraseMethod != null) { + Throwable t=null; + try { + disableBackgroundEraseMethod.invoke(comp.getToolkit(), new Object[] { comp }); + } catch (Exception e) { + t = e; + } + } + } + + /** Creates a field list used for JNA Structures. */ + public static java.util.List makeFieldList(Class cls) { + //This "assumes" compiler places fields in order as defined (some don't) + ArrayList list = new ArrayList(); + Field fields[] = cls.getFields(); + for(int a=0;a list = new ArrayList(); + + boolean caseSensitive = !isWindows(); + + for(int a=0;a 0 && args[a].charAt(0) != '\"' && (args[a].indexOf('*') != -1 || args[a].indexOf('?') != -1)) { + File x = new File(args[a]); + File parent = x.getParentFile(); + String glob = x.getName(); + if (parent == null) { + parent = new File("."); + } + String parentPath = args[a].substring(0, args[a].length() - glob.length()); + if (parentPath.indexOf('*') != -1 || parentPath.indexOf('?') != -1) { + list.add(args[a]); + continue; + } + File files[] = parent.listFiles(); + if (files == null) { + list.add(args[a]); + continue; + } + int cnt = 0; + for(int f=0;f cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("mkdir"); - cmd.add("-p"); - cmd.add(folder); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec mkdir"); - return false; - } - if (output.length() > 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - - /** - * Copies src to dst as root - */ - public static boolean copyFile(String src, String dst) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("cp"); - cmd.add(src); - cmd.add(dst); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec cp"); - return false; - } - if (output.length() > 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - - /** - * Creates Link to Target as root - */ - public static boolean createLink(String target, String link) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("ln"); - cmd.add("-s"); - cmd.add(target); - cmd.add(link); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec ln"); - return false; - } - if (output.length() > 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - - /** - * Deletes file as root - */ - public static boolean deleteFile(String file) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("rm"); - cmd.add("-f"); - cmd.add(file); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec ln"); - return false; - } - if (output.length() > 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - - /** - * Restarts a service - */ - public static boolean restartService(String name) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("service"); - cmd.add(name); - cmd.add("restart"); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec service"); - return false; - } - if (sp.getErrorLevel() != 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - - /** - * Restarts a JF service - */ - public static boolean restartJFService(String name) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("jservice"); - cmd.add(name); - cmd.add("restart"); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec jservice"); - return false; - } - if (sp.getErrorLevel() != 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - - public static boolean ubuntuUpdate() { - ShellProcess sp = new ShellProcess(); - sp.removeEnvironmentVariable("TERM"); - sp.addEnvironmentVariable("DEBIAN_FRONTEND", "noninteractive"); - String output = sp.run(new String[] {"sudo", "-E", "apt-get", "--yes", "update"}, true); - if (output == null) { - return false; - } else { - return true; - } - } - - /** - * Work with Ubuntu packages. - */ - private static boolean apt(String action, String pkg, String desc) { - JFTask task = new JFTask() { - public boolean work() { - this.setProgress(-1); - String action = (String)this.getProperty("action"); - String pkg = (String)this.getProperty("pkg"); - String desc = (String)this.getProperty("desc"); - setLabel((action.equals("install") ? "Installing " : "Removing ") + desc); - ShellProcess sp = new ShellProcess(); - sp.removeEnvironmentVariable("TERM"); - sp.addEnvironmentVariable("DEBIAN_FRONTEND", "noninteractive"); - String output = sp.run(new String[]{"sudo", "-E", "apt-get", "--yes", action, pkg}, true); - if (output == null) { - setLabel("Failed to exec apt-get"); - JFLog.log("Failed to exec apt-get"); - return false; - } - if (output.indexOf("Unable to locate package") != -1) { - setLabel("Package not found"); - JFLog.log("Package not found"); - return false; - } - setLabel("Complete"); - setProgress(100); - return true; - } - }; - task.setProperty("action", action); - task.setProperty("pkg", pkg); - task.setProperty("desc", desc); - new ProgressDialog(null, true, task).setVisible(true); - return task.getStatus(); - } - - /** - * Work with Fedora packages. - */ - private static boolean yum(String action, String pkg, String desc) { - JFTask task = new JFTask() { - public boolean work() { - this.setProgress(-1); - String action = (String)this.getProperty("action"); - String pkg = (String)this.getProperty("pkg"); - String desc = (String)this.getProperty("desc"); - setLabel((action.equals("install") ? "Installing " : "Removing ") + desc); - ShellProcess sp = new ShellProcess(); - sp.removeEnvironmentVariable("TERM"); //prevent config dialogs - String output = sp.run(new String[]{"sudo", "-E", "yum", "-y", action, pkg}, false); - if (output == null) { - setLabel("Failed to exec yum"); - JFLog.log("Failed to exec yum"); - return false; - } - setLabel("Complete"); - setProgress(100); - return true; - } - }; - task.setProperty("action", action); - task.setProperty("pkg", pkg); - task.setProperty("desc", desc); - new ProgressDialog(null, true, task).setVisible(true); - return task.getStatus(); - } - - public static boolean installPackage(String pkg, String desc) { - detectDistro(); - switch (distro) { - case Ubuntu: - return apt("install", pkg, desc); - case Fedora: - return yum("install", pkg, desc); - } - return false; - } - - public static boolean removePackage(String pkg, String desc) { - detectDistro(); - switch (distro) { - case Ubuntu: - return apt("autoremove", pkg, desc); - case Fedora: - return yum("remove", pkg, desc); - } - return false; - } - - /** - * Sets file as executable as root - */ - public static boolean setExec(String file) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("sudo"); - cmd.add("chmod"); - cmd.add("+x"); - cmd.add(file); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Failed to exec chmod"); - return false; - } - if (output.length() > 0) { - JFLog.log("Error:" + output); - return false; - } - return true; - } - private static String pkgList[][]; - - /* public static String[][] getPackages() { - if (dpkg == null) updateInstalled(); - return dpkg; - }*/ - private static String[][] ubuntu_searchPackages(String regex) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("apt-cache"); - cmd.add("search"); - cmd.add(regex); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Error:unable to execute apt-cache"); - return null; - } - String lns[] = output.split("\n"); - String ret[][] = new String[lns.length][2]; - String f[]; - for (int a = 0; a < lns.length; a++) { - f = lns[a].split(" - "); - if (f.length != 2) { - continue; - } - ret[a][0] = f[0]; //package name - ret[a][1] = f[1]; //package desc - } - return ret; - } - - private static String[][] fedora_searchPackages(String regex) { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("yum"); - cmd.add("search"); - cmd.add(regex); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Error:unable to execute yum"); - return null; - } - String lns[] = output.split("\n"); - String ret[][] = new String[lns.length][2]; - String f[]; - for (int a = 0; a < lns.length; a++) { - f = lns[a].split(" : "); - if (f.length != 2) { - continue; - } - ret[a][0] = f[0]; //package name - ret[a][1] = f[1]; //package desc - } - return ret; - } - - /** - * Searches for available packages (NOTE:There may be nulls in the output) - */ - public static String[][] searchPackages(String regex) { - detectDistro(); - switch (distro) { - case Ubuntu: - return ubuntu_searchPackages(regex); - case Fedora: - return fedora_searchPackages(regex); - } - return null; - } - - public static void ubuntu_updateInstalled() { - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("dpkg"); - cmd.add("-l"); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Error:unable to execute dpkg"); - return; - } - String lns[] = output.split("\n"); - pkgList = new String[lns.length - 5][3]; - String f[]; - for (int a = 5; a < lns.length; a++) { - f = lns[a].split(" +", 4); //greedy spaces - pkgList[a - 5][0] = f[1]; //package name - pkgList[a - 5][1] = f[3]; //package desc - pkgList[a - 5][2] = (f[0].charAt(0) == 'i' ? "true" : "false"); //package installed? - } - } - - public static void fedora_updateInstalled() { - //NOTE:can't use "rpm -qa" because the version # is mangled in the name - ShellProcess sp = new ShellProcess(); - ArrayList cmd = new ArrayList(); - cmd.add("yum"); - cmd.add("list"); - cmd.add("installed"); - String output = sp.run(cmd, false); - if (output == null) { - JFLog.log("Error:unable to execute yum"); - return; - } - String lns[] = output.split("\n"); - pkgList = new String[lns.length - 2][3]; - for (int a = 2; a < lns.length; a++) { - String f[] = lns[a].split(" +"); //greedy spaces - if (f.length != 3) { - pkgList[a-2][0] = ""; - pkgList[a-2][1] = ""; - pkgList[a-2][2] = ""; - continue; - } - int idx = f[0].lastIndexOf("."); //strip arch - if (idx == -1) { - pkgList[a-2][0] = f[0]; //package name - } else { - pkgList[a-2][0] = f[0].substring(0, idx); //package name - } - pkgList[a-2][1] = f[1]; //package desc - pkgList[a-2][2] = "true"; //package installed? - } - } - - public static void updateInstalled() { - detectDistro(); - switch (distro) { - case Ubuntu: - ubuntu_updateInstalled(); - break; - case Fedora: - fedora_updateInstalled(); - break; - } - } - - public static boolean isInstalled(String pkg) { - if (pkg == null) { - return true; - } - if (pkgList == null) { - updateInstalled(); - } - for (int a = 0; a < pkgList.length; a++) { - if (pkgList[a][0].equals(pkg)) { - return pkgList[a][2].equals("true"); - } - } - return false; - } - - public static String getPackageDesc(String pkg) { - if (pkg == null) { - return ""; - } - if (pkgList == null) { - updateInstalled(); - if (pkgList == null) { - return ""; - } - } - for (int a = 0; a < pkgList.length; a++) { - if (pkgList[a][0].equals(pkg)) { - return pkgList[a][1]; - } - } - return ""; - } - - public static boolean isMemberOf(String user, String group) { - try { - ShellProcess sp = new ShellProcess(); - String output = sp.run(new String[]{"groups", user}, false).replaceAll("\n", ""); - //output = "user : group1 group2 ..." - String groups[] = output.split(" "); - for (int a = 2; a < groups.length; a++) { - if (groups[a].equals(group)) { - return true; - } - } - return false; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - private static String expandQuotes(String inString) { - while (true) { - int i1 = inString.indexOf('\"'); - if (i1 == -1) { - return inString; - } - int i2 = inString.indexOf('\"', i1 + 1); - if (i2 == -1) { - return inString; - } - inString = inString.substring(0, i1) + inString.substring(i1 + 1, i2).replace(' ', '\u1234') + inString.substring(i2 + 1); - } - } - - private static String[] expandBackslash(String inString) { - StringBuilder out = new StringBuilder(); - char inCA[] = inString.toCharArray(); - for (int a = 0; a < inCA.length; a++) { - if (inCA[a] == '\\') { - if (inCA[a + 1] == '\\') { - if (inCA[a + 2] == '\\') { - if (inCA[a + 3] == '\\') { - out.append('\\'); - out.append('\\'); - a += 3; - continue; - } - } else if (inCA[a + 2] == ' ') { - out.append('\u1234'); - a += 2; - continue; - } else { - out.append('\\'); - a++; - continue; - } - } - } - out.append(inCA[a]); - } - String cmd[] = out.toString().split(" "); - for (int a = 0; a < cmd.length; a++) { - if (cmd[a].indexOf('\u1234') != -1) { - cmd[a] = cmd[a].replace('\u1234', ' '); - } - } - return cmd; - } - - /** - * Currently only supports %f,%F,%u,%U - */ - public static String[] expandDesktopExec(String exec, String file) { - if (file == null) { - file = ""; - } - file = '\"' + file + '\"'; - exec = exec.replaceAll("%f", file); - exec = exec.replaceAll("%F", file); - exec = exec.replaceAll("%u", file); - exec = exec.replaceAll("%U", file); - exec = expandQuotes(exec); - return expandBackslash(exec); - } - - /** - * Currently only supports %f,%F,%u,%U - */ - public static String[] expandDesktopExec(String exec, String file[]) { - String files = ""; - if (file != null) { - for (int a = 0; a < file.length; a++) { - if (a > 0) { - files += " "; - } - files += '\"' + file[a] + '\"'; - } - } else { - file = new String[1]; - file[0] = ""; - } - exec = exec.replaceAll("%f", '\"' + file[0] + '\"'); - exec = exec.replaceAll("%F", files); - exec = exec.replaceAll("%u", '\"' + file[0] + '\"'); - exec = exec.replaceAll("%U", files); - exec = expandQuotes(exec); - return expandBackslash(exec); - } - - public static boolean executeDesktop(String desktop, String file[]) { - try { - Properties props = new Properties(); - FileInputStream fis = new FileInputStream(desktop); - props.load(fis); - fis.close(); - String exec = props.getProperty("Exec"); - String path = props.getProperty("Path"); - if (path == null || path.length() == 0) { - path = System.getenv("HOME"); - if (path == null || path.length() == 0) { - path = "/"; - } - } - ProcessBuilder pb = new ProcessBuilder(); - pb.directory(new File(path)); - String expand[] = expandDesktopExec(exec, file); - pb.command(expand); - pb.start(); - return true; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - public static int detectBits() { - if (new File("/usr/lib64").exists()) { - return 64; - } - return 32; - } - - /** - * Runs a bash script as root - */ - public static boolean runScript(String lns[]) { - try { - File tmpFile = File.createTempFile("script", ".sh", new File("/tmp")); - FileOutputStream fos = new FileOutputStream(tmpFile); - fos.write("#!/bin/bash\n".getBytes()); - for (int a = 0; a < lns.length; a++) { - fos.write((lns[a] + "\n").getBytes()); - } - fos.close(); - tmpFile.setExecutable(true); - ShellProcess sp = new ShellProcess(); - String output = sp.run(new String[]{"sudo", tmpFile.getAbsolutePath()}, true); - tmpFile.delete(); - return sp.getErrorLevel() == 0; - } catch (Exception e) { - JFLog.log(e); - return false; - } - } - - private static final int None = 0; - private static final int CurrentTime = 0; - private static final int ShiftMask = 1; - - private static final int True = 1; - private static final int False = 0; - - private static final int KeyPress = 2; - private static final int KeyRelease = 3; - private static final int CreateNotify = 16; - private static final int DestroyNotify = 17; - private static final int UnmapNotify = 18; - private static final int MapNotify = 19; - private static final int ReparentNotify = 21; - private static final int ConfigureNotify = 22; - private static final int PropertyNotify = 28; - private static final int ClientMessage = 33; - - private static final int KeyPressMask = 1; - private static final int KeyReleaseMask = (1 << 1); - private static final int StructureNotifyMask = (1 << 17); - private static final int SubstructureNotifyMask = (1 << 19); - private static final int PropertyChangeMask = (1 << 22); - - public static boolean init() { - return true; - } - - public static long x11_get_id(java.awt.Window w) { - return LnxNative.x11_get_id(w); - } - - public static void x11_set_desktop(long xid) { - LnxNative.x11_set_desktop(xid); - } - - public static void x11_set_dock(long xid) { - LnxNative.x11_set_dock(xid); - } - - public static void x11_set_strut(long xid, int panelHeight, int x, int y, int width, int height) { - LnxNative.x11_set_strut(xid, panelHeight,x,y,width,height); - } - -//tray functions - - public static void x11_set_listener(X11Listener cb) { - //x11_listener = cb; //TODO - } - - /** Polls and dispatches tray events. Does not return until x11_tray_stop() is called. */ - public static void x11_tray_main(long pid, int screenWidth, int trayPos, int trayHeight) { - LnxNative.x11_tray_main(pid, screenWidth, trayPos, trayHeight); - } - - /** Repositions tray icons and the tray window itself. - * - * @param screenWidth = new screen width (-1 = has not changed) - */ - public static void x11_tray_reposition(int screenWidth, int trayPos, int trayHeight) { - LnxNative.x11_tray_reposition(screenWidth, trayPos, trayHeight); - } - - /** Stops x11_tray_main() */ - public static void x11_tray_stop() { - LnxNative.x11_tray_stop(); - } - - public static int x11_tray_width() { - return LnxNative.x11_tray_width(); - } - -//top-level x11 windows monitor - - /** Polls and dispatches top-level windows events. Does not return until x11_window_list_stop() is called. */ - public static void x11_window_list_main() { - LnxNative.x11_window_list_main(); - } - - public static void x11_window_list_stop() { - LnxNative.x11_window_list_stop(); - //TODO : send a message to ??? to cause main() loop to abort - } - - public static class Window { - public long xid; - public int pid; - public String title; //_NET_WM_NAME - public String name; //XFetchName - public String res_name, res_class; - public String file; //user defined - public long org_event_mask; - public Window(long xid, int pid, String title, String name, String res_name, String res_class) { - this.xid = xid; - this.pid = pid; - this.title = title; - this.name = name; - this.res_name = res_name; - this.res_class = res_class; - } - } - - private static ArrayList currentList = new ArrayList(); - private static Object currentListLock = new Object(); - - /** Returns list of all top-level windows. - * NOTE : x11_window_list_main() must be running. - */ - public static Window[] x11_get_window_list() { - //create a "copy" of currentList - synchronized(currentListLock) { - return currentList.toArray(new Window[0]); - } - } - - //called from native code to add/update a window - private static void x11_window_add(long xid, int pid, String title, String name, String res_name, String res_class) { - Window window = new Window(xid, pid, title, name, res_name, res_class); - synchronized(currentListLock) { - int cnt = currentList.size(); - for(int a=0;a sizes = new ArrayList(); - } - - public static class Screen { - public int idx; - public ArrayList ports = new ArrayList(); - } - - public static class Monitor { - public String name; - public String res = ""; //resolution - public int rotate; //NORMAL, RIGHT, LEFT, INVERTED - public boolean mirror; //relpos ignored - public int relpos; //NONE, LEFT, RIGHT, BELOW, ABOVE, SAME - public String relName = ""; //relative to this monitor - } - - public static final int P_NONE = 0; //only primary uses P_NONE - public static final int P_LEFT = 1; - public static final int P_ABOVE = 2; - public static final int P_RIGHT = 3; - public static final int P_BELOW = 4; - public static final int P_SAME = 5; - - public static final int R_NORMAL = 0; - public static final int R_RIGHT = 1; //CW - public static final int R_LEFT = 2; //CCW - public static final int R_INVERTED = 3; - - public static ArrayList screens = new ArrayList(); - - /** X11 : RandR : Detects current state. - * @param config = current settings (optional) - * @return new settings - */ - public static Monitor[] x11_rr_get_setup(Monitor config[]) { - //xrandr output: - //-------------- - //Screen 0: minimum 1 x 1, current X x Y, maximum 8192 x 8192 - //MonitorName [dis]connected XxY+0+0 [rotation] (normal left inverted right x axis y axis) 0mm x 0mm - // XxY freq*+ [freq2] (where *=current +=preferred) - //-------------- - //(where rotation = right, left, inverted) - - screens.clear(); - Screen screen = null; - Port port = null; - Size size = null; - ArrayList newConfig = new ArrayList(); - - ShellProcess sp = new ShellProcess(); - String output = sp.run(new String[] {"xrandr"}, false); - String lns[] = output.split("\n"); - for(int a=0;a 2 && f[2].equals("+")); - port.sizes.add(size); - } else { - //port - port = new Port(); - int i1 = lns[a].indexOf(" "); - port.name = lns[a].substring(0, i1); - port.connected = lns[a].substring(i1+1).startsWith("connected"); - screen.ports.add(port); - } - } - if (config == null) config = new Monitor[0]; - for(int b=0;b 0) { - monitor.res = port.sizes.get(0).size; - } else { - //no sizes??? - JFLog.log("Warning:Monitor " + monitor.name + " has no sizes, trying 800x600"); - monitor.res = "800x600"; //must use something or xrandr options will be corrupt - } - } - } - newConfig.add(monitor); - } - } - return x11_rr_arrangeMonitors(newConfig.toArray(new Monitor[0])); - } - - /** Arranges monitors ensuring they all have valid positions. - * @return : the same list of monitors - */ - public static Monitor[] x11_rr_arrangeMonitors(Monitor monitors[]) { - for(int m=1;m cmd = new ArrayList(); - cmd.add("xrandr"); - for(int a=0;a cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("mkdir"); + cmd.add("-p"); + cmd.add(folder); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec mkdir"); + return false; + } + if (output.length() > 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + + /** + * Copies src to dst as root + */ + public static boolean copyFile(String src, String dst) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("cp"); + cmd.add(src); + cmd.add(dst); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec cp"); + return false; + } + if (output.length() > 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + + /** + * Creates Link to Target as root + */ + public static boolean createLink(String target, String link) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("ln"); + cmd.add("-s"); + cmd.add(target); + cmd.add(link); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec ln"); + return false; + } + if (output.length() > 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + + /** + * Deletes file as root + */ + public static boolean deleteFile(String file) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("rm"); + cmd.add("-f"); + cmd.add(file); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec ln"); + return false; + } + if (output.length() > 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + + /** + * Restarts a service + */ + public static boolean restartService(String name) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("service"); + cmd.add(name); + cmd.add("restart"); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec service"); + return false; + } + if (sp.getErrorLevel() != 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + + /** + * Restarts a JF service + */ + public static boolean restartJFService(String name) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("jservice"); + cmd.add(name); + cmd.add("restart"); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec jservice"); + return false; + } + if (sp.getErrorLevel() != 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + + public static boolean ubuntuUpdate() { + ShellProcess sp = new ShellProcess(); + sp.removeEnvironmentVariable("TERM"); + sp.addEnvironmentVariable("DEBIAN_FRONTEND", "noninteractive"); + String output = sp.run(new String[] {"sudo", "-E", "apt-get", "--yes", "update"}, true); + if (output == null) { + return false; + } else { + return true; + } + } + + /** + * Work with Ubuntu packages. + */ + private static boolean apt(String action, String pkg, String desc) { + JFTask task = new JFTask() { + public boolean work() { + this.setProgress(-1); + String action = (String)this.getProperty("action"); + String pkg = (String)this.getProperty("pkg"); + String desc = (String)this.getProperty("desc"); + setLabel((action.equals("install") ? "Installing " : "Removing ") + desc); + ShellProcess sp = new ShellProcess(); + sp.removeEnvironmentVariable("TERM"); + sp.addEnvironmentVariable("DEBIAN_FRONTEND", "noninteractive"); + String output = sp.run(new String[]{"sudo", "-E", "apt-get", "--yes", action, pkg}, true); + if (output == null) { + setLabel("Failed to exec apt-get"); + JFLog.log("Failed to exec apt-get"); + return false; + } + if (output.indexOf("Unable to locate package") != -1) { + setLabel("Package not found"); + JFLog.log("Package not found"); + return false; + } + setLabel("Complete"); + setProgress(100); + return true; + } + }; + task.setProperty("action", action); + task.setProperty("pkg", pkg); + task.setProperty("desc", desc); + new ProgressDialog(null, true, task).setVisible(true); + return task.getStatus(); + } + + /** + * Work with Fedora packages. + */ + private static boolean yum(String action, String pkg, String desc) { + JFTask task = new JFTask() { + public boolean work() { + this.setProgress(-1); + String action = (String)this.getProperty("action"); + String pkg = (String)this.getProperty("pkg"); + String desc = (String)this.getProperty("desc"); + setLabel((action.equals("install") ? "Installing " : "Removing ") + desc); + ShellProcess sp = new ShellProcess(); + sp.removeEnvironmentVariable("TERM"); //prevent config dialogs + String output = sp.run(new String[]{"sudo", "-E", "yum", "-y", action, pkg}, false); + if (output == null) { + setLabel("Failed to exec yum"); + JFLog.log("Failed to exec yum"); + return false; + } + setLabel("Complete"); + setProgress(100); + return true; + } + }; + task.setProperty("action", action); + task.setProperty("pkg", pkg); + task.setProperty("desc", desc); + new ProgressDialog(null, true, task).setVisible(true); + return task.getStatus(); + } + + public static boolean installPackage(String pkg, String desc) { + detectDistro(); + switch (distro) { + case Ubuntu: + return apt("install", pkg, desc); + case Fedora: + return yum("install", pkg, desc); + } + return false; + } + + public static boolean removePackage(String pkg, String desc) { + detectDistro(); + switch (distro) { + case Ubuntu: + return apt("autoremove", pkg, desc); + case Fedora: + return yum("remove", pkg, desc); + } + return false; + } + + /** + * Sets file as executable as root + */ + public static boolean setExec(String file) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("sudo"); + cmd.add("chmod"); + cmd.add("+x"); + cmd.add(file); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Failed to exec chmod"); + return false; + } + if (output.length() > 0) { + JFLog.log("Error:" + output); + return false; + } + return true; + } + private static String pkgList[][]; + + /* public static String[][] getPackages() { + if (dpkg == null) updateInstalled(); + return dpkg; + }*/ + private static String[][] ubuntu_searchPackages(String regex) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("apt-cache"); + cmd.add("search"); + cmd.add(regex); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Error:unable to execute apt-cache"); + return null; + } + String lns[] = output.split("\n"); + String ret[][] = new String[lns.length][2]; + String f[]; + for (int a = 0; a < lns.length; a++) { + f = lns[a].split(" - "); + if (f.length != 2) { + continue; + } + ret[a][0] = f[0]; //package name + ret[a][1] = f[1]; //package desc + } + return ret; + } + + private static String[][] fedora_searchPackages(String regex) { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("yum"); + cmd.add("search"); + cmd.add(regex); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Error:unable to execute yum"); + return null; + } + String lns[] = output.split("\n"); + String ret[][] = new String[lns.length][2]; + String f[]; + for (int a = 0; a < lns.length; a++) { + f = lns[a].split(" : "); + if (f.length != 2) { + continue; + } + ret[a][0] = f[0]; //package name + ret[a][1] = f[1]; //package desc + } + return ret; + } + + /** + * Searches for available packages (NOTE:There may be nulls in the output) + */ + public static String[][] searchPackages(String regex) { + detectDistro(); + switch (distro) { + case Ubuntu: + return ubuntu_searchPackages(regex); + case Fedora: + return fedora_searchPackages(regex); + } + return null; + } + + public static void ubuntu_updateInstalled() { + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("dpkg"); + cmd.add("-l"); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Error:unable to execute dpkg"); + return; + } + String lns[] = output.split("\n"); + pkgList = new String[lns.length - 5][3]; + String f[]; + for (int a = 5; a < lns.length; a++) { + f = lns[a].split(" +", 4); //greedy spaces + pkgList[a - 5][0] = f[1]; //package name + pkgList[a - 5][1] = f[3]; //package desc + pkgList[a - 5][2] = (f[0].charAt(0) == 'i' ? "true" : "false"); //package installed? + } + } + + public static void fedora_updateInstalled() { + //NOTE:can't use "rpm -qa" because the version # is mangled in the name + ShellProcess sp = new ShellProcess(); + ArrayList cmd = new ArrayList(); + cmd.add("yum"); + cmd.add("list"); + cmd.add("installed"); + String output = sp.run(cmd, false); + if (output == null) { + JFLog.log("Error:unable to execute yum"); + return; + } + String lns[] = output.split("\n"); + pkgList = new String[lns.length - 2][3]; + for (int a = 2; a < lns.length; a++) { + String f[] = lns[a].split(" +"); //greedy spaces + if (f.length != 3) { + pkgList[a-2][0] = ""; + pkgList[a-2][1] = ""; + pkgList[a-2][2] = ""; + continue; + } + int idx = f[0].lastIndexOf("."); //strip arch + if (idx == -1) { + pkgList[a-2][0] = f[0]; //package name + } else { + pkgList[a-2][0] = f[0].substring(0, idx); //package name + } + pkgList[a-2][1] = f[1]; //package desc + pkgList[a-2][2] = "true"; //package installed? + } + } + + public static void updateInstalled() { + detectDistro(); + switch (distro) { + case Ubuntu: + ubuntu_updateInstalled(); + break; + case Fedora: + fedora_updateInstalled(); + break; + } + } + + public static boolean isInstalled(String pkg) { + if (pkg == null) { + return true; + } + if (pkgList == null) { + updateInstalled(); + } + for (int a = 0; a < pkgList.length; a++) { + if (pkgList[a][0].equals(pkg)) { + return pkgList[a][2].equals("true"); + } + } + return false; + } + + public static String getPackageDesc(String pkg) { + if (pkg == null) { + return ""; + } + if (pkgList == null) { + updateInstalled(); + if (pkgList == null) { + return ""; + } + } + for (int a = 0; a < pkgList.length; a++) { + if (pkgList[a][0].equals(pkg)) { + return pkgList[a][1]; + } + } + return ""; + } + + public static boolean isMemberOf(String user, String group) { + try { + ShellProcess sp = new ShellProcess(); + String output = sp.run(new String[]{"groups", user}, false).replaceAll("\n", ""); + //output = "user : group1 group2 ..." + String groups[] = output.split(" "); + for (int a = 2; a < groups.length; a++) { + if (groups[a].equals(group)) { + return true; + } + } + return false; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + private static String expandQuotes(String inString) { + while (true) { + int i1 = inString.indexOf('\"'); + if (i1 == -1) { + return inString; + } + int i2 = inString.indexOf('\"', i1 + 1); + if (i2 == -1) { + return inString; + } + inString = inString.substring(0, i1) + inString.substring(i1 + 1, i2).replace(' ', '\u1234') + inString.substring(i2 + 1); + } + } + + private static String[] expandBackslash(String inString) { + StringBuilder out = new StringBuilder(); + char inCA[] = inString.toCharArray(); + for (int a = 0; a < inCA.length; a++) { + if (inCA[a] == '\\') { + if (inCA[a + 1] == '\\') { + if (inCA[a + 2] == '\\') { + if (inCA[a + 3] == '\\') { + out.append('\\'); + out.append('\\'); + a += 3; + continue; + } + } else if (inCA[a + 2] == ' ') { + out.append('\u1234'); + a += 2; + continue; + } else { + out.append('\\'); + a++; + continue; + } + } + } + out.append(inCA[a]); + } + String cmd[] = out.toString().split(" "); + for (int a = 0; a < cmd.length; a++) { + if (cmd[a].indexOf('\u1234') != -1) { + cmd[a] = cmd[a].replace('\u1234', ' '); + } + } + return cmd; + } + + /** + * Currently only supports %f,%F,%u,%U + */ + public static String[] expandDesktopExec(String exec, String file) { + if (file == null) { + file = ""; + } + file = '\"' + file + '\"'; + exec = exec.replaceAll("%f", file); + exec = exec.replaceAll("%F", file); + exec = exec.replaceAll("%u", file); + exec = exec.replaceAll("%U", file); + exec = expandQuotes(exec); + return expandBackslash(exec); + } + + /** + * Currently only supports %f,%F,%u,%U + */ + public static String[] expandDesktopExec(String exec, String file[]) { + String files = ""; + if (file != null) { + for (int a = 0; a < file.length; a++) { + if (a > 0) { + files += " "; + } + files += '\"' + file[a] + '\"'; + } + } else { + file = new String[1]; + file[0] = ""; + } + exec = exec.replaceAll("%f", '\"' + file[0] + '\"'); + exec = exec.replaceAll("%F", files); + exec = exec.replaceAll("%u", '\"' + file[0] + '\"'); + exec = exec.replaceAll("%U", files); + exec = expandQuotes(exec); + return expandBackslash(exec); + } + + public static boolean executeDesktop(String desktop, String file[]) { + try { + Properties props = new Properties(); + FileInputStream fis = new FileInputStream(desktop); + props.load(fis); + fis.close(); + String exec = props.getProperty("Exec"); + String path = props.getProperty("Path"); + if (path == null || path.length() == 0) { + path = System.getenv("HOME"); + if (path == null || path.length() == 0) { + path = "/"; + } + } + ProcessBuilder pb = new ProcessBuilder(); + pb.directory(new File(path)); + String expand[] = expandDesktopExec(exec, file); + pb.command(expand); + pb.start(); + return true; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + public static int detectBits() { + if (new File("/usr/lib64").exists()) { + return 64; + } + return 32; + } + + /** + * Runs a bash script as root + */ + public static boolean runScript(String lns[]) { + try { + File tmpFile = File.createTempFile("script", ".sh", new File("/tmp")); + FileOutputStream fos = new FileOutputStream(tmpFile); + fos.write("#!/bin/bash\n".getBytes()); + for (int a = 0; a < lns.length; a++) { + fos.write((lns[a] + "\n").getBytes()); + } + fos.close(); + tmpFile.setExecutable(true); + ShellProcess sp = new ShellProcess(); + String output = sp.run(new String[]{"sudo", tmpFile.getAbsolutePath()}, true); + tmpFile.delete(); + return sp.getErrorLevel() == 0; + } catch (Exception e) { + JFLog.log(e); + return false; + } + } + + private static final int None = 0; + private static final int CurrentTime = 0; + private static final int ShiftMask = 1; + + private static final int True = 1; + private static final int False = 0; + + private static final int KeyPress = 2; + private static final int KeyRelease = 3; + private static final int CreateNotify = 16; + private static final int DestroyNotify = 17; + private static final int UnmapNotify = 18; + private static final int MapNotify = 19; + private static final int ReparentNotify = 21; + private static final int ConfigureNotify = 22; + private static final int PropertyNotify = 28; + private static final int ClientMessage = 33; + + private static final int KeyPressMask = 1; + private static final int KeyReleaseMask = (1 << 1); + private static final int StructureNotifyMask = (1 << 17); + private static final int SubstructureNotifyMask = (1 << 19); + private static final int PropertyChangeMask = (1 << 22); + + public static boolean init() { + return true; + } + + public static long x11_get_id(java.awt.Window w) { + return LnxNative.x11_get_id(w); + } + + public static void x11_set_desktop(long xid) { + LnxNative.x11_set_desktop(xid); + } + + public static void x11_set_dock(long xid) { + LnxNative.x11_set_dock(xid); + } + + public static void x11_set_strut(long xid, int panelHeight, int x, int y, int width, int height) { + LnxNative.x11_set_strut(xid, panelHeight,x,y,width,height); + } + +//tray functions + + public static void x11_set_listener(X11Listener cb) { + //x11_listener = cb; //TODO + } + + /** Polls and dispatches tray events. Does not return until x11_tray_stop() is called. */ + public static void x11_tray_main(long pid, int screenWidth, int trayPos, int trayHeight) { + LnxNative.x11_tray_main(pid, screenWidth, trayPos, trayHeight); + } + + /** Repositions tray icons and the tray window itself. + * + * @param screenWidth = new screen width (-1 = has not changed) + */ + public static void x11_tray_reposition(int screenWidth, int trayPos, int trayHeight) { + LnxNative.x11_tray_reposition(screenWidth, trayPos, trayHeight); + } + + /** Stops x11_tray_main() */ + public static void x11_tray_stop() { + LnxNative.x11_tray_stop(); + } + + public static int x11_tray_width() { + return LnxNative.x11_tray_width(); + } + +//top-level x11 windows monitor + + /** Polls and dispatches top-level windows events. Does not return until x11_window_list_stop() is called. */ + public static void x11_window_list_main() { + LnxNative.x11_window_list_main(); + } + + public static void x11_window_list_stop() { + LnxNative.x11_window_list_stop(); + //TODO : send a message to ??? to cause main() loop to abort + } + + public static class Window { + public long xid; + public int pid; + public String title; //_NET_WM_NAME + public String name; //XFetchName + public String res_name, res_class; + public String file; //user defined + public long org_event_mask; + public Window(long xid, int pid, String title, String name, String res_name, String res_class) { + this.xid = xid; + this.pid = pid; + this.title = title; + this.name = name; + this.res_name = res_name; + this.res_class = res_class; + } + } + + private static ArrayList currentList = new ArrayList(); + private static Object currentListLock = new Object(); + + /** Returns list of all top-level windows. + * NOTE : x11_window_list_main() must be running. + */ + public static Window[] x11_get_window_list() { + //create a "copy" of currentList + synchronized(currentListLock) { + return currentList.toArray(new Window[0]); + } + } + + //called from native code to add/update a window + private static void x11_window_add(long xid, int pid, String title, String name, String res_name, String res_class) { + Window window = new Window(xid, pid, title, name, res_name, res_class); + synchronized(currentListLock) { + int cnt = currentList.size(); + for(int a=0;a sizes = new ArrayList(); + } + + public static class Screen { + public int idx; + public ArrayList ports = new ArrayList(); + } + + public static class Monitor { + public String name; + public String res = ""; //resolution + public int rotate; //NORMAL, RIGHT, LEFT, INVERTED + public boolean mirror; //relpos ignored + public int relpos; //NONE, LEFT, RIGHT, BELOW, ABOVE, SAME + public String relName = ""; //relative to this monitor + } + + public static final int P_NONE = 0; //only primary uses P_NONE + public static final int P_LEFT = 1; + public static final int P_ABOVE = 2; + public static final int P_RIGHT = 3; + public static final int P_BELOW = 4; + public static final int P_SAME = 5; + + public static final int R_NORMAL = 0; + public static final int R_RIGHT = 1; //CW + public static final int R_LEFT = 2; //CCW + public static final int R_INVERTED = 3; + + public static ArrayList screens = new ArrayList(); + + /** X11 : RandR : Detects current state. + * @param config = current settings (optional) + * @return new settings + */ + public static Monitor[] x11_rr_get_setup(Monitor config[]) { + //xrandr output: + //-------------- + //Screen 0: minimum 1 x 1, current X x Y, maximum 8192 x 8192 + //MonitorName [dis]connected XxY+0+0 [rotation] (normal left inverted right x axis y axis) 0mm x 0mm + // XxY freq*+ [freq2] (where *=current +=preferred) + //-------------- + //(where rotation = right, left, inverted) + + screens.clear(); + Screen screen = null; + Port port = null; + Size size = null; + ArrayList newConfig = new ArrayList(); + + ShellProcess sp = new ShellProcess(); + String output = sp.run(new String[] {"xrandr"}, false); + String lns[] = output.split("\n"); + for(int a=0;a 2 && f[2].equals("+")); + port.sizes.add(size); + } else { + //port + port = new Port(); + int i1 = lns[a].indexOf(" "); + port.name = lns[a].substring(0, i1); + port.connected = lns[a].substring(i1+1).startsWith("connected"); + screen.ports.add(port); + } + } + if (config == null) config = new Monitor[0]; + for(int b=0;b 0) { + monitor.res = port.sizes.get(0).size; + } else { + //no sizes??? + JFLog.log("Warning:Monitor " + monitor.name + " has no sizes, trying 800x600"); + monitor.res = "800x600"; //must use something or xrandr options will be corrupt + } + } + } + newConfig.add(monitor); + } + } + return x11_rr_arrangeMonitors(newConfig.toArray(new Monitor[0])); + } + + /** Arranges monitors ensuring they all have valid positions. + * @return : the same list of monitors + */ + public static Monitor[] x11_rr_arrangeMonitors(Monitor monitors[]) { + for(int m=1;m cmd = new ArrayList(); + cmd.add("xrandr"); + for(int a=0;a