Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / pshsbr.c,v
1 head    2.4;
2 access;
3 symbols;
4 locks
5         shettich:2.4; strict;
6 comment @ * @;
7
8
9 2.4
10 date    93.08.25.17.27.12;      author jromine; state Exp;
11 branches;
12 next    2.3;
13
14 2.3
15 date    92.02.05.06.05.20;      author jromine; state Exp;
16 branches;
17 next    2.2;
18
19 2.2
20 date    90.04.05.14.56.13;      author sources; state Exp;
21 branches;
22 next    2.1;
23
24 2.1
25 date    90.02.06.13.25.40;      author sources; state Exp;
26 branches;
27 next    2.0;
28
29 2.0
30 date    89.11.17.16.02.24;      author sources; state Exp;
31 branches;
32 next    1.3;
33
34 1.3
35 date    89.09.22.13.50.45;      author sources; state Exp;
36 branches;
37 next    1.2;
38
39 1.2
40 date    89.09.22.13.48.44;      author sources; state Exp;
41 branches;
42 next    1.1;
43
44 1.1
45 date    89.05.05.14.42.00;      author sources; state Exp;
46 branches;
47 next    ;
48
49
50 desc
51 @new popsbr to use NNTP
52 @
53
54
55 2.4
56 log
57 @off_t fixes for BSD44
58 @
59 text
60 @/* pshsbr.c - NNTP client subroutines */
61 #ifndef lint
62 static char ident[] = "@@(#)$Id: pshsbr.c,v 2.3 1992/02/05 06:05:20 jromine Exp jromine $";
63 #endif  lint
64
65 /* LINTLIBRARY */
66
67 #include "../h/strings.h"
68 #include "../h/nntp.h"
69 #include <stdio.h>
70 #include <signal.h>
71
72
73 #define NOTOK   (-1)
74 #define OK      0
75 #define DONE    1
76
77 #define TRM     "."
78 #define TRMLEN  (sizeof TRM - 1)
79
80 extern int  errno;
81 #ifndef BSD44
82 extern int  sys_nerr;
83 extern char *sys_errlist[];
84 #endif
85
86 static int  poprint = 0;
87 static int  pophack = 0;
88
89 char    response[BUFSIZ];
90
91 static FILE *input;
92 static FILE *output;
93
94 #ifdef  BPOP    /* stupid */
95 static  int     xtnd_last = -1,
96                 xtnd_first = 0;
97 static char     xtnd_name[512]; /* INCREDIBLE HACK!! */
98 #endif
99
100 #define command pop_command
101 #define multiline pop_multiline
102
103 static int    traverse(), getline();
104 static                putline();
105 /* \f */
106
107 #ifndef RPOP
108 int     pop_init (host, user, pass, snoop)
109 #else   RPOP
110 int     pop_init (host, user, pass, snoop, rpop)
111 int     rpop;
112 #endif  RPOP
113 char   *host,
114        *user,
115        *pass;
116 int     snoop;
117 {
118     int     fd1,
119             fd2;
120 #ifndef RPOP
121     int     rpop = 0;
122 #endif  RPOP
123     char    buffer[BUFSIZ];
124
125     if ((fd1 = client (host, "tcp", "nntp", rpop, response)) == NOTOK)
126         return NOTOK;
127
128     if ((fd2 = dup (fd1)) == NOTOK) {
129         (void) sprintf (response, "unable to dup connection descriptor: %s",
130                 errno > 0 && errno < sys_nerr ? sys_errlist[errno]
131                 : "unknown error");
132         (void) close (fd1);
133         return NOTOK;
134     }
135     if (pop_set (fd1, fd2, snoop, (char *)0) == NOTOK)
136         return NOTOK;
137
138     (void) signal (SIGPIPE, SIG_IGN);
139
140     switch (getline (response, sizeof response, input)) {
141         case OK: 
142             if (poprint)
143                 fprintf (stderr, "<--- %s\n", response);
144             if (*response < CHAR_ERR)
145                 return OK;
146             else {
147                 (void) strcpy (buffer, response);
148                 (void) command ("QUIT");
149                 (void) strcpy (response, buffer);
150             }                   /* fall */
151
152         case NOTOK: 
153         case DONE: 
154             if (poprint)            
155                 fprintf (stderr, "%s\n", response);
156             (void) fclose (input);
157             (void) fclose (output);
158             return NOTOK;
159     }
160 /* NOTREACHED */
161 }
162
163 /* \f */
164
165 int     pop_set (in, out, snoop, myname)
166 int     in,
167         out,
168         snoop;
169 char   *myname;
170 {
171     if (myname && *myname)
172         strcpy (xtnd_name, myname);     /* interface from bbc to msh */
173
174     if ((input = fdopen (in, "r")) == NULL
175             || (output = fdopen (out, "w")) == NULL) {
176         (void) strcpy (response, "fdopen failed on connection descriptor");
177         if (input)
178             (void) fclose (input);
179         else
180             (void) close (in);
181         (void) close (out);
182         return NOTOK;
183     }
184
185     poprint = snoop;
186
187     return OK;
188 }
189
190
191 int     pop_fd (in, out)
192 char   *in,
193        *out;
194 {
195     (void) sprintf (in, "%d", fileno (input));
196     (void) sprintf (out, "%d", fileno (output));
197     return OK;
198 }
199
200 /* \f */
201
202 int     pop_stat (nmsgs, nbytes)
203 int    *nmsgs,
204        *nbytes;
205 {
206     char **ap;
207     extern char **brkstring();
208
209     if (xtnd_last < 0) {        /* in msh, xtnd_name is set from myname */
210         if (command("GROUP %s", xtnd_name) == NOTOK)
211             return NOTOK;
212
213         ap = brkstring (response, " ", "\n"); /* "211 nart first last ggg" */
214         xtnd_first = atoi (ap[2]);
215         xtnd_last  = atoi (ap[3]);
216     }
217
218     /* nmsgs is not the real nart, but an incredible simuation */
219     if (xtnd_last > 0)
220         *nmsgs = xtnd_last - xtnd_first + 1;    /* because of holes... */
221     else
222         *nmsgs = 0;
223     *nbytes = xtnd_first;       /* for subtracting offset in msh() */
224
225     return OK;
226 }
227
228 int     pop_exists (action)
229 int     (*action) ();
230 {
231     if (traverse (action, "XMSGS %d-%d", xtnd_first, xtnd_last) == OK)
232         return OK;
233
234     return traverse (action, "XHDR NONAME %d-%d", xtnd_first, xtnd_last);
235 }
236
237
238 #ifndef BPOP
239 int     pop_list (msgno, nmsgs, msgs, bytes)
240 #else   BPOP
241 int     pop_list (msgno, nmsgs, msgs, bytes, ids)
242 int    *ids;
243 #endif  BPOP
244 int     msgno,
245        *nmsgs,
246        *msgs,
247        *bytes;
248 {
249     int     i;
250 #ifndef BPOP
251     int    *ids = NULL;
252 #endif  not BPOP
253
254     if (msgno) {
255         *msgs = *bytes = 0;
256         if (command ("STAT %d", msgno) == NOTOK) 
257             return NOTOK;
258
259         if (ids) {
260             *ids = msgno;
261         }
262         return OK;
263     }
264     return NOTOK;
265 }
266
267 /* \f */
268
269 /* VARARGS2 */
270
271 static int  traverse (action, fmt, a, b, c, d)
272 int     (*action) ();
273 char   *fmt,
274        *a,
275        *b,
276        *c,
277        *d;
278 {
279     char    buffer[sizeof response];
280
281     if (command (fmt, a, b, c, d) == NOTOK)
282         return NOTOK;
283     (void) strcpy (buffer, response);
284
285     for (;;)
286         switch (multiline ()) {
287             case NOTOK: 
288                 return NOTOK;
289
290             case DONE: 
291                 (void) strcpy (response, buffer);
292                 return OK;
293
294             case OK: 
295                 (*action) (response);
296                 break;
297         }
298 }
299
300 /* \f */
301
302 int     pop_dele (msgno)
303 int     msgno;
304 {
305     return command ("DELE %d", msgno);
306 }
307
308
309 int     pop_noop () {
310     return command ("NOOP");
311 }
312
313
314 int     pop_rset () {
315     return command ("RSET");
316 }
317
318 /* \f */
319
320 int     pop_top (msgno, lines, action)
321 int     msgno,
322         lines,          /* sadly, ignored */
323         (*action) ();
324 {
325     return traverse (action, "HEAD %d", msgno);
326 }
327
328
329 int     pop_retr (msgno, action)
330 int     msgno,
331         (*action) ();
332 {
333     return traverse (action, "ARTICLE %d", msgno);
334 }
335
336
337 #ifdef  BPOP
338
339 int     pop_xtnd (action, fmt, a, b, c, d)
340 int     (*action) ();
341 char   *fmt, *a, *b, *c, *d;
342 {
343     extern char **brkstring();
344     char  buffer[BUFSIZ], **ap;
345
346     sprintf (buffer, fmt, a, b, c, d);
347     ap = brkstring (buffer, " ", "\n"); /* a hack, i know... */
348
349     if (uleq(ap[0], "x-bboards")) {     /* XTND "X-BBOARDS group */
350         /* most of these parameters are meaningless under NNTP. 
351          * bbc.c was modified to set AKA and LEADERS as appropriate,
352          * the rest are left blank.
353          */
354         return OK;
355     }
356     if (uleq (ap[0], "archive") && ap[1]) {
357         sprintf (xtnd_name, "%s", ap[1]);               /* save the name */
358         xtnd_last = 0;
359         xtnd_first = 1;         /* setup to fail in pop_stat */
360         return OK;
361     }
362     if (uleq (ap[0], "bboards")) {
363
364         if (ap[1]) {                    /* XTND "BBOARDS group" */
365             sprintf (xtnd_name, "%s", ap[1]);           /* save the name */
366             if (command("GROUP %s", xtnd_name) == NOTOK)
367                 return NOTOK;
368
369             strcpy (buffer, response);  /* action must ignore extra args */
370             ap = brkstring (response, " ", "\n");/* "211 nart first last g" */
371             xtnd_first = atoi (ap[2]);
372             xtnd_last  = atoi (ap[3]);
373
374             (*action) (buffer);         
375             return OK;
376
377         } else {                /* XTND "BBOARDS" */
378             return traverse (action, "LIST", a, b, c, d);
379         }
380     }
381     return NOTOK;       /* unknown XTND command */
382 }
383 #endif  BPOP
384
385 /* \f */
386
387 int     pop_quit () {
388     int     i;
389
390     i = command ("QUIT");
391     (void) pop_done ();
392
393     return i;
394 }
395
396
397 int     pop_done () {
398     (void) fclose (input);
399     (void) fclose (output);
400
401     return OK;
402 }
403
404 /* \f */
405
406 /* VARARGS1 */
407
408 int  command (fmt, a, b, c, d)
409 char   *fmt,
410        *a,
411        *b,
412        *c,
413        *d;
414 {
415     char   *cp,
416             buffer[BUFSIZ];
417
418     (void) sprintf (buffer, fmt, a, b, c, d);
419     if (poprint)
420         if (pophack) {
421             if (cp = index (buffer, ' '))
422                 *cp = NULL;
423             fprintf (stderr, "---> %s ********\n", buffer);
424             if (cp)
425                 *cp = ' ';
426             pophack = 0;
427         }
428         else
429             fprintf (stderr, "---> %s\n", buffer);
430
431     if (putline (buffer, output) == NOTOK)
432         return NOTOK;
433
434     switch (getline (response, sizeof response, input)) {
435         case OK: 
436             if (poprint)
437                 fprintf (stderr, "<--- %s\n", response);
438             return (*response < CHAR_ERR ? OK : NOTOK);
439
440         case NOTOK: 
441         case DONE: 
442             if (poprint)            
443                 fprintf (stderr, "%s\n", response);
444             return NOTOK;
445     }
446 /* NOTREACHED */
447 }
448
449 int  multiline () {
450     char    buffer[BUFSIZ + TRMLEN];
451
452     if (getline (buffer, sizeof buffer, input) != OK)
453         return NOTOK;
454 #ifdef  DEBUG
455     if (poprint)
456         fprintf (stderr, "<--- %s\n", response);
457 #endif  DEBUG
458     if (strncmp (buffer, TRM, TRMLEN) == 0) {
459         if (buffer[TRMLEN] == NULL)
460             return DONE;
461         else
462             (void) strcpy (response, buffer + TRMLEN);
463     }
464     else
465         (void) strcpy (response, buffer);
466
467     return OK;
468 }
469
470 /* \f */
471
472 static int  getline (s, n, iop)
473 char   *s;
474 int     n;
475 FILE * iop;
476 {
477     int     c;
478     char   *p;
479
480     p = s;
481     while (--n > 0 && (c = fgetc (iop)) != EOF)
482         if ((*p++ = c) == '\n')
483             break;
484     if (ferror (iop) && c != EOF) {
485         (void) strcpy (response, "error on connection");
486         return NOTOK;
487     }
488     if (c == EOF && p == s) {
489         (void) strcpy (response, "connection closed by foreign host");
490         return DONE;
491     }
492     *p = NULL;
493     if (*--p == '\n')
494         *p = NULL;
495     if (*--p == '\r')
496         *p = NULL;
497
498     return OK;
499 }
500
501
502 static  putline (s, iop)
503 char   *s;
504 FILE * iop;
505 {
506     (void) fprintf (iop, "%s\r\n", s);
507     (void) fflush (iop);
508     if (ferror (iop)) {
509         (void) strcpy (response, "lost connection");
510         return NOTOK;
511     }
512
513     return OK;
514 }
515 @
516
517
518 2.3
519 log
520 @changes for marshall's popi/mshcmds stuff
521 @
522 text
523 @d3 1
524 a3 1
525 static char ident[] = "@@(#)$Id: pshsbr.c,v 2.2 1990/04/05 14:56:13 sources Exp jromine $";
526 d22 1
527 d25 1
528 @
529
530
531 2.2
532 log
533 @add ID
534 @
535 text
536 @d3 1
537 a3 1
538 static char ident[] = "@@(#)$Id:$";
539 d39 4
540 a42 1
541 static int    traverse(), command(), multiline(), getline();
542 d347 1
543 a347 1
544 static int  command (fmt, a, b, c, d)
545 d388 1
546 a388 1
547 static int  multiline () {
548 @
549
550
551 2.1
552 log
553 @ANSI Compilance
554 @
555 text
556 @d2 3
557 @
558
559
560 2.0
561 log
562 @changes for SUN40 shared libraries and NNTP under bbc
563 @
564 text
565 @d36 2
566 @
567
568
569 1.3
570 log
571 @fix minor nntp bug
572 @
573 text
574 @@
575
576
577 1.2
578 log
579 @*** empty log message ***
580 @
581 text
582 @d150 4
583 a153 1
584     *nmsgs = xtnd_last - xtnd_first + 1;        /* because of holes... */
585 @
586
587
588 1.1
589 log
590 @Initial revision
591 @
592 text
593 @d1 1
594 a1 1
595 /* popsbr.c - POP client subroutines */
596 d6 1
597 d30 6
598 d56 1
599 a56 1
600     if ((fd1 = client (host, "tcp", "pop", rpop, response)) == NOTOK)
601 d66 1
602 a66 1
603     if (pop_set (fd1, fd2, snoop) == NOTOK)
604 d75 1
605 a75 4
606             if (*response == '+'
607                     && command ("USER %s", user) != NOTOK
608                     && command ("%s %s", rpop ? "RPOP" : (pophack++, "PASS"),
609                                         pass) != NOTOK)
610 d77 1
611 a77 1
612             if (*response != '+') {
613 d96 1
614 a96 1
615 int     pop_set (in, out, snoop)
616 d100 1
617 d102 3
618 d137 2
619 a138 2
620     if (command ("STAT") == NOTOK)
621         return NOTOK;
622 d140 13
623 a152 2
624     *nmsgs = *nbytes = 0;
625     (void) sscanf (response, "+OK %d %d", nmsgs, nbytes);
626 d156 5
627 d162 4
628 d183 2
629 a184 1
630         if (command ("LIST %d", msgno) == NOTOK)
631 a186 1
632         *msgs = *bytes = 0;
633 d188 1
634 a188 2
635             *ids = 0;
636             (void) sscanf (response, "+OK %d %d %d", msgs, bytes, ids);
637 a189 2
638         else
639             (void) sscanf (response, "+OK %d %d", msgs, bytes);
640 d192 1
641 a192 31
642
643     if (command ("LIST") == NOTOK)
644         return NOTOK;
645
646     for (i = 0; i < *nmsgs; i++)
647         switch (multiline ()) {
648             case NOTOK: 
649                 return NOTOK;
650             case DONE: 
651                 *nmsgs = ++i;
652                 return OK;
653             case OK: 
654                 *msgs = *bytes = 0;
655                 if (ids) {
656                     *ids = 0;
657                     (void) sscanf (response, "%d %d %d",
658                             msgs++, bytes++, ids++);
659                 }
660                 else
661                     (void) sscanf (response, "%d %d", msgs++, bytes++);
662                 break;
663         }
664     for (;;)
665         switch (multiline ()) {
666             case NOTOK: 
667                 return NOTOK;
668             case DONE: 
669                 return OK;
670             case OK: 
671                 break;
672         }
673 a196 8
674 int     pop_retr (msgno, action)
675 int     msgno,
676         (*action) ();
677 {
678     return traverse (action, "RETR %d", msgno);
679 }
680
681
682 d250 1
683 a250 1
684         lines,
685 d253 1
686 a253 1
687     return traverse (action, "TOP %d %d", msgno, lines);
688 d257 8
689 d266 1
690 d269 1
691 a269 5
692 char   *fmt,
693        *a,
694        *b,
695        *c,
696        *d;
697 d271 2
698 a272 1
699     char buffer[BUFSIZ];
700 d274 36
701 a309 2
702     (void) sprintf (buffer, "XTND %s", fmt);
703     return traverse (action, buffer, a, b, c, d);
704 d366 1
705 a366 1
706             return (*response == '+' ? OK : NOTOK);
707 d382 4
708 @