<?php

// ------------------------------------------------------------------------- //
// Voici une classe avec un exemple d'utilisation dont le but est de lire    //
// des news dans un serveur de news à l'aide du protocole NNTP (Network News //
// Transfer Protocol). Pour plus d'infos sur ce protocole voir la RFC 977.   //
// ------------------------------------------------------------------------- //
// Auteur: Nicolas Bigot                                                     //
// Email:  nbigot@free.fr                                                    //
// Web:    http://nbigot.free.fr/                                            //
// ------------------------------------------------------------------------- //

<?
// class nntp_client
// this code is aimed to read news from newsgroups
// doc there : http://www.faqs.org/rfcs/rfc977.html (see RFC 977)

class nntp_client
{
// members

var $fp;                                // pointer to opened socket
var $host_server;                       // nntp host server name
var $port;                              // port service number (nntp=119)
var $status;                            // staus : connected/disconnected
var $helo;                              // server info (text)
var $group;                             // current selected group
var $ans;                               // last server cmd reply
var $nb_articles_in_group;              // number of articles in selected group
var $first_article;                     // first articles in selected group
var $last_article;                      // last articles in selected group
var $articles;                          // list of retrived articles
var $nb_articles;                       // number of articles in list

// functions

function connect($server, $port)
{
    
$this->host_server = $server;
    
$this->port = $port;
    if (
$this->fp = fsockopen($this->host_server, $this->port))
    {
        
$this->status = 1;
        
$this->helo = fgets($this->fp, 1000);
    }
    else
        
$this->status = 0;
    return
$this->status;
}

function
close()
{
    if (
$this->status <= 0)
        return -
1;
    
$this->status = 0;
    
fputs($this->fp, "QUIT\r\n");
    
fclose($this->fp);
    return
1;
}

function
select_group($group_name)
{
    if (
$this->status <= 0)
        return -
1;
    
$this->group = $group_name;
    
fputs($this->fp, "GROUP ".$this->group."\r\n");
    
$this->ans = fgets($this->fp, 1000);
    
$args = explode(" ", $this->ans);
    if (
$args[0] != "211")
    {
        
$this->status = 2;
        return
0;
    }
    
$this->nb_articles_in_group = $args[1];
    
$this->first_article = $args[2];
    
$this->last_article = $args[3];
    
$this->status = 1;
    return
1;
}

function
read_headers($limit = 0)
{
    if (
$this->status != 1)
        return -
1;
    
$this->nb_articles = 0;
    if (
$limit == 0)
        
$start = $this->first_article;
    else
        
$start = $this->last_article - $limit + 1;
    while (
$start <= $this->last_article)
    {
        
fputs($this->fp, "STAT ".$start."\r\n");
        
$this->ans = fgets($this->fp, 1000);
        
$args = explode(" ", $this->ans);
        if (
$args[0] == "223")
        {
            
fputs($this->fp, "HEAD ".$start."\r\n");
            
$res = fgets($this->fp, 1000);
            if (
strncmp("221", $res, 3))
                continue;
            
$this->articles[$this->nb_articles]["Id"] = $start;
            while (
1)
            {
                
$res = fgets($this->fp, 1000);
                if (
$res == ".\r\n")
                    break;
                
$pos = strpos($res, ":");
                
$keyarg = substr($res, 0, $pos);
                
$keyvalue = substr($res, $pos+2);
                
$this->articles[$this->nb_articles]["$keyarg"] = $keyvalue;
            }
            
$this->nb_articles++;
        }
        
$start++;
    }
    return
1;
}

function
read_all_body_articles()
{
    if (
$this->status != 1)
        return -
1;
    for (
$i = 0; $i < $this->nb_articles; $i++)
        
$this->read_article($i);
    return
1;
}

function
read_article($index)
{
    if (
$this->status != 1)
        return -
1;
    
$article_id = $this->articles[$index]["Id"];
    
fputs($this->fp, "BODY ".$article_id."\r\n");
    
$res = fgets($this->fp, 1000);
    if (
strncmp("222", $res, 3))
        return
0;
    
$body = "";
    while (
1)
    {
        
$res = fgets($this->fp, 4000);
        if (
$res == ".\r\n")
        break;
        
$body .= $res;
    }
    
$this->articles[$index]["Body"] = $body;
    return
1;
}

}
// class

?>

<html>
<body>

<?
$newsclient
= new nntp_client;
// exemple de serveur de news
if (!$newsclient->connect("news.isdnet.fr", 119))
{
    echo
"connexion échouée!";
    exit;
}
echo
"<br>\n".$newsclient->helo."\n<br>\n";
// exemple de groupe de news
if (!$newsclient->select_group("microsoft.public.vc.mfc"))
{
    echo
"erreur dans select_group : [".$newsclient->ans."]<br>\n";
    exit;
}
if (!
$newsclient->read_headers(10))
{
    echo
"erreur dans read_headers : [".$newsclient->ans."]<br>\n";
    exit;
}
if (!
$newsclient->read_all_body_articles())
{
    echo
"erreur dans read_all_body_article<br>\n";
    exit;
}
$newsclient->close();

// affichage des news
echo "Il y a ".$newsclient->nb_articles." articles.<br><br>\n";
for (
$i = 0; $i < $newsclient->nb_articles; $i++)
{
    
$from = $newsclient->articles[$i]["From"];
    
$subject = $newsclient->articles[$i]["Subject"];
    
$date = $newsclient->articles[$i]["Date"];
    
$body = $newsclient->articles[$i]["Body"];
    echo
"<hr><br>From: $from<br>Subject: $subject<br>Date: $date<br><br>";
    echo
str_replace("\r\n", "<br>\r\n",$body)."<br>\n";
}
?>

</body>
</html>