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
6 * Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, see the file
11 #ifdef ZEPHYR_USES_KERBEROS
24 #include <sys/socket.h>
29 #define INADDR_NONE 0xffffffff
34 struct servent
*hmserv
;
35 struct hostent
*hostent
;
36 char addr
[4], hostname
[MAXHOSTNAMELEN
];
37 struct in_addr servaddr
;
38 struct sockaddr_in sin
;
40 socklen_t sinsize
= sizeof(sin
);
43 #ifdef ZEPHYR_USES_KERBEROS
46 char d1
[ANAME_SZ
], d2
[INST_SZ
];
48 /* initialize_krb_error_table(); */
51 initialize_zeph_error_table();
53 (void) memset((char *)&__HM_addr
, 0, sizeof(__HM_addr
));
55 __HM_addr
.sin_family
= AF_INET
;
57 /* Set up local loopback address for HostManager */
63 hmserv
= (struct servent
*)getservbyname(HM_SVCNAME
, "udp");
64 __HM_addr
.sin_port
= (hmserv
) ? hmserv
->s_port
: HM_SVC_FALLBACK
;
66 (void) memcpy((char *)&__HM_addr
.sin_addr
, addr
, 4);
70 /* Initialize the input queue */
74 /* if the application is a server, there might not be a zhm. The
75 code will fall back to something which might not be "right",
76 but this is is ok, since none of the servers call krb_rd_req. */
78 servaddr
.s_addr
= INADDR_NONE
;
79 if (! __Zephyr_server
) {
80 if ((code
= ZOpenPort(NULL
)) != ZERR_NONE
)
83 if ((code
= ZhmStat(NULL
, ¬ice
)) != ZERR_NONE
)
88 /* the first field, which is NUL-terminated, is the server name.
89 If this code ever support a multiplexing zhm, this will have to
90 be made smarter, and probably per-message */
92 #ifdef ZEPHYR_USES_KERBEROS
93 krealm
= krb_realmofhost(notice
.z_message
);
95 hostent
= gethostbyname(notice
.z_message
);
96 if (hostent
&& hostent
->h_addrtype
== AF_INET
)
97 memcpy(&servaddr
, hostent
->h_addr
, sizeof(servaddr
));
102 #ifdef ZEPHYR_USES_KERBEROS
104 g_strlcpy(__Zephyr_realm
, krealm
, REALM_SZ
);
105 } else if ((krb_get_tf_fullname(TKT_FILE
, d1
, d2
, __Zephyr_realm
)
107 ((krbval
= krb_get_lrealm(__Zephyr_realm
, 1)) != KSUCCESS
)) {
111 g_strlcpy(__Zephyr_realm
, "local-realm", REALM_SZ
);
114 __My_addr
.s_addr
= INADDR_NONE
;
115 if (servaddr
.s_addr
!= INADDR_NONE
) {
116 /* Try to get the local interface address by connecting a UDP
117 * socket to the server address and getting the local address.
118 * Some broken operating systems (e.g. Solaris 2.0-2.5) yield
119 * INADDR_ANY (zero), so we have to check for that. */
120 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
122 memset(&sin
, 0, sizeof(sin
));
123 sin
.sin_family
= AF_INET
;
124 memcpy(&sin
.sin_addr
, &servaddr
, sizeof(servaddr
));
125 sin
.sin_port
= HM_SRV_SVC_FALLBACK
;
126 if (connect(s
, (struct sockaddr
*) &sin
, sizeof(sin
)) == 0
127 && getsockname(s
, (struct sockaddr
*) &sin
, &sinsize
) == 0
128 && sin
.sin_addr
.s_addr
!= 0)
129 memcpy(&__My_addr
, &sin
.sin_addr
, sizeof(__My_addr
));
133 if (__My_addr
.s_addr
== INADDR_NONE
) {
134 /* We couldn't figure out the local interface address by the
135 * above method. Try by resolving the local hostname. (This
136 * is a pretty broken thing to do, and unfortunately what we
137 * always do on server machines.) */
138 if (gethostname(hostname
, sizeof(hostname
)) == 0) {
139 hostent
= gethostbyname(hostname
);
140 if (hostent
&& hostent
->h_addrtype
== AF_INET
)
141 memcpy(&__My_addr
, hostent
->h_addr
, sizeof(__My_addr
));
144 /* If the above methods failed, zero out __My_addr so things will
145 * sort of kind of work. */
146 if (__My_addr
.s_addr
== INADDR_NONE
)
147 __My_addr
.s_addr
= 0;
149 /* Get the sender so we can cache it */