diff -r 6ae5e4f8329b -r c404a87db5b7 src/org/sonews/daemon/command/OverCommand.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/sonews/daemon/command/OverCommand.java Sun Aug 29 17:43:58 2010 +0200
@@ -0,0 +1,294 @@
+/*
+ * SONEWS News Server
+ * see AUTHORS for the list of contributors
+ *
+ * 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
+ * XOVER [range] + * + * The XOVER command returns information from the overview + * database for the article(s) specified. + * + * The optional range argument may be any of the following: + * an article number + * an article number followed by a dash to indicate + * all following + * an article number followed by a dash followed by + * another article number + * + * If no argument is specified, then information from the + * current article is displayed. Successful responses start + * with a 224 response followed by the overview information + * for all matched messages. Once the output is complete, a + * period is sent on a line by itself. If no argument is + * specified, the information for the current article is + * returned. A news group must have been selected earlier, + * else a 412 error response is returned. If no articles are + * in the range specified, a 420 error response is returned + * by the server. A 502 response will be returned if the + * client only has permission to transfer articles. + * + * Each line of output will be formatted with the article number, + * followed by each of the headers in the overview database or the + * article itself (when the data is not available in the overview + * database) for that article separated by a tab character. The + * sequence of fields must be in this order: subject, author, + * date, message-id, references, byte count, and line count. Other + * optional fields may follow line count. Other optional fields may + * follow line count. These fields are specified by examining the + * response to the LIST OVERVIEW.FMT command. Where no data exists, + * a null field must be provided (i.e. the output will have two tab + * characters adjacent to each other). Servers should not output + * fields for articles that have been removed since the XOVER database + * was created. + * + * The LIST OVERVIEW.FMT command should be implemented if XOVER + * is implemented. A client can use LIST OVERVIEW.FMT to determine + * what optional fields and in which order all fields will be + * supplied by the XOVER command. + * + * Note that any tab and end-of-line characters in any header + * data that is returned will be converted to a space character. + * + * Responses: + * + * 224 Overview information follows + * 412 No news group current selected + * 420 No article(s) selected + * 502 no permission + * + * OVER defines additional responses: + * + * First form (message-id specified) + * 224 Overview information follows (multi-line) + * 430 No article with that message-id + * + * Second form (range specified) + * 224 Overview information follows (multi-line) + * 412 No newsgroup selected + * 423 No articles in that range + * + * Third form (current article number used) + * 224 Overview information follows (multi-line) + * 412 No newsgroup selected + * 420 Current article number is invalid + * + *+ * @author Christian Lins + * @since sonews/0.5.0 + */ +public class OverCommand implements Command +{ + + public static final int MAX_LINES_PER_DBREQUEST = 200; + + @Override + public String[] getSupportedCommandStrings() + { + return new String[]{"OVER", "XOVER"}; + } + + @Override + public boolean hasFinished() + { + return true; + } + + @Override + public String impliedCapability() + { + return null; + } + + @Override + public boolean isStateful() + { + return false; + } + + @Override + public void processLine(NNTPConnection conn, final String line, byte[] raw) + throws IOException, StorageBackendException + { + if(conn.getCurrentChannel() == null) + { + conn.println("412 no newsgroup selected"); + } + else + { + String[] command = line.split(" "); + + // If no parameter was specified, show information about + // the currently selected article(s) + if(command.length == 1) + { + final Article art = conn.getCurrentArticle(); + if(art == null) + { + conn.println("420 no article(s) selected"); + return; + } + + conn.println(buildOverview(art, -1)); + } + // otherwise print information about the specified range + else + { + long artStart; + long artEnd = conn.getCurrentChannel().getLastArticleNumber(); + String[] nums = command[1].split("-"); + if(nums.length >= 1) + { + try + { + artStart = Integer.parseInt(nums[0]); + } + catch(NumberFormatException e) + { + Log.get().info(e.getMessage()); + artStart = Integer.parseInt(command[1]); + } + } + else + { + artStart = conn.getCurrentChannel().getFirstArticleNumber(); + } + + if(nums.length >=2) + { + try + { + artEnd = Integer.parseInt(nums[1]); + } + catch(NumberFormatException e) + { + e.printStackTrace(); + } + } + + if(artStart > artEnd) + { + if(command[0].equalsIgnoreCase("OVER")) + { + conn.println("423 no articles in that range"); + } + else + { + conn.println("224 (empty) overview information follows:"); + conn.println("."); + } + } + else + { + for(long n = artStart; n <= artEnd; n += MAX_LINES_PER_DBREQUEST) + { + long nEnd = Math.min(n + MAX_LINES_PER_DBREQUEST - 1, artEnd); + List