1 /* $Id: nntpclient.c,v 3.0 1991/11/22 04:12:21 davison Trn $
2 */
3 /* The authors make no claims as to the fitness or correctness of this software
4 * for any use whatsoever, and it is provided as is. Any use of this software
5 * is at the user's own risk.
6 */
7
8 #include "EXTERN.h"
9 #include "common.h"
10
11 #ifdef USE_NNTP
12
13 #include "INTERN.h"
14 #include "nntpclient.h"
15
16 void finalize _((int));
17 #ifdef NNTP_HANDLE_TIMEOUT
18 char nntp_handle_timeout _((bool_int));
19 #endif
20 #ifdef NNTP_HANDLE_AUTH_ERR
21 char nntp_handle_auth_err _((bool_int));
22 #endif
23
24 #define CANTPOST \
25 "NOTE: This machine does not have permission to post articles.\n\n"
26 #define CANTUSE \
27 "This machine does not have permission to use the %s news server.\n\n"
28
29 int
nntp_connect(verbose)30 nntp_connect(verbose)
31 bool_int verbose;
32 {
33 char *server, filebuf[128];
34 int response;
35
36 if ((server = getenv("NNTPSERVER")) == Nullch)
37 server = SERVER_NAME;
38 if (server[0] == '/') {
39 register FILE *fp;
40 if ((fp = fopen(server, "r")) != Nullfp) {
41 server = Nullch;
42 while (fgets(filebuf, sizeof filebuf, fp) != Nullch) {
43 if (*filebuf == '\n' || *filebuf == '#')
44 continue;
45 if ((server = index(filebuf, '\n')) != Nullch)
46 *server = '\0';
47 server = filebuf;
48 break;
49 }
50 fclose(fp);
51 } else
52 server = Nullch;
53 if (server == Nullch) {
54 sprintf(ser_line, "\
55 Couldn't get name of news server from %s\n\
56 Either fix this file, or put NNTPSERVER in your environment.\n", SERVER_NAME);
57 nntp_init_error(ser_line);
58 return 0;
59 }
60 }
61
62 switch (response = server_init(server)) {
63 case NNTP_GOODBYE_VAL:
64 if (atoi(ser_line) == response) {
65 char tmpbuf[LBUFLEN];
66 sprintf(tmpbuf,"News server %s unavailable: %s\n",server,&ser_line[4]);
67 nntp_init_error(tmpbuf);
68 return 0;
69 }
70 case -1:
71 sprintf(ser_line,"News server %s unavailable, try again later.\n",server);
72 nntp_init_error(ser_line);
73 return 0;
74 case NNTP_ACCESS_VAL:
75 sprintf(ser_line,CANTUSE,server);
76 nntp_init_error(ser_line);
77 return 0;
78 case NNTP_NOPOSTOK_VAL:
79 if (verbose) {
80 nntp_advise(CANTPOST);
81 }
82 /* FALL THROUGH */
83 case NNTP_POSTOK_VAL:
84 break;
85 default:
86 sprintf(ser_line,"Unknown response code %d from %s.\n", response, server);
87 nntp_init_error(ser_line);
88 return 0;
89 }
90 return 1;
91 }
92
93 void
nntp_command(buf)94 nntp_command(buf)
95 char *buf;
96 {
97 #if defined(DEBUG) && defined(FLUSH)
98 if (debug & DEB_NNTP)
99 printf(">%s\n", buf) FLUSH;
100 #endif
101 #if defined(NNTP_HANDLE_TIMEOUT) || defined(NNTP_HANDLE_AUTH_ERR)
102 strcpy(last_command, buf);
103 #endif
104 fprintf(ser_wr_fp, "%s\r\n", buf);
105 fflush(ser_wr_fp);
106 }
107
108 #ifdef NNTP_HANDLE_TIMEOUT
109 extern char *instr();
110 #endif
111
112 char
nntp_check(strict)113 nntp_check(strict)
114 bool_int strict;
115 {
116 int n;
117
118 #ifdef HAS_SIGHOLD
119 sighold(SIGINT);
120 #endif
121 n = (fgets(ser_line, sizeof ser_line, ser_rd_fp) == NULL)? -1 : 0;
122 #ifdef HAS_SIGHOLD
123 sigrelse(SIGINT);
124 #endif
125 if (n < 0) {
126 nntp_close(FALSE);
127 nntp_error("\nUnexpected close of server socket.\n");
128 #ifdef NNTP_ERROR_IS_FATAL
129 finalize(1);
130 #else
131 return NNTP_CLASS_FATAL;
132 #endif
133 }
134 n = strlen(ser_line);
135 if (n >= 2 && ser_line[n-1] == '\n' && ser_line[n-2] == '\r')
136 ser_line[n-2] = '\0';
137 #if defined(DEBUG) && defined(FLUSH)
138 if (debug & DEB_NNTP)
139 printf("<%s\n", ser_line) FLUSH;
140 #endif
141 #ifdef NNTP_HANDLE_AUTH_ERR
142 if (atoi(ser_line) == NNTP_AUTH_NEEDED_VAL) {
143 return nntp_handle_auth_err(strict);
144 }
145 #endif
146 #ifdef NNTP_HANDLE_TIMEOUT
147 if (atoi(ser_line) == NNTP_TMPERR_VAL && instr(ser_line,"timeout",FALSE)) {
148 /* See if this was really a timeout */
149 return nntp_handle_timeout(strict);
150 }
151 #endif
152 if (strict && *ser_line == NNTP_CLASS_FATAL) { /* Fatal error */
153 char tmpbuf[LBUFLEN];
154 sprintf(tmpbuf,"\n%s\n",ser_line);
155 nntp_error(tmpbuf);
156 #ifdef NNTP_ERROR_IS_FATAL
157 finalize(1);
158 #endif
159 }
160 return *ser_line;
161 }
162
163 int
nntp_gets(buf,len)164 nntp_gets(buf, len)
165 char *buf;
166 int len;
167 {
168 int n;
169
170 #ifdef HAS_SIGHOLD
171 sighold(SIGINT);
172 #endif
173 n = (fgets(buf, len, ser_rd_fp) == NULL)? -1 : 0;
174 #ifdef HAS_SIGHOLD
175 sigrelse(SIGINT);
176 #endif
177 if (n < 0) {
178 nntp_close(FALSE);
179 nntp_error("\nUnexpected close of server socket.\n");
180 #ifdef NNTP_ERROR_IS_FATAL
181 finalize(1);
182 #else
183 return -1;
184 #endif
185 }
186 n = strlen(buf);
187 if (n >= 2 && buf[n-1] == '\n' && buf[n-2] == '\r') {
188 buf[n-2] = '\0';
189 return 1;
190 }
191 return 0;
192 }
193
194 void
nntp_close(send_quit)195 nntp_close(send_quit)
196 bool_int send_quit;
197 {
198 if (send_quit && ser_wr_fp != NULL && ser_rd_fp != NULL) {
199 nntp_command("QUIT");
200 nntp_check(FALSE);
201 }
202 /* the nntp_check() above might have closed these already. */
203 if (ser_wr_fp != NULL && ser_rd_fp != NULL) {
204 fclose(ser_wr_fp);
205 ser_wr_fp = NULL;
206 fclose(ser_rd_fp);
207 ser_rd_fp = NULL;
208 }
209 }
210
211 #endif /* USE_NNTP */
212