+++ /dev/null
-dnl $Id: aclocal.m4,v 1.14 2000/04/28 14:37:25 ghudson Exp $
-
-dnl Copyright 1996 by the Massachusetts Institute of Technology.
-dnl
-dnl Permission to use, copy, modify, and distribute this
-dnl software and its documentation for any purpose and without
-dnl fee is hereby granted, provided that the above copyright
-dnl notice appear in all copies and that both that copyright
-dnl notice and this permission notice appear in supporting
-dnl documentation, and that the name of M.I.T. not be used in
-dnl advertising or publicity pertaining to distribution of the
-dnl software without specific, written prior permission.
-dnl M.I.T. makes no representations about the suitability of
-dnl this software for any purpose. It is provided "as is"
-dnl without express or implied warranty.
-
-dnl This file provides local macros for packages which use specific
-dnl external libraries. The public macros are:
-dnl
-dnl ATHENA_UTIL_COM_ERR
-dnl Generates error if com_err not found.
-dnl ATHENA_UTIL_SS
-dnl Generates error if ss not found.
-dnl ATHENA_REGEXP
-dnl Sets REGEX_LIBS if rx library used; ensures POSIX
-dnl regexp support.
-dnl ATHENA_MOTIF
-dnl Sets MOTIF_LIBS and defines HAVE_MOTIF if Motif used.
-dnl ATHENA_MOTIF_REQUIRED
-dnl Generates error if Motif not found.
-dnl ATHENA_AFS
-dnl Sets AFS_LIBS and defines HAVE_AFS if AFS used. Pass
-dnl in an argument giving the desired AFS libraries;
-dnl AFS_LIBS will be set to that value if AFS is found.
-dnl AFS_DIR will be set to the prefix given.
-dnl ATHENA_AFS_REQUIRED
-dnl Generates error if AFS libraries not found. AFS_DIR
-dnl will be set to the prefix given.
-dnl ATHENA_KRB4
-dnl Sets KRB4_LIBS and defines HAVE_KRB4 if krb4 used.
-dnl ATHENA_KRB4_REQUIRED
-dnl Generates error if krb4 not found. Sets KRB4_LIBS
-dnl otherwise. (Special behavior because krb4 libraries
-dnl may be different if using krb4 compatibility libraries
-dnl from krb5.)
-dnl ATHENA_KRB5
-dnl Sets KRB5_LIBS and defines HAVE_KRB5 if krb5 used.
-dnl ATHENA_KRB5_REQUIRED
-dnl Generates error if krb5 not found.
-dnl ATHENA_HESIOD
-dnl Sets HESIOD_LIBS and defines HAVE_HESIOD if Hesiod
-dnl used.
-dnl ATHENA_HESIOD_REQUIRED
-dnl Generates error if Hesiod not found.
-dnl ATHENA_ARES
-dnl Sets ARES_LIBS and defines HAVE_ARES if libares
-dnl used.
-dnl ATHENA_ARES_REQUIRED
-dnl Generates error if libares not found.
-dnl ATHENA_ZEPHYR
-dnl Sets ZEPHYR_LIBS and defines HAVE_ZEPHYR if zephyr
-dnl used.
-dnl ATHENA_ZEPHYR_REQUIRED
-dnl Generates error if zephyr not found.
-dnl
-dnl All of the macros may extend CPPFLAGS and LDFLAGS to let the
-dnl compiler find the requested libraries. Put ATHENA_UTIL_COM_ERR
-dnl and ATHENA_UTIL_SS before ATHENA_AFS or ATHENA_AFS_REQUIRED; there
-dnl is a com_err library in the AFS libraries which requires -lutil.
-
-dnl ----- com_err -----
-
-AC_DEFUN(ATHENA_UTIL_COM_ERR,
-[AC_ARG_WITH(com_err,
- [ --with-com_err=PREFIX Specify location of com_err],
- [com_err="$withval"], [com_err=yes])
-if test "$com_err" != no; then
- if test "$com_err" != yes; then
- CPPFLAGS="$CPPFLAGS -I$com_err/include"
- LDFLAGS="$LDFLAGS -L$com_err/lib"
- fi
- AC_CHECK_LIB(com_err, com_err, :,
- [AC_MSG_ERROR(com_err library not found)])
-else
- AC_MSG_ERROR(This package requires com_err.)
-fi])
-
-dnl ----- ss -----
-
-AC_DEFUN(ATHENA_UTIL_SS,
-[AC_ARG_WITH(ss,
- [ --with-ss=PREFIX Specify location of ss (requires com_err)],
- [ss="$withval"], [ss=yes])
-if test "$ss" != no; then
- if test "$ss" != yes; then
- CPPFLAGS="$CPPFLAGS -I$ss/include"
- LDFLAGS="$LDFLAGS -L$ss/lib"
- fi
- AC_CHECK_LIB(ss, ss_perror, :,
- [AC_MSG_ERROR(ss library not found)], -lcom_err)
-else
- AC_MSG_ERROR(This package requires ss.)
-fi])
-
-dnl ----- Regular expressions -----
-
-AC_DEFUN(ATHENA_REGEXP,
-[AC_ARG_WITH(regex,
- [ --with-regex=PREFIX Use installed regex library],
- [regex="$withval"], [regex=no])
-if test "$regex" != no; then
- if test "$regex" != yes; then
- CPPFLAGS="$CPPFLAGS -I$regex/include"
- LDFLAGS="$LDFLAGS -L$regex/lib"
- fi
- AC_CHECK_LIB(regex, regcomp, REGEX_LIBS=-lregex,
- [AC_MSG_ERROR(regex library not found)])
-else
- AC_CHECK_FUNC(regcomp, :,
- [AC_MSG_ERROR(can't find POSIX regexp support)])
-fi
-AC_SUBST(REGEX_LIBS)])
-
-dnl ----- Motif -----
-
-AC_DEFUN(ATHENA_MOTIF_CHECK,
-[if test "$motif" != yes; then
- CPPFLAGS="$CPPFLAGS -I$motif/include"
- LDFLAGS="$LDFLAGS -L$motif/lib"
-fi
-AC_CHECK_LIB(Xm, XmStringFree, :, [AC_MSG_ERROR(Motif library not found)])])
-
-AC_DEFUN(ATHENA_MOTIF,
-[AC_ARG_WITH(motif,
- [ --with-motif=PREFIX Use Motif],
- [motif="$withval"], [motif=no])
-if test "$motif" != no; then
- ATHENA_MOTIF_CHECK
- MOTIF_LIBS=-lXm
- AC_DEFINE(HAVE_MOTIF)
-fi
-AC_SUBST(MOTIF_LIBS)])
-
-AC_DEFUN(ATHENA_MOTIF_REQUIRED,
-[AC_ARG_WITH(motif,
- [ --with-motif=PREFIX Specify location of Motif],
- [motif="$withval"], [motif=yes])
-if test "$motif" != no; then
- ATHENA_MOTIF_CHECK
-else
- AC_MSG_ERROR(This package requires Motif.)
-fi])
-
-dnl ----- AFS -----
-
-AC_DEFUN(ATHENA_AFS_CHECK,
-[AC_CHECK_FUNC(insque, :, AC_CHECK_LIB(compat, insque))
-AC_CHECK_FUNC(gethostbyname, :, AC_CHECK_LIB(nsl, gethostbyname))
-AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket))
-if test "$afs" != yes; then
- CPPFLAGS="$CPPFLAGS -I$afs/include"
- LDFLAGS="$LDFLAGS -L$afs/lib -L$afs/lib/afs"
-fi
-AC_CHECK_LIB(sys, pioctl, :, [AC_MSG_ERROR(AFS libraries not found)],
- -lrx -llwp -lsys)
-AFS_DIR=$afs
-AC_SUBST(AFS_DIR)])
-
-dnl Specify desired AFS libraries as a parameter.
-AC_DEFUN(ATHENA_AFS,
-[AC_ARG_WITH(afs,
- [ --with-afs=PREFIX Use AFS libraries],
- [afs="$withval"], [afs=no])
-if test "$afs" != no; then
- ATHENA_AFS_CHECK
- AFS_LIBS=$1
- AC_DEFINE(HAVE_AFS)
-fi
-AC_SUBST(AFS_LIBS)])
-
-AC_DEFUN(ATHENA_AFS_REQUIRED,
-[AC_ARG_WITH(afs,
- [ --with-afs=PREFIX Specify location of AFS libraries],
- [afs="$withval"], [afs=/usr/afsws])
-if test "$afs" != no; then
- ATHENA_AFS_CHECK
-else
- AC_MSG_ERROR(This package requires AFS libraries.)
-fi])
-
-dnl ----- Kerberos 4 -----
-
-AC_DEFUN(ATHENA_KRB4_CHECK,
-[AC_CHECK_FUNC(gethostbyname, :, AC_CHECK_LIB(nsl, gethostbyname))
-AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket))
-AC_CHECK_LIB(gen, compile)
-if test "$krb4" != yes; then
- CPPFLAGS="$CPPFLAGS -I$krb4/include"
- if test -d "$krb4/include/kerberosIV"; then
- CPPFLAGS="$CPPFLAGS -I$krb4/include/kerberosIV"
- fi
- LDFLAGS="$LDFLAGS -L$krb4/lib"
-fi
-AC_CHECK_LIB(krb4, krb_rd_req,
- [KRB4_LIBS="-lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err"],
- [AC_CHECK_LIB(krb, krb_rd_req,
- [KRB4_LIBS="-lkrb -ldes"],
- [AC_MSG_ERROR(Kerberos 4 libraries not found)],
- -ldes)],
- -ldes425 -lkrb5 -lk5crypto -lcom_err)])
-
-AC_DEFUN(ATHENA_KRB4,
-[AC_ARG_WITH(krb4,
- [ --with-krb4=PREFIX Use Kerberos 4],
- [krb4="$withval"], [krb4=no])
-if test "$krb4" != no; then
- ATHENA_KRB4_CHECK
- AC_DEFINE(HAVE_KRB4)
-fi
-AC_SUBST(KRB4_LIBS)])
-
-AC_DEFUN(ATHENA_KRB4_REQUIRED,
-[AC_ARG_WITH(krb4,
- [ --with-krb4=PREFIX Specify location of Kerberos 4],
- [krb4="$withval"], [krb4=yes])
-if test "$krb4" != no; then
- ATHENA_KRB4_CHECK
- AC_SUBST(KRB4_LIBS)
-else
- AC_MSG_ERROR(This package requires Kerberos 4.)
-fi])
-
-dnl ----- Kerberos 5 -----
-
-AC_DEFUN(ATHENA_KRB5_CHECK,
-[AC_SEARCH_LIBS(gethostbyname, nsl)
-AC_SEARCH_LIBS(socket, socket)
-AC_CHECK_LIB(gen, compile)
-if test "$krb5" != yes; then
- CPPFLAGS="$CPPFLAGS -I$krb5/include"
- LDFLAGS="$LDFLAGS -L$krb5/lib"
-fi
-AC_CHECK_LIB(krb5, krb5_init_context, :,
- [AC_MSG_ERROR(Kerberos 5 libraries not found)],
- -lk5crypto -lcom_err)])
-
-AC_DEFUN(ATHENA_KRB5,
-[AC_ARG_WITH(krb5,
- [ --with-krb5=PREFIX Use Kerberos 5],
- [krb5="$withval"], [krb5=no])
-if test "$krb5" != no; then
- ATHENA_KRB5_CHECK
- KRB5_LIBS="-lkrb5 -lk5crypto -lcom_err"
- AC_DEFINE(HAVE_KRB5)
-fi
-AC_SUBST(KRB5_LIBS)])
-
-AC_DEFUN(ATHENA_KRB5_REQUIRED,
-[AC_ARG_WITH(krb5,
- [ --with-krb5=PREFIX Specify location of Kerberos 5],
- [krb5="$withval"], [krb5=yes])
-if test "$krb5" != no; then
- ATHENA_KRB5_CHECK
-else
- AC_MSG_ERROR(This package requires Kerberos 5.)
-fi])
-
-dnl ----- Hesiod -----
-
-AC_DEFUN(ATHENA_HESIOD_CHECK,
-[AC_CHECK_FUNC(res_send, :, AC_CHECK_LIB(resolv, res_send))
-if test "$hesiod" != yes; then
- CPPFLAGS="$CPPFLAGS -I$hesiod/include"
- LDFLAGS="$LDFLAGS -L$hesiod/lib"
-fi
-AC_CHECK_LIB(hesiod, hes_resolve, :,
- [AC_MSG_ERROR(Hesiod library not found)],$LIBS)])
-
-AC_DEFUN(ATHENA_HESIOD,
-[AC_ARG_WITH(hesiod,
- [ --with-hesiod=PREFIX Use Hesiod],
- [hesiod="$withval"], [hesiod=no])
-if test "$hesiod" != no; then
- ATHENA_HESIOD_CHECK
- HESIOD_LIBS="-lhesiod"
- AC_DEFINE(HAVE_HESIOD)
-fi
-AC_SUBST(HESIOD_LIBS)])
-
-AC_DEFUN(ATHENA_HESIOD_REQUIRED,
-[AC_ARG_WITH(hesiod,
- [ --with-hesiod=PREFIX Specify location of Hesiod],
- [hesiod="$withval"], [hesiod=yes])
-if test "$hesiod" != no; then
- ATHENA_HESIOD_CHECK
-else
- AC_MSG_ERROR(This package requires Hesiod.)
-fi])
-
-dnl ----- libares -----
-
-AC_DEFUN(ATHENA_ARES_CHECK,
-[AC_CHECK_FUNC(res_send, :, AC_CHECK_LIB(resolv, res_send))
-if test "$ares" != yes; then
- CPPFLAGS="$CPPFLAGS -I$ares/include"
- LDFLAGS="$LDFLAGS -L$ares/lib"
-fi
-AC_CHECK_LIB(ares, ares_init, :, [AC_MSG_ERROR(libares not found)])])
-
-AC_DEFUN(ATHENA_ARES,
-[AC_ARG_WITH(ares,
- [ --with-ares=PREFIX Use libares],
- [ares="$withval"], [ares=no])
-if test "$ares" != no; then
- ATHENA_ARES_CHECK
- ARES_LIBS="-lares"
- AC_DEFINE(HAVE_ARES)
-fi
-AC_SUBST(ARES_LIBS)])
-
-AC_DEFUN(ATHENA_ARES_REQUIRED,
-[AC_ARG_WITH(ares,
- [ --with-ares=PREFIX Specify location of libares],
- [ares="$withval"], [ares=yes])
-if test "$ares" != no; then
- ATHENA_ARES_CHECK
-else
- AC_MSG_ERROR(This package requires libares.)
-fi])
-dnl ----- zephyr -----
-
-AC_DEFUN(ATHENA_ZEPHYR_CHECK,
-[if test "$zephyr" != yes; then
- CPPFLAGS="$CPPFLAGS -I$zephyr/include"
- LDFLAGS="$LDFLAGS -L$zephyr/lib"
-fi
-AC_CHECK_LIB(zephyr, ZFreeNotice, :, [AC_MSG_ERROR(zephyr not found)])])
-
-AC_DEFUN(ATHENA_ZEPHYR,
-[AC_ARG_WITH(zephyr,
- [ --with-zephyr=PREFIX Use zephyr],
- [zephyr="$withval"], [zephyr=no])
-if test "$zephyr" != no; then
- ATHENA_ZEPHYR_CHECK
- ZEPHYR_LIBS="-lzephyr"
- AC_DEFINE(HAVE_ZEPHYR)
-fi
-AC_SUBST(ZEPHYR_LIBS)])
-
-AC_DEFUN(ATHENA_ZEPHYR_REQUIRED,
-[AC_ARG_WITH(zephyr,
- [ --with-zephyr=PREFIX Specify location of zephyr],
- [zephyr="$withval"], [zephyr=yes])
-if test "$zephyr" != no; then
- ATHENA_ZEPHYR_CHECK
-else
- AC_MSG_ERROR(This package requires zephyr.)
-fi])
dnl Process this file with autoconf to produce a configure script.
AC_INIT(server/server.c)
+
+dnl
+dnl KRB5_SOCKADDR_SA_LEN: define HAVE_SA_LEN if sockaddr contains the sa_len
+dnl component
+dnl
+AC_DEFUN([KRB5_SOCKADDR_SA_LEN],[ dnl
+AC_MSG_CHECKING(Whether struct sockaddr contains sa_len)
+AC_CACHE_VAL(krb5_cv_sockaddr_sa_len,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>
+],
+[struct sockaddr sa;
+sa.sa_len;],
+krb5_cv_sockaddr_sa_len=yes,krb5_cv_sockaddr_sa_len=no)])
+AC_MSG_RESULT([$]krb5_cv_sockaddr_sa_len)
+if test $krb5_cv_sockaddr_sa_len = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_SA_LEN)
+ fi
+])
+
+
+
test -d h || mkdir h
test -d h/zephyr || mkdir h/zephyr
AC_PROG_YACC
AC_PROG_LEX
AC_PROG_INSTALL
-AC_PROG_RANLIB
AC_MSG_CHECKING(location of temporary directory)
if test -d /var/tmp; then
AC_PATH_XTRA
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(fcntl.h paths.h termios.h sgtty.h unistd.h malloc.h)
+AC_CHECK_HEADERS(fcntl.h paths.h termios.h sgtty.h unistd.h malloc.h ifaddrs.h)
AC_CHECK_HEADERS(sys/filio.h sys/ioctl.h sys/time.h sys/file.h sys/utsname.h)
-AC_CHECK_HEADERS(sys/select.h sys/msgbuf.h sys/cdefs.h)
+AC_CHECK_HEADERS(sys/select.h sys/msgbuf.h sys/cdefs.h X11/Xaw/Label.h)
if test "$no_x" != "yes"; then
+ if test "$ac_cv_have_x11_xaw_label_h" = yes ; then
XCLIENTS=xzwrite
- ZWGC_LIBX11=-lX11
+ fi
+ ZWGC_LIBX11=-lX11
fi
AC_SUBST(XCLIENTS)
AC_SUBST(ZWGC_LIBX11)
AC_SEARCH_LIBS(gethostbyname, nsl)
AC_SEARCH_LIBS(socket, socket)
+KRB5_SOCKADDR_SA_LEN
# Hesiod needs -lresolv on Sun systems for res_send.
if test "$hesiod" != "no"; then
ATHENA_REGEXP
ATHENA_ARES
ATHENA_UTIL_COM_ERR
-ATHENA_UTIL_SS
+dnl this is before ATHENA_UTIL_SS because on NetBSD, -lss depends on
+dnl a plethora of libraries, which require crypt(), which is dragged
+dnl in by ....
LIBS="$KRB4_LIBS $HESIOD_LIBS $LIBS"
+ATHENA_UTIL_SS
dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_CHECK_FUNCS(putenv strchr memcpy memmove waitpid getlogin strerror random)
AC_CHECK_FUNCS(lrand48 gethostid getsid getpgid krb_get_err_text krb_log)
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
AC_CONFIG_HEADER(h/config.h)
AC_OUTPUT(Makefile clients/Makefile clients/xzwrite/Makefile
clients/zaway/Makefile clients/zctl/Makefile
#define HM_SVC_FALLBACK htons((unsigned short) 2104)
#define HM_SRV_SVC_FALLBACK htons((unsigned short) 2105)
+#define ZAUTH_CKSUM_FAILED (-2) /* Used only by server. */
#define ZAUTH_UNSET (-3) /* Internal to client library. */
#define Z_MAXFRAGS 500 /* Max number of packet fragments */
#define Z_MAXNOTICESIZE 400000 /* Max size of incoming notice */
char *msg;
};
+typedef struct _Z_SrvNameAddr {
+ char *name;
+ struct in_addr addr;
+ struct in_addr my_addr;
+} Z_SrvNameAddr;
+
+typedef struct _Z_GalaxyConfig {
+ char *galaxy;
+ Z_SrvNameAddr *server_list;
+ int nservers;
+} Z_GalaxyConfig;
+
+typedef struct _Z_GalaxyList {
+ Z_GalaxyConfig galaxy_config;
+#ifdef HAVE_KRB4
+ char krealm[REALM_SZ];
+ long last_authent_time;
+ KTEXT_ST last_authent;
+#endif
+} Z_GalaxyList;
+
extern struct _Z_InputQ *__Q_Head, *__Q_Tail;
extern int __Zephyr_open; /* 0 if FD opened, 1 otherwise */
-extern int __HM_set; /* 0 if dest addr set, 1 otherwise */
extern int __Zephyr_server; /* 0 if normal client, 1 if server or zhm */
+extern Z_GalaxyList *__galaxy_list;
+extern int __ngalaxies;
+extern int __default_galaxy;
+
extern ZLocations_t *__locate_list;
extern int __locate_num;
extern int __locate_next;
Code_t Z_FormatAuthHeader __P((ZNotice_t *, char *, int, int *, Z_AuthProc));
Code_t Z_FormatHeader __P((ZNotice_t *, char *, int, int *, Z_AuthProc));
Code_t Z_FormatRawHeader __P((ZNotice_t *, char*, int,
- int*, char **, char **));
+ int*, char **, int*, char **, char **));
+void Z_SourceAddr __P((struct in_addr *, struct in_addr *));
+Code_t Z_FreeGalaxyConfig(Z_GalaxyConfig *);
+Code_t Z_ParseGalaxyConfig(char *, Z_GalaxyConfig *);
Code_t Z_ReadEnqueue __P((void));
Code_t Z_ReadWait __P((void));
-Code_t Z_SendLocation __P((char*, char*, Z_AuthProc, char*));
+Code_t Z_SendLocation __P((char *, char*, char*, Z_AuthProc, char*));
Code_t Z_SendFragmentedNotice __P((ZNotice_t *notice, int len,
Z_AuthProc cert_func,
Z_SendProc send_func));
*
* Created by: Robert French
*
- * $Id: zephyr.h,v 1.54 1999/01/22 23:18:59 ghudson Exp $
+ * $Id$
*
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of
* Technology. For copying and distribution information, see the
#define ZVERSIONHDR "ZEPH"
#define ZVERSIONMAJOR 0
-#define ZVERSIONMINOR 2
+#define ZVERSIONMINOR_NOGALAXY 2
+#define ZVERSIONMINOR_GALAXY 3
#define Z_MAXPKTLEN 1024
#define Z_MAXHEADERLEN 800
char *z_multinotice;
ZUnique_Id_t z_multiuid;
ZChecksum_t z_checksum;
+ char *z_dest_galaxy;
int z_num_other_fields;
char *z_other_fields[Z_MAXOTHERFIELDS];
caddr_t z_message;
typedef Code_t (*Z_AuthProc) ZP((ZNotice_t*, char *, int, int *));
Code_t ZMakeAuthentication ZP((ZNotice_t*, char *,int, int*));
+char *ZGetDefaultGalaxy ZP((void));
+char *ZGetRhs ZP((char *));
char *ZGetSender ZP((void));
char *ZGetVariable ZP((char *));
+Code_t ZGetGalaxyCount ZP((int *));
+Code_t ZGetGalaxyName ZP((int, char **));
Code_t ZSetVariable ZP((char *var, char *value));
Code_t ZUnsetVariable ZP((char *var));
int ZGetWGPort ZP((void));
Code_t ZFormatSmallNotice ZP((ZNotice_t*, ZPacket_t, int*, Z_AuthProc));
Code_t ZFormatRawNoticeList ZP((ZNotice_t *notice, char *list[], int nitems,
char **buffer, int *ret_len));
-Code_t ZLocateUser ZP((char *, int *, Z_AuthProc));
-Code_t ZRequestLocations ZP((char *, ZAsyncLocateData_t *,
+Code_t ZLocateUser ZP((char *, char *, int *, Z_AuthProc));
+Code_t ZRequestLocations ZP((char *, char *, ZAsyncLocateData_t *,
ZNotice_Kind_t, Z_AuthProc));
+Code_t ZGetLocations ZP((ZLocations_t *, int *));
Code_t ZhmStat ZP((struct in_addr *, ZNotice_t *));
Code_t ZInitialize ZP((void));
Code_t ZSetServerState ZP((int));
Code_t ZReceivePacket ZP((ZPacket_t, int*, struct sockaddr_in*));
Code_t ZCheckAuthentication ZP((ZNotice_t*, struct sockaddr_in*));
Code_t ZInitLocationInfo ZP((char *hostname, char *tty));
-Code_t ZSetLocation ZP((char *exposure));
-Code_t ZUnsetLocation ZP((void));
-Code_t ZFlushMyLocations ZP((void));
+Code_t ZSetLocation ZP((char *, char *exposure));
+Code_t ZUnsetLocation ZP((char *));
+Code_t ZFlushMyLocations ZP((char *));
char *ZParseExposureLevel ZP((char *text));
Code_t ZFormatRawNotice ZP((ZNotice_t *, char**, int *));
-Code_t ZRetrieveSubscriptions ZP((unsigned short, int*));
+Code_t ZRetrieveSubscriptions ZP((char *, unsigned short, int*));
+Code_t ZRetrieveDefaultSubscriptions ZP((char *, int *));
Code_t ZOpenPort ZP((unsigned short *port));
+int ZGetPort ZP((void));
Code_t ZClosePort ZP((void));
Code_t ZFlushLocations ZP((void));
Code_t ZFlushSubscriptions ZP((void));
Code_t ZPeekNotice ZP((ZNotice_t *notice, struct sockaddr_in *from));
Code_t ZIfNotice ZP((ZNotice_t *notice, struct sockaddr_in *from,
int (*predicate) ZP((ZNotice_t *, void *)), void *args));
-Code_t ZSubscribeTo ZP((ZSubscription_t *sublist, int nitems,
+Code_t ZSubscribeTo ZP((char *, ZSubscription_t *sublist, int nitems,
unsigned int port));
-Code_t ZSubscribeToSansDefaults ZP((ZSubscription_t *sublist, int nitems,
- unsigned int port));
-Code_t ZUnsubscribeTo ZP((ZSubscription_t *sublist, int nitems,
+Code_t ZSubscribeToSansDefaults ZP((char *, ZSubscription_t *sublist,
+ int nitems, unsigned int port));
+Code_t ZUnsubscribeTo ZP((char *, ZSubscription_t *sublist, int nitems,
unsigned int port));
-Code_t ZCancelSubscriptions ZP((unsigned int port));
+Code_t ZCancelSubscriptions ZP((char *, unsigned int port));
int ZPending ZP((void));
Code_t ZReceiveNotice ZP((ZNotice_t *notice, struct sockaddr_in *from));
#ifdef Z_DEBUG
extern int __Zephyr_fd;
extern int __Q_CompleteLength;
extern struct sockaddr_in __HM_addr;
-extern char __Zephyr_realm[];
#define ZGetFD() __Zephyr_fd
#define ZQLength() __Q_CompleteLength
#define ZGetDestAddr() __HM_addr
-#define ZGetRealm() __Zephyr_realm
-
#ifdef Z_DEBUG
void ZSetDebug ZP((void (*)(ZCONST char *, va_list, void *), void *));
+++ /dev/null
-/* This file is part of the Project Athena Zephyr Notification System.
- * It contains source for the ZLocateUser function.
- *
- * Created by: Robert French
- *
- * $Id: ZLocateU.c,v 1.24 1999/01/22 23:19:14 ghudson Exp $
- *
- * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
- * For copying and distribution information, see the file
- * "mit-copyright.h".
- */
-
-#ifndef lint
-static char rcsid_ZLocateUser_c[] = "$Id: ZLocateU.c,v 1.24 1999/01/22 23:19:14 ghudson Exp $";
-#endif
-
-#include <internal.h>
-
-Code_t ZLocateUser(user, nlocs)
- char *user;
- int *nlocs;
-{
- return(ZNewLocateUser(user,nlocs,ZAUTH));
-}
*
* Created by: Robert French
*
- * $Id: Zinternal.c,v 1.41 2000/01/27 03:48:53 ghudson Exp $
+ * $Id$
*
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of
* Technology.
#include <arpa/inet.h>
#include <sys/socket.h>
#include <utmp.h>
+#include <unistd.h>
+#include <netdb.h>
#ifndef lint
static const char rcsid_Zinternal_c[] =
- "$Id: Zinternal.c,v 1.41 2000/01/27 03:48:53 ghudson Exp $";
+ "$Id$";
static const char copyright[] =
"Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.";
#endif
int __Zephyr_fd = -1;
int __Zephyr_open;
int __Zephyr_port = -1;
-struct in_addr __My_addr;
int __Q_CompleteLength;
int __Q_Size;
struct _Z_InputQ *__Q_Head, *__Q_Tail;
struct sockaddr_in __HM_addr;
struct sockaddr_in __HM_addr_real;
-int __HM_set;
int __Zephyr_server;
ZLocations_t *__locate_list;
int __locate_num;
int __subscriptions_next;
int Z_discarded_packets = 0;
-#ifdef HAVE_KRB4
-C_Block __Zephyr_session;
-#endif
-char __Zephyr_realm[REALM_SZ];
+Z_GalaxyList *__galaxy_list;
+int __ngalaxies;
+int __default_galaxy;
#ifdef Z_DEBUG
void (*__Z_debug_print) __P((const char *fmt, va_list args, void *closure));
ZNotice_t notice;
ZPacket_t packet;
struct sockaddr_in olddest, from;
- int from_len, packet_len, zvlen, part, partof;
+ int i, j, from_len, packet_len, zvlen, part, partof;
char *slash;
Code_t retval;
fd_set fds;
if (find_or_insert_uid(¬ice.z_uid, notice.z_kind))
return(ZERR_NONE);
- /* Check authentication on the notice. */
- notice.z_checked_auth = ZCheckAuthentication(¬ice, &from);
+ notice.z_dest_galaxy = "unknown-galaxy";
+
+ for (i=0; i<__ngalaxies; i++)
+ for (j=0; j<__galaxy_list[i].galaxy_config.nservers; j++)
+ if (from.sin_addr.s_addr ==
+ __galaxy_list[i].galaxy_config.server_list[j].addr.s_addr) {
+ notice.z_dest_galaxy = __galaxy_list[i].galaxy_config.galaxy;
+ break;
+ }
+
+ if ((notice.z_kind != HMACK) && (notice.z_kind != SERVACK)) {
+ /* Check authentication on the notice. */
+ notice.z_checked_auth = ZCheckAuthentication(¬ice, &from);
+ }
}
static char version[BUFSIZ]; /* default init should be all \0 */
struct sockaddr_in name;
int namelen = sizeof(name);
+ int i, j;
if (!notice->z_sender)
notice->z_sender = ZGetSender();
(void) Z_gettimeofday(¬ice->z_uid.tv, (struct timezone *)0);
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);
-
- (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr));
- notice->z_multiuid = notice->z_uid;
+ for (i=0; i<__ngalaxies; i++)
+ if (notice->z_dest_galaxy == 0 ||
+ strcmp(__galaxy_list[i].galaxy_config.galaxy,
+ notice->z_dest_galaxy) == 0) {
+ memcpy(¬ice->z_uid.zuid_addr,
+ &__galaxy_list[i].galaxy_config.server_list[0].my_addr.s_addr,
+ sizeof(struct in_addr));
+ break;
+ }
- if (!version[0])
- (void) sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR,
- ZVERSIONMINOR);
- notice->z_version = version;
+ notice->z_multiuid = notice->z_uid;
return Z_FormatAuthHeader(notice, buffer, buffer_len, len, cert_routine);
}
notice->z_authent_len = 0;
notice->z_ascii_authent = "";
notice->z_checksum = 0;
- return (Z_FormatRawHeader(notice, buffer, buffer_len,
- len, NULL, NULL));
+ return (Z_FormatRawHeader(notice, buffer, buffer_len, len,
+ NULL, NULL, NULL, NULL));
}
return ((*cert_routine)(notice, buffer, buffer_len, len));
}
-Code_t Z_FormatRawHeader(notice, buffer, buffer_len, len, cstart, cend)
+Code_t Z_FormatRawHeader(notice, buffer, buffer_len, hdr_len,
+ cksum_start, cksum_len, cstart, cend)
ZNotice_t *notice;
char *buffer;
int buffer_len;
- int *len;
+ int *hdr_len;
+ char **cksum_start;
+ int *cksum_len;
char **cstart, **cend;
{
+ static char version_galaxy[BUFSIZ]; /* default init should be all \0 */
+ static char version_nogalaxy[BUFSIZ]; /* default init should be all \0 */
char newrecip[BUFSIZ];
char *ptr, *end;
int i;
ptr = buffer;
end = buffer+buffer_len;
- if (buffer_len < strlen(notice->z_version)+1)
- return (ZERR_HEADERLEN);
+ if (notice->z_dest_galaxy &&
+ *notice->z_dest_galaxy) {
+ if (ZGetRhs(notice->z_dest_galaxy) == NULL)
+ return(ZERR_GALAXYUNKNOWN);
- (void) strcpy(ptr, notice->z_version);
- ptr += strlen(ptr)+1;
+ if (!version_galaxy[0])
+ (void) sprintf(version_galaxy, "%s%d.%d", ZVERSIONHDR,
+ ZVERSIONMAJOR, ZVERSIONMINOR_GALAXY);
+
+ if (Z_AddField(&ptr, version_galaxy, end))
+ return (ZERR_HEADERLEN);
+
+ if (Z_AddField(&ptr, notice->z_dest_galaxy, end))
+ return (ZERR_HEADERLEN);
+ }
- if (ZMakeAscii32(ptr, end-ptr, Z_NUMFIELDS + notice->z_num_other_fields)
+ if (cksum_start)
+ *cksum_start = ptr;
+
+ if (!version_nogalaxy[0])
+ (void) sprintf(version_nogalaxy, "%s%d.%d", ZVERSIONHDR,
+ ZVERSIONMAJOR, ZVERSIONMINOR_NOGALAXY);
+
+ notice->z_version = version_nogalaxy;
+
+ if (Z_AddField(&ptr, version_nogalaxy, end))
+ return (ZERR_HEADERLEN);
+
+ if (ZMakeAscii32(ptr, end-ptr,
+ Z_NUMFIELDS + notice->z_num_other_fields)
== ZERR_FIELDLEN)
return (ZERR_HEADERLEN);
ptr += strlen(ptr)+1;
return (ZERR_HEADERLEN);
}
else {
- if (strlen(notice->z_recipient) + strlen(__Zephyr_realm) + 2 >
- sizeof(newrecip))
- return (ZERR_HEADERLEN);
- (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm);
+ (void) sprintf(newrecip, "%s@%s", notice->z_recipient,
+ ZGetRhs(notice->z_dest_galaxy));
if (Z_AddField(&ptr, newrecip, end))
return (ZERR_HEADERLEN);
}
if (Z_AddField(&ptr, notice->z_other_fields[i], end))
return (ZERR_HEADERLEN);
- *len = ptr-buffer;
-
+ if (cksum_len)
+ *cksum_len = ptr-*cksum_start;
+
+ *hdr_len = ptr-buffer;
+
return (ZERR_NONE);
}
ZNotice_t partnotice;
ZPacket_t buffer;
char multi[64];
- int offset, hdrsize, fragsize, ret_len, message_len, waitforack;
+ int i, offset, hdrsize, fragsize, ret_len, message_len, waitforack;
Code_t retval;
hdrsize = len-notice->z_message_len;
htonl((u_long) partnotice.z_uid.tv.tv_sec);
partnotice.z_uid.tv.tv_usec =
htonl((u_long) partnotice.z_uid.tv.tv_usec);
- (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr,
- sizeof(__My_addr));
+
+ for (i=0; i<__ngalaxies; i++)
+ if (notice->z_dest_galaxy == 0 ||
+ strcmp(__galaxy_list[i].galaxy_config.galaxy,
+ notice->z_dest_galaxy) == 0) {
+ memcpy((char *)&partnotice.z_uid.zuid_addr,
+ &__galaxy_list[i].galaxy_config.server_list[0].my_addr.s_addr,
+ sizeof(struct in_addr));
+ break;
+ }
}
message_len = min(notice->z_message_len-offset, fragsize);
partnotice.z_message = notice->z_message+offset;
return (ZERR_NONE);
}
+void Z_SourceAddr(peer_addr, my_addr)
+ struct in_addr *peer_addr, *my_addr;
+{
+ int s;
+ struct sockaddr_in s_in;
+ socklen_t sinsize;
+ struct hostent *hent;
+ char hostname[1024];
+
+ my_addr->s_addr = INADDR_NONE;
+
+ if (peer_addr->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(&s_in, 0, sizeof(s_in));
+ s_in.sin_family = AF_INET;
+ memcpy(&s_in.sin_addr, peer_addr, sizeof(*peer_addr));
+ s_in.sin_port = HM_SRV_SVC_FALLBACK;
+ sinsize = sizeof(s_in);
+ if (connect(s, (struct sockaddr *) &s_in, sizeof(s_in)) == 0
+ && getsockname(s, (struct sockaddr *) &s_in, &sinsize) == 0
+ && s_in.sin_addr.s_addr != 0)
+ memcpy(my_addr, &s_in.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) */
+ if (gethostname(hostname, sizeof(hostname)) == 0) {
+ hent = gethostbyname(hostname);
+ if (hent && hent->h_addrtype == AF_INET)
+ memcpy(my_addr, hent->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;
+}
+
+Code_t Z_ParseGalaxyConfig(str, gc)
+ char *str;
+ Z_GalaxyConfig *gc;
+{
+ char *ptra, *ptrb;
+ struct hostent *hp;
+ enum { CLUSTER, SLOC, HOSTLIST } listtype;
+ int hostcount;
+ struct in_addr *my_addr, *serv_addr;
+#ifdef HAVE_HESIOD
+ char **hes_serv_list;
+#endif
+
+ gc->galaxy = NULL;
+
+ /* skip whitespace, check for eol or comment */
+
+ ptra = str;
+ while (*ptra && isspace(*ptra)) ptra++;
+
+ if (*ptra == '\0' || *ptra == '#') {
+ /* no galaxy is ok, it's a blank line */
+ return(ZERR_NONE);
+ }
+
+ /* scan the galaxy */
+
+ ptrb = ptra;
+ while(*ptrb && !isspace(*ptrb) && *ptrb != '#') ptrb++;
+
+ if ((gc->galaxy = (char *) malloc(ptrb - ptra + 1)) == NULL)
+ return(ENOMEM);
+
+ strncpy(gc->galaxy, ptra, ptrb - ptra);
+ gc->galaxy[ptrb - ptra] = '\0';
+
+ /* skip whitespace, check for eol or comment */
+
+ ptra = ptrb;
+ while (*ptra && isspace(*ptra)) ptra++;
+
+ if (*ptra == '\0' || *ptra == '#') {
+ free(gc->galaxy);
+ return(ZERR_BADCONFGALAXY);
+ }
+
+ /* scan the type */
+
+ ptrb = ptra;
+ while(*ptrb && !isspace(*ptrb) && *ptrb != '#') ptrb++;
+
+#ifdef HAVE_HESIOD
+ if (strncasecmp("hes-cluster", ptra, ptrb - ptra) == 0) {
+ listtype = CLUSTER;
+ } else if (strncasecmp("hes-sloc", ptra, ptrb - ptra) == 0) {
+ listtype = SLOC;
+ } else
+#endif
+ if (strncasecmp("hostlist", ptra, ptrb - ptra) == 0) {
+ listtype = HOSTLIST;
+ } else {
+ free(gc->galaxy);
+ return(ZERR_BADCONF);
+ }
+
+#ifdef HAVE_HESIOD
+ if (listtype == CLUSTER || listtype == SLOC) {
+ char *zcluster;
+
+ if (listtype == CLUSTER) {
+ char hostname[1024];
+
+ if (gethostname(hostname, sizeof(hostname)) != 0) {
+ zcluster = 0;
+ } else {
+ char **clust_info, **cpp;
+
+ if ((clust_info = hes_resolve(hostname, "CLUSTER")) == NULL) {
+ zcluster = 0;
+ } else {
+ for (cpp = clust_info; *cpp; cpp++) {
+ if (strncasecmp("ZCLUSTER", *cpp, 9) == 0) {
+ register char *c;
+
+ if ((c = strchr(*cpp, ' ')) == 0) {
+ for (cpp = clust_info; *cpp; cpp++)
+ free(*cpp);
+ return(ZERR_BADCONFGALAXY);
+ } else {
+ if ((zcluster =
+ malloc((unsigned)(strlen(c+1)+1)))
+ != NULL) {
+ strcpy(zcluster, c+1);
+ } else {
+ for (cpp = clust_info; *cpp; cpp++)
+ free(*cpp);
+ return(ENOMEM);
+ }
+ }
+ break;
+ }
+ }
+ for (cpp = clust_info; *cpp; cpp++)
+ free(*cpp);
+ if (zcluster == NULL) {
+ if ((zcluster =
+ malloc((unsigned)(strlen("zephyr")+1))) != NULL)
+ strcpy(zcluster, "zephyr");
+ else
+ return(ENOMEM);
+ }
+ }
+ }
+ } else {
+ /* skip whitespace, check for eol or comment */
+
+ ptra = ptrb;
+ while (*ptra && isspace(*ptra)) ptra++;
+
+ if (*ptra == '\0' || *ptra == '#') {
+ free(gc->galaxy);
+ return(ZERR_BADCONFGALAXY);
+ }
+
+ /* scan for the service name for the sloc lookup */
+
+ ptrb = ptra;
+ while(*ptrb && !isspace(*ptrb) && *ptrb != '#') ptrb++;
+
+ if ((zcluster = (char *) malloc(ptrb - ptra + 1)) == NULL) {
+ free(gc->galaxy);
+ return(ENOMEM);
+ }
+
+ strncpy(zcluster, ptra, ptrb - ptra);
+ zcluster[ptrb - ptra] = '\0';
+
+ /* skip whitespace, check for eol or comment */
+
+ ptra = ptrb;
+ while (*ptra && isspace(*ptra)) ptra++;
+
+ if (*ptra != '\0' && *ptra != '#') {
+ free(zcluster);
+ free(gc->galaxy);
+ return(ZERR_BADCONF);
+ }
+ }
+
+ /* get the server list from hesiod */
+
+ if (((hes_serv_list = hes_resolve(zcluster, "sloc")) == NULL) ||
+ (hes_serv_list[0] == NULL)) {
+ syslog(LOG_ERR, "No hesiod for galaxy %s (%s sloc)",
+ gc->galaxy, zcluster);
+ free(zcluster);
+ free(gc->galaxy);
+ /* treat this as an empty line, since other lines may succeed */
+ gc->galaxy = NULL;
+ return(ZERR_NONE);
+ }
+
+ free(zcluster);
+ }
+#endif
+
+ /* scan hosts */
+
+ gc->server_list = NULL;
+ gc->nservers = 0;
+ hostcount = 0;
+
+ while (1) {
+ if (gc->server_list) {
+ gc->server_list = (Z_SrvNameAddr *)
+ realloc(gc->server_list,
+ sizeof(Z_SrvNameAddr)*(gc->nservers+1));
+ } else {
+ gc->server_list = (Z_SrvNameAddr *)
+ malloc(sizeof(Z_SrvNameAddr));
+ }
+
+ if (gc->server_list == NULL) {
+ free(gc->galaxy);
+ return(ENOMEM);
+ }
+
+#ifdef HAVE_HESIOD
+ if (listtype == CLUSTER || listtype == SLOC) {
+ if (*hes_serv_list == NULL)
+ break;
+
+ /* this is clean, but only because hesiod memory management
+ is gross */
+ gc->server_list[gc->nservers].name = *hes_serv_list;
+ hes_serv_list++;
+ } else
+#endif
+ if (listtype == HOSTLIST) {
+ /* skip whitespace, check for eol or comment */
+
+ ptra = ptrb;
+ while (*ptra && isspace(*ptra)) ptra++;
+
+ if (*ptra == '\0' || *ptra == '#') {
+ /* end of server list */
+ break;
+ }
+
+ /* scan a hostname */
+
+ ptrb = ptra;
+ while(*ptrb && !isspace(*ptrb) && *ptrb != '#') ptrb++;
+
+ if ((gc->server_list[gc->nservers].name =
+ (char *) malloc(ptrb - ptra + 1))
+ == NULL) {
+ free(gc->server_list);
+ free(gc->galaxy);
+ return(ENOMEM);
+ }
+
+ strncpy(gc->server_list[gc->nservers].name, ptra, ptrb - ptra);
+ gc->server_list[gc->nservers].name[ptrb - ptra] = '\0';
+ }
+
+ hostcount++;
+
+ /* now, take the hesiod or hostlist hostname, and resolve it */
+
+ if ((hp = gethostbyname(gc->server_list[gc->nservers].name)) == NULL) {
+ /* if the address lookup fails authoritatively from a
+ hostlist, return an error. Otherwise, syslog. This
+ could cause a syslog from a client, but only if a
+ lookup which succeeded from zhm earlier fails now.
+ This isn't perfect, but will do. */
+
+ if (h_errno != TRY_AGAIN && listtype == HOSTLIST) {
+ free(gc->server_list);
+ free(gc->galaxy);
+ return(ZERR_BADCONFHOST);
+ } else {
+ syslog(LOG_ERR, "Lookup for server %s for galaxy %s failed, continuing",
+ gc->server_list[gc->nservers].name, gc->galaxy);
+
+ /* in an ideal world, when we need to find a new
+ server, or when we receive a packet from a server
+ we don't know, we would redo the lookup, but this
+ takes a long time, and blocks. So for now, we'll
+ only do this when we reread the config info. */
+
+ continue;
+ }
+ }
+
+ /* XXX this isn't quite right for multihomed servers. In that
+ case, we should add an entry to server_list for each unique
+ address */
+
+ serv_addr = &gc->server_list[gc->nservers].addr;
+
+ if (hp->h_length < sizeof(*serv_addr)) {
+ syslog(LOG_ERR, "Lookup for server %s for galaxy %s failed (h_length < %d), continuing",
+ gc->server_list[gc->nservers].name, gc->galaxy,
+ sizeof(*serv_addr));;
+ continue;
+ }
+
+ memcpy((char *) serv_addr, hp->h_addr, sizeof(*serv_addr));
+
+ my_addr = &gc->server_list[gc->nservers].my_addr;
+
+ Z_SourceAddr(serv_addr, my_addr);
+
+ gc->nservers++;
+ }
+
+ if (gc->nservers == 0) {
+ if (hostcount) {
+ /* this means the net was losing. skip this galaxy, because
+ another one might be ok. */
+
+ free(gc->server_list);
+ free(gc->galaxy);
+ gc->galaxy = NULL;
+ return(ZERR_NONE);
+ } else {
+ /* this means that a hostlist was empty */
+
+ return(ZERR_BADCONFGALAXY);
+ }
+ }
+
+ return(ZERR_NONE);
+}
+
+Code_t Z_FreeGalaxyConfig(gc)
+ Z_GalaxyConfig *gc;
+{
+ int i;
+
+ for (i=0; i<gc->nservers; i++)
+ free(gc->server_list[i].name);
+
+ free(gc->server_list);
+ free(gc->galaxy);
+
+ return(ZERR_NONE);
+}
+
/*ARGSUSED*/
Code_t Z_XmitFragment(notice, buf, len, wait)
ZNotice_t *notice;
#undef ZGetDestAddr
struct sockaddr_in ZGetDestAddr () { return __HM_addr; }
-#undef ZGetRealm
-Zconst char * ZGetRealm () { return __Zephyr_realm; }
-
#undef ZSetDebug
void ZSetDebug(proc, arg)
void (*proc) __P((const char *, va_list, void *));
*
* Created by: John T. Kohl
*
- * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/main.c,v $
- * $Author: zacheiss $
+ * $Source$
+ * $Author$
*
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
* For copying and distribution information, see the file
#ifndef lint
#ifndef SABER
static const char rcsid_main_c[] =
- "$Id: main.c,v 1.69 2001/02/27 04:50:08 zacheiss Exp $";
+ "$Id$";
#endif
#endif
#define EVER (;;) /* don't stop looping */
static int do_net_setup __P((void));
+static int read_galaxy_list __P((void));
static int initialize __P((void));
static void usage __P((void));
static void do_reset __P((void));
unsigned short hm_port; /* host manager receiver port */
unsigned short hm_srv_port; /* host manager server sending port */
+galaxy_info *galaxy_list;
+int ngalaxies;
+
char *programname; /* set to the basename of argv[0] */
char myname[MAXHOSTNAMELEN]; /* my host name */
-char list_file[128];
+char acl_dir[MAXPATHLEN];
+char subs_file[MAXPATHLEN];
+char galaxy_file[MAXPATHLEN];
+char localconf_file[MAXPATHLEN];
+
#ifdef HAVE_KRB4
-char srvtab_file[128];
-char my_realm[REALM_SZ];
-static char tkt_file[128];
+char srvtab_file[MAXPATHLEN];
+char my_krealm[REALM_SZ];
+static char tkt_file[MAXPATHLEN];
#endif
-char acl_dir[128];
-char subs_file[128];
int zdebug;
#ifdef DEBUG_MALLOC
extern char *optarg;
extern int optind;
- sprintf(list_file, "%s/zephyr/%s", SYSCONFDIR, SERVER_LIST_FILE);
+ sprintf(acl_dir, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_ACL_DIR);
+ sprintf(subs_file, "%s/zephyr/%s", SYSCONFDIR, DEFAULT_SUBS_FILE);
+ sprintf(galaxy_file, "%s/zephyr/%s", SYSCONFDIR, GALAXY_FILE);
+ sprintf(localconf_file, "%s/zephyr/%s", SYSCONFDIR, LOCALCONF_FILE);
+
#ifdef HAVE_KRB4
sprintf(srvtab_file, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_SRVTAB);
sprintf(tkt_file, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_TKFILE);
#endif
- sprintf(acl_dir, "%s/zephyr/%s", SYSCONFDIR, ZEPHYR_ACL_DIR);
- sprintf(subs_file, "%s/zephyr/%s", SYSCONFDIR, DEFAULT_SUBS_FILE);
/* set name */
programname = strrchr(argv[0],'/');
programname = (programname) ? programname + 1 : argv[0];
/* process arguments */
- while ((optchar = getopt(argc, argv, "dsnv:f:k:")) != EOF) {
+ while ((optchar = getopt(argc, argv, "dsnv:f:g:")) != EOF) {
switch(optchar) {
case 'd':
zdebug = 1;
case 'n':
nofork = 1;
break;
- case 'k':
-#ifdef HAVE_KRB4
- strncpy(my_realm, optarg, REALM_SZ);
-#endif
- break;
case 'v':
bdump_version = optarg;
break;
init_from_dump = 0;
dumpfile = optarg;
break;
+ case 'g':
+ strcpy(my_galaxy, optarg);
+ break;
case '?':
default:
usage();
srvtab_file);
exit(1);
}
- /* Use local realm if not specified on command line. */
- if (!*my_realm) {
- if (krb_get_lrealm(my_realm, 1) != KSUCCESS) {
- fputs("Couldn't get local Kerberos realm; exiting.\n", stderr);
- exit(1);
+
+ /* look up our local kerberos realm now */
+
+ {
+ int retval = krb_get_lrealm(my_krealm, 1);
+ if (retval != KSUCCESS) {
+ syslog(LOG_ERR, "get_tgt: krb_get_lrealm: %s",
+ krb_get_err_text(retval));
+ return(1);
}
}
+
#endif /* HAVE_KRB4 */
#ifndef DEBUG
if (do_net_setup())
return(1);
+ read_galaxy_list();
+
server_init();
#ifdef HAVE_KRB4
ZSetServerState(1);
ZInitialize(); /* set up the library */
-#ifdef HAVE_KRB4
- /* Override what Zinitialize set for ZGetRealm() */
- if (*my_realm)
- strcpy(__Zephyr_realm, my_realm);
-#endif
init_zsrv_err_tbl(); /* set up err table */
ZSetFD(srv_socket); /* set up the socket as the input fildes */
return 0;
}
+static int read_galaxy_list()
+{
+ FILE *file;
+ char buf[1024];
+ int lineno;
+ Code_t code;
+
+ if ((file = fopen(galaxy_file, "r")) == NULL) {
+ fprintf(stderr, "Error opening configuration file %s: %s\n",
+ galaxy_file, strerror(errno));
+ exit(1);
+ }
+
+ galaxy_list = 0;
+ ngalaxies = 0;
+
+ for (lineno = 1; ; lineno++) {
+ if (fgets(buf, sizeof(buf), file) == NULL) {
+ if (ferror(file)) {
+ fprintf(stderr,
+ "Error reading configuration file %s: %s",
+ galaxy_file, strerror(errno));
+ exit(1);
+ }
+ break;
+ }
+
+ if (galaxy_list) {
+ galaxy_list = (galaxy_info *)
+ realloc(galaxy_list, sizeof(galaxy_info)*(ngalaxies+1));
+ } else {
+ galaxy_list = (galaxy_info *)
+ malloc(sizeof(galaxy_info));
+ }
+
+ if (galaxy_list == NULL) {
+ fprintf(stderr,
+ "Out of memory reading configuration file %s",
+ galaxy_file);
+ exit(1);
+ }
+
+ if (code = Z_ParseGalaxyConfig(buf,
+ &galaxy_list[ngalaxies].galaxy_config)) {
+ fprintf(stderr,
+ "Error in configuration file %s, line %d: %s",
+ galaxy_file, lineno, error_message(code));
+ exit(1);
+ }
+
+ if (galaxy_list[ngalaxies].galaxy_config.galaxy)
+ ngalaxies++;
+ }
+
+
+ if (ngalaxies == 0) {
+ fprintf(stderr,
+ "Configuration file %s did not contain any valid galaxies.");
+ exit(1);
+ }
+
+ return(0);
+}
/*
* print out a usage message.
usage()
{
#ifdef DEBUG
- fprintf(stderr, "Usage: %s [-d] [-s] [-n] [-k realm] [-f dumpfile]\n",
+ fprintf(stderr, "Usage: %s [-d] [-s] [-n] [-g galaxy] [-f dumpfile]\n",
programname);
#else
- fprintf(stderr, "Usage: %s [-d] [-n] [-k realm] [-f dumpfile]\n",
+ fprintf(stderr, "Usage: %s [-d] [-n] [-g galaxy] [-f dumpfile]\n",
programname);
#endif /* DEBUG */
exit(2);
static void dump_strings()
{
- char filename[128];
+ char filename[MAXPATHLEN];
FILE *fp;
int oerrno = errno;
FILE *fp;
int oerrno = errno;
int pid;
- char filename[128];
+ char filename[MAXPATHLEN];
pid = (fork_for_dump) ? fork() : -1;
if (pid > 0) {
#endif
/* reset various things in the server's state */
+ read_galaxy_list();
subscr_reset();
server_reset();
access_reinit();
* Code_t realm_send_realms()
* loops through all realms for a brain dump
*
- * int realm_bound_for_realm(char *realm, char *recip)
- * figures out if recip is in realm, expanding recip's realm
- *
* int realm_sender_in_realm(char *realm, char *sender)
* figures out if sender is in realm
*
int a;
/* First, look for an exact match (case insensitive) */
-#ifdef HAVE_KRB4
- if (!strcasecmp(ZGetRealm(), realmname))
- return(ZGetRealm());
-#endif
+ if (!strcasecmp(my_galaxy, realmname))
+ return(my_galaxy);
for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
if (!strcasecmp(realm->name, realmname))
return(realm->name);
/* No exact match. See if there's a partial match */
-#ifdef HAVE_KRB4
- if (!strncasecmp(ZGetRealm(), realmname, strlen(realmname)))
- return(ZGetRealm());
-#endif
+ if (!strncasecmp(my_galaxy, realmname, strlen(realmname)))
+ return(my_galaxy);
for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
if (!strncasecmp(realm->name, realmname, strlen(realmname)))
return;
}
-Realmname *
-get_realm_lists(file)
- char *file;
-{
- Realmname *rlm_list, *rlm;
- int ii, nused, ntotal;
- FILE *fp;
- char buf[REALM_SZ + MAXHOSTNAMELEN + 1]; /* one for newline */
- char realm[REALM_SZ], server[MAXHOSTNAMELEN + 1];
-
- nused = 0;
- if (!(fp = fopen(file, "r")))
- return((Realmname *)0);
-
- /* start with 16, realloc if necessary */
- ntotal = 16;
- rlm_list = (Realmname *)malloc(ntotal * sizeof(Realmname));
- if (!rlm_list) {
- syslog(LOG_CRIT, "get_realm_lists malloc");
- abort();
- }
-
- while (fgets(buf, REALM_SZ + MAXHOSTNAMELEN + 1, fp)) {
- if (sscanf(buf, "%s %s", realm, server) != 2) {
- syslog(LOG_CRIT, "bad format in %s", file);
- abort();
- }
- for (ii = 0; ii < nused; ii++) {
- /* look for this realm */
- if (!strcmp(rlm_list[ii].name, realm))
- break;
- }
- if (ii < nused) {
- rlm = &rlm_list[ii];
- if (rlm->nused +1 >= rlm->nservers) {
- /* make more space */
- rlm->servers = (char **)realloc((char *)rlm->servers,
- (unsigned)rlm->nservers * 2 *
- sizeof(char *));
- if (!rlm->servers) {
- syslog(LOG_CRIT, "get_realm_lists realloc");
- abort();
- }
- rlm->nservers *= 2;
- }
- rlm->servers[rlm->nused++] = strsave(server);
- } else {
- /* new realm */
- if (nused + 1 >= ntotal) {
- /* make more space */
- rlm_list = (Realmname *)realloc((char *)rlm_list,
- (unsigned)ntotal * 2 *
- sizeof(Realmname));
- if (!rlm_list) {
- syslog(LOG_CRIT, "get_realm_lists realloc");
- abort();
- }
- ntotal *= 2;
- }
- rlm = &rlm_list[nused++];
- strcpy(rlm->name, realm);
- rlm->nused = 0;
- rlm->nservers = 16;
- rlm->servers = (char **)malloc(rlm->nservers * sizeof(char *));
- if (!rlm->servers) {
- syslog(LOG_CRIT, "get_realm_lists malloc");
- abort();
- }
- rlm->servers[rlm->nused++] = strsave(server);
- }
- }
- if (nused + 1 >= ntotal) {
- rlm_list = (Realmname *)realloc((char *)rlm_list,
- (unsigned)(ntotal + 1) *
- sizeof(Realmname));
- if (!rlm_list) {
- syslog(LOG_CRIT, "get_realm_lists realloc");
- abort();
- }
- }
- *rlm_list[nused].name = '\0';
-
- return(rlm_list);
-}
-
Code_t
realm_send_realms()
{
}
}
-int
-realm_bound_for_realm(realm, recip)
- char *realm;
- char *recip;
-{
- char *rlm = NULL;
- int remote = strcmp(ZGetRealm(), realm);
-
- if (recip)
- rlm = strchr(recip, '@');
-
- if (!rlm && !remote)
- return 1;
-
- if (rlm && strcmp(realm_expand_realm(rlm + 1), realm) == 0)
- return 1;
-
- return 0;
-}
-
int
realm_sender_in_realm(realm, sender)
char *realm;
char *sender;
{
- char *rlm = NULL;
- int remote = strcmp(ZGetRealm(), realm);
+ char *senderrealm = NULL;
+ int local = (strcmp(my_galaxy, realm) == 0);
if (sender)
- rlm = strchr(sender, '@');
+ senderrealm = strrchr(sender, '@');
- if (!rlm && !remote)
+ if (!senderrealm && local)
return 1;
- if (rlm && strcmp((rlm + 1), realm) == 0)
+ if (senderrealm && strcmp(senderrealm + 1, realm) == 0)
return 1;
return 0;
realm = strchr(notice->z_sender, '@');
- if (!realm || !strcmp(realm + 1, ZGetRealm()))
+ if (!realm || !strcmp(realm + 1, my_galaxy))
return 1;
return 0;
sprintf(rlm_recipient, "@%s", realm->name);
notice->z_recipient = rlm_recipient;
- sendit(notice, 1, who, 0);
+ sendit(notice, 1, who, 0, 0);
}
} else if (class_is_ulocate(notice_class)) {
status = realm_ulocate_dispatch(notice, auth, who, server, realm);
sprintf(rlm_recipient, "@%s", realm->name);
notice->z_recipient = rlm_recipient;
external = 0;
- } else if (realm_bound_for_realm(ZGetRealm(), notice->z_recipient)
- && *notice->z_recipient == '@')
- {
+ } else if ((*notice->z_recipient == '@') &&
+ (strcmp(realm_expand_realm(notice->z_recipient+1),
+ my_galaxy) == 0)) {
/* we're responsible for getting this message out */
external = 1;
notice->z_recipient = "";
}
/* otherwise, send to local subscribers */
- sendit(notice, auth, who, external);
+ sendit(notice, auth, who, external, external);
}
return(status);
realm_init()
{
Client *client;
- Realmname *rlmnames;
Realm *rlm;
- int ii, jj, found;
- struct in_addr *addresses;
- struct hostent *hp;
- char list_file[128];
+ int ii, jj;
char rlmprinc[ANAME_SZ+INST_SZ+REALM_SZ+3];
- sprintf(list_file, "%s/zephyr/%s", SYSCONFDIR, REALM_LIST_FILE);
- rlmnames = get_realm_lists(list_file);
- if (!rlmnames) {
- zdbug((LOG_DEBUG, "No other realms"));
- nrealms = 0;
- return;
- }
-
- for (nrealms = 0; *rlmnames[nrealms].name; nrealms++);
+ nrealms = ngalaxies-1;
otherrealms = (Realm *)malloc(nrealms * sizeof(Realm));
if (!otherrealms) {
abort();
}
- for (ii = 0; ii < nrealms; ii++) {
- rlm = &otherrealms[ii];
- strcpy(rlm->name, rlmnames[ii].name);
+ /* copy necessary state from galaxy_list. */
+
+ rlm = otherrealms;
+ for (ii = 0; ii < ngalaxies; ii++) {
+ // skip the local galaxy
+ if (strcmp(galaxy_list[ii].galaxy_config.galaxy, my_galaxy) == 0)
+ continue;
+
+ strcpy(rlm->name, galaxy_list[ii].galaxy_config.galaxy);
- addresses = (struct in_addr *)malloc(rlmnames[ii].nused *
- sizeof(struct in_addr));
- if (!addresses) {
- syslog(LOG_CRIT, "malloc failed in realm_init");
- abort();
- }
- /* convert names to addresses */
- found = 0;
- for (jj = 0; jj < rlmnames[ii].nused; jj++) {
- hp = gethostbyname(rlmnames[ii].servers[jj]);
- if (hp) {
- memmove((caddr_t) &addresses[found], (caddr_t)hp->h_addr,
- sizeof(struct in_addr));
- found++;
- } else
- syslog(LOG_WARNING, "hostname failed, %s",
- rlmnames[ii].servers[jj]);
- /* free the hostname */
- free(rlmnames[ii].servers[jj]);
- }
- rlm->count = found;
- rlm->addrs = (struct sockaddr_in *)malloc(found *
+ rlm->count = galaxy_list[ii].galaxy_config.nservers;
+ rlm->addrs = (struct sockaddr_in *)malloc(rlm->count *
sizeof (struct sockaddr_in));
if (!rlm->addrs) {
syslog(LOG_CRIT, "malloc failed in realm_init");
rlm->addrs[jj].sin_family = AF_INET;
/* use the server port */
rlm->addrs[jj].sin_port = srv_addr.sin_port;
- rlm->addrs[jj].sin_addr = addresses[jj];
+ rlm->addrs[jj].sin_addr =
+ galaxy_list[ii].galaxy_config.server_list[jj].addr;
}
client = (Client *) malloc(sizeof(Client));
if (!client) {
/* Assume the best */
rlm->state = REALM_TARDY;
rlm->have_tkt = 1;
- free(rlmnames[ii].servers);
- free(addresses);
+
+ rlm++;
}
- free(rlmnames);
}
void
zdbug((LOG_DEBUG, "rlm_deathgram: suggesting %s to %s",
(server) ? server->addr_str : "nothing", realm->name));
-#ifdef HAVE_KRB4
if (!ticket_lookup(realm->name))
if ((retval = ticket_retrieve(realm)) != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_deathgram failed: %s",
error_message(retval));
return;
}
-#endif
if ((retval = ZFormatNotice(&snotice, &pack, &packlen, ZAUTH))
!= ZERR_NONE)
Realm *realm;
char rlm_recipient[REALM_SZ + 1];
+#ifdef HAVE_KRB4
+ char galaxy_config[1024];
+ Code_t code;
+
+ /* XXX the library won't initialize from zhm, because there might
+ not be one. We're about to call ZFormatNotice, which will call
+ ZMakeAuthentication(), which will fail because there is no
+ library galaxy list. So, we create a single galaxy entry with
+ the local realm. */
+
+ __ngalaxies = 1;
+ __galaxy_list = (Z_GalaxyList *) malloc(sizeof(Z_GalaxyList)*1);
+
+ strcpy(galaxy_config, "local-galaxy hostlist localhost");
+
+ if ((code =
+ Z_ParseGalaxyConfig(galaxy_config,
+ &__galaxy_list[0].galaxy_config))
+ != ZERR_NONE) {
+ syslog(LOG_ERR, "rlm_wakeup galaxy init: impossible error");
+ __ngalaxies = 0;
+ free(__galaxy_list);
+ return;
+ }
+
+ strcpy(__galaxy_list[0].krealm, my_krealm);
+
+ __galaxy_list[0].last_authent_time = 0;
+#endif
+
for (jj = 1; jj < nservers; jj++) { /* skip limbo server */
if (jj != me_server_idx && otherservers[jj].state == SERV_UP)
found++;
snotice.z_message = NULL;
snotice.z_message_len = 0;
-#ifdef HAVE_KRB4
if (!ticket_lookup(realm->name))
if ((retval = ticket_retrieve(realm)) != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_wakeup failed: %s",
error_message(retval));
continue;
}
-#endif
if ((retval = ZFormatNotice(&snotice, &pack, &packlen, ZAUTH))
!= ZERR_NONE)
CREDENTIALS cred;
KTEXT_ST authent;
ZNotice_t partnotice, newnotice;
+ struct in_addr my_addr;
offset = 0;
buffer_len = sizeof(ZPacket_t);
- retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen, &ptr,
- NULL);
+ retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
+ NULL, NULL, &ptr, NULL);
if (retval != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
free(buffer);
#endif
retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
- NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (retval != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
free(buffer);
fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE;
+ Z_SourceAddr(&realm->addrs[realm->idx].sin_addr, &my_addr);
+
while (offset < notice->z_message_len || !notice->z_message_len) {
(void) sprintf(multi, "%d/%d", offset+origoffset, origlen);
partnotice.z_multinotice = multi;
if (offset > 0) {
- (void) Z_gettimeofday(&partnotice.z_uid.tv,
- (struct timezone *)0);
+ (void) gettimeofday(&partnotice.z_uid.tv,
+ (struct timezone *)0);
partnotice.z_uid.tv.tv_sec = htonl((u_long)
partnotice.z_uid.tv.tv_sec);
partnotice.z_uid.tv.tv_usec =
htonl((u_long) partnotice.z_uid.tv.tv_usec);
- (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr,
- sizeof(__My_addr));
+ (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;
}
retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len,
- &hdrlen, &ptr, NULL);
+ &hdrlen, &ptr, NULL, NULL, NULL);
if (retval != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_sendit_auth raw: %s",
error_message(retval));
#endif
retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len,
- &hdrlen, NULL, NULL);
+ &hdrlen, NULL, NULL, NULL, NULL);
if (retval != ZERR_NONE) {
syslog(LOG_WARNING, "rlm_sendit_auth raw: %s",
error_message(retval));
*
* Created by: John T. Kohl
*
- * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/server.c,v $
- * $Author: zacheiss $
+ * $Source$
+ * $Author$
*
* Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
* For copying and distribution information, see the file
#include <zephyr/mit-copyright.h>
#include "zserver.h"
#include <sys/socket.h>
+#include <string.h>
#ifndef lint
#ifndef SABER
-static const char rcsid_server_c[] = "$Id: server.c,v 1.66 2001/02/27 04:51:41 zacheiss Exp $";
+static const char rcsid_server_c[] = "$Id$";
#endif
#endif
static Code_t server_register();
#endif
-static struct in_addr *get_server_addrs __P((int *number));
-static char **get_server_list __P((char *file));
-static void free_server_list __P((char **list));
+static int get_server_galaxy __P((const char *));
+
+char my_galaxy[MAXHOSTNAMELEN]; /* my galaxy name */
static Unacked *srv_nacktab[SRV_NACKTAB_HASHSIZE];
Server *otherservers; /* points to an array of the known
long timo_tardy = TIMO_TARDY;
long timo_dead = TIMO_DEAD;
-/* counters to measure old protocol use */
-#ifdef OLD_COMPAT
-int old_compat_count_uloc = 0;
-int old_compat_count_ulocate = 0;
-int old_compat_count_subscr = 0;
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
-int new_compat_count_uloc = 0;
-int new_compat_count_subscr = 0;
-#endif /* NEW_COMPAT */
-
#ifdef DEBUG
int zalone;
#endif /* DEBUG */
void
server_init()
{
- int i;
- struct in_addr *serv_addr, *server_addrs, limbo_addr;
+ int i, j;
+ struct in_addr *serv_addr, limbo_addr;
/* we don't need to mask SIGFPE here since when we are called,
the signal handler isn't set up yet. */
- /* talk to hesiod here, set nservers */
- server_addrs = get_server_addrs(&nservers);
- if (!server_addrs) {
- syslog(LOG_ERR, "No servers?!?");
+ if (get_server_galaxy(localconf_file)) {
+ syslog(LOG_ERR, "Could not read galaxy from %s", localconf_file);
+ exit(1);
+ }
+
+ for (j=0; j<ngalaxies; j++)
+ if (strcmp(galaxy_list[j].galaxy_config.galaxy, my_galaxy) == 0)
+ break;
+
+ if (j == ngalaxies) {
+ syslog(LOG_ERR, "Local galaxy (%s) not found in galaxy list",
+ my_galaxy);
exit(1);
}
else
#endif /* DEBUG */
/* increment servers to make room for 'limbo' */
- nservers++;
+ nservers = galaxy_list[j].galaxy_config.nservers+1;
otherservers = (Server *) malloc(nservers * sizeof(Server));
me_server_idx = -1;
otherservers[0].queue = NULL;
otherservers[0].dumping = 0;
- for (serv_addr = server_addrs, i = 1; i < nservers; serv_addr++, i++) {
+ for (i = 1; i < nservers; i++) {
+ serv_addr = &galaxy_list[j].galaxy_config.server_list[i-1].addr;
+
setup_server(&otherservers[i], serv_addr);
/* is this me? */
if (serv_addr->s_addr == my_addr.s_addr) {
}
}
- /* free up the addresses */
- free(server_addrs);
-
if (me_server_idx == -1) {
- syslog(LOG_WARNING, "I'm a renegade server!");
- otherservers = (Server *) realloc(otherservers,
- ++nservers * sizeof(Server));
- if (!otherservers) {
- syslog(LOG_CRIT, "renegade realloc");
- abort();
- }
- setup_server(&otherservers[nservers - 1], &my_addr);
- /* we are up. */
- otherservers[nservers - 1].state = SERV_UP;
-
- /* I don't send hello's to myself--cancel the timer */
- timer_reset(otherservers[nservers - 1].timer);
- otherservers[nservers - 1].timer = NULL;
-
- /* cancel and reschedule all the timers--pointers need
- adjusting */
- /* don't reschedule limbo's timer, so start i=1 */
- for (i = 1; i < nservers - 1; i++) {
- timer_reset(otherservers[i].timer);
- /* all the HELLO's are due now */
- otherservers[i].timer = timer_set_rel(0L, server_timo,
- &otherservers[i]);
- }
- me_server_idx = nservers - 1;
+ syslog(LOG_ERR, "I'm a renegade server!");
+ exit(1);
}
-
}
/*
server_reset()
{
int num_servers;
- struct in_addr *server_addrs;
struct in_addr *serv_addr;
Server *servers;
- int i, j;
+ int i, j, k;
int *ok_list_new, *ok_list_old;
int num_ok, new_num;
#endif /* DEBUG */
/* Find out what servers are supposed to be known. */
- server_addrs = get_server_addrs(&num_servers);
- if (!server_addrs) {
- syslog(LOG_ERR, "server_reset no servers. nothing done.");
+ for (k=0; k<ngalaxies; k++)
+ if (strcmp(galaxy_list[k].galaxy_config.galaxy, my_galaxy) == 0)
+ break;
+
+ if (k == ngalaxies) {
+ syslog(LOG_ERR, "server_reset: Local galaxy (%s) not found in galaxy list",
+ my_galaxy);
return;
}
- ok_list_new = (int *) malloc(num_servers * sizeof(int));
+
+ ok_list_new = (int *) malloc(galaxy_list[k].galaxy_config.nservers * sizeof(int));
if (!ok_list_new) {
syslog(LOG_ERR, "server_reset no mem new");
return;
num_ok = 1;
ok_list_old[0] = 1; /* limbo is OK */
- for (serv_addr = server_addrs, i = 0; i < num_servers; serv_addr++, i++) {
+ for (i=0; i<galaxy_list[k].galaxy_config.nservers; i++) {
+ serv_addr = &galaxy_list[k].galaxy_config.server_list[i].addr;
+
for (j = 1; j < nservers; j++) { /* j = 1 since we skip limbo */
if (otherservers[j].addr.sin_addr.s_addr == serv_addr->s_addr) {
/* if server is on both lists, mark */
for (i = 0; i < num_servers; i++) {
if (!ok_list_new[i]) {
setup_server(&otherservers[nservers - (new_num--)],
- &server_addrs[i]);
- syslog(LOG_INFO, "adding server %s", inet_ntoa(server_addrs[i]));
+ &galaxy_list[k].galaxy_config.server_list[i].addr);
+ syslog(LOG_INFO, "adding server %s",
+ inet_ntoa(galaxy_list[k].galaxy_config.server_list[i].addr));
}
}
- free(server_addrs);
/* reset timers, to go off now.
We can't get a time-left indication (bleagh!)
so we expire them all now. This will generally
sprintf(buf, "%d seconds operational",NOW - uptime);
upt = strsave(buf);
-#ifdef OLD_COMPAT
- if (old_compat_count_uloc)
- extrafields++;
- if (old_compat_count_ulocate)
- extrafields++;
- if (old_compat_count_subscr)
- extrafields++;
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
- if (new_compat_count_uloc)
- extrafields++;
- if (new_compat_count_subscr)
- extrafields++;
-#endif /* NEW_COMPAT */
extrafields += nrealms;
responses = (char **) malloc((NUM_FIXED + nservers + extrafields) *
sizeof(char *));
otherservers[i].dumping ? " (DUMPING)" : "");
responses[num_resp++] = strsave(buf);
}
-#ifdef OLD_COMPAT
- if (old_compat_count_uloc) {
- sprintf(buf, "%d old old location requests", old_compat_count_uloc);
- responses[num_resp++] = strsave(buf);
- }
- if (old_compat_count_ulocate) {
- sprintf(buf, "%d old old loc lookup requests",
- old_compat_count_ulocate);
- responses[num_resp++] = strsave(buf);
- }
- if (old_compat_count_subscr) {
- sprintf(buf, "%d old old subscr requests", old_compat_count_subscr);
- responses[num_resp++] = strsave(buf);
- }
-#endif /* OLD_COMPAT */
-#ifdef NEW_COMPAT
- if (new_compat_count_uloc) {
- sprintf(buf, "%d new old location requests", new_compat_count_uloc);
- responses[num_resp++] = strsave(buf);
- }
- if (new_compat_count_subscr) {
- sprintf(buf, "%d new old subscr requests", new_compat_count_subscr);
- responses[num_resp++] = strsave(buf);
- }
-#endif /* NEW_COMPAT */
for (realm = otherrealms, i = 0; i < nrealms ; i++, realm++) {
sprintf(buf, "%s(%s)/%s", realm->name,
inet_ntoa((realm->addrs[realm->idx]).sin_addr),
}
/*
- * Get a list of server addresses.
-#ifdef HAVE_HESIOD
- * This list is retrieved from Hesiod.
-#else
- * This list is read from a file.
-#endif
- * Return a pointer to an array of allocated storage. This storage is
- * freed by the caller.
+ * Get the local galaxy name.
*/
-static struct in_addr *
-get_server_addrs(number)
- int *number; /* RETURN */
-{
- int i;
- char **server_hosts = NULL;
- char **server_hosts_free = NULL;
- char **cpp;
- struct in_addr *addrs;
- struct in_addr *addr;
- struct hostent *hp;
-
- server_hosts = get_server_list(list_file);
- server_hosts_free = server_hosts;
-#ifdef HAVE_HESIOD
- if (!server_hosts)
- server_hosts = hes_resolve("zephyr","sloc");
-#endif
- if (!server_hosts)
- return NULL;
- /* count up */
- i = 0;
- for (cpp = server_hosts; *cpp; cpp++)
- i++;
-
- addrs = (struct in_addr *) malloc(i * sizeof(struct in_addr));
-
- /* Convert to in_addr's */
- for (cpp = server_hosts, addr = addrs, i = 0; *cpp; cpp++) {
- hp = gethostbyname(*cpp);
- if (hp) {
- memcpy(addr, hp->h_addr, sizeof(struct in_addr));
- addr++, i++;
- } else {
- syslog(LOG_WARNING, "hostname failed, %s", *cpp);
- }
- }
- *number = i;
- if (server_hosts_free)
- free_server_list(server_hosts_free);
- return addrs;
-}
-
-static int nhosts = 0;
-
-/*
- * read "file" to get a list of names of hosts to peer with.
- * The file should contain a list of host names, one per line.
- */
-
-static char **
-get_server_list(file)
- char *file;
+int get_server_galaxy(const char *file)
{
FILE *fp;
- char buf[MAXHOSTNAMELEN];
- char **ret_list;
- int nused = 0;
- char *newline;
+ char line[1024];
+ char *nl;
- /* start with 16, realloc if necessary */
- nhosts = 16;
- ret_list = (char **) malloc(nhosts * sizeof(char *));
+ /* if it's already set (presumably by -g), just return. */
+ if (my_galaxy[0] != '\0')
+ return;
fp = fopen(file, "r");
- if (fp) {
- while (fgets(buf, MAXHOSTNAMELEN, fp)) {
- /* nuke the newline, being careful not to overrun
- the buffer searching for it with strlen() */
- buf[MAXHOSTNAMELEN - 1] = '\0';
- newline = strchr(buf, '\n');
- if (newline)
- *newline = '\0';
-
- if (nused + 1 >= nhosts) {
- /* get more pointer space if necessary */
- /* +1 to leave room for null pointer */
- ret_list = (char **) realloc(ret_list, nhosts * 2);
- nhosts = nhosts * 2;
- }
- ret_list[nused++] = strsave(buf);
- }
- fclose(fp);
- } else {
- if (gethostname(buf, sizeof(buf)) < 0) {
- free(ret_list);
- return NULL;
+ if (!fp)
+ return(1);
+
+ while(!feof(fp)) {
+ if (!fgets(line, sizeof(line), fp)) {
+ fclose(fp);
+ return(2);
}
- ret_list[nused++] = strsave(buf);
+ if (strncasecmp(line, "galaxy=", 7) == 0)
+ break;
}
- ret_list[nused] = NULL;
- return ret_list;
-}
+ fclose(fp);
-/*
- * free storage allocated by get_server_list
- */
-static void
-free_server_list(list)
- char **list;
-{
- char **orig_list = list;
+ /* remove final newline */
+ nl = strchr(line, '\n');
+ if (nl)
+ *nl = '\0';
- if (!nhosts) /* nothing allocated */
- return;
- for (; *list; list++)
- free(*list);
- free(orig_list);
- return;
+ if (line+7 == '\0')
+ return(3);
+
+ strcpy(my_galaxy, line+7);
+
+ return(0);
}
/*
*
* Created by: John T. Kohl
*
- * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/zserver.h,v $
- * $Author: zacheiss $
+ * $Source$
+ * $Author$
* $Zephyr: /mit/zephyr/src/server/RCS/zserver.h,v 1.34 91/03/08 12:53:24 raeburn Exp $
*
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
struct _Destlist *next, **prev_p;
};
+typedef struct _galaxy_info {
+ Z_GalaxyConfig galaxy_config;
+} galaxy_info;
+
enum _Realm_state {
REALM_UP, /* Realm is up */
REALM_TARDY, /* Realm due for a hello XXX */
void clt_ack __P((ZNotice_t *notice, struct sockaddr_in *who, Sent_type sent));
void nack_release __P((Client *client));
void sendit __P((ZNotice_t *notice, int auth, struct sockaddr_in *who,
- int external));
+ int external, int local_dest));
void rexmit __P((void *));
void xmit __P((ZNotice_t *notice, struct sockaddr_in *dest, int auth,
Client *client));
Sched *check_key_sched_cache __P((des_cblock key));
void add_to_key_sched_cache __P((des_cblock key, Sched *sched));
int krb_set_key __P((char *key, int cvt));
-/* int krb_rd_req __P((KTEXT authent, char *service, char *instance,
- unsigned KRB_INT32 from_addr, AUTH_DAT *ad, char *fn)); */
+#if 0
+int krb_rd_req __P((KTEXT authent, char *service, char *instance,
+ unsigned KRB_INT32 from_addr, AUTH_DAT *ad, char *fn));
+#endif
int krb_find_ticket __P((KTEXT authent, KTEXT ticket));
int krb_get_lrealm __P((char *r, int n));
#endif
/* found in realm.c */
int realm_sender_in_realm __P((char *realm, char *sender));
-int realm_bound_for_realm __P((char *realm, char *recip));
+int realm_bound_for_my_galaxy __P((char *recip));
Realm *realm_which_realm __P((struct sockaddr_in *who));
Realm *realm_get_realm_by_name __P((char *name));
Realm *realm_get_realm_by_pid __P((int));
to right now */
extern int nfds; /* number to look at in select() */
extern int zdebug;
+extern galaxy_info *galaxy_list; /* list of all galaxies' servers */
+extern int ngalaxies;
extern char myname[]; /* domain name of this host */
-extern char list_file[];
#ifdef HAVE_KRB4
extern char srvtab_file[];
-extern char my_realm[];
+extern char my_krealm[];
#endif
extern char acl_dir[];
extern char subs_file[];
-extern const char version[];
+extern char localconf_file[];
extern u_long npackets; /* num of packets processed */
extern time_t uptime; /* time we started */
extern struct in_addr my_addr;
extern int rexmit_times[];
/* found in server.c */
+extern char my_galaxy[]; /* local galaxy of this zserver */
extern Server *otherservers; /* array of servers */
extern int me_server_idx; /* me (in the array of servers) */
extern int nservers; /* number of other servers*/
*
* Created by: John T. Kohl
*
- * $Id: zsrv_conf.h,v 1.13 1999/01/22 23:19:54 ghudson Exp $
+ * $Id$
*
* Copyright (c) 1988 by the Massachusetts Institute of Technology.
* For copying and distribution information, see the file
/* Path names are relative to CONFDIR, except for the class registry. */
-#define SERVER_LIST_FILE "server.list"
-#define REALM_LIST_FILE "realm.list"
+#define ZEPHYR_CLASS_REGISTRY "class-registry.acl"
+
+#define ZEPHYR_ACL_DIR "acl/"
+#define DEFAULT_SUBS_FILE "default.subscriptions"
+#define GALAXY_FILE "galaxy.list"
+#define LOCALCONF_FILE "zephyrd.conf"
+
#ifdef HAVE_KRB4
#define ZEPHYR_SRVTAB "srvtab"
#define ZEPHYR_TKFILE "ztkts"
#endif
-#define ZEPHYR_ACL_DIR "acl/"
-#define ZEPHYR_CLASS_REGISTRY "class-registry.acl"
-#define DEFAULT_SUBS_FILE "default.subscriptions"
#define REXMIT_TIMES { 2, 2, 4, 4, 8, 8, 16, 32, 64, 128, 256, 512, -1 }
#define NUM_REXMIT_TIMES 12
*
* Created by: David C. Jedlinsky
*
- * $Id: zhm.c,v 1.62 2000/05/19 23:19:21 zacheiss Exp $
+ * $Id$
*
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
* For copying and distribution information, see the file
* "mit-copyright.h".
*/
-#include "zhm.h"
+#include <stdio.h>
+#include <errno.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
-static const char rcsid_hm_c[] = "$Id: zhm.c,v 1.62 2000/05/19 23:19:21 zacheiss Exp $";
+#include "zhm.h"
-#ifdef HAVE_HESIOD
-int use_hesiod = 0;
-#endif
+static const char rcsid_hm_c[] = "$Id$";
#ifdef macII
#define srandom srand48
#endif
-#define PIDDIR "/var/run/"
+#ifdef _PATH_VARRUN
+#define PIDDIR _PATH_VARRUN
+#else
+#define PIDDIR "/etc/"
+#endif
-int hmdebug, rebootflag, noflushflag, errflg, dieflag, inetd, oldpid, nofork;
-int no_server = 1, nservchang, nserv, nclt;
-int booting = 1, timeout_type, deactivated = 1;
-long starttime;
+
+int hmdebug = 0, noflushflag = 0;
+time_t starttime;
u_short cli_port;
-struct sockaddr_in cli_sin, serv_sin, from;
-int numserv;
-char **serv_list = NULL;
-char prim_serv[MAXHOSTNAMELEN], cur_serv[MAXHOSTNAMELEN];
-char *zcluster;
-int deactivating = 0;
-int terminating = 0;
-struct hostent *hp;
-char hostname[MAXHOSTNAMELEN], loopback[4];
+struct sockaddr_in cli_sin;
char PidFile[128];
-static RETSIGTYPE deactivate __P((void));
-static RETSIGTYPE terminate __P((void));
-static void choose_server __P((void));
-static void init_hm __P((void));
+char *conffile = NULL;
+char *confline = NULL;
+galaxy_info *galaxy_list = NULL;
+int ngalaxies = 0;
+
+volatile int deactivating = 0;
+volatile int terminating = 0;
+
+static RETSIGTYPE deactivate __P(());
+static RETSIGTYPE terminate __P(());
+static void init_hm __P((int, int));
+static void parse_conf __P((char *, char *));
static void detach __P((void));
static void send_stats __P((ZNotice_t *, struct sockaddr_in *));
static char *strsave __P((const char *));
extern int optind;
+extern char *optarg;
-static RETSIGTYPE deactivate()
+static RETSIGTYPE deactivate(int signo)
{
deactivating = 1;
}
-static RETSIGTYPE terminate()
+static RETSIGTYPE terminate(int signo)
{
terminating = 1;
}
+static void die_gracefully()
+{
+ int i;
+
+ syslog(LOG_INFO, "Terminate signal caught...");
+
+ for (i=0; i<ngalaxies; i++)
+ galaxy_flush(&galaxy_list[i]);
+
+ unlink(PidFile);
+ closelog();
+ exit(0);
+}
+
main(argc, argv)
char *argv[];
{
ZPacket_t packet;
Code_t ret;
int opt, pak_len, i, j = 0, fd, count;
+ int dieflag = 0, rebootflag = 0, inetd = 0, nofork = 0, errflg = 0;
fd_set readers;
struct timeval tv;
+ struct hostent *hp;
+ struct sockaddr_in from;
sprintf(PidFile, "%szhm.pid", PIDDIR);
- if (gethostname(hostname, MAXHOSTNAMELEN) < 0) {
- printf("Can't find my hostname?!\n");
- exit(-1);
- }
- prim_serv[0] = '\0';
- while ((opt = getopt(argc, argv, "drhinf")) != EOF)
+ while ((opt = getopt(argc, argv, "drhinc:f")) != EOF)
switch(opt) {
case 'd':
hmdebug = 1;
case 'n':
nofork = 1;
break;
+ case 'c':
+ conffile = optarg;
+ break;
case 'f':
noflushflag = 1;
break;
errflg++;
break;
}
- if (errflg) {
- fprintf(stderr, "Usage: %s [-d] [-h] [-r] [-n] [-f] [server]\n",
- argv[0]);
- exit(2);
- }
-
- numserv = 0;
/* Override server argument? */
if (optind < argc) {
- if ((hp = gethostbyname(argv[optind++])) == NULL) {
- printf("Unknown server name: %s\n", argv[optind-1]);
+ if (conffile) {
+ errflg++;
} else {
- strncpy(prim_serv, hp->h_name, sizeof(prim_serv));
- prim_serv[sizeof(prim_serv) - 1] = '\0';
- }
+ int len;
+ static const char lg[] = "local-galaxy hostlist";
- /* argc-optind is the # of other servers on the command line */
- serv_list = (char **) malloc((argc - optind + 2) * sizeof(char *));
- if (serv_list == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- serv_list[numserv++] = prim_serv;
- for (; optind < argc; optind++) {
- if ((hp = gethostbyname(argv[optind])) == NULL) {
- printf("Unknown server name '%s', ignoring\n", argv[optind]);
- continue;
+ len = sizeof(lg)+1;
+ for (i=optind; i < argc; i++)
+ len += strlen(argv[i])+1;
+
+ if ((confline = (char *) malloc(len)) == NULL) {
+ fprintf(stderr, "Out of memory constructing default galaxy");
+ exit(1);
+ }
+ strcpy(confline, lg);
+ for (i=optind; i < argc; i++) {
+ strcat(confline, " ");
+ strcat(confline, argv[i]);
}
- serv_list[numserv++] = strsave(hp->h_name);
}
- serv_list[numserv] = NULL;
}
-#ifdef HAVE_HESIOD
- else
- use_hesiod = 1;
-#endif
- choose_server();
- if (*prim_serv == '\0') {
- printf("No valid primary server found, exiting.\n");
- exit(ZERR_SERVNAK);
+ if (errflg) {
+ fprintf(stderr, "Usage: %s [-d] [-h] [-r] [-n] [-f] [server... | -c conffile ]\n", argv[0]);
+ exit(2);
}
- init_hm();
- DPR2("zephyr server port: %u\n", ntohs(serv_sin.sin_port));
- DPR2("zephyr client port: %u\n", ntohs(cli_port));
-
- /* Main loop */
- for ever {
+ ZSetServerState(1); /* Aargh!!! */
+ if ((ret = ZInitialize()) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "initializing");
+ closelog();
+ exit(-1);
+ }
+
+ parse_conf(conffile, confline);
+
+ init_hm(inetd, nofork);
+
+ for (;;) {
/* Wait for incoming packets or queue timeouts. */
DPR("Waiting for a packet...");
+
fd = ZGetFD();
FD_ZERO(&readers);
FD_SET(fd, &readers);
+
count = select(fd + 1, &readers, NULL, NULL, timer_timeout(&tv));
if (count == -1 && errno != EINTR) {
syslog(LOG_CRIT, "select() failed: %m");
if (dieflag) {
die_gracefully();
} else {
- choose_server();
- send_flush_notice(HM_FLUSH);
- deactivated = 1;
+ for (i=0; i<ngalaxies; i++)
+ galaxy_reset(&galaxy_list[i]);
}
}
timer_process();
- if (count > 0) {
- ret = ZReceivePacket(packet, &pak_len, &from);
- if ((ret != ZERR_NONE) && (ret != EINTR)){
+ if (count == 0)
+ continue;
+
+ if ((ret = ZReceivePacket(packet, &pak_len, &from)) != ZERR_NONE) {
+ if (ret != EINTR) {
Zperr(ret);
com_err("hm", ret, "receiving notice");
- } else if (ret != EINTR) {
- /* Where did it come from? */
- if ((ret = ZParseNotice(packet, pak_len, ¬ice))
- != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "parsing notice");
- } else {
- DPR("Got a packet.\n");
- DPR("notice:\n");
- DPR2("\tz_kind: %d\n", notice.z_kind);
- DPR2("\tz_port: %u\n", ntohs(notice.z_port));
- DPR2("\tz_class: %s\n", notice.z_class);
- DPR2("\tz_class_inst: %s\n", notice.z_class_inst);
- DPR2("\tz_opcode: %s\n", notice.z_opcode);
- DPR2("\tz_sender: %s\n", notice.z_sender);
- DPR2("\tz_recip: %s\n", notice.z_recipient);
- DPR2("\tz_def_format: %s\n", notice.z_default_format);
- DPR2("\tz_message: %s\n", notice.z_message);
- if (memcmp(loopback, &from.sin_addr, 4) &&
- ((notice.z_kind == SERVACK) ||
- (notice.z_kind == SERVNAK) ||
- (notice.z_kind == HMCTL))) {
- server_manager(¬ice);
- } else {
- if (!memcmp(loopback, &from.sin_addr, 4) &&
- ((notice.z_kind == UNSAFE) ||
- (notice.z_kind == UNACKED) ||
- (notice.z_kind == ACKED) ||
- (notice.z_kind == HMCTL))) {
- /* Client program... */
- if (deactivated) {
- send_boot_notice(HM_BOOT);
- deactivated = 0;
- }
- transmission_tower(¬ice, packet, pak_len);
- DPR2("Pending = %d\n", ZPending());
- } else {
- if (notice.z_kind == STAT) {
- send_stats(¬ice, &from);
- } else {
- syslog(LOG_INFO,
- "Unknown notice type: %d",
- notice.z_kind);
- }
- }
- }
- }
}
+ continue;
+ }
+
+ /* Where did it come from? */
+ if ((ret = ZParseNotice(packet, pak_len, ¬ice)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "parsing notice");
+
+ continue;
+ }
+
+ DPR("Got a packet.\n");
+ DPR("notice:\n");
+ DPR2("\tz_kind: %d\n", notice.z_kind);
+ DPR2("\tz_port: %u\n", ntohs(notice.z_port));
+ DPR2("\tz_class: %s\n", notice.z_class);
+ DPR2("\tz_class_inst: %s\n", notice.z_class_inst);
+ DPR2("\tz_opcode: %s\n", notice.z_opcode);
+ DPR2("\tz_sender: %s\n", notice.z_sender);
+ DPR2("\tz_recip: %s\n", notice.z_recipient);
+ DPR2("\tz_def_format: %s\n", notice.z_default_format);
+ DPR2("\tz_message: %s\n", notice.z_message);
+
+ if ((from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) &&
+ ((notice.z_kind == SERVACK) ||
+ (notice.z_kind == SERVNAK) ||
+ (notice.z_kind == HMCTL))) {
+ server_manager(¬ice, &from);
+ } else if ((from.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) &&
+ ((notice.z_kind == UNSAFE) ||
+ (notice.z_kind == UNACKED) ||
+ (notice.z_kind == ACKED) ||
+ (notice.z_kind == HMCTL))) {
+ transmission_tower(¬ice, &from, packet, pak_len);
+ DPR2("Pending = %d\n", ZPending());
+ } else if (notice.z_kind == STAT) {
+ send_stats(¬ice, &from);
+ } else {
+ syslog(LOG_INFO, "Unknown notice type: %d",
+ notice.z_kind);
}
}
}
-static void choose_server()
+static void parse_conf(conffile, confline)
+ char *conffile;
+ char *confline;
{
- int i = 0;
- char **clust_info, **cpp;
-
-#ifdef HAVE_HESIOD
- if (use_hesiod) {
-
- /* Free up any previously used resources */
- if (prim_serv[0])
- i = 1;
- while (i < numserv)
- free(serv_list[i++]);
- if (serv_list)
- free(serv_list);
-
- numserv = 0;
- prim_serv[0] = '\0';
-
- if ((clust_info = hes_resolve(hostname, "CLUSTER")) == NULL) {
- zcluster = NULL;
+ struct servent *sp;
+ int zsrvport;
+ char filename[MAXPATHLEN];
+ FILE *file;
+ int lineno;
+ char buf[1024];
+ Code_t code;
+ int i;
+
+ /* this isn't a wonderful place to put this, but the alternatives
+ don't seem any better */
+
+ sp = getservbyname(SERVER_SVCNAME, "udp");
+ zsrvport = (sp) ? sp->s_port : SERVER_SVC_FALLBACK;
+
+ if (confline) {
+ if ((galaxy_list = (galaxy_info *) malloc(sizeof(galaxy_info))) == NULL) {
+ fprintf(stderr, "Out of memory parsing command line %s",
+ filename);
+ exit(1);
+ }
+
+ if (code = Z_ParseGalaxyConfig(confline,
+ &galaxy_list[ngalaxies].galaxy_config)) {
+ fprintf(stderr, "Error in command line: %s", error_message(code));
+ exit(1);
+ }
+
+ if (galaxy_list[ngalaxies].galaxy_config.galaxy == NULL) {
+ fprintf(stderr,
+ "the command line did not contain any valid galaxies.");
+ exit(1);
+ }
+
+ ngalaxies++;
+ } else {
+ if (conffile == NULL)
+ sprintf(filename, "%s/zephyr/zhm.conf", SYSCONFDIR);
+ else
+ strcpy(filename, conffile);
+
+ if ((file = fopen(filename, "r")) == NULL) {
+#ifdef ZEPHYR_USES_HESIOD
+ if ((galaxy_list = (galaxy_info *) malloc(sizeof(galaxy_info)))
+ == NULL) {
+ fprintf(stderr, "Out of memory parsing command line %s",
+ filename);
+ exit(1);
+ }
+
+ if (code = Z_ParseGalaxyConfig("local-galaxy hesiod zephyr",
+ &galaxy_list[ngalaxies].galaxy_config)) {
+ fprintf(stderr, "Internal error parsing hesiod default");
+ exit(1);
+ }
+
+ if (galaxy_list[ngalaxies].galaxy_config.galaxy == NULL) {
+ fprintf(stderr, "Internal error using hesiod default");
+ exit(1);
+ }
+
+ ngalaxies++;
+#else
+ fprintf(stderr, "Error opening configuration file %s: %s\n",
+ filename, strerror(errno));
+ exit(1);
+#endif
} else {
- for (cpp = clust_info; *cpp; cpp++) {
- /* Remove the following check once we have changed over to
- * new Hesiod format (i.e. ZCLUSTER.sloc lookup, no primary
- * server
- */
- if (!strncasecmp("ZEPHYR", *cpp, 6)) {
- register char *c;
-
- if ((c = strchr(*cpp, ' ')) == 0) {
- printf("Hesiod error getting primary server info.\n");
- } else {
- strncpy(prim_serv, c+1, sizeof(prim_serv));
- prim_serv[sizeof(prim_serv) - 1] = '\0';
+ for (lineno = 1; ; lineno++) {
+ if (fgets(buf, sizeof(buf), file) == NULL) {
+ if (ferror(file)) {
+ fprintf(stderr,
+ "Error reading configuration file %s: %s",
+ filename, strerror(errno));
+ exit(1);
}
break;
}
- if (!strncasecmp("ZCLUSTER", *cpp, 9)) {
- register char *c;
-
- if ((c = strchr(*cpp, ' ')) == 0) {
- printf("Hesiod error getting zcluster info.\n");
- } else {
- if ((zcluster = malloc((unsigned)(strlen(c+1)+1)))
- != NULL) {
- strcpy(zcluster, c+1);
- } else {
- printf("Out of memory.\n");
- exit(-5);
- }
- }
- break;
+
+ if (galaxy_list) {
+ galaxy_list = (galaxy_info *)
+ realloc(galaxy_list, sizeof(galaxy_info)*(ngalaxies+1));
+ } else {
+ galaxy_list = (galaxy_info *)
+ malloc(sizeof(galaxy_info));
}
- }
- for (cpp = clust_info; *cpp; cpp++)
- free(*cpp);
- }
- if (zcluster == NULL) {
- if ((zcluster = malloc((unsigned)(strlen("zephyr")+1))) != NULL)
- strcpy(zcluster, "zephyr");
- else {
- printf("Out of memory.\n");
- exit(-5);
- }
- }
- while ((serv_list = hes_resolve(zcluster, "sloc")) == (char **)NULL) {
- syslog(LOG_ERR, "No servers or no hesiod");
- /* wait a bit, and try again */
- sleep(30);
- }
- cpp = (char **) malloc(2 * sizeof(char *));
- if (cpp == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- if (prim_serv[0])
- cpp[numserv++] = prim_serv;
- for (i = 0; serv_list[i]; i++) {
- /* copy in non-duplicates */
- /* assume the names returned in the sloc are full domain names */
- if (!prim_serv[0] || strcasecmp(prim_serv, serv_list[i])) {
- cpp = (char **) realloc(cpp, (numserv+2) * sizeof(char *));
- if (cpp == NULL) {
- printf("Out of memory.\n");
- exit(-5);
+ if (galaxy_list == NULL) {
+ fprintf(stderr,
+ "Out of memory reading configuration file %s",
+ filename);
+ exit(1);
+ }
+
+ if (code = Z_ParseGalaxyConfig(buf,
+ &galaxy_list[ngalaxies].galaxy_config)) {
+ fprintf(stderr,
+ "Error in configuration file %s, line %d: %s",
+ filename, lineno, error_message(code));
+ exit(1);
}
- cpp[numserv++] = strsave(serv_list[i]);
+
+ if (galaxy_list[ngalaxies].galaxy_config.galaxy)
+ ngalaxies++;
}
}
- for (i = 0; serv_list[i]; i++)
- free(serv_list[i]);
- cpp[numserv] = NULL;
- serv_list = cpp;
+
+ if (ngalaxies == 0) {
+ fprintf(stderr,
+ "Configuration file %s did not contain any valid galaxies.");
+ exit(1);
+ }
}
+
+ for (i=0; i<ngalaxies; i++) {
+ galaxy_list[i].current_server = NO_SERVER;
+#if 0
+ galaxy_list[i].sin.sin_len = sizeof(struct in_addr);
#endif
-
- if (!prim_serv[0] && numserv) {
- srandom(time(NULL));
- strncpy(prim_serv, serv_list[random() % numserv], sizeof(prim_serv));
- prim_serv[sizeof(prim_serv) - 1] = '\0';
+ galaxy_list[i].sin.sin_family = AF_INET;
+ galaxy_list[i].sin.sin_port = zsrvport;
+ galaxy_list[i].state = NEED_SERVER;
+ galaxy_list[i].nchange = 0;
+ galaxy_list[i].nsrvpkts = 0;
+ galaxy_list[i].ncltpkts = 0;
+ galaxy_list[i].queue = NULL;
+ init_galaxy_queue(&galaxy_list[i]);
+ galaxy_list[i].boot_timer = NULL;
}
}
-static void init_hm()
+static void init_hm(inetd, nofork)
+ int inetd;
+ int nofork;
{
struct servent *sp;
Code_t ret;
#ifdef _POSIX_VERSION
struct sigaction sa;
#endif
+ struct hostent *hp;
+ int i;
starttime = time((time_t *)0);
OPENLOG("hm", LOG_PID, LOG_DAEMON);
- ZSetServerState(1); /* Aargh!!! */
- if ((ret = ZInitialize()) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "initializing");
- closelog();
- exit(-1);
- }
- init_queue();
-
- if (*prim_serv == '\0') {
- strncpy(prim_serv, *serv_list, sizeof(prim_serv));
- prim_serv[sizeof(prim_serv) - 1] = '\0';
- }
-
- loopback[0] = 127;
- loopback[1] = 0;
- loopback[2] = 0;
- loopback[3] = 1;
-
if (inetd) {
ZSetFD(0); /* fd 0 is on the socket, thanks to inetd */
} else {
exit(ret);
}
}
+
cli_sin = ZGetDestAddr();
- sp = getservbyname(SERVER_SVCNAME, "udp");
- memset(&serv_sin, 0, sizeof(struct sockaddr_in));
- serv_sin.sin_port = (sp) ? sp->s_port : SERVER_SVC_FALLBACK;
-
#ifndef DEBUG
if (!inetd && !nofork)
detach();
syslog(LOG_INFO, "Debugging on.");
}
- /* Set up communications with server */
- /* target is SERVER_SVCNAME port on server machine */
-
- serv_sin.sin_family = AF_INET;
-
- /* who to talk to */
- if ((hp = gethostbyname(prim_serv)) == NULL) {
- DPR("gethostbyname failed\n");
- find_next_server(NULL);
- } else {
- DPR2("Server = %s\n", prim_serv);
- strncpy(cur_serv, prim_serv, sizeof(cur_serv));
- cur_serv[sizeof(cur_serv) - 1] = '\0';
- memcpy(&serv_sin.sin_addr, hp->h_addr, 4);
- }
+ /* Initiate communication with each galaxy */
- send_boot_notice(HM_BOOT);
- deactivated = 0;
+ for (i=0; i<ngalaxies; i++)
+ galaxy_new_server(&galaxy_list[i], NULL);
#ifdef _POSIX_VERSION
sigemptyset(&sa.sa_mask);
ZNotice_t newnotice;
Code_t ret;
char *bfr;
- char *list[20];
- int len, i, nitems = 10;
+ char **list;
+ int len, i, j, nitems;
unsigned long size;
newnotice = *notice;
}
newnotice.z_kind = HMACK;
- list[0] = (char *) malloc(MAXHOSTNAMELEN);
- if (list[0] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- strcpy(list[0], cur_serv);
- list[1] = (char *) malloc(64);
- if (list[1] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- sprintf(list[1], "%d", queue_len());
- list[2] = (char *) malloc(64);
- if (list[2] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- sprintf(list[2], "%d", nclt);
- list[3] = (char *) malloc(64);
- if (list[3] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- sprintf(list[3], "%d", nserv);
- list[4] = (char *) malloc(64);
- if (list[4] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- sprintf(list[4], "%d", nservchang);
- list[5] = (char *) malloc(64);
- if (list[5] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- strncpy(list[5], rcsid_hm_c, 64);
- list[5][63] = '\0';
-
- list[6] = (char *) malloc(64);
- if (list[6] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- if (no_server)
- sprintf(list[6], "yes");
- else
- sprintf(list[6], "no");
- list[7] = (char *) malloc(64);
- if (list[7] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
+#define NSTATS 12
+
+ nitems = NSTATS*ngalaxies;
+
+ list = (char **) malloc(sizeof(char *)*nitems);
+ if (list == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
}
- sprintf(list[7], "%ld", time((time_t *)0) - starttime);
+
+ for (i=0; i<ngalaxies; i++) {
+ list[i*NSTATS] = (char *) malloc(MAXHOSTNAMELEN);
+ if (list[i*NSTATS] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ if (galaxy_list[i].current_server == NO_SERVER)
+ strcpy(list[i*NSTATS+0], "NO_SERVER");
+ else if (galaxy_list[i].current_server == EXCEPTION_SERVER)
+ strcpy(list[i*NSTATS+0], inet_ntoa(galaxy_list[i].sin.sin_addr));
+ else
+ strcpy(list[i*NSTATS+0],
+ galaxy_list[i].galaxy_config.server_list[galaxy_list[i].current_server].name);
+ list[i*NSTATS+1] = (char *) malloc(64);
+ if (list[i*NSTATS+1] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ sprintf(list[i*NSTATS+1], "%d", galaxy_queue_len(&galaxy_list[i]));
+ list[i*NSTATS+2] = (char *) malloc(64);
+ if (list[i*NSTATS+2] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ sprintf(list[i*NSTATS+2], "%d", galaxy_list[i].ncltpkts);
+ list[i*NSTATS+3] = (char *) malloc(64);
+ if (list[i*NSTATS+3] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ sprintf(list[i*NSTATS+3], "%d", galaxy_list[i].nsrvpkts);
+ list[i*NSTATS+4] = (char *) malloc(64);
+ if (list[i*NSTATS+4] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ sprintf(list[i*NSTATS+4], "%d", galaxy_list[i].nchange);
+ list[i*NSTATS+5] = (char *) malloc(64);
+ if (list[i*NSTATS+5] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ strcpy(list[i*NSTATS+5], rcsid_hm_c);
+ list[i*NSTATS+6] = (char *) malloc(64);
+ if (list[i*NSTATS+6] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ switch (galaxy_list[i].state) {
+ case NEED_SERVER:
+ sprintf(list[i*NSTATS+6], "yes (need server)");
+ break;
+ case DEAD_SERVER:
+ sprintf(list[i*NSTATS+6], "yes (dead server)");
+ break;
+ case BOOTING:
+ sprintf(list[i*NSTATS+6], "yes (booting)");
+ break;
+ case ATTACHING:
+ sprintf(list[i*NSTATS+6], "yes (attaching)");
+ break;
+ case ATTACHED:
+ sprintf(list[i*NSTATS+6], "no (attached)");
+ break;
+ default:
+ sprintf(list[i*NSTATS+6], "weird value %x", galaxy_list[i].state);
+ break;
+ }
+ list[i*NSTATS+7] = (char *) malloc(64);
+ if (list[i*NSTATS+7] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ sprintf(list[i*NSTATS+7], "%ld", (long) (time((time_t *)0) - starttime));
#ifdef adjust_size
- size = (unsigned long)sbrk(0);
- adjust_size (size);
+ size = (unsigned long)sbrk(0);
+ adjust_size (size);
#else
- size = -1;
+ size = -1;
#endif
- list[8] = (char *)malloc(64);
- if (list[8] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
- }
- sprintf(list[8], "%ld", size);
- list[9] = (char *)malloc(32);
- if (list[9] == NULL) {
- printf("Out of memory.\n");
- exit(-5);
+ list[i*NSTATS+8] = (char *)malloc(64);
+ if (list[i*NSTATS+8] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ sprintf(list[i*NSTATS+8], "%ld", size);
+ list[i*NSTATS+9] = (char *)malloc(32);
+ if (list[i*NSTATS+9] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ strcpy(list[i*NSTATS+9], MACHINE_TYPE);
+ list[i*NSTATS+10] = (char *)malloc(64);
+ if (list[i*NSTATS+10] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ strcpy(list[i*NSTATS+10], galaxy_list[i].galaxy_config.galaxy);
+
+ len = strlen(galaxy_list[i].galaxy_config.galaxy)+1;
+ len += strlen("hostlist ");
+ for (j=0; j<galaxy_list[i].galaxy_config.nservers; j++)
+ len += 1+strlen(galaxy_list[i].galaxy_config.server_list[j].name);
+ len++;
+
+ list[i*NSTATS+11] = (char *) malloc(len);
+ if (list[i*NSTATS+11] == NULL) {
+ printf("Out of memory.\n");
+ exit(5);
+ }
+ strcpy(list[i*NSTATS+11], galaxy_list[i].galaxy_config.galaxy);
+ strcat(list[i*NSTATS+11], " hostlist");
+ for (j=0; j<galaxy_list[i].galaxy_config.nservers; j++) {
+ strcat(list[i*NSTATS+11], " ");
+ strcat(list[i*NSTATS+11],
+ galaxy_list[i].galaxy_config.server_list[j].name);
+ }
}
- strncpy(list[9], MACHINE_TYPE, 32);
- list[9][31] = '\0';
/* Since ZFormatRaw* won't change the version number on notices,
we need to set the version number explicitly. This code is taken
from Zinternal.c, function Z_FormatHeader */
if (!*version)
sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR,
- ZVERSIONMINOR);
+ ZVERSIONMINOR_NOGALAXY);
newnotice.z_version = version;
+#if 1
+ if ((ret = ZSendRawList(&newnotice, list, nitems)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "sending stat notice");
+ }
+#else
if ((ret = ZFormatRawNoticeList(&newnotice, list, nitems, &bfr,
&len)) != ZERR_NONE) {
syslog(LOG_INFO, "Couldn't format stats packet");
}
}
free(bfr);
+#endif
for(i=0;i<nitems;i++)
free(list[i]);
-}
-
-void die_gracefully()
-{
- syslog(LOG_INFO, "Terminate signal caught...");
- send_flush_notice(HM_FLUSH);
- unlink(PidFile);
- closelog();
- exit(0);
+ free(list);
}
static char *strsave(sp)
-.\" $Id: zwgc.1,v 1.24 2000/08/10 15:10:52 ghudson Exp $
+.\" $Id$
' # end of TP (cf }N below)
' # copied here, since we use @ in some of our tags, and that
' # messes up \w and \h
be correct (even for authentic messages).
.TP
.B fullsender
-The notice sender's name, including the zephyr realm name.
+The notice sender's name, including the kerberos realm name.
.TP
.B instance
The instance of the current notice.
(sent to several people), the recipient is set to ``*''.
.TP
.B sender
-Usually a shortened version of fullsender. If the realm of the sender
-is equal to the realm of the recipient,
+Usually a shortened version of fullsender. If the kerberos realm of
+the sender is equal to the kerberos realm of the zephyr servers,
.I sender
omits the realm name.
.TP