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