| 18 #include <sys/socket.h> |
18 #include <sys/socket.h> |
| 19 #include <utmp.h> |
19 #include <utmp.h> |
| 20 |
20 |
| 21 #ifndef lint |
21 #ifndef lint |
| 22 static const char rcsid_Zinternal_c[] = |
22 static const char rcsid_Zinternal_c[] = |
| 23 "$Id: Zinternal.c 2096 2001-07-31 01:00:39Z warmenhoven $"; |
23 "$Id: Zinternal.c 2432 2001-10-03 19:38:28Z warmenhoven $"; |
| 24 static const char copyright[] = |
24 static const char copyright[] = |
| 25 "Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology."; |
25 "Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology."; |
| 26 #endif |
26 #endif |
| 27 |
27 |
| 28 extern char *inet_ntoa (); |
28 extern char *inet_ntoa (); |
| 29 |
29 |
| 30 int __Zephyr_fd = -1; |
30 int __Zephyr_fd = -1; |
| 31 int __Zephyr_open; |
31 int __Zephyr_open; |
| 32 int __Zephyr_port = -1; |
32 int __Zephyr_port = -1; |
| 33 int __My_length; |
33 struct in_addr __My_addr; |
| 34 char *__My_addr; |
|
| 35 int __Q_CompleteLength; |
34 int __Q_CompleteLength; |
| 36 int __Q_Size; |
35 int __Q_Size; |
| 37 struct _Z_InputQ *__Q_Head, *__Q_Tail; |
36 struct _Z_InputQ *__Q_Head, *__Q_Tail; |
| 38 struct sockaddr_in __HM_addr; |
37 struct sockaddr_in __HM_addr; |
| 39 struct sockaddr_in __HM_addr_real; |
38 struct sockaddr_in __HM_addr_real; |
| 43 int __locate_num; |
42 int __locate_num; |
| 44 int __locate_next; |
43 int __locate_next; |
| 45 ZSubscription_t *__subscriptions_list; |
44 ZSubscription_t *__subscriptions_list; |
| 46 int __subscriptions_num; |
45 int __subscriptions_num; |
| 47 int __subscriptions_next; |
46 int __subscriptions_next; |
| |
47 int Z_discarded_packets = 0; |
| 48 |
48 |
| 49 #ifdef ZEPHYR_USES_KERBEROS |
49 #ifdef ZEPHYR_USES_KERBEROS |
| 50 C_Block __Zephyr_session; |
50 C_Block __Zephyr_session; |
| |
51 #endif |
| 51 char __Zephyr_realm[REALM_SZ]; |
52 char __Zephyr_realm[REALM_SZ]; |
| 52 #endif |
|
| 53 |
53 |
| 54 #ifdef Z_DEBUG |
54 #ifdef Z_DEBUG |
| 55 void (*__Z_debug_print) __P((const char *fmt, va_list args, void *closure)); |
55 void (*__Z_debug_print) __P((const char *fmt, va_list args, void *closure)); |
| 56 void *__Z_debug_print_closure; |
56 void *__Z_debug_print_closure; |
| 57 #endif |
57 #endif |
| 131 num++; |
131 num++; |
| 132 |
132 |
| 133 return 0; |
133 return 0; |
| 134 } |
134 } |
| 135 |
135 |
| 136 /* Get the address of the local host and cache it */ |
|
| 137 |
|
| 138 Code_t Z_GetMyAddr() |
|
| 139 { |
|
| 140 register struct hostent *myhost; |
|
| 141 char hostname[MAXHOSTNAMELEN]; |
|
| 142 |
|
| 143 if (__My_length > 0) |
|
| 144 return (ZERR_NONE); |
|
| 145 |
|
| 146 if (gethostname(hostname, MAXHOSTNAMELEN) < 0) |
|
| 147 return (errno); |
|
| 148 |
|
| 149 if (!(myhost = gethostbyname(hostname))) |
|
| 150 return (errno); |
|
| 151 |
|
| 152 /* If h_length is 0, that is a serious problem and it doesn't |
|
| 153 make it worse for malloc(0) to return NULL, so don't worry |
|
| 154 about that case. */ |
|
| 155 if (!(__My_addr = (char *)malloc((unsigned)myhost->h_length))) |
|
| 156 return (ENOMEM); |
|
| 157 |
|
| 158 __My_length = myhost->h_length; |
|
| 159 |
|
| 160 (void) memcpy(__My_addr, myhost->h_addr, myhost->h_length); |
|
| 161 |
|
| 162 return (ZERR_NONE); |
|
| 163 } |
|
| 164 |
|
| 165 |
136 |
| 166 /* Return 1 if there is a packet waiting, 0 otherwise */ |
137 /* Return 1 if there is a packet waiting, 0 otherwise */ |
| 167 |
138 |
| 168 int Z_PacketWaiting() |
139 int Z_PacketWaiting() |
| 169 { |
140 { |
| 252 { |
223 { |
| 253 register struct _Z_InputQ *qptr; |
224 register struct _Z_InputQ *qptr; |
| 254 ZNotice_t notice; |
225 ZNotice_t notice; |
| 255 ZPacket_t packet; |
226 ZPacket_t packet; |
| 256 struct sockaddr_in olddest, from; |
227 struct sockaddr_in olddest, from; |
| 257 int from_len, packet_len, part, partof; |
228 int from_len, packet_len, zvlen, part, partof; |
| 258 char *slash; |
229 char *slash; |
| 259 Code_t retval; |
230 Code_t retval; |
| 260 register int i; |
231 fd_set fds; |
| |
232 struct timeval tv; |
| 261 |
233 |
| 262 if (ZGetFD() < 0) |
234 if (ZGetFD() < 0) |
| 263 return (ZERR_NOPORT); |
235 return (ZERR_NOPORT); |
| 264 |
236 |
| |
237 FD_ZERO(&fds); |
| |
238 FD_SET(ZGetFD(), &fds); |
| |
239 tv.tv_sec = 60; |
| |
240 tv.tv_usec = 0; |
| |
241 |
| |
242 if (select(ZGetFD() + 1, &fds, NULL, NULL, &tv) < 0) |
| |
243 return (errno); |
| |
244 if (!FD_ISSET(ZGetFD(), &fds)) |
| |
245 return ETIMEDOUT; |
| |
246 |
| 265 from_len = sizeof(struct sockaddr_in); |
247 from_len = sizeof(struct sockaddr_in); |
| 266 |
248 |
| 267 packet_len = recvfrom(ZGetFD(), packet, sizeof(packet), 0, |
249 packet_len = recvfrom(ZGetFD(), packet, sizeof(packet), 0, |
| 268 (struct sockaddr *)&from, &from_len); |
250 (struct sockaddr *)&from, &from_len); |
| 269 |
251 |
| 271 return (errno); |
253 return (errno); |
| 272 |
254 |
| 273 if (!packet_len) |
255 if (!packet_len) |
| 274 return (ZERR_EOF); |
256 return (ZERR_EOF); |
| 275 |
257 |
| 276 /* XXX Check for null data (debugging) */ |
258 /* Ignore obviously non-Zephyr packets. */ |
| 277 for (i = packet_len - 1; i >= 0; i--) |
259 zvlen = sizeof(ZVERSIONHDR) - 1; |
| 278 if (packet[i]) |
260 if (packet_len < zvlen || memcmp(packet, ZVERSIONHDR, zvlen) != 0) { |
| 279 goto not_all_null; |
261 Z_discarded_packets++; |
| 280 #ifdef Z_DEBUG |
262 return (ZERR_NONE); |
| 281 Z_debug ("got null packet from %s", inet_ntoa (from.sin_addr)); |
263 } |
| 282 #endif |
|
| 283 return ZERR_NONE; |
|
| 284 not_all_null: |
|
| 285 |
264 |
| 286 /* Parse the notice */ |
265 /* Parse the notice */ |
| 287 if ((retval = ZParseNotice(packet, packet_len, ¬ice)) != ZERR_NONE) |
266 if ((retval = ZParseNotice(packet, packet_len, ¬ice)) != ZERR_NONE) |
| 288 return (retval); |
267 return (retval); |
| 289 |
268 |
| 629 |
608 |
| 630 (void) gettimeofday(¬ice->z_uid.tv, (struct timezone *)0); |
609 (void) gettimeofday(¬ice->z_uid.tv, (struct timezone *)0); |
| 631 notice->z_uid.tv.tv_sec = htonl((u_long) notice->z_uid.tv.tv_sec); |
610 notice->z_uid.tv.tv_sec = htonl((u_long) notice->z_uid.tv.tv_sec); |
| 632 notice->z_uid.tv.tv_usec = htonl((u_long) notice->z_uid.tv.tv_usec); |
611 notice->z_uid.tv.tv_usec = htonl((u_long) notice->z_uid.tv.tv_usec); |
| 633 |
612 |
| 634 if ((retval = Z_GetMyAddr()) != ZERR_NONE) |
613 (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); |
| 635 return (retval); |
|
| 636 |
|
| 637 (void) memcpy((char *)¬ice->z_uid.zuid_addr, __My_addr, __My_length); |
|
| 638 |
614 |
| 639 notice->z_multiuid = notice->z_uid; |
615 notice->z_multiuid = notice->z_uid; |
| 640 |
616 |
| 641 if (!version[0]) |
617 if (!version[0]) |
| 642 (void) sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR, |
618 (void) sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR, |
| 740 if (Z_AddField(&ptr, notice->z_recipient, end)) |
716 if (Z_AddField(&ptr, notice->z_recipient, end)) |
| 741 return (ZERR_HEADERLEN); |
717 return (ZERR_HEADERLEN); |
| 742 } |
718 } |
| 743 else { |
719 else { |
| 744 if (strlen(notice->z_recipient) + strlen(__Zephyr_realm) + 2 > |
720 if (strlen(notice->z_recipient) + strlen(__Zephyr_realm) + 2 > |
| 745 sizeof(newrecip)) |
721 sizeof(newrecip)) |
| 746 return (ZERR_HEADERLEN); |
722 return (ZERR_HEADERLEN); |
| 747 (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm); |
723 (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm); |
| 748 if (Z_AddField(&ptr, newrecip, end)) |
724 if (Z_AddField(&ptr, newrecip, end)) |
| 749 return (ZERR_HEADERLEN); |
725 return (ZERR_HEADERLEN); |
| 750 } |
726 } |
| 751 if (Z_AddField(&ptr, notice->z_default_format, end)) |
727 if (Z_AddField(&ptr, notice->z_default_format, end)) |
| 903 (struct timezone *)0); |
879 (struct timezone *)0); |
| 904 partnotice.z_uid.tv.tv_sec = |
880 partnotice.z_uid.tv.tv_sec = |
| 905 htonl((u_long) partnotice.z_uid.tv.tv_sec); |
881 htonl((u_long) partnotice.z_uid.tv.tv_sec); |
| 906 partnotice.z_uid.tv.tv_usec = |
882 partnotice.z_uid.tv.tv_usec = |
| 907 htonl((u_long) partnotice.z_uid.tv.tv_usec); |
883 htonl((u_long) partnotice.z_uid.tv.tv_usec); |
| 908 if ((retval = Z_GetMyAddr()) != ZERR_NONE) |
884 (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr, |
| 909 return (retval); |
885 sizeof(__My_addr)); |
| 910 (void) memcpy((char *)&partnotice.z_uid.zuid_addr, __My_addr, |
|
| 911 __My_length); |
|
| 912 } |
886 } |
| 913 message_len = min(notice->z_message_len-offset, fragsize); |
887 message_len = min(notice->z_message_len-offset, fragsize); |
| 914 partnotice.z_message = notice->z_message+offset; |
888 partnotice.z_message = notice->z_message+offset; |
| 915 partnotice.z_message_len = message_len; |
889 partnotice.z_message_len = message_len; |
| 916 if ((retval = Z_FormatAuthHeader(&partnotice, buffer, Z_MAXHEADERLEN, |
890 if ((retval = Z_FormatAuthHeader(&partnotice, buffer, Z_MAXHEADERLEN, |