// Copyright 1999 Memesoft.  All rights reserved.

package krb5.lib.util;

import java.io.*;
import java.applet.*;

/**
 * System Utility
 */
public class SysUtil {

	/**
	 * Architecture
	 */
    static String arch;

	/**
	 * Whether it is little Endian
	 */
    static boolean littleEndian = false;

	/**
	 * Applet context
	 */
	static AppletContext appletContext;
	
    static {
        arch = System.getProperty("os.arch");
        //XXX need to add others
        if (arch.equalsIgnoreCase("x86")) {
            littleEndian = true;
        }
    }

	/**
	 * ntohs
	 *
	 * @return short is a result
	 * @param x is of type short
	 */
	public static short ntohs(short x) {
	    return littleEndian ? (short)((0x0000ff00 & x) >>> 8 | x << 8) : x;
	}

	/**
	 * ntohl
	 *
	 * @return int is a result
	 * @param x is of type int
	 */
	public static int ntohl(int x) {
	    return littleEndian ? x >>> 24 | x << 24 | (0x00ff0000 & x) >>> 8 |
	        (0x0000ff00 & x) << 8 : x;
	}

	/**
	 * htons
	 *
	 * @return short is a result
	 * @param x is of type short
	 */
	public static short htons(short x) {
	    return littleEndian ? (short)((0x0000ff00 & x) >>> 8 | x << 8) : x;
	}

	/**
	 * htonl
	 *
	 * @return int is a result
	 * @param x is of type int
	 */
	public static int htonl(int x) {
	    return littleEndian ? x >>> 24 | x << 24 | (0x00ff0000 & x) >>> 8 |
	        (0x0000ff00 & x) << 8 : x;
	}

	/**
	 * Returns environment information
	 *
	 * @return String is a result
	 * @param name is of type String
	 */
	public static synchronized String getenv(String name) {
        String result = "";
		String cmd = null;
		String str = "";
		File envdump = null;
		String os_name = System.getProperty("os.name");

		if (os_name.equalsIgnoreCase("Windows NT") ||
			os_name.equalsIgnoreCase("Windows 2000")) {
			str = "%" + name + "%";
			cmd = "cmd /c echo " + str;
		}
		
		if (os_name.equalsIgnoreCase("Windows 98") ||
			os_name.equalsIgnoreCase("Windows 95")) {

			String user_home = System.getProperty("user.home");
			String file_sep = System.getProperty("file.separator");
			str = "%" + name + "%";
			cmd = user_home + file_sep + "envdump.bat";
			envdump = new File(cmd);
			try {
				if (envdump.exists())
					envdump.delete();
				BufferedWriter wr = new BufferedWriter(
					new OutputStreamWriter(new FileOutputStream(envdump)));
				wr.write("@echo " + str);
				wr.close();
			} catch (Exception e) {}
		}
		
        //okay, try this
		if (cmd == null) {
			cmd = "/bin/sh -c echo $" + name;
		}
		
		if (cmd != null) {
			try {
				Process proc = Runtime.getRuntime().exec(cmd);
				BufferedReader inp = new BufferedReader(
 					new InputStreamReader(proc.getInputStream()));
				result = inp.readLine();
			} catch (Exception e) {}
			if (envdump != null) {
				try {
					envdump.delete();
				} catch (Exception e) {}
			}
			if (str.equals(result))
			    result = "";
		}

		return result;
	}

	/**
	 * Sets applet context
	 *
	 * @param ctx is of type AppletContext
	 */
	public static synchronized void setAppletContext(AppletContext ctx) {
	    //there is only one first appletContext as far as this library is concerned
	    if (appletContext == null)
	        appletContext = ctx;
	}

	/**
	 * Returns applet context
	 *
	 * @return AppletContext is a result
	 */
	public static synchronized AppletContext getAppletContext() {
	    return appletContext;
	}

	/**
	 * Checks whether it is applet
	 *
	 * @return boolean is a result
	 */
	public static synchronized boolean isApplet() {
	    if (appletContext != null)
	        return true;
    	//we assume we are in an applet if there is a security manager set
    	//XXX check that this is true in java 1.2
	    SecurityManager sm = System.getSecurityManager();
	    if (sm != null)
    	    return true;
	    return false;
	}

	/**
	 * Hexidecimal digit
	 */
	public static final String[] hex_digit = {
		"0", "1", "2", "3", "4", "5", "6", "7",
		"8", "9", "a", "b", "c", "d", "e", "f"
	};

	/**
	 * Byte to hex string
	 *
	 * @return String is a result
	 * @param x is of type byte
	 */
	public static String byte2hexString(byte x) {
		String s = "";
		for (int i = 0; i < 2; i++) {
			s = hex_digit[((((int)x) & 0xff) & (15 << (i * 4))) >>> (i * 4)] + s;
		}
		return s;
	}

	/**
	 * Int to hex string
	 *
	 * @return String is a result
	 * @param x is of type int
	 */
	public static String int2hexString(int x) {
		String s = "";
		for (int i = 0; i < 8; i++) {
			s = hex_digit[(x & (15 << (i * 4))) >>> (i * 4)] + s;
		}
		return s;
	}

	/**
	 * Int to binary string
	 *
	 * @return String is a result
	 * @param x is of type int
	 */
	public static String int2binString(int x) {
		String s = "";
		for (int i = 0; i < 32; i++) {
			if ((i > 0) && (i % 4 == 0)) s = " " + s;
			s = hex_digit[(x & (1 << i)) >>> i] + s;
		}
		return s;
	}

	/**
	 * Long to hex string
	 *
	 * @return String is a result
	 * @param x is of type long
	 */
	public static String long2hexString(long x) {
		String s = "";
		for (int i = 0; i < 16; i++) {
			s = hex_digit[(int)((x & (15L << (i * 4))) >>> (i * 4))] + s;
		}
		return s;
	}

	/**
	 * Long to binary string
	 *
	 * @return String is a result
	 * @param x is of type long
	 */
	public static String long2binString(long x) {
		String s = "";
		for (int i = 0; i < 64; i++) {
			if ((i > 0) && (i % 4 == 0)) s = " " + s;
			s = hex_digit[(int)((x & (1L << i)) >>> i)] + s;
		}
		return s;
	}

	/**
	 * Byte to hex string
	 *
	 * @return String is a result
	 * @param input is of type byte[]
	 */
	public static String byte2hexString(byte[] input) {
		return byte2hexString(input, 0, input.length);
	}

	/**
	 * Byte to hex string
	 *
	 * @return String is a result
	 * @param input is of type byte[]
	 * @param offset is of type int
	 */
	public static String byte2hexString(byte[] input, int offset) {
		return byte2hexString(input, offset, input.length);
	}

	/**
	 * Byte to hex string
	 *
	 * @return String is a result
	 * @param input is of type byte[]
	 * @param offset is of type int
	 * @param length is of type int
	 */
	public static String byte2hexString(byte[] input, int offset, int length) {
		String result = "";
		for (int i = 0; i < length; i++) {
			if (i + offset < input.length) {
				result += byte2hexString(input[i + offset]);
			}
		}
		return result;
	}
}