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