diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bea94fe --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +# Dual: a simple manager for custom hostnames +# +# Copyright (C) 2021 luca0N! +# +# 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. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# Contact me by e-mail via . + +Dual.jar: + javac -d build/ -classpath src/ src/com/luca0n/dual/config/*.java src/com/luca0n/dual/common/*.java + jar -cfve Dual.jar com.luca0n.dual.common.Dual -C build/ . diff --git a/cfg/gen.cfg b/cfg/gen.cfg new file mode 100644 index 0000000..646b799 --- /dev/null +++ b/cfg/gen.cfg @@ -0,0 +1,52 @@ +# Dual: a simple manager for custom hostnames +# +# Copyright (C) 2021 luca0N! +# +# 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. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# Contact me by e-mail via . + +# #### ## ## ## ## +# ## ## ## ## ## ## ## +# ## ## ## ## ## ## ## configuration +# ## ## ## ## ###### ## file +# ## ## ## ## ## ## ## +# #### ## ## ## ##### +# +# Configuration file for Dual. +# +# Lines that begin with the "#" character are comments. Everything written in a +# line after "#" is considered a comment. Comments are ignored. +[Dual] +# Put instructions that should be sent to Dual here. + +# Provide the path to the hosts file here if you want to override the default +# path or you're using an unsupported operating system. +# hostsPath=/etc/hosts + +# FetchType specifies the way Dual should retrieve the desired IP address that +# is going to be associated with the specified hostname. +# +# The following values are allowed for this option: +# - Resolve: gets the target IP address by resolving the provided address. +# - RawFetch: gets the target IP address by connecting to the provided +# address that outputs the desired IP address in plain text. +FetchType=Resolve + +# The Source value should be equal to a domain name (like foo.example.org) when +# using the Resolve Type or equal to a web URL (like +# https://www.example.org/api/get?entry=913804). +Source=Nautilus.luca0N.com + +# The Target value is the desired local hostname. +Target=Nautilus diff --git a/src/com/luca0n/dual/common/ConfigSyntaxException.java b/src/com/luca0n/dual/common/ConfigSyntaxException.java new file mode 100644 index 0000000..d542e69 --- /dev/null +++ b/src/com/luca0n/dual/common/ConfigSyntaxException.java @@ -0,0 +1,32 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.common; + +import java.lang.Exception; + +public class ConfigSyntaxException extends Exception { + public ConfigSyntaxException(){ + super(); + } + public ConfigSyntaxException(String message){ + super(message); + } +} diff --git a/src/com/luca0n/dual/common/Dual.java b/src/com/luca0n/dual/common/Dual.java new file mode 100644 index 0000000..ed3c468 --- /dev/null +++ b/src/com/luca0n/dual/common/Dual.java @@ -0,0 +1,159 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.common; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.FileSystems; +import java.nio.file.Path; + +import com.luca0n.dual.common.ConfigSyntaxException; +import com.luca0n.dual.common.NoSuchNamespaceException; +import com.luca0n.dual.common.NoSuchKeyException; +import com.luca0n.dual.common.UnsupportedOperatingSystemException; +import com.luca0n.dual.config.Config; +import com.luca0n.dual.config.ConfigUtil; + +/** + * @version 1.0 + * @since 2021-03-21 + */ +public class Dual { + public static final String NAME = "Dual"; + public static final String VERSION = "1.0"; + private static final String AUTO_GEN_COMMENT = "This entry was auto-generated by " + NAME + "."; + public static final int VERSION_CODE = 1; + + private static final String[] SUPPORTED_OPERATING_SYSTEMS = { + "Linux", + "Windows" + }; + + public static void main(String[] args){ + try { + run(); + } catch (Exception e){ + e.printStackTrace(); + System.exit(1); + } + } + public static void run() throws ConfigSyntaxException, + NoSuchNamespaceException, NoSuchKeyException, IOException, + UnsupportedOperatingSystemException { + // Read configuration file + Config c = ConfigUtil.fromFile(ConfigUtil.DEFAULT_CONFIG); + + Config.Namespace n = c.getNamespace("Dual"); + + if (n == null) + throw new NoSuchNamespaceException("Could not find required namespace Dual in the default configuration file."); + + String type = n.getValue("FetchType"), + source = n.getValue("Source"), + target = n.getValue("Target"), + hostsPath = n.getValue("hostsPath"); + + // Check for null values. + if (source == null) + throw new NoSuchKeyException("Could not find required key Dual.Source in the default configuration file."); + else if (target == null) + throw new NoSuchKeyException("Could not find required key Dual.Target in the default configuration file."); + + System.out.printf("%s: All tests passed.\n", NAME); + + if (type == null){ + type = "Resolve"; + System.out.printf("%s: WARNING: no FetchType specified. Assuming Resolve FetchType...\n", NAME); + } + + System.out.printf("%s: Using %s FetchType and %s Source.\n", NAME, type, source); + System.out.printf("%s: Using %s hostname.\n", NAME, target); + + // Check OS. + String os = System.getProperty("os.name"); + boolean supportedOs = false; + for (String sos : SUPPORTED_OPERATING_SYSTEMS) + if (os.contains(sos)){ + supportedOs = true; + break; + } + + if (!supportedOs && hostsPath == null){ + StringBuilder msg = new StringBuilder(); + msg.append("Unsupported operating system: ") + .append(os) + .append(". ") + .append("This program must be run under "); + + for (int x = 0; x < SUPPORTED_OPERATING_SYSTEMS.length; x++){ + if (x == SUPPORTED_OPERATING_SYSTEMS.length - 1) + msg.append(" or ") + .append(SUPPORTED_OPERATING_SYSTEMS[x]) + .append(". "); + else if (x == 0) + msg.append(SUPPORTED_OPERATING_SYSTEMS[x]); + else + msg.append(", ") + .append(SUPPORTED_OPERATING_SYSTEMS[x]); + } + + msg.append("If you want to override this system requirement, please provide a path to the hosts file on your operating system."); + + throw new UnsupportedOperatingSystemException(msg.toString()); + } + + System.out.printf(hostsPath == null ? "%s: using %s settings.\n" : "%s: using custom settings for %s.\n", NAME, os); + + // Open hosts file. + + if (hostsPath == null){ + boolean isWindows = os.contains(SUPPORTED_OPERATING_SYSTEMS[1]); + hostsPath = isWindows ? "C:\\WINDOWS\\System32\\drivers\\etc\\hosts" : "/etc/hosts"; + } + + System.out.printf("%s: opening %s...\n", NAME, hostsPath); + + Path path = FileSystems.getDefault().getPath(hostsPath); + byte[] fileBytes = Files.readAllBytes(path); + + String[] lines = new String(fileBytes).split(System.lineSeparator()); + + for (String line : lines){ + // Check if this line is a comment. + if (line.startsWith("#")) + // Ignore this line. + continue; + + String[] contents = line.split("#")[0]; + // Check if this line was auto-generated by this program. + if (contents.length == 2){ + // Check line comment. + if (contents[1].equals(AUTO_GEN_COMMENT)){ + // Remove this entry if we're going to replace it. + + } + } + + + } + + } +} diff --git a/src/com/luca0n/dual/common/NoSuchKeyException.java b/src/com/luca0n/dual/common/NoSuchKeyException.java new file mode 100644 index 0000000..e0d3818 --- /dev/null +++ b/src/com/luca0n/dual/common/NoSuchKeyException.java @@ -0,0 +1,32 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.common; + +import java.lang.Exception; + +public class NoSuchKeyException extends Exception { + public NoSuchKeyException(){ + super(); + } + public NoSuchKeyException(String message){ + super(message); + } +} diff --git a/src/com/luca0n/dual/common/NoSuchNamespaceException.java b/src/com/luca0n/dual/common/NoSuchNamespaceException.java new file mode 100644 index 0000000..ba1cc3b --- /dev/null +++ b/src/com/luca0n/dual/common/NoSuchNamespaceException.java @@ -0,0 +1,32 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.common; + +import java.lang.Exception; + +public class NoSuchNamespaceException extends Exception { + public NoSuchNamespaceException(){ + super(); + } + public NoSuchNamespaceException(String message){ + super(message); + } +} diff --git a/src/com/luca0n/dual/common/UnsupportedOperatingSystemException.java b/src/com/luca0n/dual/common/UnsupportedOperatingSystemException.java new file mode 100644 index 0000000..d5feb4a --- /dev/null +++ b/src/com/luca0n/dual/common/UnsupportedOperatingSystemException.java @@ -0,0 +1,32 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.common; + +import java.lang.Exception; + +public class UnsupportedOperatingSystemException extends Exception { + public UnsupportedOperatingSystemException(){ + super(); + } + public UnsupportedOperatingSystemException(String message){ + super(message); + } +} diff --git a/src/com/luca0n/dual/config/Config.java b/src/com/luca0n/dual/config/Config.java new file mode 100644 index 0000000..88cbd40 --- /dev/null +++ b/src/com/luca0n/dual/config/Config.java @@ -0,0 +1,64 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.config; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +/** + * @since 2021-03-21 + */ +public class Config { + List namespaces; + protected Config(List namespaces){ + this.namespaces = namespaces; + } + + public Namespace getNamespace(String name){ + for (Namespace n : namespaces) + if (n.getName().equals(name)) + return n; + return null; + } + + public static class Namespace { + private Map entries; + private String name; + protected Namespace(String name){ + this.name = name; + this.entries = new HashMap<>(); + } + protected Namespace(String name, Map entries){ + this.name = name; + this.entries = entries; + } + protected void putEntry(String k, String v){ + entries.put(k, v); + } + public String getValue(String key){ + return entries.get(key); + } + public String getName(){ + return name; + } + } +} diff --git a/src/com/luca0n/dual/config/ConfigUtil.java b/src/com/luca0n/dual/config/ConfigUtil.java new file mode 100644 index 0000000..d0f0d95 --- /dev/null +++ b/src/com/luca0n/dual/config/ConfigUtil.java @@ -0,0 +1,87 @@ +/* +Dual: a simple manager for custom hostnames + +Copyright (C) 2021 luca0N! + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Contact me by e-mail via . +*/ + +package com.luca0n.dual.config; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.nio.file.Path; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.io.IOException; + +import com.luca0n.dual.common.ConfigSyntaxException; +import com.luca0n.dual.config.Config; + +/** + * @since @2021-03-21 + */ +public class ConfigUtil { + public static final String DEFAULT_CONFIG = "gen.cfg"; + public static Config fromFile(String filename) + throws IOException, ConfigSyntaxException{ + Path path = FileSystems.getDefault().getPath("cfg", filename); + byte[] fileBytes = Files.readAllBytes(path); + + String[] lines = new String(fileBytes).split(System.lineSeparator()); + + Map v = new HashMap<>(); + List n = new ArrayList<>(); + Config.Namespace currentNamespace = null; + + for (String line : lines){ + // Ignore commented lines. + if (line.startsWith("#")) + continue; + + // Ignore comments. + String content = line.split("#")[0]; + + // Check if this is a namespace declaration. + if (content.startsWith("[")){ + // This line must end with a "]". + if (!content.endsWith("]")) + throw new ConfigSyntaxException("Invalid namespace declaration: missing \"]\""); + // Append current namespace to the namespace array if it exists. + if (currentNamespace != null) + n.add(currentNamespace); + // Create a new namespace. + String nsName = content.substring(1, content.length() - 1); + currentNamespace = new Config.Namespace(nsName); + } + + // Check if this is a K/V line. + if (content.contains("=")){ + String[] contentSplit = content.split("="); + String key = contentSplit[0], + value = contentSplit[1]; + currentNamespace.putEntry(key, value); + } + } + + // Add the last namespace to the namespace array. + n.add(currentNamespace); + + Config c = new Config(n); + return c; + } +}