Le protocole NNTP: Client GCC


Ce programme propose une implementation trés simple de quelques fonctionnalités de NNTP. Pour l'utiliser il suffit de modifier la chaine group pour quelle corresponde au newsgrou p qui vous interesse. Ensuite compiler le programme à l'aide de gcc. L'execution produira un fichier pour chaque message disponible pour ce groupe de discussion.
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PACKET_SIZE  1024

void appli(void);

int  to_server_socket = -1;
char server_name[] = "news.wanadoo.fr";  /* nom du host du serveur */
int  port = 119;
char group[] = "group alt.tv.alias\n";

char subject[] = "Subject: transfert ";

int main (int argc, char *argv[])
{
    struct sockaddr_in serverSockAddr;    /* addresse de la socket */
    struct hostent *serverHostEnt;        /* description du host serveur */
    unsigned long hostAddr;               /* addresse du serveur */
    char *filename;

    if ( argc == 2 ) filename = argv[1];
    else filename = NULL; /* use stdin */

    bzero((void *)&serverSockAddr,sizeof(serverSockAddr));
    /* initialise a zero serverSockAddr */
    /* converti l'adresse ip 9.100.1.1 en entier long */
    hostAddr = inet_addr(server_name);

    if ( (long)hostAddr != (long)-1)
      bcopy((void *)&hostAddr,
            (void *)&serverSockAddr.sin_addr,sizeof(hostAddr));
    else
    /* si on a donne un nom  */
    {
      serverHostEnt = gethostbyname(server_name);
      bcopy((void *)serverHostEnt->h_addr,
            (void *)&serverSockAddr.sin_addr,serverHostEnt->h_length);
    }

    serverSockAddr.sin_port = htons(port);    /* host to network port  */
    serverSockAddr.sin_family = AF_INET;      /* AF_*** : INET=internet */
    /* creation de la socket */
    to_server_socket = socket(AF_INET,SOCK_STREAM,0);
    /* requete de connexion */
    connect(to_server_socket,(struct sockaddr *)&serverSockAddr,
            sizeof(serverSockAddr));
    appli();

    /* fermeture de la connection */
    shutdown(to_server_socket,2);
    close(to_server_socket);
    return 0;
}

int writen(int fd, char *ptr, int n)
{
int nl, nw;
 nl = n;
 while ( nl > 0 ) {
  nw = write(fd, ptr, nl);
  if ( nw <= 0 ) return nw;     /*erreur*/
  nl -= nw;
  ptr += nw;
 }
 return (n-nl);
}


int readn(int fd, char *ptr, int n){
int nl, nr;
 nl = n;
 while ( nl > 0 ) {
  nr = read(fd,ptr,nl);
  if (nr < 0 ) return nr;     /*erreur*/
  else if ( nr == 0 ) break;
  nl -= nr;
  ptr += nr;
  if ( *(ptr-2) == '\r' &&  *(ptr-1) == '\n' )
    break;
 }
 *ptr = 0x00;
 return (n-nl);
}

void appli (void) {
char buf[PACKET_SIZE+1];
unsigned long n,nb, p, d;
char fn[20];
FILE *f;

  buf[0] = 0x00;
  readn(to_server_socket,buf,PACKET_SIZE);
  printf(buf);
  writen(to_server_socket,group,strlen(group));
  readn(to_server_socket,buf,PACKET_SIZE);
  printf(buf);
  sscanf(buf,"211 %ld %ld %ld",&n,&p,&d);
  for (nb=p; nb<=d; nb++) {
    sprintf(fn,"f_%ld",nb);
    f = fopen(fn,"wb");
    sprintf(buf,"ARTICLE %ld\r\n",nb);
    writen(to_server_socket,buf,strlen(buf));
    do {
      n=readn(to_server_socket,buf, PACKET_SIZE);
      fprintf(f,"%s",buf);
      if ( ! strncmp("\r\n.\r\n",&buf[n-5],5) ) break;
      bzero(buf, PACKET_SIZE+1);
    } while ( 1 );
    fclose(f);
  }
}