1 /*
2 * (C) Maint Laboratory 2003-2004
3 * Author: Elohin Igor'
4 * e-mail: maint@unona.ru
5 * fido : 2:5070/222.52
6 * URL : http://maint.unona.ru
7 */
8 #include <stdio.h>
9 #include <sys/types.h>
10 #include <netdb.h>
11 #include <netinet/in.h>
12 #include <sys/socket.h>
13 #include <sys/socket.h>
14 #include <errno.h>
15 #include "../common.h"
16
17 #define NNTP_BAD_COMMAND_VAL 500
18
19 FILE *inp_nntp;
20 FILE *out_nntp;
21
nntp_connect(char * host,int port,char * line)22 int nntp_connect(char *host, int port, char *line)
23 {
24 struct hostent *hp;
25 char **ap;
26 char *p;
27 char *dest;
28 struct sockaddr_in server;
29 int i, j;
30 char buf[BUFSIZE + 2];
31
32 if ((hp = gethostbyname(host)) == NULL) {
33 myerror("Not a host name");
34 return -1;
35 }
36 ap = hp->h_addr_list;
37 /* Set up the socket address. */
38 memset((void *) &server, 0, sizeof(server));
39 server.sin_family = hp->h_addrtype;
40 server.sin_port = htons(port);
41 /* Loop through the address list, trying to connect. */
42 for (; ap && *ap; ap++) {
43 /* Make a socket and try to connect. */
44 if ((i = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
45 break;
46 p = (char *) *ap;
47 for (dest = (char *) &server.sin_addr, j = hp->h_length; --j >= 0;)
48 *dest++ = *p++;
49 if (connect(i, (struct sockaddr *) &server, sizeof server) < 0) {
50 close(i);
51 continue;
52 }
53
54 /* Connected -- now make sure we can post. */
55 if ((inp_nntp = fdopen(i, "r")) == NULL) {
56 close(i);
57 continue;
58 }
59 if (fgets(buf, sizeof(buf), inp_nntp) == NULL) {
60 fclose(inp_nntp);
61 close(i);
62 continue;
63 }
64 j = atoi(buf);
65 if (j != 200 && j != 201) {
66 fclose(inp_nntp);
67 close(i);
68 break;
69 }
70
71 if ((out_nntp = fdopen(dup(i), "w")) == NULL) {
72 fclose(inp_nntp);
73 close(i);
74 continue;
75 }
76 return 0;
77 }
78 return -1;
79 }
connect_server(char * host,int port)80 int connect_server(char *host, int port)
81 {
82 char line1[BUFSIZE + 2];
83 char line2[BUFSIZE];
84
85 if (nntp_connect(host, port, line1) < 0) {
86 if (line1[0] == '\0') {
87 myerror("I/O problem");
88 return -1;
89 }
90 myerror("Server rejected connection; return it's reply code.");
91 return atoi(line1);
92 }
93
94 /* Send the INN command; if understood, use that reply. */
95 put_server("MODE READER");
96 if (get_server(line2) < 0)
97 return -1;
98 if (atoi(line2) != NNTP_BAD_COMMAND_VAL)
99 strcpy(line1, line2);
100 /* Connected; return server's reply code. */
101 return atoi(line1);
102 }
disconnect_server()103 void disconnect_server()
104 {
105 char buf[BUFSIZE];
106
107 if (out_nntp != NULL && inp_nntp != NULL) {
108 put_server("QUIT");
109 fclose(out_nntp);
110 out_nntp = NULL;
111
112 get_server(buf);
113 fclose(inp_nntp);
114 inp_nntp = NULL;
115 }
116 }
get_server(char * buf)117 int get_server(char *buf)
118 {
119 char *p;
120
121 if (fgets(buf, BUFSIZE, inp_nntp) == NULL)
122 return -1;
123 p = &buf[strlen(buf)];
124 if (p >= &buf[2] && p[-2] == '\r' && p[-1] == '\n')
125 p[-2] = '\0';
126 return 0;
127 }
get_line(char * buf)128 char *get_line(char *buf)
129 {
130 char *p;
131
132 if (fgets(buf, BUFSIZE, inp_nntp) == NULL)
133 return NULL;
134 p = &buf[strlen(buf)];
135 if (p >= &buf[2] && p[-2] == '\r' && p[-1] == '\n')
136 p[-2] = '\0';
137 return buf;
138 }
put_server(char * buf)139 void put_server(char *buf)
140 {
141 fprintf(out_nntp, "%s\r\n", buf);
142 fflush(out_nntp);
143 }
144