# HG changeset patch
# User cli
# Date 1315753279 -7200
# Node ID 8df94bfd3e2f943cebeafe2224e88aced804fd99
# Parent b78e7761915246923ab36c027531325cc069d4a0
Fix for #14
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/Main.java
--- a/src/org/sonews/Main.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/Main.java Sun Sep 11 17:01:19 2011 +0200
@@ -45,6 +45,8 @@
/** Version information of the sonews daemon */
public static final String VERSION = "sonews/1.1.0";
+
+ /** The server's startup date */
public static final Date STARTDATE = new Date();
/**
@@ -81,13 +83,16 @@
mlgw = true;
} else if (args[n].equals("-p")) {
port = Integer.parseInt(args[++n]);
- } else if (args[n].equals("-plugin")) {
+ } else if (args[n].equals("-plugin-storage")) {
System.out.println("Warning: -plugin-storage is not implemented!");
} else if (args[n].equals("-plugin-command")) {
try {
CommandSelector.addCommandHandler(args[++n]);
} catch (Exception ex) {
- Log.get().warning("Could not load command plugin: " + args[n]);
+ StringBuilder strBuf = new StringBuilder();
+ strBuf.append("Could not load command plugin: ");
+ strBuf.append(args[n]);
+ Log.get().warning(strBuf.toString());
Log.get().log(Level.INFO, "Main.java", ex);
}
} else if (args[n].equals("-plugin-storage")) {
@@ -113,10 +118,10 @@
Log.get().info("Group 'control' created.");
}
} catch (StorageBackendException ex) {
- ex.printStackTrace();
+ Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
System.err.println("Database initialization failed with " + ex.toString());
System.err.println("Make sure you have specified the correct database"
- + " settings in sonews.conf!");
+ + " settings in sonews.conf!");
return;
}
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/ShutdownHook.java
--- a/src/org/sonews/ShutdownHook.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/ShutdownHook.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews;
import java.sql.SQLException;
@@ -27,15 +26,13 @@
* @author Christian Lins
* @since sonews/0.5.0
*/
-class ShutdownHook extends Thread
-{
+class ShutdownHook extends Thread {
/**
* Called when the JVM exits.
*/
@Override
- public void run()
- {
+ public void run() {
System.out.println("sonews: Trying to shutdown all threads...");
Map threadsMap = Thread.getAllStackTraces();
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/acl/AccessControl.java
--- a/src/org/sonews/acl/AccessControl.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/acl/AccessControl.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.acl;
/**
@@ -23,8 +22,7 @@
* @author Christian Lins
* @since sonews/1.1
*/
-public interface AccessControl
-{
+public interface AccessControl {
boolean hasPermission(String user, char[] secret, String permission);
}
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/acl/AuthInfoCommand.java
--- a/src/org/sonews/acl/AuthInfoCommand.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/acl/AuthInfoCommand.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.acl;
import java.io.IOException;
@@ -28,37 +27,31 @@
* @author Christian Lins
* @since sonews/1.1
*/
-public class AuthInfoCommand implements Command
-{
+public class AuthInfoCommand implements Command {
@Override
- public String[] getSupportedCommandStrings()
- {
+ public String[] getSupportedCommandStrings() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
- public boolean hasFinished()
- {
+ public boolean hasFinished() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
- public String impliedCapability()
- {
+ public String impliedCapability() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
- public boolean isStateful()
- {
+ public boolean isStateful() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void processLine(NNTPConnection conn, String line, byte[] rawLine)
- throws IOException, StorageBackendException
- {
+ throws IOException, StorageBackendException {
throw new UnsupportedOperationException("Not supported yet.");
}
}
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/config/AbstractConfig.java
--- a/src/org/sonews/config/AbstractConfig.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/config/AbstractConfig.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.config;
/**
@@ -23,19 +22,16 @@
* @author Christian Lins
* @since sonews/0.5.0
*/
-public abstract class AbstractConfig
-{
+public abstract class AbstractConfig {
public abstract String get(String key, String defVal);
- public int get(final String key, final int defVal)
- {
+ public int get(final String key, final int defVal) {
return Integer.parseInt(
- get(key, Integer.toString(defVal)));
+ get(key, Integer.toString(defVal)));
}
- public boolean get(String key, boolean defVal)
- {
+ public boolean get(String key, boolean defVal) {
String val = get(key, Boolean.toString(defVal));
return Boolean.parseBoolean(val);
}
@@ -46,8 +42,7 @@
* @param defVal
* @return
*/
- public long get(String key, long defVal)
- {
+ public long get(String key, long defVal) {
String val = get(key, Long.toString(defVal));
return Long.parseLong(val);
}
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/config/BackendConfig.java
--- a/src/org/sonews/config/BackendConfig.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/config/BackendConfig.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.config;
import java.util.logging.Level;
@@ -30,19 +29,16 @@
* @author Christian Lins
* @since sonews/0.5.0
*/
-class BackendConfig extends AbstractConfig
-{
+class BackendConfig extends AbstractConfig {
private static BackendConfig instance = new BackendConfig();
- public static BackendConfig getInstance()
- {
+ public static BackendConfig getInstance() {
return instance;
}
private final TimeoutMap values = new TimeoutMap();
- private BackendConfig()
- {
+ private BackendConfig() {
super();
}
@@ -54,8 +50,7 @@
* @return
*/
@Override
- public String get(String key, String defaultValue)
- {
+ public String get(String key, String defaultValue) {
try {
String configValue = values.get(key);
if (configValue == null) {
@@ -85,8 +80,7 @@
* @param key
* @param value
*/
- public void set(String key, String value)
- {
+ public void set(String key, String value) {
values.put(key, value);
try {
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/config/CommandLineConfig.java
--- a/src/org/sonews/config/CommandLineConfig.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/config/CommandLineConfig.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.config;
import java.util.Map;
@@ -25,24 +24,20 @@
*
* @author Christian Lins
*/
-class CommandLineConfig extends AbstractConfig
-{
+class CommandLineConfig extends AbstractConfig {
private static final CommandLineConfig instance = new CommandLineConfig();
- public static CommandLineConfig getInstance()
- {
+ public static CommandLineConfig getInstance() {
return instance;
}
private final Map values = new HashMap();
- private CommandLineConfig()
- {
+ private CommandLineConfig() {
}
@Override
- public String get(String key, String def)
- {
+ public String get(String key, String def) {
synchronized (this.values) {
if (this.values.containsKey(key)) {
def = this.values.get(key);
@@ -52,8 +47,7 @@
}
@Override
- public void set(String key, String val)
- {
+ public void set(String key, String val) {
synchronized (this.values) {
this.values.put(key, val);
}
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/config/Config.java
--- a/src/org/sonews/config/Config.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/config/Config.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.config;
/**
@@ -23,8 +22,7 @@
* @author Christian Lins
* @since sonews/1.0
*/
-public class Config extends AbstractConfig
-{
+public class Config extends AbstractConfig {
public static final int LEVEL_CLI = 1;
public static final int LEVEL_FILE = 2;
@@ -91,18 +89,15 @@
};
private static Config instance = new Config();
- public static Config inst()
- {
+ public static Config inst() {
return instance;
}
- private Config()
- {
+ private Config() {
}
@Override
- public String get(String key, String def)
- {
+ public String get(String key, String def) {
String val = CommandLineConfig.getInstance().get(key, null);
if (val == null) {
@@ -116,8 +111,7 @@
return val;
}
- public String get(int maxLevel, String key, String def)
- {
+ public String get(int maxLevel, String key, String def) {
String val = CommandLineConfig.getInstance().get(key, null);
if (val == null && maxLevel >= LEVEL_FILE) {
@@ -131,13 +125,11 @@
}
@Override
- public void set(String key, String val)
- {
+ public void set(String key, String val) {
set(LEVEL_BACKEND, key, val);
}
- public void set(int level, String key, String val)
- {
+ public void set(int level, String key, String val) {
switch (level) {
case LEVEL_CLI: {
CommandLineConfig.getInstance().set(key, val);
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/daemon/NNTPConnection.java
--- a/src/org/sonews/daemon/NNTPConnection.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/daemon/NNTPConnection.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.daemon;
import java.io.IOException;
@@ -30,6 +29,7 @@
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.logging.Level;
import org.sonews.daemon.command.Command;
import org.sonews.storage.Article;
import org.sonews.storage.Group;
@@ -43,8 +43,7 @@
* @author Christian Lins
* @since sonews/0.5.0
*/
-public final class NNTPConnection
-{
+public final class NNTPConnection {
public static final String NEWLINE = "\r\n"; // RFC defines this as newline
public static final String MESSAGE_ID_PATTERN = "<[^>]+>";
@@ -62,8 +61,7 @@
private SelectionKey writeSelKey = null;
public NNTPConnection(final SocketChannel channel)
- throws IOException
- {
+ throws IOException {
if (channel == null) {
throw new IllegalArgumentException("channel is null");
}
@@ -77,8 +75,7 @@
* safe and returns true of the read lock was successfully set. If the lock
* is still hold by another Thread the method returns false.
*/
- boolean tryReadLock()
- {
+ boolean tryReadLock() {
// As synchronizing simple types may cause deadlocks,
// we use a gate object.
synchronized (readLockGate) {
@@ -96,8 +93,7 @@
* @throws IllegalMonitorStateException if a Thread not holding the lock
* tries to release it.
*/
- void unlockReadLock()
- {
+ void unlockReadLock() {
synchronized (readLockGate) {
if (readLock == Thread.currentThread().hashCode()) {
readLock = 0;
@@ -110,8 +106,7 @@
/**
* @return Current input buffer of this NNTPConnection instance.
*/
- public ByteBuffer getInputBuffer()
- {
+ public ByteBuffer getInputBuffer() {
return this.lineBuffers.getInputBuffer();
}
@@ -119,34 +114,29 @@
* @return Output buffer of this NNTPConnection which has at least one byte
* free storage.
*/
- public ByteBuffer getOutputBuffer()
- {
+ public ByteBuffer getOutputBuffer() {
return this.lineBuffers.getOutputBuffer();
}
/**
* @return ChannelLineBuffers instance associated with this NNTPConnection.
*/
- public ChannelLineBuffers getBuffers()
- {
+ public ChannelLineBuffers getBuffers() {
return this.lineBuffers;
}
/**
* @return true if this connection comes from a local remote address.
*/
- public boolean isLocalConnection()
- {
+ public boolean isLocalConnection() {
return ((InetSocketAddress) this.channel.socket().getRemoteSocketAddress()).getHostName().equalsIgnoreCase("localhost");
}
- void setWriteSelectionKey(SelectionKey selKey)
- {
+ void setWriteSelectionKey(SelectionKey selKey) {
this.writeSelKey = selKey;
}
- public void shutdownInput()
- {
+ public void shutdownInput() {
try {
// Closes the input line of the channel's socket, so no new data
// will be received and a timeout can be triggered.
@@ -156,14 +146,10 @@
}
}
- public void shutdownOutput()
- {
- cancelTimer.schedule(new TimerTask()
- {
-
+ public void shutdownOutput() {
+ cancelTimer.schedule(new TimerTask() {
@Override
- public void run()
- {
+ public void run() {
try {
// Closes the output line of the channel's socket.
channel.socket().shutdownOutput();
@@ -178,41 +164,34 @@
}, 3000);
}
- public SocketChannel getSocketChannel()
- {
+ public SocketChannel getSocketChannel() {
return this.channel;
}
- public Article getCurrentArticle()
- {
+ public Article getCurrentArticle() {
return this.currentArticle;
}
- public Charset getCurrentCharset()
- {
+ public Charset getCurrentCharset() {
return this.charset;
}
/**
* @return The currently selected communication channel (not SocketChannel)
*/
- public Group getCurrentChannel()
- {
+ public Group getCurrentChannel() {
return this.currentGroup;
}
- public void setCurrentArticle(final Article article)
- {
+ public void setCurrentArticle(final Article article) {
this.currentArticle = article;
}
- public void setCurrentGroup(final Group group)
- {
+ public void setCurrentGroup(final Group group) {
this.currentGroup = group;
}
- public long getLastActivity()
- {
+ public long getLastActivity() {
return this.lastActivity;
}
@@ -222,8 +201,7 @@
* @throws IllegalArgumentException if raw is null.
* @throws IllegalStateException if calling thread does not own the readLock.
*/
- void lineReceived(byte[] raw)
- {
+ void lineReceived(byte[] raw) {
if (raw == null) {
throw new IllegalArgumentException("raw is null");
}
@@ -262,17 +240,25 @@
}
} catch (ClosedChannelException ex0) {
try {
- Log.get().info("Connection to " + channel.socket().getRemoteSocketAddress()
- + " closed: " + ex0);
+ StringBuilder strBuf = new StringBuilder();
+ strBuf.append("Connection to ");
+ strBuf.append(channel.socket().getRemoteSocketAddress());
+ strBuf.append(" closed: ");
+ strBuf.append(ex0);
+ Log.get().info(strBuf.toString());
} catch (Exception ex0a) {
ex0a.printStackTrace();
}
- } catch (Exception ex1) // This will catch a second StorageBackendException
- {
+ } catch (Exception ex1) { // This will catch a second StorageBackendException
try {
command = null;
- ex1.printStackTrace();
- println("500 Internal server error");
+ Log.get().log(Level.WARNING, ex1.getLocalizedMessage(), ex1);
+ println("403 Internal server error");
+
+ // Should we end the connection here?
+ // RFC says we MUST return 400 before closing the connection
+ shutdownInput();
+ shutdownOutput();
} catch (Exception ex2) {
ex2.printStackTrace();
}
@@ -289,8 +275,7 @@
* @param line
* @return
*/
- private Command parseCommandLine(String line)
- {
+ private Command parseCommandLine(String line) {
String cmdStr = line.split(" ")[0];
return CommandSelector.getInstance().get(cmdStr);
}
@@ -303,8 +288,7 @@
* @param line
*/
public void println(final CharSequence line, final Charset charset)
- throws IOException
- {
+ throws IOException {
writeToChannel(CharBuffer.wrap(line), charset, line);
writeToChannel(CharBuffer.wrap(NEWLINE), charset, null);
}
@@ -315,8 +299,7 @@
* @param rawLines
*/
public void println(final byte[] rawLines)
- throws IOException
- {
+ throws IOException {
this.lineBuffers.addOutputBuffer(ByteBuffer.wrap(rawLines));
writeToChannel(CharBuffer.wrap(NEWLINE), charset, null);
}
@@ -328,9 +311,8 @@
* @throws java.io.IOException
*/
private void writeToChannel(CharBuffer characters, final Charset charset,
- CharSequence debugLine)
- throws IOException
- {
+ CharSequence debugLine)
+ throws IOException {
if (!charset.canEncode()) {
Log.get().severe("FATAL: Charset " + charset + " cannot encode!");
return;
@@ -343,8 +325,7 @@
enableWriteEvents(debugLine);
}
- private void enableWriteEvents(CharSequence debugLine)
- {
+ private void enableWriteEvents(CharSequence debugLine) {
// Enable OP_WRITE events so that the buffers are processed
try {
this.writeSelKey.interestOps(SelectionKey.OP_WRITE);
@@ -363,24 +344,20 @@
}
public void println(final CharSequence line)
- throws IOException
- {
+ throws IOException {
println(line, charset);
}
public void print(final String line)
- throws IOException
- {
+ throws IOException {
writeToChannel(CharBuffer.wrap(line), charset, line);
}
- public void setCurrentCharset(final Charset charset)
- {
+ public void setCurrentCharset(final Charset charset) {
this.charset = charset;
}
- void setLastActivity(long timestamp)
- {
+ void setLastActivity(long timestamp) {
this.lastActivity = timestamp;
}
}
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/daemon/command/ListCommand.java
--- a/src/org/sonews/daemon/command/ListCommand.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/daemon/command/ListCommand.java Sun Sep 11 17:01:19 2011 +0200
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
package org.sonews.daemon.command;
import java.io.IOException;
@@ -34,37 +33,31 @@
* @author Dennis Schwerdel
* @since n3tpd/0.1
*/
-public class ListCommand implements Command
-{
+public class ListCommand implements Command {
@Override
- public String[] getSupportedCommandStrings()
- {
- return new String[] {"LIST"};
+ public String[] getSupportedCommandStrings() {
+ return new String[]{"LIST"};
}
@Override
- public boolean hasFinished()
- {
+ public boolean hasFinished() {
return true;
}
@Override
- public String impliedCapability()
- {
+ public String impliedCapability() {
return null;
}
@Override
- public boolean isStateful()
- {
+ public boolean isStateful() {
return false;
}
@Override
public void processLine(NNTPConnection conn, final String line, byte[] raw)
- throws IOException, StorageBackendException
- {
+ throws IOException, StorageBackendException {
final String[] command = line.split(" ");
if (command.length >= 2) {
@@ -90,7 +83,7 @@
conn.println(".");
} else if (command[1].equalsIgnoreCase("ACTIVE")) {
String pattern = command.length == 2
- ? null : command[2].replace("*", "\\w*");
+ ? null : command[2].replace("*", "\\w*");
printGroupInfo(conn, pattern);
} else {
conn.println("500 unknown argument to LIST command");
@@ -101,21 +94,20 @@
}
private void printGroupInfo(NNTPConnection conn, String pattern)
- throws IOException, StorageBackendException
- {
+ throws IOException, StorageBackendException {
final List groups = Group.getAll();
if (groups != null) {
conn.println("215 list of newsgroups follows");
for (Group g : groups) {
try {
Matcher matcher = pattern == null
- ? null : Pattern.compile(pattern).matcher(g.getName());
+ ? null : Pattern.compile(pattern).matcher(g.getName());
if (!g.isDeleted()
- && (matcher == null || matcher.find())) {
+ && (matcher == null || matcher.find())) {
String writeable = g.isWriteable() ? " y" : " n";
// Indeed first the higher article number then the lower
conn.println(g.getName() + " " + g.getLastArticleNumber() + " "
- + g.getFirstArticleNumber() + writeable);
+ + g.getFirstArticleNumber() + writeable);
}
} catch (PatternSyntaxException ex) {
Log.get().info(ex.toString());
diff -r b78e77619152 -r 8df94bfd3e2f src/org/sonews/util/Stats.java
--- a/src/org/sonews/util/Stats.java Sun Sep 11 15:05:04 2011 +0200
+++ b/src/org/sonews/util/Stats.java Sun Sep 11 17:01:19 2011 +0200
@@ -18,6 +18,7 @@
package org.sonews.util;
import java.util.Calendar;
+import java.util.logging.Level;
import org.sonews.config.Config;
import org.sonews.storage.Group;
import org.sonews.storage.StorageBackendException;
@@ -63,10 +64,14 @@
System.currentTimeMillis(), type, group.getInternalID());
}
} else {
- Log.get().info("Group " + groupname + " does not exist.");
+ StringBuilder strBuf = new StringBuilder();
+ strBuf.append("Group ");
+ strBuf.append(groupname);
+ strBuf.append(" does not exist.");
+ Log.get().info(strBuf.toString());
}
} catch (StorageBackendException ex) {
- ex.printStackTrace();
+ Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}
}
@@ -86,7 +91,7 @@
try {
return StorageManager.current().countGroups();
} catch (StorageBackendException ex) {
- ex.printStackTrace();
+ Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
return -1;
}
}
@@ -95,7 +100,7 @@
try {
return StorageManager.current().countArticles();
} catch (StorageBackendException ex) {
- ex.printStackTrace();
+ Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
return -1;
}
}
@@ -117,7 +122,7 @@
try {
return StorageManager.current().getEventsCount(eventType, startTimestamp, endTimestamp, group);
} catch (StorageBackendException ex) {
- ex.printStackTrace();
+ Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
return -1;
}
}
@@ -146,7 +151,7 @@
try {
return StorageManager.current().getEventsPerHour(key, gid);
} catch (StorageBackendException ex) {
- ex.printStackTrace();
+ Log.get().log(Level.SEVERE, ex.getLocalizedMessage(), ex);
return -1;
}
}