extern void initialize_zeph_error_table ();
extern int errno;
typedef	int		sigset_t;	
typedef	unsigned int	speed_t;	
typedef	unsigned long	tcflag_t;	
typedef	unsigned char	cc_t;		
typedef	int		pid_t;		
typedef	unsigned short	mode_t;		
typedef	short		nlink_t;	
typedef	long		clock_t;	
typedef	long		time_t;		
typedef	int		size_t;		
typedef int		ptrdiff_t;	
typedef	unsigned short	wchar_t;	
typedef	unsigned char	u_char;
typedef	unsigned short	u_short;
typedef	unsigned int	u_int;
typedef	unsigned long	u_long;
typedef	unsigned short	ushort;		
typedef	unsigned int	uint;		
typedef	struct  _physadr_t { int r[1]; } *physadr_t;
typedef	struct label_t {
	int	val[2];
} label_t;
typedef	struct	_quad_t { long val[2]; } quad_t;
typedef	long	daddr_t;
typedef	char *	caddr_t;
typedef	unsigned long	ino_t;
typedef	short	dev_t;
typedef	long	off_t;
typedef	unsigned short	uid_t;
typedef	unsigned short	gid_t;
typedef	long	key_t;
typedef	char *	addr_t;
typedef	long	fd_mask;
typedef	struct fd_set {
	fd_mask	fds_bits[(((256)+(( (sizeof (fd_mask) * 8))-1))/( (sizeof (fd_mask) * 8)))];
} fd_set;
struct timeval {
	long	tv_sec;		
	long	tv_usec;	
};
struct timezone {
	int	tz_minuteswest;	
	int	tz_dsttime;	
};
struct	itimerval {
	struct	timeval it_interval;	
	struct	timeval it_value;	
};
struct	tm {
	int	tm_sec;
	int	tm_min;
	int	tm_hour;
	int	tm_mday;
	int	tm_mon;
	int	tm_year;
	int	tm_wday;
	int	tm_yday;
	int	tm_isdst;
	char	*tm_zone;
	long	tm_gmtoff;
};
extern	struct tm *gmtime(), *localtime();
extern	char *asctime(), *ctime();
extern	void tzset(), tzsetwall();
extern  int dysize();
extern  time_t timelocal(), timegm();
extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		
} _iob[];
extern struct _iobuf	*fopen();
extern struct _iobuf	*fdopen();
extern struct _iobuf	*freopen();
extern struct _iobuf	*popen();
extern struct _iobuf	*tmpfile();
extern long	ftell();
extern char	*fgets();
extern char	*gets();
extern char	*sprintf();
extern char	*ctermid();
extern char	*cuserid();
extern char	*tempnam();
extern char	*tmpnam();
typedef unsigned char des_cblock[8];	
typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16];
typedef struct des_ks_struct bit_64;
extern char *krb_err_txt[256];
struct ktext {
    int     length;		
    unsigned char dat[1250];	
    unsigned long mbz;		
};
typedef struct ktext *KTEXT;
typedef struct ktext KTEXT_ST;
struct auth_dat {
    unsigned char k_flags;	
    char    pname[40];	
    char    pinst[40];	
    char    prealm[40];	
    unsigned long checksum;	
    des_cblock session;		
    int     life;		
    unsigned long time_sec;	
    unsigned long address;	
    KTEXT_ST reply;		
};
typedef struct auth_dat AUTH_DAT;
struct credentials {
    char    service[40];	
    char    instance[40];	
    char    realm[40];	
    des_cblock session;		
    int     lifetime;		
    int     kvno;		
    KTEXT_ST ticket_st;		
    long    issue_date;		
    char    pname[40];	
    char    pinst[40];	
};
typedef struct credentials CREDENTIALS;
struct msg_dat {
    unsigned char *app_data;	
    unsigned long app_length;	
    unsigned long hash;		
    int     swap;		
    long    time_sec;		
    unsigned char time_5ms;	
};
typedef struct msg_dat MSG_DAT;
char *tkt_string();
struct in_addr {
	union {
		struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
		struct { u_short s_w1,s_w2; } S_un_w;
		u_long S_addr;
	} S_un;
};
struct sockaddr_in {
	short	sin_family;
	u_short	sin_port;
	struct	in_addr sin_addr;
	char	sin_zero[8];
};
    typedef char ZPacket_t[1024];
    typedef enum { UNSAFE, UNACKED, ACKED, HMACK, HMCTL, SERVACK, SERVNAK,
		       CLIENTACK, STAT } ZNotice_Kind_t;
    typedef struct _ZUnique_Id_t {
	struct	in_addr zuid_addr;
	struct	timeval	tv;
    } ZUnique_Id_t;
    typedef u_long ZChecksum_t;
    typedef struct _ZNotice_t {
	char		*z_packet;
	char		*z_version;
	ZNotice_Kind_t	z_kind;
	ZUnique_Id_t	z_uid;
	struct		timeval z_time;
	u_short		z_port;
	int		z_auth;
	int		z_authent_len;
	char		*z_ascii_authent;
	char		*z_class;
	char		*z_class_inst;
	char		*z_opcode;
	char		*z_sender;
	char		*z_recipient;
	char		*z_default_format;
	char		*z_multinotice;
	ZUnique_Id_t	z_multiuid;
	ZChecksum_t	z_checksum;
	int		z_num_other_fields;
	char		*z_other_fields[10];
	caddr_t		z_message;
	int		z_message_len;
    } ZNotice_t;
    typedef struct _ZSubscriptions_t {
	char	*recipient;
	char	*class;		
	char	*classinst;
    } ZSubscription_t;
    typedef int Code_t;
    typedef struct _ZLocations_t {
	char	*host;
	char	*time;
	char	*tty;
    } ZLocations_t;
    extern int __Zephyr_fd;
    extern int __Zephyr_port;
    extern struct sockaddr_in __HM_addr;
    extern int __Q_CompleteLength;
    extern char __Zephyr_realm[];
    extern int krb_err_base;
    extern int errno;
    extern des_cblock __Zephyr_session;
    extern int ZCompareUIDPred (),
	       ZCompareMultiUIDPred ();
    typedef Code_t (*Z_AuthProc) ();
    extern Code_t ZMakeAuthentication ();
    extern char *ZGetSender (), *ZGetVariable ();
    extern int ZGetWGPort ();
    extern Code_t ZSetDestAddr ();
    extern Code_t ZFormatNoticeList 
();
    extern Code_t ZParseNotice ();
    extern Code_t ZReadAscii ();
    extern Code_t ZSendPacket ();
    extern Code_t ZSendList ();
    extern Code_t ZFormatNotice ();
    extern Code_t ZInitialize ();
    extern Code_t ZSetServerState ();
    extern Code_t ZSetFD ();
    extern Code_t ZFormatSmallRawNotice ();
    extern int ZCompareUID ();
    extern Code_t ZSrvSendRawList 
();
    extern Code_t ZMakeAscii ();
    extern Code_t ZReceivePacket 
();
    extern Code_t ZCheckAuthentication 
();
    extern Code_t ZFormatAuthenticNotice 
();
    extern Code_t ZFormatRawNotice ();
struct	linger {
	int	l_onoff;		
	int	l_linger;		
};
struct sockaddr {
	u_short	sa_family;		
	char	sa_data[14];		
};
struct sockproto {
	u_short	sp_family;		
	u_short	sp_protocol;		
};
struct msghdr {
	caddr_t	msg_name;		
	int	msg_namelen;		
	struct	iovec *msg_iov;		
	int	msg_iovlen;		
	caddr_t	msg_accrights;		
	int	msg_accrightslen;
};
typedef	int	faultcode_t;	
void	(*signal())();
void  (*sigset())();
int   sighold();
int   sigrelse();
int   sigignore();
struct	sigvec {
	void	(*sv_handler)();	
	int	sv_mask;		
	int	sv_flags;		
};
struct	sigstack {
	char	*ss_sp;			
	int	ss_onstack;		
};
struct	sigcontext {
	int	sc_onstack;		
	int	sc_mask;		
	int	sc_sp;			
	int	sc_pc;			
	int	sc_npc;			
	int	sc_psr;			
	int	sc_g1;			
	int	sc_o0;
	int	sc_wbcnt;		
	char	*sc_spbuf[31]; 
	int	sc_wbuf[31][16]; 
};
struct	sigaction {
	void 		(*sa_handler)();
	sigset_t	sa_mask;
	int		sa_flags;
};
void	(*signal())();
int	kill();
int	sigaction(
);
int	sigaddset();
int	sigdelset();
int	sigemptyset();
int	sigfillset();
int	sigismember();
int	sigpending();
int	sigprocmask();
int	sigsuspend();
struct	hostent {
	char	*h_name;	
	char	**h_aliases;	
	int	h_addrtype;	
	int	h_length;	
	char	**h_addr_list;	
};
struct	netent {
	char		*n_name;	
	char		**n_aliases;	
	int		n_addrtype;	
	unsigned long	n_net;		
};
struct	servent {
	char	*s_name;	
	char	**s_aliases;	
	int	s_port;		
	char	*s_proto;	
};
struct	protoent {
	char	*p_name;	
	char	**p_aliases;	
	int	p_proto;	
};
struct rpcent {
	char	*r_name;	
	char	**r_aliases;	
	int	r_number;	
};
struct hostent	*gethostbyname(), *gethostbyaddr(), *gethostent();
struct netent	*getnetbyname(), *getnetbyaddr(), *getnetent();
struct servent	*getservbyname(), *getservbyport(), *getservent();
struct protoent	*getprotobyname(), *getprotobynumber(), *getprotoent();
struct rpcent	*getrpcbyname(), *getrpcbynumber(), *getrpcent();
extern  int h_errno;	
extern char *malloc();
extern Code_t send_outgoing();
extern void init_queue(), retransmit_queue();
extern int etext;
typedef struct _Queue {
     long timeout;
     int retries;
     ZNotice_t z_notice;
     caddr_t z_packet;
     struct sockaddr_in reply;
} Queue;
struct _qelem {
     struct _qelem *q_forw;
     struct _qelem *q_back;
     Queue *q_data;
};
typedef struct _qelem Qelem;
typedef struct _realmentry {
    char realm[40 + 1];		
    char *hostlist[256];	
    char **cur_serv_list;
    char *cur_serv;			
    char *prim_serv;			
    struct sockaddr_in host_sin;	
    struct sockaddr_in *hp;		
    int booting;			
    int no_server;			
    int deactivated;			
    int nservchang;			
    int nserv;				
    Qelem *queue;			
    struct _realmentry *next;		
} RealmEntry;
extern struct sockaddr_in *ZGetRemoteServer();
extern char *list_remote_servers();
extern char *ZGetDestRealm();
extern char *ZGetSubRealm();
extern char *ZGetOrigRealm();
extern RealmEntry *ZGetFirstRealm(); 
extern RealmEntry *ZGetNextRealm(); 
extern RealmEntry *ZGetRealmFromAddr();
extern RealmEntry *ZGetRealmFromRealm();
extern RealmEntry *ZGetRealmFromNotice();
static char rcsid_newqueue_c[] = "$Header: /afs/media-lab.mit.edu/user/warlord/C/zephyr/zhm/RCS/newqueue.c,v 1.2 92/03/12 16:14:33 warlord Exp $";
extern long time();
Qelem *is_in_queue();
extern int timeout_type;
void init_queue(hm_queue)
Qelem *hm_queue;
{
     while (hm_queue->q_forw != hm_queue) {
	  free(hm_queue->q_forw->q_data->z_packet);
	  free((char *)hm_queue->q_forw->q_data);
	  remque(hm_queue->q_forw);
	  free((char *)hm_queue->q_forw);
     }
     hm_queue->q_forw = hm_queue->q_back = hm_queue;
     hm_queue->q_data = 0;
     ;
}
Code_t add_notice_to_queue(hm_queue, notice, packet, repl, len)
Qelem *hm_queue;
ZNotice_t *notice;
caddr_t packet;
struct sockaddr_in *repl;
int len;
{
     Qelem *elem;
     Queue *entry;
     ;
     if (!is_in_queue(hm_queue, notice)) {
	  elem = (Qelem *)malloc(sizeof(Qelem));
	  entry = (Queue *)malloc(sizeof(Queue));
	  entry->timeout = time((time_t *)0) + 25;
	  entry->retries = 0;
	  entry->z_packet = (char *)malloc(1024);
	  bcopy(packet, entry->z_packet, 1024);
	  if (ZParseNotice(entry->z_packet, len, &entry->z_notice)
	      != 0) {
	       syslog(3, "ZParseNotice failed, but succeeded before");
	       free(entry->z_packet);
	  } else {
	       entry->reply = *repl;
	       elem->q_data = entry;
	       elem->q_forw = elem;
	       elem->q_back = elem;
	       insque(elem, hm_queue->q_back);
	  }
     }
	  return(0);
}
Code_t remove_notice_from_queue(hm_queue, notice, kind, repl)
Qelem *hm_queue;
ZNotice_t *notice;
ZNotice_Kind_t *kind;
struct sockaddr_in *repl;
{
     Qelem *elem;
     ;
     if ((elem = is_in_queue(hm_queue, notice)) == 0)
	  return((-772103672L));
     else {
	  *kind = elem->q_data->z_notice.z_kind;
	  *repl = elem->q_data->reply;
	  free(elem->q_data->z_packet);
	  free((char *)elem->q_data);
	  remque(elem);
	  free((char *)elem);
	  clear_alarm();
	  return(0);
     }
}
void retransmit_queue(hm_queue, sin)
Qelem *hm_queue;
struct sockaddr_in *sin;
{
     Qelem *srch;
     Code_t ret;
     time_t this_time;
     this_time = time((time_t *)0);
     ;
     if ((ret = ZSetDestAddr(sin)) != 0) {
	  ;
	  com_err("queue", ret, "setting destination");
     }
     if ((srch = hm_queue->q_forw) != hm_queue) {
	  do {
	       ;
	       ;
;
	       ;
;
	       ;
	       ;
	       ;
	       if ((ret = send_outgoing(&srch->q_data->z_notice))
		   != 0) {
		    ;
		    com_err("queue", ret, "sending raw notice");
	       }
	       srch->q_data->timeout = this_time + 25;
	       srch->q_data->retries = 0;
	       srch = srch->q_forw;
	  } while (srch != hm_queue);
	  set_alarm();
     }
}
int queue_len(hm_queue)
Qelem *hm_queue;
{
     int length = 0;
     Qelem *srch;
     if ((srch = hm_queue->q_forw) != hm_queue) {
	  do {
	       length++;
	       srch = srch->q_forw;
	  } while (srch != hm_queue);
     }
     return(length);
}
Qelem *is_in_queue(hm_queue, notice)
Qelem *hm_queue;
ZNotice_t *notice;
{
     Qelem *srch;
     srch = hm_queue->q_forw;
     if (srch == hm_queue)
	  return(0);
     do {
	  if (ZCompareUID(&(srch->q_data->z_notice.z_uid), &(notice->z_uid)))
	       return(srch);
	  srch = srch->q_forw;
     } while (srch != hm_queue);
     return(0);
}
void resend_notices(hm_queue, sin)
Qelem *hm_queue;
struct sockaddr_in *sin;
{
     Qelem *srch;
     Code_t ret;
     RealmEntry *Realm;
     time_t this_time;
     ;
     if ((ret = ZSetDestAddr(sin)) != 0) {
	  ;
	  com_err("queue", ret, "setting destination");
     }
     if ((srch = hm_queue->q_forw) == hm_queue) {
	  syslog (6, "No notices, shouldn't have happened!");
     } else do {
	  if (srch->q_data->timeout <= (this_time = time((time_t *)0))) {
	       if (++(srch->q_data->retries) > 2) {
		    Realm = ZGetRealmFromAddr((char *)&(sin->sin_addr));
		    new_server(Realm, (char *)0);
		    break;
	       } else {
		    ;
		    ;
;
;
;
;
;
;
		    if ((ret = send_outgoing(&srch->q_data->z_notice)) 
			!= 0) {
			 ;
			 com_err("queue", ret, "sending raw notice");
		    }
		    srch->q_data->timeout = this_time + 25;
		    srch = srch->q_forw;
		}
	   }
     } while (srch != hm_queue);
     set_alarm();
}
