/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
/*
 * Ok, we connect to the nntp port on the remote site.  We issue a 
 * group command to get some useful info on the group.
 * Then we fetch the articles one by one.  From the oldest one we
 * have.
 */
#include "inet.h"
#include "socket.h"
#include "board.h"


#define TP(RABBIT) tell_object(find_player("brandobas"), RABBIT)
#define SAVE_DIR "/net/save/nntp_"

static string group_name, in_message, *pending;
int cur_article;
static int last_article;

void load_me();
void save_me();

void create() {
  pending = ({ });
  seteuid(getuid());
} /* create() */

void do_connect(string g_n) {
  if (group_name) {
    pending += ({ g_n });
    return ;
  }
  group_name = g_n;
  load_me();
  INETD->open_to_service("nntp", STREAM, "nntp_server");
} /* do_connect() */

void do_fetch(int article) {
} /* do_fetch() */

void read_callback(int fd, string mess) {
  int tmp, number, start, finish;
  string str, from, header, body, s1, s2, subject;

  TP("Got "+mess[0..2]+"("+strlen(mess)+") - "+
     replace_string(mess[strlen(mess)-5..1000000], "\n", "\\n")+
     "\n");
  if (in_message) {
    in_message += mess;
    if (in_message[strlen(in_message)-5..1000000] != "\r\n.\r\n") {
      TP("Collecting message.\n");
      return ;
    } else {
      mess = in_message;
      in_message = 0;
      TP("New mess "+mess[0..2]+"\n");
    }
  }
  switch (mess[0..2]) {
    case "200" :
    case "201" :
      previous_object()->write_fd(fd, "group "+group_name+"\n");
      return ;
    case "211" :
      sscanf(mess, "%d %d %d %d %s", tmp, number, start, finish, str);
      TP("Got news group info, "+start+".."+finish+".\n");
/*
 * Ok, excelent...
 */
/* Find the new articles and grab them one by one... */
      last_article = finish;
      if (cur_article < start)
        cur_article = start;
      if (cur_article <= finish)
        previous_object()->write_fd(fd, "article "+(cur_article++)+"\n");
      else {
        previous_object()->close_fd(fd);
        group_name = 0;
        if (sizeof(pending)) {
          do_connect(pending[0]);
          pending = pending[1..10000];
        }
      }
      return ;
    case "220" :
/* Article retrived. */
/* Ok, now get the info we want out of it... */
      if (mess[strlen(mess)-5..10000000] != "\r\n.\r\n") {
        in_message = mess;
        break;
      }
      mess = replace_string(mess, "\r", "");
      sscanf(mess, "%s\n\n%s", header, body);
      sscanf(header, "%s\nFrom: %s\n%s", s1, from, subject, s2);
      sscanf(from, "%s %s", from, s1);
      sscanf(header, "%s\nSubject: %s\n%s", s1, subject, s2);
      TP("From "+from+" with a subject of "+subject+" and a body of ");
      BOARD_HAND->add_message(group_name, from, subject, body);
      save_me();
      if (cur_article <= last_article)
        previous_object()->write_fd(fd, "article "+(cur_article++)+"\n");
      else {
        previous_object()->close_fd(fd);
        group_name = 0;
        save_me();
        if (sizeof(pending)) {
          do_connect(pending[0]);
          pending = pending[1..10000];
        }
      }
      return ;
    case "423" :
      if (cur_article <= last_article)
        previous_object()->write_fd(fd, "article "+(cur_article++)+"\n");
      else {
        previous_object()->close_fd(fd);
        group_name = 0;
        save_me();
        if (sizeof(pending)) {
          do_connect(pending[0]);
          pending = pending[1..10000];
        }
      }
      break;
    default :
      TP("Error "+mess);
      break;
  }
} /* read_callback() */

void connected(int fd) {
  TP("We are connected.\n");
} /* connected() */

void dest_me() {
  if (group_name)
    save_me();
  destruct(this_object());
} /* dest_me() */

void save_me() {
  save_object(SAVE_DIR+group_name);
} /* save_me() */

void load_me() {
  restore_object(SAVE_DIR+group_name);
} /* load_me() */