]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/pshsbr.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / pshsbr.c
1 /* pshsbr.c - NNTP client subroutines */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: pshsbr.c,v 2.4 1993/08/25 17:27:12 jromine Exp shettich $";
4 #endif lint
5
6 /* LINTLIBRARY */
7
8 #include "../h/strings.h"
9 #include "../h/nntp.h"
10 #include <stdio.h>
11 #include <signal.h>
12
13
14 #define NOTOK (-1)
15 #define OK 0
16 #define DONE 1
17
18 #define TRM "."
19 #define TRMLEN (sizeof TRM - 1)
20
21 extern int errno;
22 #ifndef BSD44
23 extern int sys_nerr;
24 extern char *sys_errlist[];
25 #endif
26
27 static int poprint = 0;
28 static int pophack = 0;
29
30 char response[BUFSIZ];
31
32 static FILE *input;
33 static FILE *output;
34
35 #ifdef BPOP /* stupid */
36 static int xtnd_last = -1,
37 xtnd_first = 0;
38 static char xtnd_name[512]; /* INCREDIBLE HACK!! */
39 #endif
40
41 #define command pop_command
42 #define multiline pop_multiline
43
44 static int traverse(), getline();
45 static putline();
46 /* \f */
47
48 int pop_init (host, user, pass, snoop)
49 #else RPOP
50 char *host,
51 *user,
52 *pass;
53 int snoop;
54 {
55 int fd1,
56 fd2;
57 char buffer[BUFSIZ];
58
59 if ((fd1 = client (host, "tcp", "nntp", response)) == NOTOK)
60 return NOTOK;
61
62 if ((fd2 = dup (fd1)) == NOTOK) {
63 (void) sprintf (response, "unable to dup connection descriptor: %s",
64 errno > 0 && errno < sys_nerr ? sys_errlist[errno]
65 : "unknown error");
66 (void) close (fd1);
67 return NOTOK;
68 }
69 if (pop_set (fd1, fd2, snoop, (char *)0) == NOTOK)
70 return NOTOK;
71
72 (void) signal (SIGPIPE, SIG_IGN);
73
74 switch (getline (response, sizeof response, input)) {
75 case OK:
76 if (poprint)
77 fprintf (stderr, "<--- %s\n", response);
78 if (*response < CHAR_ERR)
79 return OK;
80 else {
81 (void) strcpy (buffer, response);
82 (void) command ("QUIT");
83 (void) strcpy (response, buffer);
84 } /* fall */
85
86 case NOTOK:
87 case DONE:
88 if (poprint)
89 fprintf (stderr, "%s\n", response);
90 (void) fclose (input);
91 (void) fclose (output);
92 return NOTOK;
93 }
94 /* NOTREACHED */
95 }
96
97 /* \f */
98
99 int pop_set (in, out, snoop, myname)
100 int in,
101 out,
102 snoop;
103 char *myname;
104 {
105 if (myname && *myname)
106 strcpy (xtnd_name, myname); /* interface from bbc to msh */
107
108 if ((input = fdopen (in, "r")) == NULL
109 || (output = fdopen (out, "w")) == NULL) {
110 (void) strcpy (response, "fdopen failed on connection descriptor");
111 if (input)
112 (void) fclose (input);
113 else
114 (void) close (in);
115 (void) close (out);
116 return NOTOK;
117 }
118
119 poprint = snoop;
120
121 return OK;
122 }
123
124
125 int pop_fd (in, out)
126 char *in,
127 *out;
128 {
129 (void) sprintf (in, "%d", fileno (input));
130 (void) sprintf (out, "%d", fileno (output));
131 return OK;
132 }
133
134 /* \f */
135
136 int pop_stat (nmsgs, nbytes)
137 int *nmsgs,
138 *nbytes;
139 {
140 char **ap;
141 extern char **brkstring();
142
143 if (xtnd_last < 0) { /* in msh, xtnd_name is set from myname */
144 if (command("GROUP %s", xtnd_name) == NOTOK)
145 return NOTOK;
146
147 ap = brkstring (response, " ", "\n"); /* "211 nart first last ggg" */
148 xtnd_first = atoi (ap[2]);
149 xtnd_last = atoi (ap[3]);
150 }
151
152 /* nmsgs is not the real nart, but an incredible simuation */
153 if (xtnd_last > 0)
154 *nmsgs = xtnd_last - xtnd_first + 1; /* because of holes... */
155 else
156 *nmsgs = 0;
157 *nbytes = xtnd_first; /* for subtracting offset in msh() */
158
159 return OK;
160 }
161
162 int pop_exists (action)
163 int (*action) ();
164 {
165 if (traverse (action, "XMSGS %d-%d", xtnd_first, xtnd_last) == OK)
166 return OK;
167
168 return traverse (action, "XHDR NONAME %d-%d", xtnd_first, xtnd_last);
169 }
170
171
172 #ifndef BPOP
173 int pop_list (msgno, nmsgs, msgs, bytes)
174 #else BPOP
175 int pop_list (msgno, nmsgs, msgs, bytes, ids)
176 int *ids;
177 #endif BPOP
178 int msgno,
179 *nmsgs,
180 *msgs,
181 *bytes;
182 {
183 int i;
184 #ifndef BPOP
185 int *ids = NULL;
186 #endif not BPOP
187
188 if (msgno) {
189 *msgs = *bytes = 0;
190 if (command ("STAT %d", msgno) == NOTOK)
191 return NOTOK;
192
193 if (ids) {
194 *ids = msgno;
195 }
196 return OK;
197 }
198 return NOTOK;
199 }
200
201 /* \f */
202
203 /* VARARGS2 */
204
205 static int traverse (action, fmt, a, b, c, d)
206 int (*action) ();
207 char *fmt,
208 *a,
209 *b,
210 *c,
211 *d;
212 {
213 char buffer[sizeof response];
214
215 if (command (fmt, a, b, c, d) == NOTOK)
216 return NOTOK;
217 (void) strcpy (buffer, response);
218
219 for (;;)
220 switch (multiline ()) {
221 case NOTOK:
222 return NOTOK;
223
224 case DONE:
225 (void) strcpy (response, buffer);
226 return OK;
227
228 case OK:
229 (*action) (response);
230 break;
231 }
232 }
233
234 /* \f */
235
236 int pop_dele (msgno)
237 int msgno;
238 {
239 return command ("DELE %d", msgno);
240 }
241
242
243 int pop_noop () {
244 return command ("NOOP");
245 }
246
247
248 int pop_rset () {
249 return command ("RSET");
250 }
251
252 /* \f */
253
254 int pop_top (msgno, lines, action)
255 int msgno,
256 lines, /* sadly, ignored */
257 (*action) ();
258 {
259 return traverse (action, "HEAD %d", msgno);
260 }
261
262
263 int pop_retr (msgno, action)
264 int msgno,
265 (*action) ();
266 {
267 return traverse (action, "ARTICLE %d", msgno);
268 }
269
270
271 #ifdef BPOP
272
273 int pop_xtnd (action, fmt, a, b, c, d)
274 int (*action) ();
275 char *fmt, *a, *b, *c, *d;
276 {
277 extern char **brkstring();
278 char buffer[BUFSIZ], **ap;
279
280 sprintf (buffer, fmt, a, b, c, d);
281 ap = brkstring (buffer, " ", "\n"); /* a hack, i know... */
282
283 if (uleq(ap[0], "x-bboards")) { /* XTND "X-BBOARDS group */
284 /* most of these parameters are meaningless under NNTP.
285 * bbc.c was modified to set AKA and LEADERS as appropriate,
286 * the rest are left blank.
287 */
288 return OK;
289 }
290 if (uleq (ap[0], "archive") && ap[1]) {
291 sprintf (xtnd_name, "%s", ap[1]); /* save the name */
292 xtnd_last = 0;
293 xtnd_first = 1; /* setup to fail in pop_stat */
294 return OK;
295 }
296 if (uleq (ap[0], "bboards")) {
297
298 if (ap[1]) { /* XTND "BBOARDS group" */
299 sprintf (xtnd_name, "%s", ap[1]); /* save the name */
300 if (command("GROUP %s", xtnd_name) == NOTOK)
301 return NOTOK;
302
303 strcpy (buffer, response); /* action must ignore extra args */
304 ap = brkstring (response, " ", "\n");/* "211 nart first last g" */
305 xtnd_first = atoi (ap[2]);
306 xtnd_last = atoi (ap[3]);
307
308 (*action) (buffer);
309 return OK;
310
311 } else { /* XTND "BBOARDS" */
312 return traverse (action, "LIST", a, b, c, d);
313 }
314 }
315 return NOTOK; /* unknown XTND command */
316 }
317 #endif BPOP
318
319 /* \f */
320
321 int pop_quit () {
322 int i;
323
324 i = command ("QUIT");
325 (void) pop_done ();
326
327 return i;
328 }
329
330
331 int pop_done () {
332 (void) fclose (input);
333 (void) fclose (output);
334
335 return OK;
336 }
337
338 /* \f */
339
340 /* VARARGS1 */
341
342 int command (fmt, a, b, c, d)
343 char *fmt,
344 *a,
345 *b,
346 *c,
347 *d;
348 {
349 char *cp,
350 buffer[BUFSIZ];
351
352 (void) sprintf (buffer, fmt, a, b, c, d);
353 if (poprint)
354 if (pophack) {
355 if (cp = index (buffer, ' '))
356 *cp = NULL;
357 fprintf (stderr, "---> %s ********\n", buffer);
358 if (cp)
359 *cp = ' ';
360 pophack = 0;
361 }
362 else
363 fprintf (stderr, "---> %s\n", buffer);
364
365 if (putline (buffer, output) == NOTOK)
366 return NOTOK;
367
368 switch (getline (response, sizeof response, input)) {
369 case OK:
370 if (poprint)
371 fprintf (stderr, "<--- %s\n", response);
372 return (*response < CHAR_ERR ? OK : NOTOK);
373
374 case NOTOK:
375 case DONE:
376 if (poprint)
377 fprintf (stderr, "%s\n", response);
378 return NOTOK;
379 }
380 /* NOTREACHED */
381 }
382
383 int multiline () {
384 char buffer[BUFSIZ + TRMLEN];
385
386 if (getline (buffer, sizeof buffer, input) != OK)
387 return NOTOK;
388 #ifdef DEBUG
389 if (poprint)
390 fprintf (stderr, "<--- %s\n", response);
391 #endif DEBUG
392 if (strncmp (buffer, TRM, TRMLEN) == 0) {
393 if (buffer[TRMLEN] == NULL)
394 return DONE;
395 else
396 (void) strcpy (response, buffer + TRMLEN);
397 }
398 else
399 (void) strcpy (response, buffer);
400
401 return OK;
402 }
403
404 /* \f */
405
406 static int getline (s, n, iop)
407 char *s;
408 int n;
409 FILE * iop;
410 {
411 int c;
412 char *p;
413
414 p = s;
415 while (--n > 0 && (c = fgetc (iop)) != EOF)
416 if ((*p++ = c) == '\n')
417 break;
418 if (ferror (iop) && c != EOF) {
419 (void) strcpy (response, "error on connection");
420 return NOTOK;
421 }
422 if (c == EOF && p == s) {
423 (void) strcpy (response, "connection closed by foreign host");
424 return DONE;
425 }
426 *p = NULL;
427 if (*--p == '\n')
428 *p = NULL;
429 if (*--p == '\r')
430 *p = NULL;
431
432 return OK;
433 }
434
435
436 static putline (s, iop)
437 char *s;
438 FILE * iop;
439 {
440 (void) fprintf (iop, "%s\r\n", s);
441 (void) fflush (iop);
442 if (ferror (iop)) {
443 (void) strcpy (response, "lost connection");
444 return NOTOK;
445 }
446
447 return OK;
448 }