version 1.6, 1996/10/18 17:17:09 |
version 1.7, 1997/04/12 19:54:50 |
|
|
|
|
#define START_PORT 5120 /* arbitrary */ |
#define START_PORT 5120 /* arbitrary */ |
|
|
|
int getport __P((int *)); |
|
|
int |
int |
kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm, |
kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm, |
cred, schedule, msg_data, laddr, faddr, authopts) |
cred, schedule, msg_data, laddr, faddr, authopts) |
|
|
long oldmask; |
long oldmask; |
struct sockaddr_in sin, from; |
struct sockaddr_in sin, from; |
char c; |
char c; |
#ifdef ATHENA_COMPAT |
|
int lport = IPPORT_RESERVED - 1; |
int lport = IPPORT_RESERVED - 1; |
#else |
|
int lport = START_PORT; |
|
#endif |
|
struct hostent *hp; |
struct hostent *hp; |
int rc; |
int rc; |
char *host_save; |
char *host_save; |
|
|
|
|
oldmask = sigblock(sigmask(SIGURG)); |
oldmask = sigblock(sigmask(SIGURG)); |
for (;;) { |
for (;;) { |
s = rresvport(&lport); |
s = getport(&lport); |
if (s < 0) { |
if (s < 0) { |
if (errno == EAGAIN) |
if (errno == EAGAIN) |
fprintf(stderr, |
fprintf(stderr, |
|
|
lport = 0; |
lport = 0; |
} else { |
} else { |
char num[8]; |
char num[8]; |
int s2 = rresvport(&lport), s3; |
int s2 = getport(&lport), s3; |
int len = sizeof(from); |
int len = sizeof(from); |
|
|
if (s2 < 0) { |
if (s2 < 0) { |
|
|
(void) close(s); |
(void) close(s); |
sigsetmask(oldmask); |
sigsetmask(oldmask); |
return (status); |
return (status); |
|
} |
|
|
|
int |
|
getport(alport) |
|
int *alport; |
|
{ |
|
struct sockaddr_in sin; |
|
int s; |
|
|
|
/* First try to get a "reserved" [sic] port, for interoperability with |
|
broken klogind (aix, e.g.) */ |
|
|
|
s = rresvport(alport); |
|
if (s >= 0) |
|
return s; |
|
|
|
/* Failed; if EACCES, we're not root, so just get an unreserved port |
|
and hope that's good enough */ |
|
|
|
if (errno != EACCES) |
|
return -1; |
|
|
|
if (*alport < IPPORT_RESERVED) |
|
*alport = START_PORT; |
|
sin.sin_family = AF_INET; |
|
sin.sin_addr.s_addr = INADDR_ANY; |
|
s = socket(AF_INET, SOCK_STREAM, 0); |
|
if (s < 0) |
|
return (-1); |
|
for (;;) { |
|
sin.sin_port = htons((u_short)*alport); |
|
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) |
|
return (s); |
|
if (errno != EADDRINUSE) { |
|
(void) close(s); |
|
return (-1); |
|
} |
|
(*alport)--; |
|
if (*alport == IPPORT_RESERVED) { |
|
(void) close(s); |
|
errno = EAGAIN; /* close */ |
|
return (-1); |
|
} |
|
} |
} |
} |