home *** CD-ROM | disk | FTP | other *** search
/ Tutto per Internet / Internet.iso / soft95 / News / souper95 / nntpcl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-10  |  5.2 KB  |  256 lines

  1. /* $Id: nntpcl.c 1.3 1995/06/25 16:39:27 cthuang Exp $
  2.  *
  3.  * NNTP client routines
  4.  */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <netdb.h>
  12. #include "socket.h"
  13. #include "nntp.h"
  14. #include "nntpcl.h"
  15.  
  16. extern char *nntpServer;
  17.  
  18. /* Open connection to NNTP server.
  19.  * Return socket handle or -1 on error.
  20.  */
  21. int
  22. nntpConnect (void)
  23. {
  24.     struct servent *sp;
  25.     char buf[BUFSIZ];
  26.     int response;
  27.     int socket;
  28.  
  29.     if (nntpServer == NULL) {
  30.     fprintf(stderr,
  31.         "Set the NNTPSERVER environment variable to the news host.\n");
  32.     exit(EXIT_FAILURE);
  33.     }
  34.  
  35.     if ((sp = getservbyname("nntp", "tcp")) == NULL) {
  36.     fprintf(stderr, "nntp/tcp: Unknown service.\n");
  37.     return -1;
  38.     }
  39.  
  40.     socket = Socket(nntpServer, ntohs(sp->s_port));
  41.     if (socket < 0) {
  42.     fprintf(stderr, "Cannot connect to news server %s\n", nntpServer);
  43.     return -1;
  44.     }
  45.  
  46.     if (SockGets(socket, buf, sizeof(buf)) == 0) {
  47.     response = atoi(buf);
  48.     switch (response) {
  49.     case OK_NOPOST:
  50.         printf("You cannot post articles to the news server %s\n",
  51.         nntpServer);
  52.         break;
  53.  
  54.     case OK_CANPOST:
  55.         break;
  56.  
  57.     case ERR_ACCESS:
  58.         printf("You do not have permission to use the news server %s\n",
  59.         nntpServer);
  60.         return -1;
  61.  
  62.     default:
  63.         printf("Unexpected response from news server %s\n", nntpServer);
  64.         puts(buf);
  65.         return -1;
  66.     }
  67.     }
  68.  
  69.     /* This is for INN */
  70.     SockPuts(socket, "mode reader");
  71.     SockGets(socket, buf, sizeof(buf));
  72.  
  73.     return socket;
  74. }
  75.  
  76. /* Close NNTP connection. */
  77.  
  78. void
  79. nntpClose (int socket)
  80. {
  81.     SockPuts(socket, "QUIT");
  82.     SockClose(socket);
  83. }
  84.  
  85. /* Select newsgroup to read from
  86.  * Return TRUE if successful.
  87.  */
  88. int
  89. nntpGroup (int socket, const char *ngname, ArticleNumber *pLo,
  90.     ArticleNumber *pHi)
  91. {
  92.     char buf[BUFSIZ];
  93.     int count;
  94.  
  95.     SockPrintf(socket, "GROUP %s\r\n", ngname);
  96.     if (SockGets(socket, buf, sizeof(buf)) != 0) {
  97.     return 0;
  98.     }
  99.  
  100.     if (buf[0] == CHAR_OK) {
  101.     sscanf(buf+4, "%d %d %d", &count, pLo, pHi);
  102.     } else {
  103.     fprintf(stderr, "%s: %s\n", buf, ngname);
  104.     }
  105.     return buf[0] == CHAR_OK;
  106. }
  107.  
  108. /* Request overview for the current newsgroup.
  109.  * Return TRUE if successful.
  110.  */
  111. int
  112. nntpXover (int socket, ArticleNumber lo, ArticleNumber hi)
  113. {
  114.     char buf[BUFSIZ];
  115.  
  116.     if (lo < hi)
  117.     SockPrintf(socket, "XOVER %ld-%ld\r\n", lo, hi);
  118.     else
  119.     SockPrintf(socket, "XOVER %ld\r\n", lo);
  120.  
  121.     if (SockGets(socket, buf, sizeof(buf)) != 0)
  122.     return 0;
  123.     if (buf[0] != CHAR_OK)
  124.     fprintf(stderr, "%s\n", buf);
  125.  
  126.     return buf[0] == CHAR_OK;
  127. }
  128.  
  129. /* Get next article in group.
  130.  * Return TRUE if successful.
  131.  */
  132. int
  133. nntpNext (int socket, ArticleNumber *pArtNum)
  134. {
  135.     char buf[BUFSIZ];
  136.  
  137.     SockPrintf(socket, "NEXT\r\n");
  138.     if (SockGets(socket, buf, sizeof(buf)) != 0) {
  139.     return 0;
  140.     }
  141.  
  142.     if (buf[0] == CHAR_OK) {
  143.     sscanf(buf+4, "%ld", pArtNum);
  144.     }
  145.     return buf[0] == CHAR_OK;
  146. }
  147.  
  148. /* Get article from server.
  149.  * Return TRUE if successful.
  150.  */
  151. int
  152. nntpArticle (int socket, const char *cmd, ArticleNumber artnum, FILE *outf)
  153. {
  154.     char buf[BUFSIZ];
  155.     char *bufp;
  156.  
  157.     SockPrintf(socket, "%s %ld\r\n", cmd, artnum);
  158.     if (SockGets(socket, buf, sizeof(buf)) < 0) {
  159.     return 0;
  160.     }
  161.  
  162.     if (buf[0] == CHAR_FATAL) {    /* Fatal error */
  163.     fprintf(stderr, "%s\n", buf);
  164.     exit(EXIT_FAILURE);
  165.     }
  166.  
  167.     if (buf[0] != CHAR_OK) {        /* and get it's reaction */
  168.     return 0;
  169.     }
  170.  
  171.     while (SockGets(socket, buf, sizeof(buf)) == 0) {
  172.     bufp = buf;
  173.     if (buf[0] == '.') {
  174.         ++bufp;
  175.         if (buf[1] == '\0')
  176.         break;
  177.     }
  178.  
  179.     fputs(bufp, outf);
  180.     fputc('\n', outf);
  181.     }
  182.  
  183.     return 1;
  184. }
  185.  
  186. /* Get date from server.
  187.  * Return TRUE if successful.
  188.  */
  189. int
  190. nntpDate (int socket, char *dest)
  191. {
  192.     char buf[BUFSIZ];
  193.  
  194.     SockPuts(socket, "DATE");
  195.     if (SockGets(socket, buf, sizeof(buf)) != 0) {
  196.     return 0;
  197.     }
  198.  
  199.     if (buf[0] == CHAR_INF) {
  200.     sscanf(buf+4, "%s", dest);
  201.     } else {
  202.     fprintf(stderr, "%s\n", buf);
  203.     }
  204.     return buf[0] == CHAR_INF;
  205. }
  206.  
  207. /* Post article to NNTP server.
  208.  * Return TRUE if successful.
  209. */
  210. int
  211. nntpPost (int socket, FILE *inf, size_t bytes)
  212. {
  213.     char buf[BUFSIZ], *s;
  214.     size_t len, count;
  215.     long offset;
  216.  
  217.     SockPuts(socket, "POST");
  218.     if (SockGets(socket, buf, sizeof(buf)) < 0) {
  219.     return 0;
  220.     }
  221.     if (buf[0] != CHAR_CONT) {
  222.     if (atoi(buf) == ERR_NOPOST) {
  223.         fprintf(stderr, "You cannot post to this server.\n");
  224.     }
  225.     fprintf(stderr, "%s\n", buf);
  226.     return 0;
  227.     }
  228.  
  229.     offset = ftell(inf);
  230.     count = bytes;
  231.     while (fgets(buf, sizeof(buf), inf) && count > 0) {
  232.     count -= strlen(buf);
  233.     if ((s = strchr(buf, '\n')) != NULL)
  234.         *s = '\0';
  235.     if (buf[0] == '.')
  236.         SockWrite(socket, buf, 1);
  237.     SockPrintf(socket, "%s\r\n", buf);
  238.     }
  239.     fseek(inf, offset+bytes, SEEK_SET);
  240.  
  241.     SockPrintf(socket, ".\r\n");
  242.  
  243.     if (SockGets(socket, buf, sizeof(buf)) < 0) {
  244.     return 0;
  245.     }
  246.     if (buf[0] != CHAR_OK) {
  247.     if (atoi(buf) == ERR_POSTFAIL) {
  248.         fprintf(stderr, "Article not accepted by server; not posted.\n");
  249.     }
  250.     fprintf(stderr, "%s\n", buf);
  251.     return 0;
  252.     }
  253.  
  254.     return 1;
  255. }
  256.