source: trunk/athena/bin/from/popmail.c @ 13606

Revision 13606, 4.8 KB checked in by danw, 25 years ago (diff)
warnsify
Line 
1/*
2 * $Id: popmail.c,v 1.11 1999-09-21 01:40:07 danw Exp $
3 *
4 */
5
6static const char rcsid[] = "$Id: popmail.c,v 1.11 1999-09-21 01:40:07 danw Exp $";
7
8#include <stdio.h>
9#include <sys/types.h>
10#include <sys/file.h>
11#include <sys/socket.h>
12#include <errno.h>
13#include <string.h>
14#include <stdlib.h>
15#include <netinet/in.h>
16#include <netdb.h>
17#include <unistd.h>
18#include <stdarg.h>
19#ifdef HAVE_HESIOD
20#include <hesiod.h>
21#endif
22#ifdef HAVE_KRB4
23#include <krb.h>
24#endif
25
26#include "from.h"
27
28#define NOTOK (-1)
29#define OK 0
30#define DONE 1
31
32extern FILE *sfi;
33extern FILE *sfo;
34extern char Errmsg[80];
35#ifdef HAVE_KRB4
36#define KPOP_PORT 1109
37#endif
38extern int popmail_debug;
39
40int pop_init(char *host)
41{
42    register struct hostent *hp;
43    register struct servent *sp;
44    struct sockaddr_in sin;
45    register int s;
46#ifdef HAVE_KRB4
47    KTEXT ticket = (KTEXT)NULL;
48    int rem;
49    long authopts;
50    char *hostname;
51#else
52    int lport = IPPORT_RESERVED - 1;
53#endif
54
55    if (!host)
56        return(NOTOK);
57    hp = gethostbyname(host);
58    if (hp == NULL) {
59        (void) sprintf(Errmsg, "MAILHOST unknown: %s", host);
60        return(NOTOK);
61    }
62
63#ifdef HAVE_KRB4
64    sp = getservbyname("kpop", "tcp");
65    if (sp == 0)
66        sin.sin_port = htons(KPOP_PORT);
67    else
68        sin.sin_port = sp->s_port;
69#else
70    sp = getservbyname("pop", "tcp");
71    if (sp == 0) {
72        (void) strcpy(Errmsg, "tcp/pop: unknown service");
73        return(NOTOK);
74    }
75    sin.sin_port = sp->s_port;
76#endif
77
78    sin.sin_family = hp->h_addrtype;
79    memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
80#ifdef HAVE_KRB4
81    s = socket(AF_INET, SOCK_STREAM, 0);
82#else
83    s = rresvport(&lport);
84#endif
85    if (s < 0) {
86        (void) sprintf(Errmsg, "error creating socket: %s", strerror(errno));
87        return(NOTOK);
88    }
89
90    if (connect(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
91        (void) sprintf(Errmsg, "error during connect: %s", strerror(errno));
92        (void) close(s);
93        return(NOTOK);
94    }
95#ifdef HAVE_KRB4
96    ticket = (KTEXT)malloc( sizeof(KTEXT_ST) );
97    if (ticket == NULL) {
98        fprintf (stderr, "from: out of memory");
99        exit (1);
100    }
101    rem=KSUCCESS;
102    authopts = 0L;
103
104    /* We stash hp->h_name as krb_realmofhost may stomp on the
105       internal structures pointed by hp*/
106    hostname = malloc(strlen(hp->h_name)+1);
107    if (hostname == NULL) {
108        fprintf(stderr, "from: out of memory");
109        exit(1);
110    }
111    strcpy(hostname, hp->h_name);
112    rem = krb_sendauth(authopts, s, ticket, "pop", hostname,
113                       (char *) krb_realmofhost(hostname),
114                       0, (MSG_DAT *) 0, (CREDENTIALS *) 0,
115                       (bit_64 *) 0, (struct sockaddr_in *)0,
116                       (struct sockaddr_in *)0,"ZMAIL0.0");
117    free(hostname);
118    if (rem != KSUCCESS) {
119        (void) sprintf(Errmsg, "kerberos error: %s",krb_err_txt[rem]);
120        (void) close(s);
121        return(NOTOK);
122    }
123#endif
124
125    sfi = fdopen(s, "r");
126    sfo = fdopen(s, "w");
127    if (sfi == NULL || sfo == NULL) {
128        (void) sprintf(Errmsg, "error in fdopen\n");
129        (void) close(s);
130        return(NOTOK);
131    }
132
133    return(OK);
134}
135
136int pop_command(char *fmt, ...)
137{
138    char buf[4096];
139    va_list ap;
140
141    va_start(ap, fmt);
142    vsprintf(buf, fmt, ap);
143    va_end(ap);
144
145    if (popmail_debug) fprintf(stderr, "---> %s\n", buf);
146    if (putline(buf, Errmsg, sfo) == NOTOK) return(NOTOK);
147
148    if (getline(buf, sizeof buf, sfi) != OK) {
149        (void) strcpy(Errmsg, buf);
150        return(NOTOK);
151    }
152
153    if (popmail_debug) fprintf(stderr, "<--- %s\n", buf);
154    if (*buf != '+') {
155        (void) strcpy(Errmsg, buf);
156        return(NOTOK);
157    } else {
158        return(OK);
159    }
160}
161
162   
163int pop_stat(int *nmsgs, int *nbytes)
164{
165    char buf[4096];
166
167    if (popmail_debug) fprintf(stderr, "---> STAT\n");
168    if (putline("STAT", Errmsg, sfo) == NOTOK) return(NOTOK);
169
170    if (getline(buf, sizeof buf, sfi) != OK) {
171        (void) strcpy(Errmsg, buf);
172        return(NOTOK);
173    }
174
175    if (popmail_debug) fprintf(stderr, "<--- %s\n", buf);
176    if (*buf != '+') {
177        (void) strcpy(Errmsg, buf);
178        return(NOTOK);
179    } else {
180        (void) sscanf(buf, "+OK %d %d", nmsgs, nbytes);
181        return(OK);
182    }
183}
184
185
186int putline(char *buf, char *err, FILE *f)
187{
188    fprintf(f, "%s\r\n", buf);
189    (void) fflush(f);
190    if (ferror(f)) {
191        (void) strcpy(err, "lost connection");
192        return(NOTOK);
193    }
194    return(OK);
195}
196
197int getline(char *buf, int n, FILE *f)
198{
199    register char *p;
200    int c;
201
202    p = buf;
203    while (--n > 0 && (c = fgetc(f)) != EOF)
204      if ((*p++ = c) == '\n') break;
205
206    if (ferror(f)) {
207        (void) strcpy(buf, "error on connection");
208        return (NOTOK);
209    }
210
211    if (c == EOF && p == buf) {
212        (void) strcpy(buf, "connection closed by foreign host");
213        return (DONE);
214    }
215
216    *p = '\0';
217    if (*--p == '\n') *p = '\0';
218    if (*--p == '\r') *p = '\0';
219    return(OK);
220}
221
222int multiline(char *buf, int n, FILE *f)
223{
224    if (getline(buf, n, f) != OK) return (NOTOK);
225    if (*buf == '.') {
226        if (*(buf+1) == '\0') {
227            return (DONE);
228        } else {
229            (void) strcpy(buf, buf+1);
230        }
231    }
232    return(OK);
233}
Note: See TracBrowser for help on using the repository browser.