package org.itxtech.daedalus.util;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
/**
* Daedalus Project
*
* @author iTX Technologies
* @link https://itxtech.org
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
public class RulesResolver implements Runnable {
private static final String TAG = "DRulesResolver";
public static final int STATUS_LOADED = 0;
public static final int STATUS_LOADING = 1;
public static final int STATUS_NOT_LOADED = 2;
public static final int STATUS_PENDING_LOAD = 3;
public static final int MODE_HOSTS = 0;
public static final int MODE_DNSMASQ = 1;
private static int status = STATUS_NOT_LOADED;
private static int mode = MODE_HOSTS;
private static String[] hostsFiles;
private static String[] dnsmasqFiles;
private static HashMap<String, String> rules;
private static boolean shutdown = false;
public RulesResolver() {
status = STATUS_NOT_LOADED;
hostsFiles = new String[0];
dnsmasqFiles = new String[0];
shutdown = false;
}
public static void shutdown() {
shutdown = true;
}
public static boolean isLoaded() {
return status == STATUS_LOADED;
}
public static void startLoadHosts(String[] loadFile) {
Log.d(TAG, "Loading hosts file " + loadFile.length);
hostsFiles = loadFile;
mode = MODE_HOSTS;
status = STATUS_PENDING_LOAD;
}
public static void startLoadDnsmasq(String[] loadPath) {
Log.d(TAG, "Loading DNSMasq file " + loadPath.length);
dnsmasqFiles = loadPath;
mode = MODE_DNSMASQ;
status = STATUS_PENDING_LOAD;
}
public static void clean() {
rules = null;
}
public static String resolve(String hostname) {
if (rules == null) {
return null;
}
if (rules.containsKey(hostname)) {
return rules.get(hostname);
}
if (mode == MODE_DNSMASQ) {
String[] pieces = hostname.split("\\.");
StringBuilder builder;
for (int i = 1; i < pieces.length; i++) {
builder = new StringBuilder();
for (int j = i; j < pieces.length; j++) {
builder.append(pieces[j]);
if (j < pieces.length - 1) {
builder.append(".");
}
}
if (rules.containsKey(builder.toString())) {
return rules.get(builder.toString());
}
}
}
return null;
}
private void load() {
try {
status = STATUS_LOADING;
rules = new HashMap<>();
if (mode == MODE_HOSTS) {
for (String hostsFile : hostsFiles) {
File file = new File(hostsFile);
if (file.canRead()) {
FileInputStream stream = new FileInputStream(file);
BufferedReader dataIO = new BufferedReader(new InputStreamReader(stream));
String strLine;
String[] data;
while ((strLine = dataIO.readLine()) != null) {
//Log.d(TAG, strLine);
if (!strLine.equals("") && !strLine.startsWith("#")) {
data = strLine.split("\\s+");
rules.put(data[1], data[0]);
Log.d(TAG, "Putting " + data[0] + " " + data[1]);
}
}
dataIO.close();
stream.close();
}
}
} else if (mode == MODE_DNSMASQ) {
for (String dnsmasqFile : dnsmasqFiles) {
File file = new File(dnsmasqFile);
if (file.canRead()) {
Log.d(TAG, "load: Loading DNSMasq configuration " + file.toString());
FileInputStream stream = new FileInputStream(file);
BufferedReader dataIO = new BufferedReader(new InputStreamReader(stream));
String strLine;
String[] data;
while ((strLine = dataIO.readLine()) != null) {
if (!strLine.equals("") && !strLine.startsWith("#")) {
data = strLine.split("/");
if (data.length == 3 && data[0].equals("address=")) {
if (data[1].startsWith(".")) {
data[1] = data[1].substring(1, data[1].length());
}
rules.put(data[1], data[2]);
//Log.d(TAG, "Putting " + data[1] + " " + data[2]);
}
}
}
dataIO.close();
stream.close();
}
}
}
status = STATUS_LOADED;
} catch (Exception e) {
Log.e(TAG, e.toString());
status = STATUS_NOT_LOADED;
}
}
@Override
public void run() {
try {
while (!shutdown) {
if (status == STATUS_PENDING_LOAD) {
load();
}
Thread.sleep(100);
}
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
}