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

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