Annotation of 43BSD/contrib/mh/uip/popsbr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.