# HG changeset patch # User Eric Warmenhoven # Date 1002137908 0 # Node ID 7ba69b8e0de5b56e2566c6a16b126e8f85f6424c # Parent a2cc1cf4198fceb529f207821f813f72d3444880 [gaim-migrate @ 2432] Salvatore Valente says this is better. committer: Tailor Script diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/.cvsignore --- a/src/protocols/zephyr/.cvsignore Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/.cvsignore Wed Oct 03 19:38:28 2001 +0000 @@ -49,6 +49,7 @@ ZSubs.lo ZVariables.lo ZWait4Not.lo +ZhmStat.lo Zinternal.lo error_message.lo et_name.lo diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/Makefile.am --- a/src/protocols/zephyr/Makefile.am Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/Makefile.am Wed Oct 03 19:38:28 2001 +0000 @@ -129,6 +129,7 @@ ZSubs.c \ ZVariables.c \ ZWait4Not.c \ + ZhmStat.c \ Zinternal.c \ com_err.h \ error_message.c \ diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/ZInit.c --- a/src/protocols/zephyr/ZInit.c Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/ZInit.c Wed Oct 03 19:38:28 2001 +0000 @@ -24,12 +24,24 @@ #include #endif +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + Code_t ZInitialize() { struct servent *hmserv; - char addr[4]; + struct hostent *hostent; + char addr[4], hostname[MAXHOSTNAMELEN]; + struct in_addr servaddr; + struct sockaddr_in sin; + int s, sinsize = sizeof(sin); + Code_t code; + ZNotice_t notice; #ifdef ZEPHYR_USES_KERBEROS + char *krealm = NULL; int krbval; + char d1[ANAME_SZ], d2[INST_SZ]; initialize_krb_error_table(); #endif @@ -53,17 +65,88 @@ __HM_set = 0; + /* Initialize the input queue */ + __Q_Tail = NULL; + __Q_Head = NULL; + + /* if the application is a server, there might not be a zhm. The + code will fall back to something which might not be "right", + but this is is ok, since none of the servers call krb_rd_req. */ + + servaddr.s_addr = INADDR_NONE; + if (! __Zephyr_server) { + if ((code = ZOpenPort(NULL)) != ZERR_NONE) + return(code); + + if ((code = ZhmStat(NULL, ¬ice)) != ZERR_NONE) + return(code); + + ZClosePort(); + + /* the first field, which is NUL-terminated, is the server name. + If this code ever support a multiplexing zhm, this will have to + be made smarter, and probably per-message */ + #ifdef ZEPHYR_USES_KERBEROS - if ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS) + krealm = krb_realmofhost(notice.z_message); +#endif + hostent = gethostbyname(notice.z_message); + if (hostent && hostent->h_addrtype == AF_INET) + memcpy(&servaddr, hostent->h_addr, sizeof(servaddr)); + + ZFreeNotice(¬ice); + } + +#ifdef ZEPHYR_USES_KERBEROS + if (krealm) { + strcpy(__Zephyr_realm, krealm); + } else if ((krb_get_tf_fullname(TKT_FILE, d1, d2, __Zephyr_realm) + != KSUCCESS) && + ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)) { return (krbval); + } +#else + strcpy(__Zephyr_realm, "local-realm"); #endif + __My_addr.s_addr = INADDR_NONE; + if (servaddr.s_addr != INADDR_NONE) { + /* Try to get the local interface address by connecting a UDP + * socket to the server address and getting the local address. + * Some broken operating systems (e.g. Solaris 2.0-2.5) yield + * INADDR_ANY (zero), so we have to check for that. */ + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s != -1) { + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + memcpy(&sin.sin_addr, &servaddr, sizeof(servaddr)); + sin.sin_port = HM_SRV_SVC_FALLBACK; + if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0 + && getsockname(s, (struct sockaddr *) &sin, &sinsize) == 0 + && sin.sin_addr.s_addr != 0) + memcpy(&__My_addr, &sin.sin_addr, sizeof(__My_addr)); + close(s); + } + } + if (__My_addr.s_addr == INADDR_NONE) { + /* We couldn't figure out the local interface address by the + * above method. Try by resolving the local hostname. (This + * is a pretty broken thing to do, and unfortunately what we + * always do on server machines.) */ + if (gethostname(hostname, sizeof(hostname)) == 0) { + hostent = gethostbyname(hostname); + if (hostent && hostent->h_addrtype == AF_INET) + memcpy(&__My_addr, hostent->h_addr, sizeof(__My_addr)); + } + } + /* If the above methods failed, zero out __My_addr so things will + * sort of kind of work. */ + if (__My_addr.s_addr == INADDR_NONE) + __My_addr.s_addr = 0; + /* Get the sender so we can cache it */ (void) ZGetSender(); - /* Initialize the input queue */ - __Q_Tail = NULL; - __Q_Head = NULL; - return (ZERR_NONE); } + diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/ZLocations.c --- a/src/protocols/zephyr/ZLocations.c Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/ZLocations.c Wed Oct 03 19:38:28 2001 +0000 @@ -55,7 +55,7 @@ int retval; time_t ourtime; ZNotice_t notice, retnotice; - char *bptr[3]; + char *bptr[3], *p; #ifndef X_DISPLAY_MISSING char *display; #endif @@ -89,36 +89,29 @@ (void) strncpy(host, hent->h_name, sizeof(host)); host[sizeof(host) - 1] = '\0'; } - bptr[0] = host; #ifndef X_DISPLAY_MISSING if ((display = getenv("DISPLAY")) && *display) { (void) strcpy(mytty, display); - bptr[2] = mytty; } else { #endif ttyp = ttyname(0); - if (ttyp) { - bptr[2] = strrchr(ttyp, '/'); - if (bptr[2]) - bptr[2]++; - else - bptr[2] = ttyp; + if (ttyp && *ttyp) { + p = strchr(ttyp + 1, '/'); + strcpy(mytty, (p) ? p + 1 : ttyp); + } else { + strcpy(mytty, "unknown"); } - else - bptr[2] = "unknown"; - (void) strcpy(mytty, bptr[2]); #ifndef X_DISPLAY_MISSING } #endif reenter = 1; - } else { - bptr[0] = host; - bptr[2] = mytty; } ourtime = time((time_t *)0); + bptr[0] = host; bptr[1] = ctime(&ourtime); bptr[1][strlen(bptr[1])-1] = '\0'; + bptr[2] = mytty; if ((retval = ZSendList(¬ice, bptr, 3, auth)) != ZERR_NONE) diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/ZSendPkt.c --- a/src/protocols/zephyr/ZSendPkt.c Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/ZSendPkt.c Wed Oct 03 19:38:28 2001 +0000 @@ -20,7 +20,7 @@ #include #include -static int wait_for_ack(); +static int wait_for_hmack(); Code_t ZSendPacket(packet, len, waitforack) char *packet; @@ -53,7 +53,7 @@ if ((retval = ZParseNotice(packet, len, ¬ice)) != ZERR_NONE) return (retval); - retval = Z_WaitForNotice (&acknotice, wait_for_ack, ¬ice.z_uid, + retval = Z_WaitForNotice (&acknotice, wait_for_hmack, ¬ice.z_uid, HM_TIMEOUT); if (retval == ETIMEDOUT) return ZERR_HMDEAD; @@ -62,12 +62,9 @@ return retval; } -static int wait_for_ack(notice, uid) +static int wait_for_hmack(notice, uid) ZNotice_t *notice; ZUnique_Id_t *uid; { - return (ZCompareUID(¬ice->z_uid, uid) && - (notice->z_kind == HMACK || - notice->z_kind == SERVACK || - notice->z_kind == CLIENTACK )); + return (notice->z_kind == HMACK && ZCompareUID(¬ice->z_uid, uid)); } diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/ZSubs.c --- a/src/protocols/zephyr/ZSubs.c Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/ZSubs.c Wed Oct 03 19:38:28 2001 +0000 @@ -16,7 +16,7 @@ #include #ifndef lint -static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c 2096 2001-07-31 01:00:39Z warmenhoven $"; +static const char rcsid_ZSubscriptions_c[] = "$Id: ZSubs.c 2432 2001-10-03 19:38:28Z warmenhoven $"; #endif static Code_t Z_Subscriptions __P((register ZSubscription_t *sublist, @@ -103,7 +103,7 @@ retval = Z_FormatHeader(¬ice, header, sizeof(header), &hdrlen, ZAUTH); if (retval != ZERR_NONE && !authit) retval = Z_FormatHeader(¬ice, header, sizeof(header), - &hdrlen, ZAUTH); + &hdrlen, ZNOAUTH); if (retval != ZERR_NONE) { free((char *)list); return(retval); diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/ZhmStat.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/zephyr/ZhmStat.c Wed Oct 03 19:38:28 2001 +0000 @@ -0,0 +1,72 @@ +/* This file is part of the Project Athena Zephyr Notification System. + * It contains the ZhmStat() function. + * + * Created by: Marc Horowitz + * + * $Id: ZhmStat.c 2432 2001-10-03 19:38:28Z warmenhoven $ + * + * Copyright (c) 1996 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file + * "mit-copyright.h". + */ + +#include +#include + +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK 0x7f000001 +#endif + +Code_t ZhmStat(hostaddr, notice) + struct in_addr *hostaddr; + ZNotice_t *notice; +{ + struct servent *sp; + struct sockaddr_in sin; + ZNotice_t req; + Code_t code; + struct timeval tv; + fd_set readers; + + (void) memset((char *)&sin, 0, sizeof(struct sockaddr_in)); + + sp = getservbyname(HM_SVCNAME, "udp"); + + sin.sin_port = (sp) ? sp->s_port : HM_SVC_FALLBACK; + sin.sin_family = AF_INET; + + if (hostaddr) + sin.sin_addr = *hostaddr; + else + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + (void) memset((char *)&req, 0, sizeof(req)); + req.z_kind = STAT; + req.z_port = 0; + req.z_class = HM_STAT_CLASS; + req.z_class_inst = HM_STAT_CLIENT; + req.z_opcode = HM_GIMMESTATS; + req.z_sender = ""; + req.z_recipient = ""; + req.z_default_format = ""; + req.z_message_len = 0; + + if ((code = ZSetDestAddr(&sin)) != ZERR_NONE) + return(code); + + if ((code = ZSendNotice(&req, ZNOAUTH)) != ZERR_NONE) + return(code); + + /* Wait up to ten seconds for a response. */ + FD_ZERO(&readers); + FD_SET(ZGetFD(), &readers); + tv.tv_sec = 10; + tv.tv_usec = 0; + code = select(ZGetFD() + 1, &readers, NULL, NULL, &tv); + if (code < 0 && errno != EINTR) + return(errno); + if (code == 0 || (code < 0 && errno == EINTR) || ZPending() == 0) + return(ZERR_HMDEAD); + + return(ZReceiveNotice(notice, (struct sockaddr_in *) 0)); +} diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/Zinternal.c --- a/src/protocols/zephyr/Zinternal.c Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/Zinternal.c Wed Oct 03 19:38:28 2001 +0000 @@ -20,7 +20,7 @@ #ifndef lint static const char rcsid_Zinternal_c[] = - "$Id: Zinternal.c 2096 2001-07-31 01:00:39Z warmenhoven $"; + "$Id: Zinternal.c 2432 2001-10-03 19:38:28Z warmenhoven $"; static const char copyright[] = "Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology."; #endif @@ -30,8 +30,7 @@ int __Zephyr_fd = -1; int __Zephyr_open; int __Zephyr_port = -1; -int __My_length; -char *__My_addr; +struct in_addr __My_addr; int __Q_CompleteLength; int __Q_Size; struct _Z_InputQ *__Q_Head, *__Q_Tail; @@ -45,11 +44,12 @@ ZSubscription_t *__subscriptions_list; int __subscriptions_num; int __subscriptions_next; +int Z_discarded_packets = 0; #ifdef ZEPHYR_USES_KERBEROS C_Block __Zephyr_session; +#endif char __Zephyr_realm[REALM_SZ]; -#endif #ifdef Z_DEBUG void (*__Z_debug_print) __P((const char *fmt, va_list args, void *closure)); @@ -133,35 +133,6 @@ return 0; } -/* Get the address of the local host and cache it */ - -Code_t Z_GetMyAddr() -{ - register struct hostent *myhost; - char hostname[MAXHOSTNAMELEN]; - - if (__My_length > 0) - return (ZERR_NONE); - - if (gethostname(hostname, MAXHOSTNAMELEN) < 0) - return (errno); - - if (!(myhost = gethostbyname(hostname))) - return (errno); - - /* If h_length is 0, that is a serious problem and it doesn't - make it worse for malloc(0) to return NULL, so don't worry - about that case. */ - if (!(__My_addr = (char *)malloc((unsigned)myhost->h_length))) - return (ENOMEM); - - __My_length = myhost->h_length; - - (void) memcpy(__My_addr, myhost->h_addr, myhost->h_length); - - return (ZERR_NONE); -} - /* Return 1 if there is a packet waiting, 0 otherwise */ @@ -254,14 +225,25 @@ ZNotice_t notice; ZPacket_t packet; struct sockaddr_in olddest, from; - int from_len, packet_len, part, partof; + int from_len, packet_len, zvlen, part, partof; char *slash; Code_t retval; - register int i; + fd_set fds; + struct timeval tv; if (ZGetFD() < 0) return (ZERR_NOPORT); + FD_ZERO(&fds); + FD_SET(ZGetFD(), &fds); + tv.tv_sec = 60; + tv.tv_usec = 0; + + if (select(ZGetFD() + 1, &fds, NULL, NULL, &tv) < 0) + return (errno); + if (!FD_ISSET(ZGetFD(), &fds)) + return ETIMEDOUT; + from_len = sizeof(struct sockaddr_in); packet_len = recvfrom(ZGetFD(), packet, sizeof(packet), 0, @@ -273,15 +255,12 @@ if (!packet_len) return (ZERR_EOF); - /* XXX Check for null data (debugging) */ - for (i = packet_len - 1; i >= 0; i--) - if (packet[i]) - goto not_all_null; -#ifdef Z_DEBUG - Z_debug ("got null packet from %s", inet_ntoa (from.sin_addr)); -#endif - return ZERR_NONE; - not_all_null: + /* Ignore obviously non-Zephyr packets. */ + zvlen = sizeof(ZVERSIONHDR) - 1; + if (packet_len < zvlen || memcmp(packet, ZVERSIONHDR, zvlen) != 0) { + Z_discarded_packets++; + return (ZERR_NONE); + } /* Parse the notice */ if ((retval = ZParseNotice(packet, packet_len, ¬ice)) != ZERR_NONE) @@ -631,10 +610,7 @@ notice->z_uid.tv.tv_sec = htonl((u_long) notice->z_uid.tv.tv_sec); notice->z_uid.tv.tv_usec = htonl((u_long) notice->z_uid.tv.tv_usec); - if ((retval = Z_GetMyAddr()) != ZERR_NONE) - return (retval); - - (void) memcpy((char *)¬ice->z_uid.zuid_addr, __My_addr, __My_length); + (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); notice->z_multiuid = notice->z_uid; @@ -742,8 +718,8 @@ } else { if (strlen(notice->z_recipient) + strlen(__Zephyr_realm) + 2 > - sizeof(newrecip)) - return (ZERR_HEADERLEN); + sizeof(newrecip)) + return (ZERR_HEADERLEN); (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm); if (Z_AddField(&ptr, newrecip, end)) return (ZERR_HEADERLEN); @@ -905,10 +881,8 @@ htonl((u_long) partnotice.z_uid.tv.tv_sec); partnotice.z_uid.tv.tv_usec = htonl((u_long) partnotice.z_uid.tv.tv_usec); - if ((retval = Z_GetMyAddr()) != ZERR_NONE) - return (retval); - (void) memcpy((char *)&partnotice.z_uid.zuid_addr, __My_addr, - __My_length); + (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr, + sizeof(__My_addr)); } message_len = min(notice->z_message_len-offset, fragsize); partnotice.z_message = notice->z_message+offset; diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/internal.h --- a/src/protocols/zephyr/internal.h Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/internal.h Wed Oct 03 19:38:28 2001 +0000 @@ -69,6 +69,7 @@ extern int __subscriptions_next; extern int __Zephyr_port; /* Port number */ +extern struct in_addr __My_addr; typedef Code_t (*Z_SendProc) __P((ZNotice_t *, char *, int, int)); diff -r a2cc1cf4198f -r 7ba69b8e0de5 src/protocols/zephyr/zephyr.h --- a/src/protocols/zephyr/zephyr.h Wed Oct 03 18:13:50 2001 +0000 +++ b/src/protocols/zephyr/zephyr.h Wed Oct 03 19:38:28 2001 +0000 @@ -5,7 +5,7 @@ * * $Source$ * $Author: warmenhoven $ - * $Id: zephyr.h 2096 2001-07-31 01:00:39Z warmenhoven $ + * $Id: zephyr.h 2432 2001-10-03 19:38:28Z warmenhoven $ * * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of * Technology. For copying and distribution information, see the @@ -21,9 +21,6 @@ #include #include -#ifdef ZEPHYR_USES_KERBEROS -#include -#endif #ifndef IPPROTO_MAX /* Make sure not already included */ #include @@ -166,6 +163,7 @@ Code_t ZLocateUser ZP((char *, int *, Z_AuthProc)); Code_t ZRequestLocations ZP((char *, ZAsyncLocateData_t *, ZNotice_Kind_t, Z_AuthProc)); +Code_t ZhmStat ZP((struct in_addr *, ZNotice_t *)); Code_t ZInitialize ZP((void)); Code_t ZSetServerState ZP((int)); Code_t ZSetFD ZP((int)); @@ -178,10 +176,9 @@ Code_t ZMakeAscii16 ZP((char *, int, unsigned int)); Code_t ZReceivePacket ZP((ZPacket_t, int*, struct sockaddr_in*)); Code_t ZCheckAuthentication ZP((ZNotice_t*, struct sockaddr_in*)); +Code_t ZSetLocation ZP((char *exposure)); +Code_t ZUnsetLocation ZP((void)); Code_t ZFlushMyLocations ZP((void)); -#ifdef ZEPHYR_USES_KERBEROS -Code_t ZFormatAuthenticNotice ZP((ZNotice_t*, char*, int, int*, C_Block)); -#endif Code_t ZFormatRawNotice ZP((ZNotice_t *, char**, int *)); Code_t ZRetrieveSubscriptions ZP((unsigned short, int*)); Code_t ZOpenPort ZP((unsigned short *port)); @@ -230,15 +227,6 @@ #define ZGetDestAddr() __HM_addr #define ZGetRealm() __Zephyr_realm -#ifdef ZEPHYR_USES_KERBEROS -/* Session key for last parsed packet - server only */ -extern C_Block __Zephyr_session; -#define ZGetSession() (__Zephyr_session) -#else -#define __Zephyr_realm ("local-realm") -#endif - - #ifdef Z_DEBUG void ZSetDebug ZP((void (*)(ZCONST char *, va_list, void *), void *)); #define ZSetDebug(proc,closure) (__Z_debug_print=(proc), \ @@ -338,5 +326,6 @@ #define USER_REREAD "REREAD" /* Opcode: Reread desc file */ #define USER_SHUTDOWN "SHUTDOWN" /* Opcode: Go catatonic */ #define USER_STARTUP "STARTUP" /* Opcode: Come out of it */ +#define USER_EXIT "EXIT" /* Opcode: Exit the client */ #endif /* __ZEPHYR_H__ */