1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It contains source for the ZSendPacket function.
3  *
4  *	Created by:	Robert French
5  *
6  *	Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
7  *	For copying and distribution information, see the file
8  *	"mit-copyright.h".
9  */
10 
11 #include "internal.h"
12 #ifdef WIN32
13 #include <winsock.h>
14 #else
15 #include <sys/socket.h>
16 #endif
17 
18 static int wait_for_hmack(ZNotice_t *notice, void *uid);
19 
ZSendPacket(packet,len,waitforack)20 Code_t ZSendPacket(packet, len, waitforack)
21     char *packet;
22     int len;
23     int waitforack;
24 {
25     Code_t retval;
26     struct sockaddr_in dest;
27     ZNotice_t notice, acknotice;
28 
29     if (!packet || len < 0)
30 	return (ZERR_ILLVAL);
31 
32     if (len > Z_MAXPKTLEN)
33 	return (ZERR_PKTLEN);
34 
35     if (ZGetFD() < 0)
36 	if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE)
37 	    return (retval);
38 
39     dest = ZGetDestAddr();
40 
41     if (sendto(ZGetFD(), packet, len, 0, (struct sockaddr *)&dest,
42 	       sizeof(dest)) < 0)
43 	return (errno);
44 
45     if (!waitforack)
46 	return (ZERR_NONE);
47 
48     if ((retval = ZParseNotice(packet, len, &notice)) != ZERR_NONE)
49 	return (retval);
50 
51     retval = Z_WaitForNotice (&acknotice, wait_for_hmack, &notice.z_uid,
52 			      HM_TIMEOUT);
53     if (retval == ETIMEDOUT)
54       return ZERR_HMDEAD;
55     if (retval == ZERR_NONE)
56       ZFreeNotice (&acknotice);
57     return retval;
58 }
59 
wait_for_hmack(ZNotice_t * notice,void * uid)60 static int wait_for_hmack(ZNotice_t *notice, void *uid)
61 {
62     return (notice->z_kind == HMACK && ZCompareUID(&notice->z_uid, (ZUnique_Id_t *)uid));
63 }
64