1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZInitialize function.
4 * Created by: Robert French
7 * $Author: warmenhoven $
9 * Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
16 static char rcsid_ZInitialize_c
[] =
17 "$Zephyr: /afs/athena.mit.edu/astaff/project/zephyr/src/lib/RCS/ZInitialize.c,v 1.17 89/05/30 18:11:25 jtkohl Exp $";
22 #include <sys/socket.h>
23 #ifdef ZEPHYR_USES_KERBEROS
28 #define INADDR_NONE 0xffffffff
33 struct servent
*hmserv
;
34 struct hostent
*hostent
;
35 char addr
[4], hostname
[MAXHOSTNAMELEN
];
36 struct in_addr servaddr
;
37 struct sockaddr_in sin
;
38 int s
, sinsize
= sizeof(sin
);
41 #ifdef ZEPHYR_USES_KERBEROS
44 char d1
[ANAME_SZ
], d2
[INST_SZ
];
46 initialize_krb_error_table();
49 initialize_zeph_error_table();
51 (void) memset((char *)&__HM_addr
, 0, sizeof(__HM_addr
));
53 __HM_addr
.sin_family
= AF_INET
;
55 /* Set up local loopback address for HostManager */
61 hmserv
= (struct servent
*)getservbyname(HM_SVCNAME
, "udp");
62 __HM_addr
.sin_port
= (hmserv
) ? hmserv
->s_port
: HM_SVC_FALLBACK
;
64 (void) memcpy((char *)&__HM_addr
.sin_addr
, addr
, 4);
68 /* Initialize the input queue */
72 /* if the application is a server, there might not be a zhm. The
73 code will fall back to something which might not be "right",
74 but this is is ok, since none of the servers call krb_rd_req. */
76 servaddr
.s_addr
= INADDR_NONE
;
77 if (! __Zephyr_server
) {
78 if ((code
= ZOpenPort(NULL
)) != ZERR_NONE
)
81 if ((code
= ZhmStat(NULL
, ¬ice
)) != ZERR_NONE
)
86 /* the first field, which is NUL-terminated, is the server name.
87 If this code ever support a multiplexing zhm, this will have to
88 be made smarter, and probably per-message */
90 #ifdef ZEPHYR_USES_KERBEROS
91 krealm
= krb_realmofhost(notice
.z_message
);
93 hostent
= gethostbyname(notice
.z_message
);
94 if (hostent
&& hostent
->h_addrtype
== AF_INET
)
95 memcpy(&servaddr
, hostent
->h_addr
, sizeof(servaddr
));
100 #ifdef ZEPHYR_USES_KERBEROS
102 strcpy(__Zephyr_realm
, krealm
);
103 } else if ((krb_get_tf_fullname(TKT_FILE
, d1
, d2
, __Zephyr_realm
)
105 ((krbval
= krb_get_lrealm(__Zephyr_realm
, 1)) != KSUCCESS
)) {
109 strcpy(__Zephyr_realm
, "local-realm");
112 __My_addr
.s_addr
= INADDR_NONE
;
113 if (servaddr
.s_addr
!= INADDR_NONE
) {
114 /* Try to get the local interface address by connecting a UDP
115 * socket to the server address and getting the local address.
116 * Some broken operating systems (e.g. Solaris 2.0-2.5) yield
117 * INADDR_ANY (zero), so we have to check for that. */
118 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
120 memset(&sin
, 0, sizeof(sin
));
121 sin
.sin_family
= AF_INET
;
122 memcpy(&sin
.sin_addr
, &servaddr
, sizeof(servaddr
));
123 sin
.sin_port
= HM_SRV_SVC_FALLBACK
;
124 if (connect(s
, (struct sockaddr
*) &sin
, sizeof(sin
)) == 0
125 && getsockname(s
, (struct sockaddr
*) &sin
, &sinsize
) == 0
126 && sin
.sin_addr
.s_addr
!= 0)
127 memcpy(&__My_addr
, &sin
.sin_addr
, sizeof(__My_addr
));
131 if (__My_addr
.s_addr
== INADDR_NONE
) {
132 /* We couldn't figure out the local interface address by the
133 * above method. Try by resolving the local hostname. (This
134 * is a pretty broken thing to do, and unfortunately what we
135 * always do on server machines.) */
136 if (gethostname(hostname
, sizeof(hostname
)) == 0) {
137 hostent
= gethostbyname(hostname
);
138 if (hostent
&& hostent
->h_addrtype
== AF_INET
)
139 memcpy(&__My_addr
, hostent
->h_addr
, sizeof(__My_addr
));
142 /* If the above methods failed, zero out __My_addr so things will
143 * sort of kind of work. */
144 if (__My_addr
.s_addr
== INADDR_NONE
)
145 __My_addr
.s_addr
= 0;
147 /* Get the sender so we can cache it */