001: /*
002: * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.net.dns;
027:
028: import java.util.List;
029: import java.util.LinkedList;
030: import java.util.StringTokenizer;
031: import java.io.BufferedReader;
032: import java.io.FileReader;
033: import java.io.IOException;
034:
035: /*
036: * An implementation of ResolverConfiguration for Solaris
037: * and Linux.
038: */
039:
040: public class ResolverConfigurationImpl extends ResolverConfiguration {
041: // Lock helds whilst loading configuration or checking
042: private static Object lock = new Object();
043:
044: // Time of last refresh.
045: private static long lastRefresh = -1;
046:
047: // Cache timeout (300 seconds) - should be converted into property
048: // or configured as preference in the future.
049: private static final int TIMEOUT = 300000;
050:
051: // Resolver options
052: private final Options opts;
053:
054: // Parse /etc/resolv.conf to get the values for a particular
055: // keyword.
056: //
057: private LinkedList resolvconf(String keyword, int maxperkeyword,
058: int maxkeywords) {
059: LinkedList ll = new LinkedList();
060:
061: try {
062: BufferedReader in = new BufferedReader(new FileReader(
063: "/etc/resolv.conf"));
064: String line;
065: while ((line = in.readLine()) != null) {
066: int maxvalues = maxperkeyword;
067: if (line.length() == 0)
068: continue;
069: if (line.charAt(0) == '#' || line.charAt(0) == ';')
070: continue;
071: if (!line.startsWith(keyword))
072: continue;
073: String value = line.substring(keyword.length());
074: if (value.length() == 0)
075: continue;
076: if (value.charAt(0) != ' ' && value.charAt(0) != '\t')
077: continue;
078: StringTokenizer st = new StringTokenizer(value, " \t");
079: while (st.hasMoreTokens()) {
080: String val = st.nextToken();
081: if (val.charAt(0) == '#' || val.charAt(0) == ';') {
082: break;
083: }
084: ll.add(val);
085: if (--maxvalues == 0) {
086: break;
087: }
088: }
089: if (--maxkeywords == 0) {
090: break;
091: }
092: }
093: in.close();
094: } catch (IOException ioe) {
095: // problem reading value
096: }
097:
098: return ll;
099: }
100:
101: private LinkedList searchlist;
102: private LinkedList nameservers;
103:
104: // Load DNS configuration from OS
105:
106: private void loadConfig() {
107: assert Thread.holdsLock(lock);
108:
109: // check if cached settings have expired.
110: if (lastRefresh >= 0) {
111: long currTime = System.currentTimeMillis();
112: if ((currTime - lastRefresh) < TIMEOUT) {
113: return;
114: }
115: }
116:
117: // get the name servers from /etc/resolv.conf
118: nameservers = (LinkedList) java.security.AccessController
119: .doPrivileged(new java.security.PrivilegedAction() {
120: public Object run() {
121: // typically MAXNS is 3 but we've picked 5 here
122: // to allow for additional servers if required.
123: return resolvconf("nameserver", 1, 5);
124: } /* run */
125: });
126:
127: // get the search list (or domain)
128: searchlist = getSearchList();
129:
130: // update the timestamp on the configuration
131: lastRefresh = System.currentTimeMillis();
132: }
133:
134: // obtain search list or local domain
135:
136: private LinkedList getSearchList() {
137:
138: LinkedList sl;
139:
140: // first try the search keyword in /etc/resolv.conf
141:
142: sl = (LinkedList) java.security.AccessController
143: .doPrivileged(new java.security.PrivilegedAction() {
144: public Object run() {
145: LinkedList ll;
146:
147: // first try search keyword (max 6 domains)
148: ll = resolvconf("search", 6, 1);
149: if (ll.size() > 0) {
150: return ll;
151: }
152:
153: return null;
154:
155: } /* run */
156:
157: });
158: if (sl != null) {
159: return sl;
160: }
161:
162: // No search keyword so use local domain
163:
164: // LOCALDOMAIN has absolute priority on Solaris
165:
166: String localDomain = localDomain0();
167: if (localDomain != null && localDomain.length() > 0) {
168: sl = new LinkedList();
169: sl.add(localDomain);
170: return sl;
171: }
172:
173: // try domain keyword in /etc/resolv.conf
174:
175: sl = (LinkedList) java.security.AccessController
176: .doPrivileged(new java.security.PrivilegedAction() {
177: public Object run() {
178: LinkedList ll;
179:
180: ll = resolvconf("domain", 1, 1);
181: if (ll.size() > 0) {
182: return ll;
183: }
184: return null;
185:
186: } /* run */
187: });
188: if (sl != null) {
189: return sl;
190: }
191:
192: // no local domain so try fallback (RPC) domain or
193: // hostname
194:
195: sl = new LinkedList();
196: String domain = fallbackDomain0();
197: if (domain != null && domain.length() > 0) {
198: sl.add(domain);
199: }
200:
201: return sl;
202: }
203:
204: // ----
205:
206: ResolverConfigurationImpl() {
207: opts = new OptionsImpl();
208: }
209:
210: public List searchlist() {
211: synchronized (lock) {
212: loadConfig();
213:
214: // List is mutable so return a shallow copy
215: return (List) searchlist.clone();
216: }
217: }
218:
219: public List nameservers() {
220: synchronized (lock) {
221: loadConfig();
222:
223: // List is mutable so return a shallow copy
224: return (List) nameservers.clone();
225: }
226: }
227:
228: public Options options() {
229: return opts;
230: }
231:
232: // --- Native methods --
233:
234: static native String localDomain0();
235:
236: static native String fallbackDomain0();
237:
238: static {
239: java.security.AccessController
240: .doPrivileged(new sun.security.action.LoadLibraryAction(
241: "net"));
242: }
243:
244: }
245:
246: /**
247: * Implementation of {@link ResolverConfiguration.Options}
248: */
249: class OptionsImpl extends ResolverConfiguration.Options {
250: }
|