This is pop_init.c in view mode; [Download] [Up]
/* * Copyright (c) 1989 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1997 by Qualcomm Incorporated. */ #include <config.h> #include <errno.h> #include <stdio.h> #include <sys/types.h> #if HAVE_SYS_NETINET_IN_H # include <sys/netinet/in.h> #endif #if HAVE_NETINET_IN_H # include <netinet/in.h> #endif #include <netdb.h> #include <arpa/inet.h> #include <string.h> #if HAVE_SYS_PARAM_H # include <sys/param.h> #endif #if HAVE_STRINGS_H # include <strings.h> #endif #ifndef HAVE_INDEX # define index(s,c) strchr(s,c) # define rindex(s,c) strrchr(s,c) #endif #ifndef HAVE_BCOPY # define bcopy(src,dest,len) (void) (memcpy(dest, src, len)) # define bzero(dest,len) (void) (memset(dest, (char)NULL, len)) # define bcmp(b1,b2,n) memcmp(b1,b2,n) #endif #include <popper.h> /* CNS Kerberos IV */ #ifdef KERBEROS AUTH_DAT kdata; #endif extern int errno; /* #ifdef POPSCO extern struct state _res; #endif */ #ifndef HAVE_STRDUP #include <stddef.h> #include <stdlib.h> char * strdup(str) char *str; { int len; char *copy; len = strlen(str) + 1; if (!(copy = malloc((u_int)len))) return((char *)NULL); bcopy(str, copy, len); return(copy); } #endif authenticate(p, addr) POP *p; struct sockaddr_in *addr; { #ifdef KERBEROS Key_schedule schedule; KTEXT_ST ticket; char instance[INST_SZ]; char version[9]; int auth; if (p->kerberos) { strcpy(instance, "*"); auth = krb_recvauth(0L, 0, &ticket, KERBEROS_SERVICE, instance, addr, (struct sockaddr_in *) NULL, &kdata, "", schedule, version); if (auth != KSUCCESS) { pop_msg(p, POP_FAILURE, "Kerberos authentication failure: %s", krb_err_txt[auth]); pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) %s", p->client, kdata.pname, kdata.pinst, kdata.prealm, krb_err_txt[auth]); return(POP_FAILURE); } # ifdef DEBUG if (p->debug) pop_log(p, POP_DEBUG, "%s.%s@%s (%s): ok", kdata.pname, kdata.pinst, kdata.prealm, inet_ntoa(addr->sin_addr)); # endif /* DEBUG */ strncpy(p->user, kdata.pname, sizeof(p->user)); } #endif /* KERBEROS */ return(POP_SUCCESS); } /* * init: Start a Post Office Protocol session */ pop_init(p, argcount, argmessage) POP * p; int argcount; char ** argmessage; { struct sockaddr_in cs; /* Communication parameters */ struct hostent * ch; /* Client host information */ int errflag = 0; int c; int len; extern char * optarg; int options = 0; int sp = 0; /* Socket pointer */ char * trace_file_name; struct hostent * hp = NULL; /* Initialize the POP parameter block */ bzero ((char *)p,(int)sizeof(POP)); /* Initialize maildrop status variables in the POP parameter block */ p->msgs_deleted = 0; p->last_msg = 0; p->bytes_deleted = 0; p->drop_size = 0; p->mmdf_separator = NULL; p->bulldir = BULLDIR; p->dirty = 0; p->xmitting = 0; p->kerberos = 0; #ifdef SERVER_MODE p->server_mode = 1; #else p->server_mode = 0; #endif /* Save my name in a global variable */ p->myname = argmessage[0]; /* Get the name of our host */ if ((p->myhost = (char *)malloc(MAXHOSTNAMELEN+1)) == NULL) { perror("malloc"); exit(1); } (void)gethostname(p->myhost,MAXHOSTNAMELEN); if (hp = gethostbyname(p->myhost)) { if (! index(hp->h_name, '.')) { /* FQN not returned */ /* * SVR4 resolver is stupid and returns h_name as whatever * you gave gethostbyname. Thus do a reverse lookup * on the first address and hope for the best. */ u_long x = *(u_long *)hp->h_addr_list[0]; if ((hp = gethostbyaddr((char *)&x, 4, AF_INET)) != NULL) { (void) strncpy (p->myhost, hp->h_name, MAXHOSTNAMELEN); p->myhost[MAXHOSTNAMELEN] = '\0'; } } else { (void) strncpy (p->myhost, hp->h_name, MAXHOSTNAMELEN); p->myhost[MAXHOSTNAMELEN] = '\0'; } } /* Open the log file */ #ifdef SYSLOG42 (void)openlog(p->myname,0); #else (void)openlog(p->myname,POP_LOGOPTS,POP_FACILITY); #endif /* Process command line arguments */ while ((c = getopt(argcount,argmessage,"dkst:T:b:")) != EOF) switch (c) { /* Debugging requested */ case 'd': p->debug++; options |= SO_DEBUG; #ifdef DEBUG if (p->debug) pop_log(p,POP_PRIORITY,"Debugging turned on"); #endif break; #ifdef KERBEROS case 'k': p->kerberos++; break; #endif /* KERBEROS */ /* Stats requested */ case 's': p->stats++; break; /* Bulletins requested */ case 'b': p->bulldir = optarg; break; /* Debugging trace file specified */ case 't': p->debug++; #ifdef DEBUG if (p->trace) pop_log(p,POP_PRIORITY, "Tracing session and debugging information in file \"%s\"", trace_file_name); #endif if ((p->trace = fopen(optarg,"a+")) == NULL) { pop_log(p,POP_PRIORITY, "Unable to open trace file \"%s\", err = %d", optarg,errno); exit(1); } trace_file_name = optarg; break; /* Timeout value passed. Default changed */ case 'T': pop_timeout = atoi(optarg); break; /* Unknown option received */ default: errflag++; } /* Exit if bad options specified */ if (errflag) { #ifdef KERBEROS (void)fprintf(stderr,"Usage: %s [-d] [-k] [-s] [-t trace-file] [-T timeout] [-b bulldir]\n",argmessage[0]); #else (void)fprintf(stderr,"Usage: %s [-d] [-s] [-t trace-file] [-T timeout] [-b bulldir]\n",argmessage[0]); #endif exit(1); } /* Get the address and socket of the client to whom I am speaking */ len = sizeof(cs); if (getpeername(sp,(struct sockaddr *)&cs,&len) < 0){ pop_log(p,POP_PRIORITY, "Unable to obtain socket and address of client, err = %d",errno); exit(1); } /* Save the dotted decimal form of the client's IP address in the POP parameter block */ p->ipaddr = (char *)strdup(inet_ntoa(cs.sin_addr)); /* Save the client's port */ p->ipport = ntohs(cs.sin_port); /* Get the canonical name of the host to whom I am speaking */ ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr), AF_INET); if (ch == NULL){ pop_log(p,POP_PRIORITY, "(v%s) Unable to get canonical name of client, err = %d", VERSION, errno); p->client = p->ipaddr; } /* Save the cannonical name of the client host in the POP parameter block */ else { #ifndef BIND43 p->client = (char *)strdup(ch->h_name); #else # ifndef SCOR5 # include <arpa/nameser.h> # include <resolv.h> # endif /* Distrust distant nameservers */ #if !(defined(BSD) && (BSD >= 199103)) && !defined(OSF1) && !defined(HPUX10) # if (!defined(__RES)) || (__RES < 19940415) # ifdef SCOR5 extern struct __res_state _res; # else extern struct state _res; # endif # endif #endif struct hostent * ch_again; char * * addrp; char h_name[MAXHOSTNAMELEN + 1]; /* We already have a fully-qualified name */ #ifdef RES_DEFNAMES _res.options &= ~RES_DEFNAMES; #endif strncpy(h_name, ch->h_name, sizeof(h_name)); /* See if the name obtained for the client's IP address returns an address */ if ((ch_again = gethostbyname(h_name)) == NULL) { pop_log(p,POP_PRIORITY, "Client at \"%s\" resolves to an unknown host name \"%s\"", p->ipaddr, h_name); p->client = p->ipaddr; } else { /* Save the host name (the previous value was destroyed by gethostbyname) */ p->client = (char *)strdup(ch_again->h_name); /* Look for the client's IP address in the list returned for its name */ for (addrp=ch_again->h_addr_list; *addrp; ++addrp) if (bcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break; if (!*addrp) { pop_log (p,POP_PRIORITY, "Client address \"%s\" not listed for its host name \"%s\"", p->ipaddr,h_name); p->client = p->ipaddr; } } #ifdef RES_DEFNAMES /* * Must restore nameserver options since code in crypt uses * gethostbyname call without fully qualified domain name! */ _res.options |= RES_DEFNAMES; #endif #endif /* BIND43 */ } /* Create input file stream for TCP/IP communication */ if ((p->input = fdopen(sp,"r")) == NULL){ pop_log(p,POP_PRIORITY, "Unable to open communication stream for input, err = %d",errno); exit (1); } /* Create output file stream for TCP/IP communication */ if ((p->output = fdopen(sp,"w")) == NULL){ pop_log(p,POP_PRIORITY, "Unable to open communication stream for output, err = %d",errno); exit (1); } #ifdef DEBUG if (p->debug) pop_log(p,POP_PRIORITY, "(v%s) Servicing request from \"%s\" at %s", VERSION,p->client,p->ipaddr); #endif return(authenticate(p, &cs)); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.