1: /* popsbr.c - POP client subroutines */
   2: 
   3: /* LINTLIBRARY */
   4: 
   5: #include "../h/strings.h"
   6: #include <stdio.h>
   7: #include <signal.h>
   8: 
   9: 
  10: #define NOTOK   (-1)
  11: #define OK  0
  12: #define DONE    1
  13: 
  14: #define TRM "."
  15: #define TRMLEN  (sizeof TRM - 1)
  16: 
  17: extern int  errno;
  18: extern int  sys_nerr;
  19: extern char *sys_errlist[];
  20: 
  21: static int  poprint = 0;
  22: static int  pophack = 0;
  23: 
  24: char    response[BUFSIZ];
  25: 
  26: static FILE *input;
  27: static FILE *output;
  28: 
  29: /*  */
  30: 
  31: #ifndef RPOP
  32: int     pop_init (host, user, pass, snoop)
  33: #else   RPOP
  34: int     pop_init (host, user, pass, snoop, rpop)
  35: int     rpop;
  36: #endif	RPOP
  37: char   *host,
  38:        *user,
  39:        *pass;
  40: int snoop;
  41: {
  42:     int     fd1,
  43:             fd2;
  44: #ifndef RPOP
  45:     int     rpop = 0;
  46: #endif	RPOP
  47:     char    buffer[BUFSIZ];
  48: 
  49:     if ((fd1 = client (host, "tcp", "pop", rpop, response)) == NOTOK)
  50:     return NOTOK;
  51: 
  52:     if ((fd2 = dup (fd1)) == NOTOK) {
  53:     (void) sprintf (response, "unable to dup connection descriptor: %s",
  54:         errno > 0 && errno < sys_nerr ? sys_errlist[errno]
  55:         : "unknown error");
  56:     (void) close (fd1);
  57:     return NOTOK;
  58:     }
  59:     if (pop_set (fd1, fd2, snoop) == NOTOK)
  60:     return NOTOK;
  61: 
  62:     (void) signal (SIGPIPE, SIG_IGN);
  63: 
  64:     switch (getline (response, sizeof response, input)) {
  65:     case OK:
  66:         if (poprint)
  67:         fprintf (stderr, "<--- %s\n", response);
  68:         if (*response == '+'
  69:             && command ("USER %s", user) != NOTOK
  70:             && command ("%s %s", rpop ? "RPOP" : (pophack++, "PASS"),
  71:                     pass) != NOTOK)
  72:         return OK;
  73:         if (*response != '+') {
  74:         (void) strcpy (buffer, response);
  75:         (void) command ("QUIT");
  76:         (void) strcpy (response, buffer);
  77:         }           /* fall */
  78: 
  79:     case NOTOK:
  80:     case DONE:
  81:         if (poprint)
  82:         fprintf (stderr, "%s\n", response);
  83:         (void) fclose (input);
  84:         (void) fclose (output);
  85:         return NOTOK;
  86:     }
  87: /* NOTREACHED */
  88: }
  89: 
  90: /*  */
  91: 
  92: int pop_set (in, out, snoop)
  93: int in,
  94:     out,
  95:     snoop;
  96: {
  97:     if ((input = fdopen (in, "r")) == NULL
  98:         || (output = fdopen (out, "w")) == NULL) {
  99:     (void) strcpy (response, "fdopen failed on connection descriptor");
 100:     if (input)
 101:         (void) fclose (input);
 102:     else
 103:         (void) close (in);
 104:     (void) close (out);
 105:     return NOTOK;
 106:     }
 107: 
 108:     poprint = snoop;
 109: 
 110:     return OK;
 111: }
 112: 
 113: 
 114: int pop_fd (in, out)
 115: char   *in,
 116:        *out;
 117: {
 118:     (void) sprintf (in, "%d", fileno (input));
 119:     (void) sprintf (out, "%d", fileno (output));
 120:     return OK;
 121: }
 122: 
 123: /*  */
 124: 
 125: int     pop_stat (nmsgs, nbytes)
 126: int    *nmsgs,
 127:        *nbytes;
 128: {
 129:     if (command ("STAT") == NOTOK)
 130:     return NOTOK;
 131: 
 132:     *nmsgs = *nbytes = 0;
 133:     (void) sscanf (response, "+OK %d %d", nmsgs, nbytes);
 134:     return OK;
 135: }
 136: 
 137: 
 138: #ifndef BPOP
 139: int     pop_list (msgno, nmsgs, msgs, bytes)
 140: #else   BPOP
 141: int     pop_list (msgno, nmsgs, msgs, bytes, ids)
 142: int    *ids;
 143: #endif	BPOP
 144: int     msgno,
 145:        *nmsgs,
 146:        *msgs,
 147:        *bytes;
 148: {
 149:     int     i;
 150: #ifndef BPOP
 151:     int    *ids = NULL;
 152: #endif	not BPOP
 153: 
 154:     if (msgno) {
 155:     if (command ("LIST %d", msgno) == NOTOK)
 156:         return NOTOK;
 157: 
 158:     *msgs = *bytes = 0;
 159:     if (ids) {
 160:         *ids = 0;
 161:         (void) sscanf (response, "+OK %d %d %d", msgs, bytes, ids);
 162:     }
 163:     else
 164:         (void) sscanf (response, "+OK %d %d", msgs, bytes);
 165:     return OK;
 166:     }
 167: 
 168:     if (command ("LIST") == NOTOK)
 169:     return NOTOK;
 170: 
 171:     for (i = 0; i < *nmsgs; i++)
 172:     switch (multiline ()) {
 173:         case NOTOK:
 174:         return NOTOK;
 175:         case DONE:
 176:         *nmsgs = ++i;
 177:         return OK;
 178:         case OK:
 179:         *msgs = *bytes = 0;
 180:         if (ids) {
 181:             *ids = 0;
 182:             (void) sscanf (response, "%d %d %d",
 183:                 msgs++, bytes++, ids++);
 184:         }
 185:         else
 186:             (void) sscanf (response, "%d %d", msgs++, bytes++);
 187:         break;
 188:     }
 189:     for (;;)
 190:     switch (multiline ()) {
 191:         case NOTOK:
 192:         return NOTOK;
 193:         case DONE:
 194:         return OK;
 195:         case OK:
 196:         break;
 197:     }
 198: }
 199: 
 200: /*  */
 201: 
 202: int     pop_retr (msgno, action)
 203: int     msgno,
 204:         (*action) ();
 205: {
 206:     return traverse (action, "RETR %d", msgno);
 207: }
 208: 
 209: 
 210: /* VARARGS2 */
 211: 
 212: static int  traverse (action, fmt, a, b, c, d)
 213: int     (*action) ();
 214: char   *fmt,
 215:        *a,
 216:        *b,
 217:        *c,
 218:        *d;
 219: {
 220:     char    buffer[sizeof response];
 221: 
 222:     if (command (fmt, a, b, c, d) == NOTOK)
 223:     return NOTOK;
 224:     (void) strcpy (buffer, response);
 225: 
 226:     for (;;)
 227:     switch (multiline ()) {
 228:         case NOTOK:
 229:         return NOTOK;
 230: 
 231:         case DONE:
 232:         (void) strcpy (response, buffer);
 233:         return OK;
 234: 
 235:         case OK:
 236:         (*action) (response);
 237:         break;
 238:     }
 239: }
 240: 
 241: /*  */
 242: 
 243: int     pop_dele (msgno)
 244: int     msgno;
 245: {
 246:     return command ("DELE %d", msgno);
 247: }
 248: 
 249: 
 250: int     pop_noop () {
 251:     return command ("NOOP");
 252: }
 253: 
 254: 
 255: int     pop_rset () {
 256:     return command ("RSET");
 257: }
 258: 
 259: /*  */
 260: 
 261: int     pop_top (msgno, lines, action)
 262: int     msgno,
 263:     lines,
 264:         (*action) ();
 265: {
 266:     return traverse (action, "TOP %d %d", msgno, lines);
 267: }
 268: 
 269: 
 270: #ifdef  BPOP
 271: int pop_xtnd (action, fmt, a, b, c, d)
 272: int     (*action) ();
 273: char   *fmt,
 274:        *a,
 275:        *b,
 276:        *c,
 277:        *d;
 278: {
 279:     char buffer[BUFSIZ];
 280: 
 281:     (void) sprintf (buffer, "XTND %s", fmt);
 282:     return traverse (action, buffer, a, b, c, d);
 283: }
 284: #endif	BPOP
 285: 
 286: /*  */
 287: 
 288: int     pop_quit () {
 289:     int     i;
 290: 
 291:     i = command ("QUIT");
 292:     (void) pop_done ();
 293: 
 294:     return i;
 295: }
 296: 
 297: 
 298: int     pop_done () {
 299:     (void) fclose (input);
 300:     (void) fclose (output);
 301: 
 302:     return OK;
 303: }
 304: 
 305: /*  */
 306: 
 307: /* VARARGS1 */
 308: 
 309: static int  command (fmt, a, b, c, d)
 310: char   *fmt,
 311:        *a,
 312:        *b,
 313:        *c,
 314:        *d;
 315: {
 316:     char   *cp,
 317:         buffer[BUFSIZ];
 318: 
 319:     (void) sprintf (buffer, fmt, a, b, c, d);
 320:     if (poprint)
 321:     if (pophack) {
 322:         if (cp = index (buffer, ' '))
 323:         *cp = NULL;
 324:         fprintf (stderr, "---> %s ********\n", buffer);
 325:         if (cp)
 326:         *cp = ' ';
 327:         pophack = 0;
 328:     }
 329:     else
 330:         fprintf (stderr, "---> %s\n", buffer);
 331: 
 332:     if (putline (buffer, output) == NOTOK)
 333:     return NOTOK;
 334: 
 335:     switch (getline (response, sizeof response, input)) {
 336:     case OK:
 337:         if (poprint)
 338:         fprintf (stderr, "<--- %s\n", response);
 339:         return (*response == '+' ? OK : NOTOK);
 340: 
 341:     case NOTOK:
 342:     case DONE:
 343:         if (poprint)
 344:         fprintf (stderr, "%s\n", response);
 345:         return NOTOK;
 346:     }
 347: /* NOTREACHED */
 348: }
 349: 
 350: static int  multiline () {
 351:     char    buffer[BUFSIZ + TRMLEN];
 352: 
 353:     if (getline (buffer, sizeof buffer, input) != OK)
 354:     return NOTOK;
 355:     if (strncmp (buffer, TRM, TRMLEN) == 0) {
 356:     if (buffer[TRMLEN] == NULL)
 357:         return DONE;
 358:     else
 359:         (void) strcpy (response, buffer + TRMLEN);
 360:     }
 361:     else
 362:     (void) strcpy (response, buffer);
 363: 
 364:     return OK;
 365: }
 366: 
 367: /*  */
 368: 
 369: static int  getline (s, n, iop)
 370: char   *s;
 371: int     n;
 372: FILE * iop;
 373: {
 374:     int     c;
 375:     char   *p;
 376: 
 377:     p = s;
 378:     while (--n > 0 && (c = fgetc (iop)) != EOF)
 379:     if ((*p++ = c) == '\n')
 380:         break;
 381:     if (ferror (iop)) {
 382:     (void) strcpy (response, "error on connection");
 383:     return NOTOK;
 384:     }
 385:     if (c == EOF && p == s) {
 386:     (void) strcpy (response, "connection closed by foreign host");
 387:     return DONE;
 388:     }
 389:     *p = NULL;
 390:     if (*--p == '\n')
 391:     *p = NULL;
 392:     if (*--p == '\r')
 393:     *p = NULL;
 394: 
 395:     return OK;
 396: }
 397: 
 398: 
 399: static  putline (s, iop)
 400: char   *s;
 401: FILE * iop;
 402: {
 403:     (void) fprintf (iop, "%s\r\n", s);
 404:     (void) fflush (iop);
 405:     if (ferror (iop)) {
 406:     (void) strcpy (response, "lost connection");
 407:     return NOTOK;
 408:     }
 409: 
 410:     return OK;
 411: }

Defined functions

command defined in line 309; used 11 times
getline defined in line 369; used 3 times
multiline defined in line 350; used 3 times
pop_dele defined in line 243; used 1 times
pop_done defined in line 298; used 2 times
pop_fd defined in line 114; used 1 times
pop_list defined in line 139; used 1 times
pop_noop defined in line 250; never used
pop_retr defined in line 202; used 3 times
pop_rset defined in line 255; never used
pop_set defined in line 92; used 2 times
pop_top defined in line 261; used 1 times
pop_xtnd defined in line 271; used 4 times
putline defined in line 399; used 1 times
traverse defined in line 212; used 3 times

Defined variables

pophack defined in line 22; used 3 times
poprint defined in line 21; used 6 times
response defined in line 24; used 47 times

Defined macros

DONE defined in line 12; used 2 times
NOTOK defined in line 10; used 28 times
OK defined in line 11; used 14 times
TRM defined in line 14; used 2 times
TRMLEN defined in line 15; used 4 times
Last modified: 1986-01-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1422
Valid CSS Valid XHTML 1.0 Strict