Skip to content
Snippets Groups Projects
Select Git revision
20 results

NNTP.pmod

Blame
    • David Hedbor's avatar
      98fe34be
      - Ident.pmod now uses Stdio.FILE->gets() instead of · 98fe34be
      David Hedbor authored
        Stdio.File->read(), since the latter sometimes didn't work (blocked
        Stdio.File->indefinitely).
      - NNTP.pmod now sends commands ending with \r\n instead of just \n.
      - Added second argument, port, to SMTP.client.create to allow usage of
        non-standard ports.
      
      Rev: lib/modules/Protocols.pmod/Ident.pmod:1.4
      Rev: lib/modules/Protocols.pmod/NNTP.pmod:1.5
      Rev: lib/modules/Protocols.pmod/SMTP.pmod:1.6
      98fe34be
      History
      - Ident.pmod now uses Stdio.FILE->gets() instead of
      David Hedbor authored
        Stdio.File->read(), since the latter sometimes didn't work (blocked
        Stdio.File->indefinitely).
      - NNTP.pmod now sends commands ending with \r\n instead of just \n.
      - Added second argument, port, to SMTP.client.create to allow usage of
        non-standard ports.
      
      Rev: lib/modules/Protocols.pmod/Ident.pmod:1.4
      Rev: lib/modules/Protocols.pmod/NNTP.pmod:1.5
      Rev: lib/modules/Protocols.pmod/SMTP.pmod:1.6
    NNTP.pmod 2.89 KiB
    // Not finished - Fredrik Hubinette
    
    class protocol
    {
      inherit Stdio.FILE : news;
    
      string rest;
    
      int readreturncode()
      {
        int space, code;
        do {
          space=' ';
          string tmp=news::gets();
          if(!tmp) return 0;
          sscanf(tmp,"%d%c%s",code,space,rest);
        } while(space == '-');
        return code;
      }
    
      string *read_body_lines()
      {
        string *ret=({});
        string s;
        while(s = news::gets())
        {
          if(s=="." || s==".\r") return ret;
          sscanf(s,".%s",s);
          ret+=({s});
        }
        throw(({"NNTP: connection closed by news server.\n",backtrace()}));
      }
    
      string readreturnbody()
      {
        string *tmp=read_body_lines();
        return tmp*"\n"+"\n";
      }
    
      void writebody(string s)
      {
        s=replace(s,"\r","");
        foreach(s/"\n",string line)
          {
    	if(strlen(line) && line[0]=='.')
    	  line="."+line+"\r\n";
    	else
    	  line=line+"\r\n";
    	if(news::write(line) != strlen(line))
    	  throw(({"NNTP: Failed to write body\n",backtrace()}));
          }
        news::write(".\r\n");
      }
    
      int command(string cmd)
      {
        news::write(cmd+"\r\n");
        return readreturncode();
      }
    
      int failsafe_command(string cmd)
      {
        if(command(cmd)/100 != 2)
          throw(({"NEWS "+cmd+" failed\n",backtrace()}));
      }
    
      string do_cmd_with_body(string cmd)
      {
        failsafe_command(cmd);
        return readreturnbody();
      }
    
    };
    
    class client
    {
      inherit protocol;
    
      class Group
      {
        string group;
        int min;
        int max;
      }
    
      array(object(Group)) list_groups()
      {
        array(object(Group)) ret=({});
        failsafe_command("list active");
        foreach(read_body_lines(),string line)
          {
    	object o=Group();
    	if(sscanf(line,"%s %d %d",o->group,o->max,o->min)==3)
    	  ret+=({o});
          }
    
        return ret;
        
      }
    
      object(Group) current_group;
    
      void set_group(object(Group) o)
      {
        if(current_group==o)
          return;
        failsafe_command("group "+o->group);
        current_group=o;
      }
    
      object(Group) go_to_group(string group)
      {
        failsafe_command("group "+group);
        object o=Group();
        o->grop=group;
        sscanf(rest,"%d %d %d",int num,o->min,o->max);
        current_group=o;
        return o;
      }
    
      string head(void|int|string x)
      {
        failsafe_command("head"+(x?" "+x:""));
        return readreturnbody();
      }
    
      string body(void|int|string x)
      {
        failsafe_command("body"+(x?" "+x:""));
        return readreturnbody();
      }
    
      string article(void|int|string x)
      {
        failsafe_command("article"+(x?" "+x:""));
        return readreturnbody();
      }
    
      void create(string|void server)
      {
        if(!server)
        {
          server=getenv("NNTPSERVER");
    
          if(!server)
          {
    	// Check /etc/nntpserver here 
          }
        }
    
        if(!connect(server,119))
        {
          throw(({"Failed to connect to news server.\n",backtrace()}));
        }
    
        if(readreturncode()/100 != 2)
          throw(({"Connection refused by NNTP server.\n",backtrace()}));
    
        if(command("mode reader")/100 !=2)
          throw(({"NNTP: mode reader failed.\n",backtrace()}));
        
      }
    };