|
|
1.1 root 1: /*
2: * NNTP client routines.
3: *
4: * %W% (Berkeley) %G%
5: */
6:
7: #include <stdio.h>
8: #include <sys/types.h>
9: #include <sys/socket.h>
10: #include <netinet/in.h>
11: #include <netdb.h>
12: #include "response_codes.h"
13:
14: FILE *ser_rd_fp;
15: FILE *ser_wr_fp;
16:
17: /*
18: * server_init Get a connection to the remote news server.
19: *
20: * Parameters: "machine" is the machine to connect to.
21: *
22: * Returns: -1 on error, 0 otherwise.
23: *
24: * Side effects: Connects to server.
25: */
26:
27: server_init(machine)
28: char *machine;
29: {
30: int sockt_rd, sockt_wr;
31: char line[256];
32:
33: sockt_rd = getsocket(machine); /* Get a socket to the */
34: if (sockt_rd < 0) /* server, abort on */
35: return (-1);
36:
37: /*
38: * Now we'll make file pointers (i.e., buffered I/O) out of
39: * the socket file descriptor. Note that we can't just
40: * open a fp for reading and writing -- we have to open
41: * up two separate fp's, one for reading, one for writing.
42: */
43:
44: if ((ser_rd_fp = fdopen(sockt_rd, "r")) == NULL) {
45: perror("server_init: fdopen #1");
46: return (-1);
47: }
48:
49: sockt_wr = dup(sockt_rd);
50: if ((ser_wr_fp = fdopen(sockt_wr, "w")) == NULL) {
51: perror("server_init: fdopen #2");
52: return (-1);
53: }
54:
55: /* Now get the server's signon message */
56:
57: (void) get_server(line, sizeof(line));
58: if (line[0] != CHAR_OK) {
59: (void) close(sockt_rd);
60: (void) close(sockt_wr);
61: return (-1); /* And abort if it's not good */
62: }
63: return (0);
64: }
65:
66:
67: /*
68: * getsocket -- get us a socket connected to the news server.
69: *
70: * Parameters: "machine" is the machine the server is running on.
71: *
72: * Returns: Socket connected to the news server if
73: * all is ok, else -1 on error.
74: *
75: * Side effects: Connects to server.
76: *
77: * Errors: Printed via perror.
78: */
79:
80: getsocket(machine)
81: char *machine;
82: {
83: int s;
84: struct sockaddr_in sin;
85: struct servent *getservbyname(), *sp;
86: struct hostent *gethostbyname(), *hp;
87:
88: if ((sp = getservbyname("nntp", "tcp")) == NULL) {
89: fprintf(stderr, "nntp/tcp: Unknown service.\n");
90: return (-1);
91: }
92:
93: if ((hp = gethostbyname(machine)) == NULL) {
94: fprintf(stderr, "%s: Unknown host.\n", machine);
95: return (-1);
96: }
97:
98: bzero((char *) &sin, sizeof(sin));
99: bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
100: sin.sin_family = hp->h_addrtype;
101: sin.sin_port = sp->s_port;
102:
103: if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* Get the socket */
104: perror("socket");
105: return (-1);
106: }
107:
108: /* And then connect */
109:
110: if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
111: perror("connect");
112: return (-1);
113: }
114:
115: return (s);
116: }
117:
118:
119: /*
120: * put_server -- send a line of text to the server, terminating it
121: * with CR and LF, as per ARPA standard.
122: *
123: * Parameters: "string" is the string to be sent to the
124: * server.
125: *
126: * Returns: Nothing.
127: *
128: * Side effects: Talks to the server.
129: *
130: * Note: This routine flushes the buffer each time
131: * it is called. For large transmissions
132: * (i.e., posting news) don't use it. Instead,
133: * do the fprintf's yourself, and then a final
134: * fflush.
135: */
136:
137: void
138: put_server(string)
139: char *string;
140: {
141: /* fprintf(stderr, ">>> %s\n", string); */
142: fprintf(ser_wr_fp, "%s\r\n", string);
143: (void) fflush(ser_wr_fp);
144: }
145:
146:
147: /*
148: * get_server -- get a line of text from the server. Strips
149: * CR's and LF's.
150: *
151: * Parameters: "string" has the buffer space for the
152: * line received.
153: * "size" is the size of the buffer.
154: *
155: * Returns: -1 on error, 0 otherwise.
156: *
157: * Side effects: Talks to server, changes contents of "string".
158: */
159:
160: get_server(string, size)
161: char *string;
162: int size;
163: {
164: register char *cp;
165: char *index();
166:
167: if (fgets(string, size, ser_rd_fp) == NULL)
168: return (-1);
169:
170: if ((cp = index(string, '\r')) != NULL)
171: *cp = '\0';
172: else if ((cp = index(string, '\n')) != NULL)
173: *cp = '\0';
174: /* fprintf(stderr, "<<< %s\n", string); */
175:
176: return (0);
177: }
178:
179:
180: /*
181: * close_server -- close the connection to the server, after sending
182: * the "quit" command.
183: *
184: * Parameters: None.
185: *
186: * Returns: Nothing.
187: *
188: * Side effects: Closes the connection with the server.
189: * You can't use "put_server" or "get_server"
190: * after this routine is called.
191: */
192:
193: void
194: close_server()
195: {
196: char ser_line[256];
197:
198: put_server("QUIT");
199: (void) get_server(ser_line, sizeof(ser_line));
200:
201: (void) fclose(ser_wr_fp);
202: (void) fclose(ser_rd_fp);
203: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.