17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
59a70fc3bSMark J. Nelson  * Common Development and Distribution License (the "License").
69a70fc3bSMark J. Nelson  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  * Copyright 1999-2003 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate //  SLPConfig.java
287c478bd9Sstevel@tonic-gate //
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /**
317c478bd9Sstevel@tonic-gate  * This class is a singleton - it has the configuration which
327c478bd9Sstevel@tonic-gate  * is the default.  It reads from a configuration file and
337c478bd9Sstevel@tonic-gate  * this overrides the default.  If the config file does not
347c478bd9Sstevel@tonic-gate  * expressly forbid it, the ServiceLocationManager interface
357c478bd9Sstevel@tonic-gate  * allows some of these configuration options to be modified.
367c478bd9Sstevel@tonic-gate  * This configuration is refered to by many points of the
377c478bd9Sstevel@tonic-gate  * implementation. Note that the class itself is abstract,
387c478bd9Sstevel@tonic-gate  * and is extended by two classes, one that allows slpd to
397c478bd9Sstevel@tonic-gate  * run as an SA server only, the other allows it to run
407c478bd9Sstevel@tonic-gate  * as a DA as well.
417c478bd9Sstevel@tonic-gate  *
427c478bd9Sstevel@tonic-gate  * @see com.sun.slp.ServiceLocationManager
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate package com.sun.slp;
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate import java.net.*;
487c478bd9Sstevel@tonic-gate import java.util.*;
497c478bd9Sstevel@tonic-gate import java.text.*;
507c478bd9Sstevel@tonic-gate import java.io.*;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*
537c478bd9Sstevel@tonic-gate  * This class contains all configuration information.  It
547c478bd9Sstevel@tonic-gate  * is hard coded to know the defaults, and will read a config
557c478bd9Sstevel@tonic-gate  * file if it is present.  The config file will override the
567c478bd9Sstevel@tonic-gate  * default values and policy.  If the config file allows it
577c478bd9Sstevel@tonic-gate  * the user may reset some of these values using the
587c478bd9Sstevel@tonic-gate  * ServiceLocationManager interface.
597c478bd9Sstevel@tonic-gate  *
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate class SLPConfig {
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate     /**
647c478bd9Sstevel@tonic-gate      * A Java properties file defines `\' as an escape character, which
657c478bd9Sstevel@tonic-gate      * conflicts with the SLP API escape convention. Therefore, we need
667c478bd9Sstevel@tonic-gate      * to subclass properties so we can parse in the file ourselves.
677c478bd9Sstevel@tonic-gate      */
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate     public static class SLPProperties extends Properties {
707c478bd9Sstevel@tonic-gate 
SLPProperties(Properties p)717c478bd9Sstevel@tonic-gate 	SLPProperties(Properties p) {
727c478bd9Sstevel@tonic-gate 	    super(p);
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	}
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 	// Parse the SLP properties file ourselves. Groan! We don't recognize
777c478bd9Sstevel@tonic-gate 	//  backslash as an escape.
787c478bd9Sstevel@tonic-gate 
load(InputStream in)797c478bd9Sstevel@tonic-gate 	public synchronized void load(InputStream in) throws IOException {
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	    BufferedReader rd = new BufferedReader(new InputStreamReader(in));
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	    while (rd.ready()) {
847c478bd9Sstevel@tonic-gate 		String ln = rd.readLine();
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 		// Throw out anything that begins with '#' or ';'.
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 		if (ln.startsWith("#") ||
897c478bd9Sstevel@tonic-gate 		    ln.startsWith(";") ||
907c478bd9Sstevel@tonic-gate 		    ln.length() <= 0) {
917c478bd9Sstevel@tonic-gate 		    continue;
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 		}
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 		// Parse out equals sign, if any. Note that we trim any
96*55fea89dSDan Cross 		//  white space preceding or following data strings.
97*55fea89dSDan Cross 		//  Although the grammar doesn't allow it, users may
987c478bd9Sstevel@tonic-gate 		//  enter blanks in their configuration files.
997c478bd9Sstevel@tonic-gate 		// NOTE:  White space is not allowed in the data of
1007c478bd9Sstevel@tonic-gate 		//  property tag or values.  If included, according
101*55fea89dSDan Cross 		//  to RFC 2614, Section 2.1 these MUST be escaped,
102*55fea89dSDan Cross 		//  ie. space would be represented with '\20'.
103*55fea89dSDan Cross 		//  Therefore, it is *completely* safe to perform
104*55fea89dSDan Cross 		//  these trim()s.  They will catch errors resulting
105*55fea89dSDan Cross 		//  from sloppy data entry in slp.conf files and
106*55fea89dSDan Cross 		//  never corrupt or alter correctly formatted
1077c478bd9Sstevel@tonic-gate 		//  properties.
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 		SLPTokenizer tk = new SLPTokenizer(ln, "=");
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 		if (!tk.hasMoreTokens()) {// empty line...
1127c478bd9Sstevel@tonic-gate 		    continue;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 		}
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 		String prop = tk.nextToken().trim();
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 		if (prop.trim().length() <= 0) {// line has just spaces...
1197c478bd9Sstevel@tonic-gate 		    continue;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 		}
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 		if (!tk.hasMoreTokens()) {// line has no definition...
1247c478bd9Sstevel@tonic-gate 		    continue;
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 		}
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 		// Register the property.
1297c478bd9Sstevel@tonic-gate 		String def = tk.nextToken().trim();
1307c478bd9Sstevel@tonic-gate 		this.setProperty(prop, def);
1317c478bd9Sstevel@tonic-gate 	    }
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate     }
1357c478bd9Sstevel@tonic-gate 
SLPConfig()1367c478bd9Sstevel@tonic-gate     protected SLPConfig() {
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	// Create a temporary, default log to report any errors during
1397c478bd9Sstevel@tonic-gate 	//  configuration.
1407c478bd9Sstevel@tonic-gate 	log = new StderrLog();
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	// Initialize properties. Properties on command line override config
1437c478bd9Sstevel@tonic-gate 	//  file properties, and both override defaults.
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	Properties sysProps = (Properties)(System.getProperties().clone());
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	// Load Defalts.
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	try {
1507c478bd9Sstevel@tonic-gate 	    Class.forName("com.sun.slp.Defaults");
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	} catch (ClassNotFoundException ex) {
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	    Assert.printMessageAndDie(this,
1557c478bd9Sstevel@tonic-gate 				      "no_class",
1567c478bd9Sstevel@tonic-gate 				      new Object[] {"com.sun.slp.Defaults"});
1577c478bd9Sstevel@tonic-gate 	}
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	// System properties now contain Defaults
1607c478bd9Sstevel@tonic-gate 	Properties defaultProps = System.getProperties();
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	// Load config file.
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	SLPProperties slpProps = new SLPProperties(new Properties());
1657c478bd9Sstevel@tonic-gate 	try {
1667c478bd9Sstevel@tonic-gate 	    InputStream fis = getConfigURLStream();
1677c478bd9Sstevel@tonic-gate 	    if (fis != null) {
1687c478bd9Sstevel@tonic-gate 		slpProps.load(fis);
1697c478bd9Sstevel@tonic-gate 		System.setProperties(slpProps);
1707c478bd9Sstevel@tonic-gate 	    }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {
1737c478bd9Sstevel@tonic-gate 	    writeLog("unparsable_config_file",
1747c478bd9Sstevel@tonic-gate 		     new Object[] {ex.getMessage()});
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	// Add config properties to Defaults, overwritting any pre-existing
1787c478bd9Sstevel@tonic-gate 	//  entries
1797c478bd9Sstevel@tonic-gate 	defaultProps.putAll(slpProps);
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	// Now add in system props, overwritting any pre-existing entries
1827c478bd9Sstevel@tonic-gate 	defaultProps.putAll(sysProps);
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	System.setProperties(defaultProps);
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	// Initialize useScopes property. This is read-only after the file
1887c478bd9Sstevel@tonic-gate 	//  has been loaded.
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	configuredScopes = initializeScopes("net.slp.useScopes");
1917c478bd9Sstevel@tonic-gate 	saConfiguredScopes = (Vector)configuredScopes.clone();
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 	// Add default scope to scopes for SA.
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	if (saConfiguredScopes.size() <= 0) {
1967c478bd9Sstevel@tonic-gate 	    saConfiguredScopes.addElement(Defaults.DEFAULT_SCOPE);
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	}
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	// Initialize SA scopes. This uses a Sun specific property for
2017c478bd9Sstevel@tonic-gate 	//  scopes only used by the SA and adds in the DA scopes.
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	saOnlyScopes = initializeScopes(DATable.SA_ONLY_SCOPES_PROP);
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	// Initialized preconfigured DAs.
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	preconfiguredDAs = initializePreconfiguredDAs();
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	// Initialize broadcast flag.
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	broadcastOnly = Boolean.getBoolean("net.slp.isBroadcastOnly");
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	// Initialize logging. Default is stderr, first check for alternate.
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	String failed = null;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	try {
2187c478bd9Sstevel@tonic-gate 	    String loggerClassName =
2197c478bd9Sstevel@tonic-gate 		System.getProperty("sun.net.slp.loggerClass");
2207c478bd9Sstevel@tonic-gate 	    if (loggerClassName != null) {
2217c478bd9Sstevel@tonic-gate 		Class loggerClass = Class.forName(loggerClassName);
2227c478bd9Sstevel@tonic-gate 		// Protect against disastrous pilot error, such as trying
2237c478bd9Sstevel@tonic-gate 		// to use com.sun.slp.SLPConfig as the log class
2247c478bd9Sstevel@tonic-gate 		// (causes stack recursion)
2257c478bd9Sstevel@tonic-gate 		if (Class.forName("java.io.Writer").isAssignableFrom(
2267c478bd9Sstevel@tonic-gate 							loggerClass)) {
2277c478bd9Sstevel@tonic-gate 		    Object logger = loggerClass.newInstance();
2287c478bd9Sstevel@tonic-gate 		    log = (Writer) logger;
2297c478bd9Sstevel@tonic-gate 		} else {
2307c478bd9Sstevel@tonic-gate 		    failed = formatMessage(
2317c478bd9Sstevel@tonic-gate 					   "bad_log_class",
2327c478bd9Sstevel@tonic-gate 					   new Object[] {
2337c478bd9Sstevel@tonic-gate 			loggerClass.toString()}) + "\n";
2347c478bd9Sstevel@tonic-gate 		}
2357c478bd9Sstevel@tonic-gate 	    }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	} catch (Throwable ex) {
2387c478bd9Sstevel@tonic-gate 	    log = null;
2397c478bd9Sstevel@tonic-gate 	    failed = formatMessage(
2407c478bd9Sstevel@tonic-gate 				   "bad_log",
2417c478bd9Sstevel@tonic-gate 				   new Object[] {
2427c478bd9Sstevel@tonic-gate 		ex.toString()}) + "\n";
2437c478bd9Sstevel@tonic-gate 	}
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	// If no alternate log, revert to minimal default
2467c478bd9Sstevel@tonic-gate 	if (log == null) {
2477c478bd9Sstevel@tonic-gate 	    log = new StderrLog();
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	    // If the alternate log failed, log it through the default log
2507c478bd9Sstevel@tonic-gate 	    if (failed != null) {
2517c478bd9Sstevel@tonic-gate 		try {
2527c478bd9Sstevel@tonic-gate 		    synchronized (log) {
2537c478bd9Sstevel@tonic-gate 			log.write(failed);
2547c478bd9Sstevel@tonic-gate 			log.flush();
2557c478bd9Sstevel@tonic-gate 		    }
2567c478bd9Sstevel@tonic-gate 		} catch (IOException giveUp) {}
2577c478bd9Sstevel@tonic-gate 	    }
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate     }
2617c478bd9Sstevel@tonic-gate 
getConfigURLStream()2627c478bd9Sstevel@tonic-gate     private InputStream getConfigURLStream() {
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	// Open a URL onto the configuration file.
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	String conf = System.getProperty("sun.net.slp.configURL");
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	if (conf == null) {
2697c478bd9Sstevel@tonic-gate 	    conf = Defaults.SOLARIS_CONF;
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	}
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	InputStream str = null;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	try {
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	    URL confURL = new URL(conf);
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	    str = confURL.openStream();
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	} catch (MalformedURLException ex) {
2827c478bd9Sstevel@tonic-gate 	    writeLog("url_malformed",
2837c478bd9Sstevel@tonic-gate 		     new Object[] {conf});
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {
2867c478bd9Sstevel@tonic-gate 	    if (conf != Defaults.SOLARIS_CONF) {
2877c478bd9Sstevel@tonic-gate 		// don't complain if we can't find our own default
2887c478bd9Sstevel@tonic-gate 		writeLog("unparsable_config_file",
2897c478bd9Sstevel@tonic-gate 			 new Object[] {ex.getMessage()});
2907c478bd9Sstevel@tonic-gate 	    }
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	return str;
2957c478bd9Sstevel@tonic-gate     }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
2987c478bd9Sstevel@tonic-gate     // Property manipulation functions
2997c478bd9Sstevel@tonic-gate     //
3007c478bd9Sstevel@tonic-gate 
OKBound(int i, int lb, int ub)3017c478bd9Sstevel@tonic-gate     private boolean OKBound(int i, int lb, int ub) {
3027c478bd9Sstevel@tonic-gate 	if (i < lb || i > ub)
3037c478bd9Sstevel@tonic-gate 	    return false;
3047c478bd9Sstevel@tonic-gate 	else
3057c478bd9Sstevel@tonic-gate 	    return true;
3067c478bd9Sstevel@tonic-gate     }
3077c478bd9Sstevel@tonic-gate 
getIntProperty(String prop, int df, int lb, int ub)3087c478bd9Sstevel@tonic-gate     int getIntProperty(String prop, int df, int lb, int ub) {
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	int i = Integer.getInteger(prop, df).intValue();
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	if (OKBound(i, lb, ub)) {
3137c478bd9Sstevel@tonic-gate 	    return i;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	} else {
3167c478bd9Sstevel@tonic-gate 	    writeLog("bad_prop_tag", new Object[] {prop});
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	    return df;
3197c478bd9Sstevel@tonic-gate 	}
3207c478bd9Sstevel@tonic-gate     }
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
3237c478bd9Sstevel@tonic-gate     // Multicast radius
3247c478bd9Sstevel@tonic-gate     //
3257c478bd9Sstevel@tonic-gate     private int iMinMCRadius = 1;   // link local scope
3267c478bd9Sstevel@tonic-gate     private int iMaxMCRadius = 255; // universal scope
3277c478bd9Sstevel@tonic-gate 
getMCRadius()3287c478bd9Sstevel@tonic-gate     int getMCRadius() {
3297c478bd9Sstevel@tonic-gate 	return getIntProperty("net.slp.multicastTTL",
3307c478bd9Sstevel@tonic-gate 			      Defaults.iMulticastRadius,
3317c478bd9Sstevel@tonic-gate 			      iMinMCRadius,
3327c478bd9Sstevel@tonic-gate 			      iMaxMCRadius);
3337c478bd9Sstevel@tonic-gate     }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
3367c478bd9Sstevel@tonic-gate     // Heartbeat interval, seconds.
3377c478bd9Sstevel@tonic-gate     //
3387c478bd9Sstevel@tonic-gate     private final int iMinHeart = 2000;    // 10 minutes
3397c478bd9Sstevel@tonic-gate     private final int iMaxHeart = 259200000; // 3 days
3407c478bd9Sstevel@tonic-gate 
getAdvertHeartbeatTime()3417c478bd9Sstevel@tonic-gate     int getAdvertHeartbeatTime() {
3427c478bd9Sstevel@tonic-gate 	return getIntProperty("net.slp.DAHeartBeat",
3437c478bd9Sstevel@tonic-gate 			      Defaults.iHeartbeat,
3447c478bd9Sstevel@tonic-gate 			      iMinHeart,
3457c478bd9Sstevel@tonic-gate 			      iMaxHeart);
3467c478bd9Sstevel@tonic-gate     }
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
3497c478bd9Sstevel@tonic-gate     // Active discovery interval, seconds.
3507c478bd9Sstevel@tonic-gate     //
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate     private final int iMinDisc = 300;    // 5 minutes
3537c478bd9Sstevel@tonic-gate     private final int iMaxDisc = 10800;  // 3 hours
3547c478bd9Sstevel@tonic-gate 
getActiveDiscoveryInterval()3557c478bd9Sstevel@tonic-gate     int getActiveDiscoveryInterval() {
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	// We allow zero in order to turn active discovery off, but
3587c478bd9Sstevel@tonic-gate 	//  if 5 minutes is the smallest actual time.
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 	int prop = getIntProperty("net.slp.DAActiveDiscoveryInterval",
3617c478bd9Sstevel@tonic-gate 				  Defaults.iActiveDiscoveryInterval,
3627c478bd9Sstevel@tonic-gate 				  0,
3637c478bd9Sstevel@tonic-gate 				  iMaxDisc);
3647c478bd9Sstevel@tonic-gate 	if (prop > 0 && prop < iMinDisc) {
3657c478bd9Sstevel@tonic-gate 	    writeLog("bad_prop_tag",
3667c478bd9Sstevel@tonic-gate 		     new Object[] {"net.slp.DAActiveDiscoveryInterval"});
3677c478bd9Sstevel@tonic-gate 	    return iMinDisc;
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	}
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	return prop;
3727c478bd9Sstevel@tonic-gate     }
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
3767c478bd9Sstevel@tonic-gate     // Active discovery granularity, seconds.
3777c478bd9Sstevel@tonic-gate     //
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate     private int iMaxDiscGran = iMaxDisc * 2;
3807c478bd9Sstevel@tonic-gate 
getActiveDiscoveryGranularity()3817c478bd9Sstevel@tonic-gate     int getActiveDiscoveryGranularity() {
3827c478bd9Sstevel@tonic-gate 	return getIntProperty("sun.net.slp.DAActiveDiscoveryGranularity",
3837c478bd9Sstevel@tonic-gate 			      Defaults.iActiveDiscoveryGranularity,
3847c478bd9Sstevel@tonic-gate 			      0,
3857c478bd9Sstevel@tonic-gate 			      iMaxDiscGran);
3867c478bd9Sstevel@tonic-gate     }
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
3897c478bd9Sstevel@tonic-gate     // Bound for random wait, milliseconds.
3907c478bd9Sstevel@tonic-gate     //
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate     private final int iMinWait = 1000;  // 1 sec.
3937c478bd9Sstevel@tonic-gate     private final int iMaxWait = 3000;  // 3 sec.
3947c478bd9Sstevel@tonic-gate 
getRandomWaitBound()3957c478bd9Sstevel@tonic-gate     int getRandomWaitBound() {
3967c478bd9Sstevel@tonic-gate 	return getIntProperty("net.slp.randomWaitBound",
3977c478bd9Sstevel@tonic-gate 			      Defaults.iRandomWaitBound,
3987c478bd9Sstevel@tonic-gate 			      iMinWait,
3997c478bd9Sstevel@tonic-gate 			      iMaxWait);
4007c478bd9Sstevel@tonic-gate     }
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate     private static Random randomWait = null;
4037c478bd9Sstevel@tonic-gate 
getRandomWait()4047c478bd9Sstevel@tonic-gate     long getRandomWait() {
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	if (randomWait == null) {
4077c478bd9Sstevel@tonic-gate 	    randomWait = new Random();
4087c478bd9Sstevel@tonic-gate 	}
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	double r = randomWait.nextDouble();
4117c478bd9Sstevel@tonic-gate 	double max = (double)getRandomWaitBound();
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate 	return (long)(max * r);
4147c478bd9Sstevel@tonic-gate     }
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
4177c478bd9Sstevel@tonic-gate     // TCP timeout, milliseconds.
4187c478bd9Sstevel@tonic-gate     //
4197c478bd9Sstevel@tonic-gate     final static private int iMinTimeout = 100;
4207c478bd9Sstevel@tonic-gate     final static private int iMaxTimeout = 360000;
4217c478bd9Sstevel@tonic-gate 
getTCPTimeout()4227c478bd9Sstevel@tonic-gate     int getTCPTimeout() {
4237c478bd9Sstevel@tonic-gate 	return getIntProperty("sun.net.slp.TCPTimeout",
4247c478bd9Sstevel@tonic-gate 			      Defaults.iTCPTimeout,
4257c478bd9Sstevel@tonic-gate 			      iMinTimeout,
4267c478bd9Sstevel@tonic-gate 			      iMaxTimeout);
4277c478bd9Sstevel@tonic-gate     }
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
4307c478bd9Sstevel@tonic-gate     //  Path MTU
4317c478bd9Sstevel@tonic-gate     //
4327c478bd9Sstevel@tonic-gate     private final int iMinMTU = 128; // used for some ppp connections
4337c478bd9Sstevel@tonic-gate     private final int iMaxMTU = 8192; // used on some LANs
4347c478bd9Sstevel@tonic-gate 
getMTU()4357c478bd9Sstevel@tonic-gate     int getMTU() {
4367c478bd9Sstevel@tonic-gate 	return getIntProperty("net.slp.MTU",
4377c478bd9Sstevel@tonic-gate 			      Defaults.iMTU,
4387c478bd9Sstevel@tonic-gate 			      iMinMTU,
4397c478bd9Sstevel@tonic-gate 			      iMaxMTU);
4407c478bd9Sstevel@tonic-gate     }
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
4447c478bd9Sstevel@tonic-gate     // Serialized registrations.
4457c478bd9Sstevel@tonic-gate     //
4467c478bd9Sstevel@tonic-gate 
getSerializedRegURL()4477c478bd9Sstevel@tonic-gate     String getSerializedRegURL() {
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	return System.getProperty("net.slp.serializedRegURL", null);
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate     }
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
4547c478bd9Sstevel@tonic-gate     // Are we running as a DA or SA server?
4557c478bd9Sstevel@tonic-gate     //
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate     protected static boolean isSA = false;
4587c478bd9Sstevel@tonic-gate 
isDA()4597c478bd9Sstevel@tonic-gate     boolean isDA() {
4607c478bd9Sstevel@tonic-gate 	return false;
4617c478bd9Sstevel@tonic-gate     }
4627c478bd9Sstevel@tonic-gate 
isSA()4637c478bd9Sstevel@tonic-gate     boolean isSA() {
4647c478bd9Sstevel@tonic-gate 	return isSA;
4657c478bd9Sstevel@tonic-gate     }
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
4687c478bd9Sstevel@tonic-gate     // DA and SA attributes
4697c478bd9Sstevel@tonic-gate     //
4707c478bd9Sstevel@tonic-gate 
getDAAttributes()4717c478bd9Sstevel@tonic-gate     Vector getDAAttributes() {
4727c478bd9Sstevel@tonic-gate 	return getAttributes("net.slp.DAAttributes",
4737c478bd9Sstevel@tonic-gate 			     Defaults.defaultDAAttributes,
4747c478bd9Sstevel@tonic-gate 			     true);
4757c478bd9Sstevel@tonic-gate     }
4767c478bd9Sstevel@tonic-gate 
getSAAttributes()4777c478bd9Sstevel@tonic-gate     Vector getSAAttributes() {
4787c478bd9Sstevel@tonic-gate 	return getAttributes("net.slp.SAAttributes",
4797c478bd9Sstevel@tonic-gate 			     Defaults.defaultSAAttributes,
4807c478bd9Sstevel@tonic-gate 			     false);
4817c478bd9Sstevel@tonic-gate     }
4827c478bd9Sstevel@tonic-gate 
getAttributes(String prop, Vector defaults, boolean daAttrs)4837c478bd9Sstevel@tonic-gate     private Vector getAttributes(String prop,
4847c478bd9Sstevel@tonic-gate 				 Vector defaults,
4857c478bd9Sstevel@tonic-gate 				 boolean daAttrs) {
4867c478bd9Sstevel@tonic-gate 	String attrList =
4877c478bd9Sstevel@tonic-gate 	    System.getProperty(prop);
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	if (attrList == null || attrList.length() <= 0) {
4907c478bd9Sstevel@tonic-gate 	    return (Vector)defaults.clone();
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 	}
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	try {
4957c478bd9Sstevel@tonic-gate 	    Vector sAttrs =
4967c478bd9Sstevel@tonic-gate 		SrvLocHeader.parseCommaSeparatedListIn(attrList, false);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	    Vector attrs = new Vector();
4997c478bd9Sstevel@tonic-gate 	    int i, n = sAttrs.size();
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 	    // Create attribute objects.
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 	    for (i = 0; i < n; i++) {
5047c478bd9Sstevel@tonic-gate 		String attrExp = (String)sAttrs.elementAt(i);
5057c478bd9Sstevel@tonic-gate 		ServiceLocationAttribute attr =
5067c478bd9Sstevel@tonic-gate 		    new ServiceLocationAttribute(attrExp, false);
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 		// If this is the min-refresh-interval, then check the value.
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 		if (daAttrs &&
5117c478bd9Sstevel@tonic-gate 		    attr.getId().equals(
5127c478bd9Sstevel@tonic-gate 				Defaults.MIN_REFRESH_INTERVAL_ATTR_ID)) {
5137c478bd9Sstevel@tonic-gate 		    Vector values = attr.getValues();
5147c478bd9Sstevel@tonic-gate 		    boolean errorp = true;
515*55fea89dSDan Cross 
5167c478bd9Sstevel@tonic-gate 		    if (values != null && values.size() == 1) {
5177c478bd9Sstevel@tonic-gate 			Object val = values.elementAt(0);
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 			if (val instanceof Integer) {
5207c478bd9Sstevel@tonic-gate 			    int ival = ((Integer)val).intValue();
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 			    if (ival >= 0 &&
5237c478bd9Sstevel@tonic-gate 				ival <= ServiceURL.LIFETIME_MAXIMUM) {
5247c478bd9Sstevel@tonic-gate 				errorp = false;
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 			    }
5277c478bd9Sstevel@tonic-gate 			}
5287c478bd9Sstevel@tonic-gate 		    }
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 		    // Throw exception if it didn't work.
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 		    if (errorp) {
5337c478bd9Sstevel@tonic-gate 			throw new ServiceLocationException(
5347c478bd9Sstevel@tonic-gate 				ServiceLocationException.PARSE_ERROR,
5357c478bd9Sstevel@tonic-gate 				"syntax_error_prop",
5367c478bd9Sstevel@tonic-gate 				new Object[] {prop, attrs});
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 		    }
5397c478bd9Sstevel@tonic-gate 		}
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 		// Add attribute to vector.
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 		attrs.addElement(attr);
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	    }
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	    return attrs;
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate 	} catch (Exception ex) {
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 	    writeLog("syntax_error_prop",
5527c478bd9Sstevel@tonic-gate 		     new Object[] {prop, attrList});
5537c478bd9Sstevel@tonic-gate 	    return (Vector)defaults.clone();
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	}
5567c478bd9Sstevel@tonic-gate     }
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate     // -------------------------------------------------------------
5597c478bd9Sstevel@tonic-gate     // Do we support V1?
5607c478bd9Sstevel@tonic-gate     //
5617c478bd9Sstevel@tonic-gate 
isV1Supported()5627c478bd9Sstevel@tonic-gate     boolean isV1Supported() {
5637c478bd9Sstevel@tonic-gate 	return false;
5647c478bd9Sstevel@tonic-gate     }
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate     // -------------------------------------------------------------
5677c478bd9Sstevel@tonic-gate     // Queue length for server socket.
5687c478bd9Sstevel@tonic-gate     //
5697c478bd9Sstevel@tonic-gate 
getServerSocketQueueLength()5707c478bd9Sstevel@tonic-gate     int getServerSocketQueueLength() {
5717c478bd9Sstevel@tonic-gate 	return getIntProperty("sun.net.slp.serverSocketQueueLength",
5727c478bd9Sstevel@tonic-gate 			      Defaults.iSocketQueueLength,
5737c478bd9Sstevel@tonic-gate 			      0,
5747c478bd9Sstevel@tonic-gate 			      Integer.MAX_VALUE);
5757c478bd9Sstevel@tonic-gate     }
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
5787c478bd9Sstevel@tonic-gate     // Testing options
5797c478bd9Sstevel@tonic-gate     //
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 
traceAll()5827c478bd9Sstevel@tonic-gate     boolean traceAll() {// not official!
5837c478bd9Sstevel@tonic-gate 	return Boolean.getBoolean("sun.net.slp.traceALL");
5847c478bd9Sstevel@tonic-gate     }
5857c478bd9Sstevel@tonic-gate 
regTest()5867c478bd9Sstevel@tonic-gate     boolean regTest() {
5877c478bd9Sstevel@tonic-gate 	if (Boolean.getBoolean("sun.net.slp.traceALL") ||
5887c478bd9Sstevel@tonic-gate 	    Boolean.getBoolean("net.slp.traceReg"))
5897c478bd9Sstevel@tonic-gate 	    return true;
5907c478bd9Sstevel@tonic-gate 	else
5917c478bd9Sstevel@tonic-gate 	    return false;
5927c478bd9Sstevel@tonic-gate     }
5937c478bd9Sstevel@tonic-gate 
traceMsg()5947c478bd9Sstevel@tonic-gate     boolean traceMsg() {
5957c478bd9Sstevel@tonic-gate 	if (Boolean.getBoolean("sun.net.slp.traceALL") ||
5967c478bd9Sstevel@tonic-gate 	    Boolean.getBoolean("net.slp.traceMsg"))
5977c478bd9Sstevel@tonic-gate 	    return true;
5987c478bd9Sstevel@tonic-gate 	else
5997c478bd9Sstevel@tonic-gate 	    return false;
6007c478bd9Sstevel@tonic-gate     }
6017c478bd9Sstevel@tonic-gate 
traceDrop()6027c478bd9Sstevel@tonic-gate     boolean traceDrop() {
6037c478bd9Sstevel@tonic-gate 	if (Boolean.getBoolean("sun.net.slp.traceALL") ||
6047c478bd9Sstevel@tonic-gate 	    Boolean.getBoolean("net.slp.traceDrop"))
6057c478bd9Sstevel@tonic-gate 	    return true;
6067c478bd9Sstevel@tonic-gate 	else
6077c478bd9Sstevel@tonic-gate 	    return false;
6087c478bd9Sstevel@tonic-gate     }
6097c478bd9Sstevel@tonic-gate 
traceDATraffic()6107c478bd9Sstevel@tonic-gate     boolean traceDATraffic() {
6117c478bd9Sstevel@tonic-gate 	if (Boolean.getBoolean("sun.net.slp.traceALL") ||
6127c478bd9Sstevel@tonic-gate 	    Boolean.getBoolean("net.slp.traceDATraffic"))
6137c478bd9Sstevel@tonic-gate 	    return true;
6147c478bd9Sstevel@tonic-gate 	else
6157c478bd9Sstevel@tonic-gate 	    return false;
6167c478bd9Sstevel@tonic-gate     }
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate     // cannot use Boolean.getBoolean as the default is 'true'
6197c478bd9Sstevel@tonic-gate     // using that mechanism, absense would be considered 'false'
6207c478bd9Sstevel@tonic-gate 
passiveDADetection()6217c478bd9Sstevel@tonic-gate     boolean passiveDADetection() {
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate 	String sPassive =
6247c478bd9Sstevel@tonic-gate 	    System.getProperty("net.slp.passiveDADetection", "true");
6257c478bd9Sstevel@tonic-gate 	if (sPassive.equalsIgnoreCase("true"))
6267c478bd9Sstevel@tonic-gate 	    return true;
6277c478bd9Sstevel@tonic-gate 	else
6287c478bd9Sstevel@tonic-gate 	    return false;
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate     }
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate     // Initialized when the SLPConfig object is created to avoid changing
6337c478bd9Sstevel@tonic-gate     //  during the program.
6347c478bd9Sstevel@tonic-gate     private boolean broadcastOnly = false;
6357c478bd9Sstevel@tonic-gate 
isBroadcastOnly()6367c478bd9Sstevel@tonic-gate     boolean isBroadcastOnly() {
6377c478bd9Sstevel@tonic-gate 	return broadcastOnly;
6387c478bd9Sstevel@tonic-gate     }
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
6427c478bd9Sstevel@tonic-gate     // Multicast/broadcast socket mangement.
6437c478bd9Sstevel@tonic-gate     //
6447c478bd9Sstevel@tonic-gate     DatagramSocket broadSocket = null;   // cached broadcast socket.
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate     // Reopen the multicast/broadcast socket bound to the
6487c478bd9Sstevel@tonic-gate     //  interface. If groups is not null, then join all
6497c478bd9Sstevel@tonic-gate     //  the groups. Otherwise, this is send only.
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate     DatagramSocket
refreshMulticastSocketOnInterface(InetAddress interfac, Vector groups)6527c478bd9Sstevel@tonic-gate 	refreshMulticastSocketOnInterface(InetAddress interfac,
6537c478bd9Sstevel@tonic-gate 					  Vector groups) {
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 	try {
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 	    // Reopen it.
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate 	    DatagramSocket dss =
6607c478bd9Sstevel@tonic-gate 		getMulticastSocketOnInterface(interfac,
6617c478bd9Sstevel@tonic-gate 					      (groups == null ? true:false));
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	    if ((groups != null) && (dss instanceof MulticastSocket)) {
6647c478bd9Sstevel@tonic-gate 		int i, n = groups.size();
6657c478bd9Sstevel@tonic-gate 		MulticastSocket mss = (MulticastSocket)dss;
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
6687c478bd9Sstevel@tonic-gate 		    InetAddress maddr = (InetAddress)groups.elementAt(i);
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 		    mss.joinGroup(maddr);
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 		}
6737c478bd9Sstevel@tonic-gate 	    }
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	    return dss;
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 	} catch (Exception ex) {
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	    // Any exception in error recovery causes program to die.
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	    Assert.slpassert(false,
6827c478bd9Sstevel@tonic-gate 			  "cast_socket_failure",
6837c478bd9Sstevel@tonic-gate 			  new Object[] {ex, ex.getMessage()});
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	}
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	return null;
6887c478bd9Sstevel@tonic-gate     }
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate     // Open a multicast/broadcast socket on the interface. Note that if
6917c478bd9Sstevel@tonic-gate     //  the socket is broadcast, the network interface is not specified in the
6927c478bd9Sstevel@tonic-gate     //  creation message. Is it bound to all interfaces? The isSend parameter
6937c478bd9Sstevel@tonic-gate     //  specifies whether the socket is for send only.
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate     DatagramSocket
getMulticastSocketOnInterface(InetAddress interfac, boolean isSend)6967c478bd9Sstevel@tonic-gate 	getMulticastSocketOnInterface(InetAddress interfac, boolean isSend)
6977c478bd9Sstevel@tonic-gate 	throws ServiceLocationException {
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 	DatagramSocket castSocket = null;
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 	// Substitute broadcast if we are configured for it.
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	if (isBroadcastOnly()) {
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 	    try {
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 		// If transmit, then simply return a new socket.
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 		if (isSend) {
7107c478bd9Sstevel@tonic-gate 		    castSocket = new DatagramSocket();
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate 		} else {
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 		    // Return cached socket if there.
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 		    if (broadSocket != null) {
7177c478bd9Sstevel@tonic-gate 			castSocket = broadSocket;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 		    } else {
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 			// Make a new broadcast socket.
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 			castSocket =
7247c478bd9Sstevel@tonic-gate 			    new DatagramSocket(Defaults.iSLPPort,
7257c478bd9Sstevel@tonic-gate 					       getBroadcastAddress());
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 		    }
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 		    // Cache for future reference.
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate 		    broadSocket = castSocket;
7327c478bd9Sstevel@tonic-gate 		}
7337c478bd9Sstevel@tonic-gate 	    } catch (SocketException ex) {
734*55fea89dSDan Cross 		throw
7357c478bd9Sstevel@tonic-gate 		    new ServiceLocationException(
7367c478bd9Sstevel@tonic-gate 				ServiceLocationException.NETWORK_INIT_FAILED,
7377c478bd9Sstevel@tonic-gate 				"socket_creation_failure",
7387c478bd9Sstevel@tonic-gate 				new Object[] {
7397c478bd9Sstevel@tonic-gate 			getBroadcastAddress(), ex.getMessage()});
7407c478bd9Sstevel@tonic-gate 	    }
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	} else {
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 	    // Create a multicast socket.
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 	    MulticastSocket ms;
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 	    try {
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 		if (isSend) {
7517c478bd9Sstevel@tonic-gate 		    ms = new MulticastSocket();
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 		} else {
7547c478bd9Sstevel@tonic-gate 		    ms = new MulticastSocket(Defaults.iSLPPort);
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 		}
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 	    } catch (IOException ex) {
7597c478bd9Sstevel@tonic-gate 		throw
7607c478bd9Sstevel@tonic-gate 		    new ServiceLocationException(
7617c478bd9Sstevel@tonic-gate 				ServiceLocationException.NETWORK_INIT_FAILED,
7627c478bd9Sstevel@tonic-gate 				"socket_creation_failure",
7637c478bd9Sstevel@tonic-gate 				new Object[] {interfac, ex.getMessage()});
7647c478bd9Sstevel@tonic-gate 	    }
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 	    try {
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 		// Set the TTL and the interface on the multicast socket.
7707c478bd9Sstevel@tonic-gate 		//  Client is responsible for joining group.
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 		ms.setTimeToLive(getMCRadius());
7737c478bd9Sstevel@tonic-gate 		ms.setInterface(interfac);
7747c478bd9Sstevel@tonic-gate 
7757c478bd9Sstevel@tonic-gate 	    } catch (IOException ex) {
7767c478bd9Sstevel@tonic-gate 		throw
7777c478bd9Sstevel@tonic-gate 		    new ServiceLocationException(
7787c478bd9Sstevel@tonic-gate 				ServiceLocationException.NETWORK_INIT_FAILED,
7797c478bd9Sstevel@tonic-gate 				"socket_initializtion_failure",
7807c478bd9Sstevel@tonic-gate 				new Object[] {interfac, ex.getMessage()});
7817c478bd9Sstevel@tonic-gate 	    }
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	    castSocket = ms;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	}
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	return castSocket;
7887c478bd9Sstevel@tonic-gate     }
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
7917c478bd9Sstevel@tonic-gate     // Type hint
7927c478bd9Sstevel@tonic-gate     //
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate     // Return a vector of ServiceType objects for the type hint.
7957c478bd9Sstevel@tonic-gate 
getTypeHint()7967c478bd9Sstevel@tonic-gate     Vector getTypeHint() {
7977c478bd9Sstevel@tonic-gate 	Vector hint = new Vector();
7987c478bd9Sstevel@tonic-gate 	String sTypeList = System.getProperty("net.slp.typeHint", "");
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	if (sTypeList.length() <= 0) {
8017c478bd9Sstevel@tonic-gate 	    return hint;
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	}
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	// Create a vector of ServiceType objects for the type hint.
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	try {
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 	    hint = SrvLocHeader.parseCommaSeparatedListIn(sTypeList, true);
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 	    int i, n = hint.size();
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 	    for (i = 0; i < n; i++) {
8147c478bd9Sstevel@tonic-gate 		String type = (String)hint.elementAt(i);
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 		hint.setElementAt(new ServiceType(type), i);
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	    }
8197c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	    writeLog("syntax_error_prop",
8227c478bd9Sstevel@tonic-gate 		     new Object[] {"net.slp.typeHint", sTypeList});
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	    hint.removeAllElements();
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	}
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 	return hint;
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate     }
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
8337c478bd9Sstevel@tonic-gate     // Configured scope handling
8347c478bd9Sstevel@tonic-gate     //
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate     // Vector of configured scopes.
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate     private Vector configuredScopes = null;
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate     // Vector of configures scopes for SA.
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate     private Vector saConfiguredScopes = null;
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate     // Vector of scopes only in the sa server.
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate     private Vector saOnlyScopes = null;
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate     // Return the configured scopes.
8497c478bd9Sstevel@tonic-gate 
getConfiguredScopes()8507c478bd9Sstevel@tonic-gate     Vector getConfiguredScopes() {
8517c478bd9Sstevel@tonic-gate 	return (Vector)configuredScopes.clone();
8527c478bd9Sstevel@tonic-gate     }
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate     // Return SA scopes.
8557c478bd9Sstevel@tonic-gate 
getSAOnlyScopes()8567c478bd9Sstevel@tonic-gate     Vector getSAOnlyScopes() {
8577c478bd9Sstevel@tonic-gate 	return (Vector)saOnlyScopes.clone();
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate     }
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate     // Return the configured scopes for the SA.
8627c478bd9Sstevel@tonic-gate 
getSAConfiguredScopes()8637c478bd9Sstevel@tonic-gate     Vector getSAConfiguredScopes() {
8647c478bd9Sstevel@tonic-gate 	return (Vector)saConfiguredScopes.clone();
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate     }
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate     // Add scopes discovered during preconfigured DA contact.
8697c478bd9Sstevel@tonic-gate     //  These count as configured scopes.
8707c478bd9Sstevel@tonic-gate 
addPreconfiguredDAScopes(Vector scopes)8717c478bd9Sstevel@tonic-gate     void addPreconfiguredDAScopes(Vector scopes) {
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 	int i, n = scopes.size();
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
8767c478bd9Sstevel@tonic-gate 	    Object scope = scopes.elementAt(i);
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	    if (!configuredScopes.contains(scope)) {
8797c478bd9Sstevel@tonic-gate 		configuredScopes.addElement(scope);
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate 	    }
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 	    // There better be none extra here for the SA server/DA.
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	    if (isSA() || isDA()) {
8867c478bd9Sstevel@tonic-gate 		Assert.slpassert(saConfiguredScopes.contains(scope),
8877c478bd9Sstevel@tonic-gate 			      "sa_new_scope",
8887c478bd9Sstevel@tonic-gate 			      new Object[] {scope, saConfiguredScopes});
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate 	    }
8917c478bd9Sstevel@tonic-gate 	}
8927c478bd9Sstevel@tonic-gate     }
8937c478bd9Sstevel@tonic-gate 
8947c478bd9Sstevel@tonic-gate     // Initialize the scopes list on property.
8957c478bd9Sstevel@tonic-gate 
initializeScopes(String prop)8967c478bd9Sstevel@tonic-gate     private Vector initializeScopes(String prop) {
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	String sScopes = System.getProperty(prop);
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 	if (sScopes == null || sScopes.length() <= 0) {
9017c478bd9Sstevel@tonic-gate 	    return new Vector();
9027c478bd9Sstevel@tonic-gate 	}
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 	try {
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 	    Vector vv =
9077c478bd9Sstevel@tonic-gate 		SrvLocHeader.parseCommaSeparatedListIn(sScopes, true);
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate 	    // Unescape scope strings.
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	    SLPHeaderV2.unescapeScopeStrings(vv);
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	    // Validate, lower case scope names.
9147c478bd9Sstevel@tonic-gate 
9157c478bd9Sstevel@tonic-gate 	    DATable.validateScopes(vv, getLocale());
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate 	    if (vv.size() > 0) {
9187c478bd9Sstevel@tonic-gate 		return vv;
9197c478bd9Sstevel@tonic-gate 	    }
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
9227c478bd9Sstevel@tonic-gate 	    writeLog("syntax_error_prop",
9237c478bd9Sstevel@tonic-gate 		     new Object[] {
9247c478bd9Sstevel@tonic-gate 		prop,
9257c478bd9Sstevel@tonic-gate 		    sScopes});
926*55fea89dSDan Cross 
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 	}
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate 	return new Vector();
9317c478bd9Sstevel@tonic-gate     }
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate     // Vector of preconfigured DAs. Read only after initialized.
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate     private Vector preconfiguredDAs = null;
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate     // Return a vector of DA addresses.
9387c478bd9Sstevel@tonic-gate 
getPreconfiguredDAs()9397c478bd9Sstevel@tonic-gate     Vector getPreconfiguredDAs() {
9407c478bd9Sstevel@tonic-gate 	return (Vector)preconfiguredDAs.clone();
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate     }
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate     // Initialize preconfigured DA list.
9457c478bd9Sstevel@tonic-gate 
initializePreconfiguredDAs()9467c478bd9Sstevel@tonic-gate     private Vector initializePreconfiguredDAs() {
9477c478bd9Sstevel@tonic-gate 	String sDAList = System.getProperty("net.slp.DAAddresses", "");
9487c478bd9Sstevel@tonic-gate 	Vector ret = new Vector();
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate 	sDAList.trim();
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 	if (sDAList.length() <= 0) {
9537c478bd9Sstevel@tonic-gate 	    return ret;
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 	}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	try {
9587c478bd9Sstevel@tonic-gate 
9597c478bd9Sstevel@tonic-gate 	    ret = SrvLocHeader.parseCommaSeparatedListIn(sDAList, true);
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 	    writeLog("syntax_error_prop",
9647c478bd9Sstevel@tonic-gate 		     new Object[] {"net.slp.DAAddress", sDAList});
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	    return ret;
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate 	}
9697c478bd9Sstevel@tonic-gate 
9707c478bd9Sstevel@tonic-gate 	// Convert to InetAddress objects.
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate 	int i;
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 	for (i = 0; i < ret.size(); i++) {
9757c478bd9Sstevel@tonic-gate 	    String da = "";
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 	    try {
9787c478bd9Sstevel@tonic-gate 		da = ((String)ret.elementAt(i)).trim();
9797c478bd9Sstevel@tonic-gate 		InetAddress daAddr = InetAddress.getByName(da);
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate 		ret.setElementAt(daAddr, i);
9827c478bd9Sstevel@tonic-gate 
9837c478bd9Sstevel@tonic-gate 	    } catch (UnknownHostException ex) {
9847c478bd9Sstevel@tonic-gate 
9857c478bd9Sstevel@tonic-gate 		writeLog("resolve_failed",
9867c478bd9Sstevel@tonic-gate 			 new Object[] {da});
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 		/*
9897c478bd9Sstevel@tonic-gate 		 *  Must decrement the index 'i' otherwise the next iteration
9907c478bd9Sstevel@tonic-gate 		 *  around the loop will miss the element immediately after
9917c478bd9Sstevel@tonic-gate 		 *  the element removed.
9927c478bd9Sstevel@tonic-gate 		 *
9937c478bd9Sstevel@tonic-gate 		 *  WARNING: Do not use 'i' again until the loop has
9947c478bd9Sstevel@tonic-gate 		 *           iterated as it may, after decrementing,
9957c478bd9Sstevel@tonic-gate 		 *           be negative.
9967c478bd9Sstevel@tonic-gate 		 */
9977c478bd9Sstevel@tonic-gate 		ret.removeElementAt(i);
9987c478bd9Sstevel@tonic-gate 		i--;
9997c478bd9Sstevel@tonic-gate 		continue;
10007c478bd9Sstevel@tonic-gate 	    }
10017c478bd9Sstevel@tonic-gate 	}
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 	return ret;
10057c478bd9Sstevel@tonic-gate     }
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
10087c478bd9Sstevel@tonic-gate     // SLPv1 Support Switches
10097c478bd9Sstevel@tonic-gate     //
10107c478bd9Sstevel@tonic-gate 
getSLPv1NotSupported()10117c478bd9Sstevel@tonic-gate     boolean getSLPv1NotSupported() {// not official!
10127c478bd9Sstevel@tonic-gate 	return Boolean.getBoolean("sun.net.slp.SLPv1NotSupported");
10137c478bd9Sstevel@tonic-gate 
10147c478bd9Sstevel@tonic-gate     }
10157c478bd9Sstevel@tonic-gate 
getAcceptSLPv1UnscopedRegs()10167c478bd9Sstevel@tonic-gate     boolean getAcceptSLPv1UnscopedRegs() {// not official!
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	if (!getSLPv1NotSupported()) {
10197c478bd9Sstevel@tonic-gate 	    return Boolean.getBoolean("sun.net.slp.acceptSLPv1UnscopedRegs");
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate 	}
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 	return false;
10247c478bd9Sstevel@tonic-gate     }
10257c478bd9Sstevel@tonic-gate 
10267c478bd9Sstevel@tonic-gate     // ------------------------------------------------------------
10277c478bd9Sstevel@tonic-gate     // Accessor for SLPConfig object
10287c478bd9Sstevel@tonic-gate     //
10297c478bd9Sstevel@tonic-gate 
10307c478bd9Sstevel@tonic-gate     protected static SLPConfig theSLPConfig = null;
10317c478bd9Sstevel@tonic-gate 
getSLPConfig()10327c478bd9Sstevel@tonic-gate     static SLPConfig getSLPConfig() {
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 	if (theSLPConfig == null) {
10357c478bd9Sstevel@tonic-gate 	    theSLPConfig = new SLPConfig();
10367c478bd9Sstevel@tonic-gate 	}
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate 	return theSLPConfig;
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate     }
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate     /**
10437c478bd9Sstevel@tonic-gate      * @return Maximum number of messages/objects to return.
10447c478bd9Sstevel@tonic-gate      */
10457c478bd9Sstevel@tonic-gate 
getMaximumResults()10467c478bd9Sstevel@tonic-gate     int getMaximumResults()  {
10477c478bd9Sstevel@tonic-gate 	int i = Integer.getInteger("net.slp.maxResults",
10487c478bd9Sstevel@tonic-gate 				   Defaults.iMaximumResults).intValue();
10497c478bd9Sstevel@tonic-gate 	if (i == -1) {
10507c478bd9Sstevel@tonic-gate 	    i = Integer.MAX_VALUE;
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 	}
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 	if (OKBound(i, 1, Integer.MAX_VALUE)) {
10557c478bd9Sstevel@tonic-gate 	    return i;
10567c478bd9Sstevel@tonic-gate 
10577c478bd9Sstevel@tonic-gate 	} else {
10587c478bd9Sstevel@tonic-gate 
10597c478bd9Sstevel@tonic-gate 	    writeLog("bad_prop_tag",
10607c478bd9Sstevel@tonic-gate 		     new Object[] {
10617c478bd9Sstevel@tonic-gate 		"net.slp.maxResults"});
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 	    return Defaults.iMaximumResults;
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	}
10667c478bd9Sstevel@tonic-gate     }
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate     /**
10697c478bd9Sstevel@tonic-gate      * Convert a language tag into a locale.
10707c478bd9Sstevel@tonic-gate      */
10717c478bd9Sstevel@tonic-gate 
langTagToLocale(String ltag)10727c478bd9Sstevel@tonic-gate     static Locale langTagToLocale(String ltag) {
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate 	// We treat the first part as the ISO 639 language and the
10757c478bd9Sstevel@tonic-gate 	// second part as the ISO 3166 country tag, even though RFC
10767c478bd9Sstevel@tonic-gate 	// 1766 doesn't necessarily require that. We should probably
10777c478bd9Sstevel@tonic-gate 	// use a lookup table here to determine if they are correct.
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate 	StringTokenizer tk = new StringTokenizer(ltag, "-");
10807c478bd9Sstevel@tonic-gate 	String lang = "";
10817c478bd9Sstevel@tonic-gate 	String country = "";
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 	if (tk.hasMoreTokens()) {
10847c478bd9Sstevel@tonic-gate 	    lang = tk.nextToken();
10857c478bd9Sstevel@tonic-gate 
10867c478bd9Sstevel@tonic-gate 	    if (tk.hasMoreTokens()) {
10877c478bd9Sstevel@tonic-gate 		country = tk.nextToken("");
10887c478bd9Sstevel@tonic-gate 					// country name may have "-" in it...
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate 	    }
10917c478bd9Sstevel@tonic-gate 	}
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 	return new Locale(lang, country);
10947c478bd9Sstevel@tonic-gate     }
10957c478bd9Sstevel@tonic-gate 
10967c478bd9Sstevel@tonic-gate     /**
10977c478bd9Sstevel@tonic-gate      * Convert a Locale object into a language tag for output.
10987c478bd9Sstevel@tonic-gate      *
10997c478bd9Sstevel@tonic-gate      * @param locale The Locale.
11007c478bd9Sstevel@tonic-gate      * @return String with the language tag encoded.
11017c478bd9Sstevel@tonic-gate      */
11027c478bd9Sstevel@tonic-gate 
localeToLangTag(Locale locale)11037c478bd9Sstevel@tonic-gate     static String localeToLangTag(Locale locale) {
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate 	// Construct the language tag.
11067c478bd9Sstevel@tonic-gate 
11077c478bd9Sstevel@tonic-gate 	String ltag = locale.getCountry();
11087c478bd9Sstevel@tonic-gate 	ltag = locale.getLanguage() + (ltag.length() <= 0 ? "" : ("-" + ltag));
11097c478bd9Sstevel@tonic-gate 
11107c478bd9Sstevel@tonic-gate 	return ltag;
11117c478bd9Sstevel@tonic-gate 
11127c478bd9Sstevel@tonic-gate     }
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate     /**
11157c478bd9Sstevel@tonic-gate      * @return the language requests will be made in.
11167c478bd9Sstevel@tonic-gate      */
getLocale()11177c478bd9Sstevel@tonic-gate     static Locale  getLocale()    {
11187c478bd9Sstevel@tonic-gate 	String s = System.getProperty("net.slp.locale");
11197c478bd9Sstevel@tonic-gate 
11207c478bd9Sstevel@tonic-gate 	if (s != null && s.length() > 0) {
11217c478bd9Sstevel@tonic-gate 	    return langTagToLocale(s);
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate 	} else {
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate 	    // Return the Java default if the SLP property is not set.
11267c478bd9Sstevel@tonic-gate 
11277c478bd9Sstevel@tonic-gate 	    return Locale.getDefault();
11287c478bd9Sstevel@tonic-gate 
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate     }
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate     /**
11337c478bd9Sstevel@tonic-gate      * @return the InetAddress of the broadcast interface.
11347c478bd9Sstevel@tonic-gate      */
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate     static private InetAddress broadcastAddress;
11377c478bd9Sstevel@tonic-gate 
getBroadcastAddress()11387c478bd9Sstevel@tonic-gate     static InetAddress getBroadcastAddress() {
11397c478bd9Sstevel@tonic-gate 	if (broadcastAddress == null) {
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 	    try {
11427c478bd9Sstevel@tonic-gate 		broadcastAddress =
11437c478bd9Sstevel@tonic-gate 		    InetAddress.getByName(Defaults.sBroadcast);
11447c478bd9Sstevel@tonic-gate 	    } catch (UnknownHostException uhe) {
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 		Assert.slpassert(false,
11477c478bd9Sstevel@tonic-gate 			      "cast_address_failure",
11487c478bd9Sstevel@tonic-gate 			      new Object[] {Defaults.sBroadcast});
11497c478bd9Sstevel@tonic-gate 
11507c478bd9Sstevel@tonic-gate 	    }
11517c478bd9Sstevel@tonic-gate 	}
11527c478bd9Sstevel@tonic-gate 	return broadcastAddress;
11537c478bd9Sstevel@tonic-gate     }
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate 
11567c478bd9Sstevel@tonic-gate     /**
11577c478bd9Sstevel@tonic-gate      * @return the InetAddress of the multicast group.
11587c478bd9Sstevel@tonic-gate      */
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate     static private InetAddress multicastAddress;
11617c478bd9Sstevel@tonic-gate 
getMulticastAddress()11627c478bd9Sstevel@tonic-gate     static InetAddress getMulticastAddress() {
11637c478bd9Sstevel@tonic-gate 	if (multicastAddress == null) {
11647c478bd9Sstevel@tonic-gate 
11657c478bd9Sstevel@tonic-gate 	    try {
11667c478bd9Sstevel@tonic-gate 		multicastAddress =
11677c478bd9Sstevel@tonic-gate 		    InetAddress.getByName(Defaults.sGeneralSLPMCAddress);
11687c478bd9Sstevel@tonic-gate 	    } catch (UnknownHostException uhe) {
11697c478bd9Sstevel@tonic-gate 		Assert.slpassert(false,
11707c478bd9Sstevel@tonic-gate 			      "cast_address_failure",
11717c478bd9Sstevel@tonic-gate 			      new Object[] {Defaults.sGeneralSLPMCAddress});
11727c478bd9Sstevel@tonic-gate 
11737c478bd9Sstevel@tonic-gate 	    }
11747c478bd9Sstevel@tonic-gate 	}
11757c478bd9Sstevel@tonic-gate 	return multicastAddress;
11767c478bd9Sstevel@tonic-gate     }
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate     /**
11797c478bd9Sstevel@tonic-gate      * @return the interfaces on which SLP should listen and transmit.
11807c478bd9Sstevel@tonic-gate      */
11817c478bd9Sstevel@tonic-gate 
11827c478bd9Sstevel@tonic-gate     private static Vector interfaces = null;
11837c478bd9Sstevel@tonic-gate 
getInterfaces()11847c478bd9Sstevel@tonic-gate     Vector getInterfaces() {
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	if (interfaces == null) {
11877c478bd9Sstevel@tonic-gate 	    InetAddress iaLocal = null;
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate 	    // Get local host.
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 	    try {
11927c478bd9Sstevel@tonic-gate 		iaLocal =  InetAddress.getLocalHost();
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate 	    }  catch (UnknownHostException ex) {
11957c478bd9Sstevel@tonic-gate 		Assert.slpassert(false,
11967c478bd9Sstevel@tonic-gate 			      "resolve_failed",
11977c478bd9Sstevel@tonic-gate 			      new Object[] {"localhost"});
11987c478bd9Sstevel@tonic-gate 	    }
11997c478bd9Sstevel@tonic-gate 
12007c478bd9Sstevel@tonic-gate 	    String mcastI = System.getProperty("net.slp.interfaces");
12017c478bd9Sstevel@tonic-gate 	    interfaces = new Vector();
12027c478bd9Sstevel@tonic-gate 
12037c478bd9Sstevel@tonic-gate 	    // Only add local host if nothing else is given.
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate 	    if (mcastI == null || mcastI.length() <= 0) {
12067c478bd9Sstevel@tonic-gate 		interfaces.addElement(iaLocal);
12077c478bd9Sstevel@tonic-gate 		return interfaces;
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 	    }
12107c478bd9Sstevel@tonic-gate 
12117c478bd9Sstevel@tonic-gate 	    Vector nintr;
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 	    try {
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 		nintr = SrvLocHeader.parseCommaSeparatedListIn(mcastI, true);
12167c478bd9Sstevel@tonic-gate 
12177c478bd9Sstevel@tonic-gate 	    } catch (ServiceLocationException ex) {
12187c478bd9Sstevel@tonic-gate 		writeLog("syntax_error_prop",
12197c478bd9Sstevel@tonic-gate 			 new Object[] {
12207c478bd9Sstevel@tonic-gate 		    "net.slp.multicastInterfaces",
12217c478bd9Sstevel@tonic-gate 			mcastI});
12227c478bd9Sstevel@tonic-gate 
12237c478bd9Sstevel@tonic-gate 		// Add local host.
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate 		interfaces.addElement(iaLocal);
1226*55fea89dSDan Cross 
12277c478bd9Sstevel@tonic-gate 		return interfaces;
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 	    }
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate 	    // See if they are really there.
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate 	    int i, n = nintr.size();
12347c478bd9Sstevel@tonic-gate 
12357c478bd9Sstevel@tonic-gate 	    for (i = 0; i < n; i++) {
12367c478bd9Sstevel@tonic-gate 		InetAddress ia;
12377c478bd9Sstevel@tonic-gate 		String host = (String)nintr.elementAt(i);
12387c478bd9Sstevel@tonic-gate 
12397c478bd9Sstevel@tonic-gate 		try {
12407c478bd9Sstevel@tonic-gate 
12417c478bd9Sstevel@tonic-gate 		    ia = InetAddress.getByName(host);
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate 		} catch (UnknownHostException ex) {
12447c478bd9Sstevel@tonic-gate 		    writeLog("unknown_interface",
12457c478bd9Sstevel@tonic-gate 			     new Object[] {host,
12467c478bd9Sstevel@tonic-gate 					       "net.slp.multicastInterfaces"});
12477c478bd9Sstevel@tonic-gate 		    continue;
12487c478bd9Sstevel@tonic-gate 
12497c478bd9Sstevel@tonic-gate 		}
12507c478bd9Sstevel@tonic-gate 
12517c478bd9Sstevel@tonic-gate 		if (!interfaces.contains(ia)) {
12527c478bd9Sstevel@tonic-gate 
12537c478bd9Sstevel@tonic-gate 		    // Add default at beginning.
12547c478bd9Sstevel@tonic-gate 
12557c478bd9Sstevel@tonic-gate 		    if (ia.equals(iaLocal)) {
12567c478bd9Sstevel@tonic-gate 			interfaces.insertElementAt(ia, 0);
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate 		    } else {
12597c478bd9Sstevel@tonic-gate 			interfaces.addElement(ia);
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate 		    }
12627c478bd9Sstevel@tonic-gate 		}
12637c478bd9Sstevel@tonic-gate 	    }
12647c478bd9Sstevel@tonic-gate 	}
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 	return interfaces;
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate     }
12697c478bd9Sstevel@tonic-gate 
12707c478bd9Sstevel@tonic-gate     /**
12717c478bd9Sstevel@tonic-gate      * @return An InetAddress object representing 127.0.0.1
12727c478bd9Sstevel@tonic-gate      */
getLoopback()12737c478bd9Sstevel@tonic-gate     InetAddress getLoopback() {
12747c478bd9Sstevel@tonic-gate 	InetAddress iaLoopback = null;
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 	try {
12777c478bd9Sstevel@tonic-gate 	    iaLoopback = InetAddress.getByName(Defaults.LOOPBACK_ADDRESS);
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate 	}  catch (UnknownHostException ex) {
12807c478bd9Sstevel@tonic-gate 	    Assert.slpassert(false,
12817c478bd9Sstevel@tonic-gate 			  "resolve_failed",
12827c478bd9Sstevel@tonic-gate 			  new Object[] {"localhost loopback"});
12837c478bd9Sstevel@tonic-gate 	}
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate 	return iaLoopback;
12867c478bd9Sstevel@tonic-gate     }
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate     /**
12897c478bd9Sstevel@tonic-gate      * @return The default interface, which should be the first in the
12907c478bd9Sstevel@tonic-gate      *         interfaces vector Vector.
12917c478bd9Sstevel@tonic-gate      */
12927c478bd9Sstevel@tonic-gate 
getLocalHost()12937c478bd9Sstevel@tonic-gate     InetAddress getLocalHost() {
12947c478bd9Sstevel@tonic-gate 	Vector inter = getInterfaces();
12957c478bd9Sstevel@tonic-gate 	return (InetAddress)inter.elementAt(0);
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate     }
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate     // Return true if the address is one of the local interfaces.
13007c478bd9Sstevel@tonic-gate 
isLocalHostSource(InetAddress addr)13017c478bd9Sstevel@tonic-gate     boolean isLocalHostSource(InetAddress addr) {
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate 	// First check loopback
13047c478bd9Sstevel@tonic-gate 
13057c478bd9Sstevel@tonic-gate 	if (addr.equals(getLoopback())) {
13067c478bd9Sstevel@tonic-gate 	    return true;
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate 	}
13097c478bd9Sstevel@tonic-gate 
13107c478bd9Sstevel@tonic-gate 	return interfaces.contains(addr);
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate     }
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate     // -----------------
13157c478bd9Sstevel@tonic-gate     // Timeouts
13167c478bd9Sstevel@tonic-gate     //
13177c478bd9Sstevel@tonic-gate 
13187c478bd9Sstevel@tonic-gate     // Return the maximum wait for multicast convergence.
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate     final static private int iMultiMin = 1000;  // one second
13217c478bd9Sstevel@tonic-gate     final static private int iMultiMax = 60000; // one minute
13227c478bd9Sstevel@tonic-gate 
getMulticastMaximumWait()13237c478bd9Sstevel@tonic-gate     int getMulticastMaximumWait() {
13247c478bd9Sstevel@tonic-gate 
13257c478bd9Sstevel@tonic-gate 	return getIntProperty("net.slp.multicastMaximumWait",
13267c478bd9Sstevel@tonic-gate 			      Defaults.iMulticastMaxWait,
13277c478bd9Sstevel@tonic-gate 			      iMultiMin,
13287c478bd9Sstevel@tonic-gate 			      iMultiMax);
13297c478bd9Sstevel@tonic-gate     }
13307c478bd9Sstevel@tonic-gate 
13317c478bd9Sstevel@tonic-gate     /*
13327c478bd9Sstevel@tonic-gate      * @return Vector of timeouts for multicast convergence.
13337c478bd9Sstevel@tonic-gate      */
13347c478bd9Sstevel@tonic-gate 
getMulticastTimeouts()13357c478bd9Sstevel@tonic-gate     int[] getMulticastTimeouts() {
13367c478bd9Sstevel@tonic-gate 	int[] timeouts = parseTimeouts("net.slp.multicastTimeouts",
13377c478bd9Sstevel@tonic-gate 			     Defaults.a_iConvergeTimeout);
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 	timeouts = capTimeouts("net.slp.multicastTimeouts",
13407c478bd9Sstevel@tonic-gate 			       timeouts,
13417c478bd9Sstevel@tonic-gate 			       false,
13427c478bd9Sstevel@tonic-gate 			       0,
13437c478bd9Sstevel@tonic-gate 			       0);
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate 	return timeouts;
13467c478bd9Sstevel@tonic-gate     }
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate     /**
13497c478bd9Sstevel@tonic-gate      * @return Vector of timeouts to try for datagram transmission.
13507c478bd9Sstevel@tonic-gate      */
13517c478bd9Sstevel@tonic-gate 
getDatagramTimeouts()13527c478bd9Sstevel@tonic-gate     int[] getDatagramTimeouts() {
13537c478bd9Sstevel@tonic-gate 	int[] timeouts = parseTimeouts("net.slp.datagramTimeouts",
13547c478bd9Sstevel@tonic-gate 			     Defaults.a_iDatagramTimeout);
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 	timeouts = capTimeouts("net.slp.datagramTimeouts",
13577c478bd9Sstevel@tonic-gate 			       timeouts,
13587c478bd9Sstevel@tonic-gate 			       true,
13597c478bd9Sstevel@tonic-gate 			       iMultiMin,
13607c478bd9Sstevel@tonic-gate 			       iMultiMax);
13617c478bd9Sstevel@tonic-gate 
13627c478bd9Sstevel@tonic-gate 	return timeouts;
13637c478bd9Sstevel@tonic-gate     }
13647c478bd9Sstevel@tonic-gate 
13657c478bd9Sstevel@tonic-gate     /**
13667c478bd9Sstevel@tonic-gate      * @return Vector of timeouts for DA discovery multicast.
13677c478bd9Sstevel@tonic-gate      */
13687c478bd9Sstevel@tonic-gate 
getDADiscoveryTimeouts()13697c478bd9Sstevel@tonic-gate     int[] getDADiscoveryTimeouts() {
13707c478bd9Sstevel@tonic-gate 	int[] timeouts = parseTimeouts("net.slp.DADiscoveryTimeouts",
13717c478bd9Sstevel@tonic-gate 			     Defaults.a_iDADiscoveryTimeout);
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate 	timeouts = capTimeouts("net.slp.DADiscoveryTimeouts",
13747c478bd9Sstevel@tonic-gate 				timeouts,
13757c478bd9Sstevel@tonic-gate 				false,
13767c478bd9Sstevel@tonic-gate 				0,
13777c478bd9Sstevel@tonic-gate 				0);
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate 	return timeouts;
13807c478bd9Sstevel@tonic-gate     }
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate     /**
13837c478bd9Sstevel@tonic-gate      *  This method ensures that all the timeouts are within valid ranges.
13847c478bd9Sstevel@tonic-gate      *  The sum of all timeouts for the given property name must not
13857c478bd9Sstevel@tonic-gate      *  exceed the value returned by <i>getMulticastMaximumWait()</i>. If
13867c478bd9Sstevel@tonic-gate      *  the sum of all timeouts does exceed the maximum wait period the
13877c478bd9Sstevel@tonic-gate      *  timeouts are averaged out so that the sum equals the maximum wait
13887c478bd9Sstevel@tonic-gate      *  period.
13897c478bd9Sstevel@tonic-gate      *	<br>
13907c478bd9Sstevel@tonic-gate      *  Additional range checking is also performed when <i>rangeCheck</i>
13917c478bd9Sstevel@tonic-gate      *  is true. Then the sum of all timeouts must also be between <i>min</i>
13927c478bd9Sstevel@tonic-gate      *  and <i>max</i>. If the sum of all timeouts is not within the range
13937c478bd9Sstevel@tonic-gate      *  the average is taken from the closest range boundary.
13947c478bd9Sstevel@tonic-gate      *
13957c478bd9Sstevel@tonic-gate      *  @param property
13967c478bd9Sstevel@tonic-gate      *	    Name of timeout property being capped. This is only present for
13977c478bd9Sstevel@tonic-gate      *	    reporting purposes and no actual manipulation of the property
13987c478bd9Sstevel@tonic-gate      *      is made within this method.
13997c478bd9Sstevel@tonic-gate      *  @param timeouts
14007c478bd9Sstevel@tonic-gate      *      Array of timeout values.
14017c478bd9Sstevel@tonic-gate      *  @param rangeCheck
14027c478bd9Sstevel@tonic-gate      *      Indicator of whether additional range checking is required. When
14037c478bd9Sstevel@tonic-gate      *      false <i>min</i> and <i>max</i> are ignored.
14047c478bd9Sstevel@tonic-gate      *  @param min
14057c478bd9Sstevel@tonic-gate      *      Additional range checking lower boundary.
14067c478bd9Sstevel@tonic-gate      *  @param max
14077c478bd9Sstevel@tonic-gate      *      Additional range checking upper boundary.
14087c478bd9Sstevel@tonic-gate      *  @return
14097c478bd9Sstevel@tonic-gate      *      Array of capped timeouts. Note this may be the same array as
14107c478bd9Sstevel@tonic-gate      *      passed in (<i>timeouts</i>).
14117c478bd9Sstevel@tonic-gate      */
capTimeouts(String property, int[] timeouts, boolean rangeCheck, int min, int max)14127c478bd9Sstevel@tonic-gate     private int[] capTimeouts(String property,
14137c478bd9Sstevel@tonic-gate 			      int[] timeouts,
14147c478bd9Sstevel@tonic-gate 			      boolean rangeCheck,
14157c478bd9Sstevel@tonic-gate 			      int min,
14167c478bd9Sstevel@tonic-gate 			      int max) {
14177c478bd9Sstevel@tonic-gate 
14187c478bd9Sstevel@tonic-gate 	int averagedTimeout;
14197c478bd9Sstevel@tonic-gate 	int totalWait = 0;
14207c478bd9Sstevel@tonic-gate 
14217c478bd9Sstevel@tonic-gate 	for (int index = 0; index < timeouts.length; index++) {
14227c478bd9Sstevel@tonic-gate 	    totalWait += timeouts[index];
14237c478bd9Sstevel@tonic-gate 	}
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate 	if (rangeCheck) {
14267c478bd9Sstevel@tonic-gate 	    // If sum of timeouts within limits then finished.
14277c478bd9Sstevel@tonic-gate 	    if (totalWait >= min && totalWait <= max) {
14287c478bd9Sstevel@tonic-gate 		return timeouts;
14297c478bd9Sstevel@tonic-gate 	    }
14307c478bd9Sstevel@tonic-gate 
14317c478bd9Sstevel@tonic-gate 	    // Average out the timeouts so the sum is equal to the closest
14327c478bd9Sstevel@tonic-gate 	    // range boundary.
14337c478bd9Sstevel@tonic-gate 	    if (totalWait < min) {
14347c478bd9Sstevel@tonic-gate 		averagedTimeout = min / timeouts.length;
14357c478bd9Sstevel@tonic-gate 	    } else {
14367c478bd9Sstevel@tonic-gate 		averagedTimeout = max / timeouts.length;
14377c478bd9Sstevel@tonic-gate 	    }
14387c478bd9Sstevel@tonic-gate 
14397c478bd9Sstevel@tonic-gate 	    writeLog("capped_range_timeout_prop",
14407c478bd9Sstevel@tonic-gate 		     new Object[] {property,
14417c478bd9Sstevel@tonic-gate 				   String.valueOf(totalWait),
14427c478bd9Sstevel@tonic-gate 				   String.valueOf(min),
14437c478bd9Sstevel@tonic-gate 				   String.valueOf(max),
14447c478bd9Sstevel@tonic-gate 				   String.valueOf(timeouts.length),
14457c478bd9Sstevel@tonic-gate 				   String.valueOf(averagedTimeout)});
14467c478bd9Sstevel@tonic-gate 	} else {
14477c478bd9Sstevel@tonic-gate 	    // Sum of all timeouts must not exceed this value.
14487c478bd9Sstevel@tonic-gate 	    int maximumWait = getMulticastMaximumWait();
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate 	    // If sum of timeouts within limits then finished.
14517c478bd9Sstevel@tonic-gate 	    if (totalWait <= maximumWait) {
14527c478bd9Sstevel@tonic-gate 		return timeouts;
14537c478bd9Sstevel@tonic-gate 	    }
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate 	    // Average out the timeouts so the sum is equal to the maximum
14567c478bd9Sstevel@tonic-gate 	    // timeout.
14577c478bd9Sstevel@tonic-gate 	    averagedTimeout = maximumWait / timeouts.length;
14587c478bd9Sstevel@tonic-gate 
14597c478bd9Sstevel@tonic-gate 	    writeLog("capped_timeout_prop",
14607c478bd9Sstevel@tonic-gate 		     new Object[] {property,
14617c478bd9Sstevel@tonic-gate 				   String.valueOf(totalWait),
14627c478bd9Sstevel@tonic-gate 				   String.valueOf(maximumWait),
14637c478bd9Sstevel@tonic-gate 				   String.valueOf(timeouts.length),
14647c478bd9Sstevel@tonic-gate 				   String.valueOf(averagedTimeout)});
14657c478bd9Sstevel@tonic-gate 	}
14667c478bd9Sstevel@tonic-gate 
14677c478bd9Sstevel@tonic-gate 	for (int index = 0; index < timeouts.length; index++) {
14687c478bd9Sstevel@tonic-gate 	    timeouts[index] = averagedTimeout;
14697c478bd9Sstevel@tonic-gate 	}
14707c478bd9Sstevel@tonic-gate 
14717c478bd9Sstevel@tonic-gate 	return timeouts;
14727c478bd9Sstevel@tonic-gate     }
14737c478bd9Sstevel@tonic-gate 
parseTimeouts(String property, int[] defaults)14747c478bd9Sstevel@tonic-gate     private int[] parseTimeouts(String property, int[] defaults) {
14757c478bd9Sstevel@tonic-gate 
14767c478bd9Sstevel@tonic-gate 	String sTimeouts = System.getProperty(property);
14777c478bd9Sstevel@tonic-gate 
14787c478bd9Sstevel@tonic-gate 	if (sTimeouts == null || sTimeouts.length() <= 0) {
14797c478bd9Sstevel@tonic-gate 	    return defaults;
14807c478bd9Sstevel@tonic-gate 
14817c478bd9Sstevel@tonic-gate 	}
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate 	Vector timeouts = null;
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate 	try {
14867c478bd9Sstevel@tonic-gate 	    timeouts = SrvLocHeader.parseCommaSeparatedListIn(sTimeouts, true);
14877c478bd9Sstevel@tonic-gate 
14887c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
14897c478bd9Sstevel@tonic-gate 	    writeLog("syntax_error_prop",
14907c478bd9Sstevel@tonic-gate 		     new Object[] {property, sTimeouts});
14917c478bd9Sstevel@tonic-gate 	    return defaults;
14927c478bd9Sstevel@tonic-gate 
14937c478bd9Sstevel@tonic-gate 	}
14947c478bd9Sstevel@tonic-gate 
14957c478bd9Sstevel@tonic-gate 	int iCount = 0;
14967c478bd9Sstevel@tonic-gate 	int[] iTOs = new int[timeouts.size()];
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate 	for (Enumeration en = timeouts.elements(); en.hasMoreElements(); ) {
14997c478bd9Sstevel@tonic-gate 	    String s1 = (String)en.nextElement();
15007c478bd9Sstevel@tonic-gate 
15017c478bd9Sstevel@tonic-gate 	    try {
15027c478bd9Sstevel@tonic-gate 		iTOs[iCount] = Integer.parseInt(s1);
15037c478bd9Sstevel@tonic-gate 
15047c478bd9Sstevel@tonic-gate 	    }	catch (NumberFormatException nfe) {
15057c478bd9Sstevel@tonic-gate 		writeLog("syntax_error_prop",
15067c478bd9Sstevel@tonic-gate 			 new Object[] {property, sTimeouts});
15077c478bd9Sstevel@tonic-gate 		return defaults;
15087c478bd9Sstevel@tonic-gate 
15097c478bd9Sstevel@tonic-gate 	    }
15107c478bd9Sstevel@tonic-gate 
15117c478bd9Sstevel@tonic-gate 	    if (iTOs[iCount] < 0) {
15127c478bd9Sstevel@tonic-gate 		writeLog("invalid_timeout_prop",
15137c478bd9Sstevel@tonic-gate 			 new Object[] {property, String.valueOf(iTOs[iCount])});
15147c478bd9Sstevel@tonic-gate 		return defaults;
15157c478bd9Sstevel@tonic-gate 	    }
15167c478bd9Sstevel@tonic-gate 
15177c478bd9Sstevel@tonic-gate 	    iCount++;
15187c478bd9Sstevel@tonic-gate 	}
15197c478bd9Sstevel@tonic-gate 
15207c478bd9Sstevel@tonic-gate 	return iTOs;
15217c478bd9Sstevel@tonic-gate     }
15227c478bd9Sstevel@tonic-gate 
15237c478bd9Sstevel@tonic-gate     // -----------------------------
15247c478bd9Sstevel@tonic-gate     // SLP Time Calculation
15257c478bd9Sstevel@tonic-gate     //
15267c478bd9Sstevel@tonic-gate 
15277c478bd9Sstevel@tonic-gate     /**
15287c478bd9Sstevel@tonic-gate      * Returns the number of seconds since 00:00 Universal Coordinated
15297c478bd9Sstevel@tonic-gate      * Time, January 1, 1970.
15307c478bd9Sstevel@tonic-gate      *
15317c478bd9Sstevel@tonic-gate      * Java returns the number of milliseconds, so all the method does is
15327c478bd9Sstevel@tonic-gate      * divide by 1000.
15337c478bd9Sstevel@tonic-gate      *
15347c478bd9Sstevel@tonic-gate      * This implementation still will have a problem when the Java time
15357c478bd9Sstevel@tonic-gate      * values wraps, but there isn't much we can do now.
15367c478bd9Sstevel@tonic-gate      */
currentSLPTime()15377c478bd9Sstevel@tonic-gate     static long currentSLPTime() {
15387c478bd9Sstevel@tonic-gate 	return (System.currentTimeMillis() / 1000);
15397c478bd9Sstevel@tonic-gate     }
15407c478bd9Sstevel@tonic-gate 
15417c478bd9Sstevel@tonic-gate     /* security */
15427c478bd9Sstevel@tonic-gate 
15437c478bd9Sstevel@tonic-gate     // Indicates whether security class is available.
15447c478bd9Sstevel@tonic-gate 
getSecurityEnabled()15457c478bd9Sstevel@tonic-gate     boolean getSecurityEnabled() {
15467c478bd9Sstevel@tonic-gate 	return securityEnabled;
15477c478bd9Sstevel@tonic-gate 
15487c478bd9Sstevel@tonic-gate     }
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate     private static boolean securityEnabled;
15517c478bd9Sstevel@tonic-gate 
15527c478bd9Sstevel@tonic-gate     // Indicates whether the securityEnabled property is true
15537c478bd9Sstevel@tonic-gate 
getHasSecurity()15547c478bd9Sstevel@tonic-gate     boolean getHasSecurity() {
15557c478bd9Sstevel@tonic-gate 	return securityEnabled &&
15567c478bd9Sstevel@tonic-gate 	    (new Boolean(System.getProperty("net.slp.securityEnabled",
15577c478bd9Sstevel@tonic-gate 					    "false")).booleanValue());
15587c478bd9Sstevel@tonic-gate     }
15597c478bd9Sstevel@tonic-gate 
15607c478bd9Sstevel@tonic-gate     // I18N Support.
15617c478bd9Sstevel@tonic-gate 
15627c478bd9Sstevel@tonic-gate     private static final String BASE_BUNDLE_NAME = "com/sun/slp/ClientLib";
15637c478bd9Sstevel@tonic-gate 
getMessageBundle(Locale locale)15647c478bd9Sstevel@tonic-gate     ResourceBundle getMessageBundle(Locale locale) {
15657c478bd9Sstevel@tonic-gate 
15667c478bd9Sstevel@tonic-gate 	ResourceBundle msgBundle = null;
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate 	// First try the Solaris Java locale area
15697c478bd9Sstevel@tonic-gate 
15707c478bd9Sstevel@tonic-gate 	try {
15717c478bd9Sstevel@tonic-gate 	    URL[] urls = new URL[] {new URL("file:/usr/share/lib/locale/")};
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate 	    URLClassLoader ld = new URLClassLoader(urls);
15747c478bd9Sstevel@tonic-gate 
15757c478bd9Sstevel@tonic-gate 	    msgBundle = ResourceBundle.getBundle(BASE_BUNDLE_NAME, locale, ld);
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate 	    return msgBundle;
15787c478bd9Sstevel@tonic-gate 	} catch (MalformedURLException e) {	// shouldn't get here
15797c478bd9Sstevel@tonic-gate 	} catch (MissingResourceException ex) {
15807c478bd9Sstevel@tonic-gate 	    System.err.println("Missing resource bundle ``"+
15817c478bd9Sstevel@tonic-gate 			       "/usr/share/lib/locale/" + BASE_BUNDLE_NAME +
15827c478bd9Sstevel@tonic-gate 			       "'' for locale ``" +
15837c478bd9Sstevel@tonic-gate 			       locale + "''; trying default...");
15847c478bd9Sstevel@tonic-gate 	}
15857c478bd9Sstevel@tonic-gate 
15867c478bd9Sstevel@tonic-gate 	try {
15877c478bd9Sstevel@tonic-gate 	    msgBundle = ResourceBundle.getBundle(BASE_BUNDLE_NAME, locale);
15887c478bd9Sstevel@tonic-gate 
15897c478bd9Sstevel@tonic-gate 	} catch (MissingResourceException ex) {  // can't localize this one!
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate 	    // We can't print out to the log, because we may be in the
15927c478bd9Sstevel@tonic-gate 	    //  process of trying to.
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate 	    System.err.println("Missing resource bundle ``"+
15957c478bd9Sstevel@tonic-gate 			       BASE_BUNDLE_NAME+
15967c478bd9Sstevel@tonic-gate 			       "'' for locale ``"+
15977c478bd9Sstevel@tonic-gate 			       locale+
15987c478bd9Sstevel@tonic-gate 			       "''");
15997c478bd9Sstevel@tonic-gate 	    // Hosed if the default locale is missing.
16007c478bd9Sstevel@tonic-gate 
16017c478bd9Sstevel@tonic-gate 	    if (locale.equals(Defaults.locale)) {
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate 		System.err.println("Exiting...");
16047c478bd9Sstevel@tonic-gate 		System.exit(1);
16057c478bd9Sstevel@tonic-gate 	    }
16067c478bd9Sstevel@tonic-gate 
16077c478bd9Sstevel@tonic-gate 	    // Otherwise, return the default locale.
16087c478bd9Sstevel@tonic-gate 
16097c478bd9Sstevel@tonic-gate 	    System.err.println("Using SLP default locale ``" +
16107c478bd9Sstevel@tonic-gate 			       Defaults.locale +
16117c478bd9Sstevel@tonic-gate 			       "''");
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 	    msgBundle = getMessageBundle(Defaults.locale);
16147c478bd9Sstevel@tonic-gate 
16157c478bd9Sstevel@tonic-gate 	}
16167c478bd9Sstevel@tonic-gate 
16177c478bd9Sstevel@tonic-gate 	return msgBundle;
16187c478bd9Sstevel@tonic-gate     }
16197c478bd9Sstevel@tonic-gate 
formatMessage(String msgTag, Object[] params)16207c478bd9Sstevel@tonic-gate     String formatMessage(String msgTag, Object[] params) {
16217c478bd9Sstevel@tonic-gate 	ResourceBundle bundle = getMessageBundle(getLocale());
16227c478bd9Sstevel@tonic-gate 	return formatMessageInternal(msgTag, params, bundle);
16237c478bd9Sstevel@tonic-gate 
16247c478bd9Sstevel@tonic-gate     }
16257c478bd9Sstevel@tonic-gate 
16267c478bd9Sstevel@tonic-gate     // MessageFormat is picky about types. Convert the params into strings.
16277c478bd9Sstevel@tonic-gate 
convertToString(Object[] params)16287c478bd9Sstevel@tonic-gate     static void convertToString(Object[] params) {
16297c478bd9Sstevel@tonic-gate 	int i, n = params.length;
16307c478bd9Sstevel@tonic-gate 
16317c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
16327c478bd9Sstevel@tonic-gate 
16337c478bd9Sstevel@tonic-gate 	    if (params[i] != null) {
16347c478bd9Sstevel@tonic-gate 		params[i] = params[i].toString();
16357c478bd9Sstevel@tonic-gate 
16367c478bd9Sstevel@tonic-gate 	    } else {
16377c478bd9Sstevel@tonic-gate 		params[i] = "<null>";
16387c478bd9Sstevel@tonic-gate 
16397c478bd9Sstevel@tonic-gate 	    }
16407c478bd9Sstevel@tonic-gate 	}
16417c478bd9Sstevel@tonic-gate     }
16427c478bd9Sstevel@tonic-gate 
16437c478bd9Sstevel@tonic-gate     static String
formatMessageInternal(String msgTag, Object[] params, ResourceBundle bundle)16447c478bd9Sstevel@tonic-gate 	formatMessageInternal(String msgTag,
16457c478bd9Sstevel@tonic-gate 			      Object[] params,
16467c478bd9Sstevel@tonic-gate 			      ResourceBundle bundle) {
16477c478bd9Sstevel@tonic-gate 	String pattern = "";
16487c478bd9Sstevel@tonic-gate 
16497c478bd9Sstevel@tonic-gate 	try {
16507c478bd9Sstevel@tonic-gate 	    pattern = bundle.getString(msgTag);
16517c478bd9Sstevel@tonic-gate 
16527c478bd9Sstevel@tonic-gate 	} catch (MissingResourceException ex) {
16537c478bd9Sstevel@tonic-gate 
16547c478bd9Sstevel@tonic-gate 	    // Attempt to report error. Can't use Assert here because it
16557c478bd9Sstevel@tonic-gate 	    //  calls back into SLPConfig.
16567c478bd9Sstevel@tonic-gate 	    String msg = "Can''t find message ``{0}''''.";
16577c478bd9Sstevel@tonic-gate 
16587c478bd9Sstevel@tonic-gate 	    try {
16597c478bd9Sstevel@tonic-gate 		pattern = bundle.getString("cant_find_resource");
16607c478bd9Sstevel@tonic-gate 		msg = MessageFormat.format(pattern, new Object[] {msgTag});
1661*55fea89dSDan Cross 
16627c478bd9Sstevel@tonic-gate 	    } catch (MissingResourceException exx) {
16637c478bd9Sstevel@tonic-gate 
16647c478bd9Sstevel@tonic-gate 	    }
16657c478bd9Sstevel@tonic-gate 
16667c478bd9Sstevel@tonic-gate 	    System.err.println(msg);
16677c478bd9Sstevel@tonic-gate 	    System.exit(-1);
16687c478bd9Sstevel@tonic-gate 	}
16697c478bd9Sstevel@tonic-gate 
16707c478bd9Sstevel@tonic-gate 	convertToString(params);
16717c478bd9Sstevel@tonic-gate 
16727c478bd9Sstevel@tonic-gate 	return MessageFormat.format(pattern, params);
16737c478bd9Sstevel@tonic-gate     }
16747c478bd9Sstevel@tonic-gate 
16757c478bd9Sstevel@tonic-gate     // logging.
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate     // Protected so slpd can replace it.
16787c478bd9Sstevel@tonic-gate 
16797c478bd9Sstevel@tonic-gate     protected Writer log;
16807c478bd9Sstevel@tonic-gate 
16817c478bd9Sstevel@tonic-gate     // Synchronized so writes from multiple threads don't get interleaved.
16827c478bd9Sstevel@tonic-gate 
writeLog(String msgTag, Object[] params)16837c478bd9Sstevel@tonic-gate     void writeLog(String msgTag, Object[] params) {
16847c478bd9Sstevel@tonic-gate 
16857c478bd9Sstevel@tonic-gate 	// MessageFormat is picky about types. Convert the params into strings.
16867c478bd9Sstevel@tonic-gate 
16877c478bd9Sstevel@tonic-gate 	convertToString(params);
16887c478bd9Sstevel@tonic-gate 
16897c478bd9Sstevel@tonic-gate 	try {
16907c478bd9Sstevel@tonic-gate 	    synchronized (log) {
16917c478bd9Sstevel@tonic-gate 		log.write(formatMessage(msgTag, params));
16927c478bd9Sstevel@tonic-gate 		log.flush();
16937c478bd9Sstevel@tonic-gate 	    }
16947c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {}
16957c478bd9Sstevel@tonic-gate     }
16967c478bd9Sstevel@tonic-gate 
writeLogLine(String msgTag, Object[] params)16977c478bd9Sstevel@tonic-gate     void writeLogLine(String msgTag, Object[] params) {
16987c478bd9Sstevel@tonic-gate 
16997c478bd9Sstevel@tonic-gate 	try {
17007c478bd9Sstevel@tonic-gate 	    String pattern = getMessageBundle(getLocale()).getString(msgTag);
17017c478bd9Sstevel@tonic-gate 
17027c478bd9Sstevel@tonic-gate 	    synchronized (log) {
17037c478bd9Sstevel@tonic-gate 		log.write(formatMessage(msgTag, params));
17047c478bd9Sstevel@tonic-gate 		log.write("\n");
17057c478bd9Sstevel@tonic-gate 		log.flush();
17067c478bd9Sstevel@tonic-gate 	    }
17077c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {}
17087c478bd9Sstevel@tonic-gate 
17097c478bd9Sstevel@tonic-gate     }
17107c478bd9Sstevel@tonic-gate 
getDateString()17117c478bd9Sstevel@tonic-gate     static String getDateString() {
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate 	DateFormat df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
17147c478bd9Sstevel@tonic-gate 						       DateFormat.DEFAULT,
17157c478bd9Sstevel@tonic-gate 						       getLocale());
17167c478bd9Sstevel@tonic-gate 	Calendar calendar = Calendar.getInstance(getLocale());
17177c478bd9Sstevel@tonic-gate 	return df.format(calendar.getTime());
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate     }
17207c478bd9Sstevel@tonic-gate 
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate     // On load, check whether the signature class is available, and turn
17237c478bd9Sstevel@tonic-gate     //  security off if not.
17247c478bd9Sstevel@tonic-gate 
17257c478bd9Sstevel@tonic-gate     static {
17267c478bd9Sstevel@tonic-gate 
17277c478bd9Sstevel@tonic-gate 	securityEnabled = true;
17287c478bd9Sstevel@tonic-gate 	try {
17297c478bd9Sstevel@tonic-gate 	    Class c = Class.forName("com.sun.slp.AuthBlock");
17307c478bd9Sstevel@tonic-gate 
17317c478bd9Sstevel@tonic-gate 	} catch (ClassNotFoundException e) {
17327c478bd9Sstevel@tonic-gate 	    securityEnabled = false;
17337c478bd9Sstevel@tonic-gate 	}
17347c478bd9Sstevel@tonic-gate     }
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate }
1737