|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.