1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It contains source for the ZOpenPort function.
3  *
4  *	Created by:	Robert French
5  *
6  *	Copyright (c) 1987 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 #include "debug.h"
13 #ifdef WIN32
14 #include <winsock2.h>
15 #else
16 #include <sys/socket.h>
17 #endif
18 
ZOpenPort(port)19 Code_t ZOpenPort(port)
20     unsigned short *port;
21 {
22     struct sockaddr_in bindin;
23     socklen_t len;
24 
25     (void) ZClosePort();
26     memset(&bindin, 0, sizeof(bindin));
27 
28     if ((__Zephyr_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
29 	__Zephyr_fd = -1;
30 	return (errno);
31     }
32 
33 #ifdef SO_BSDCOMPAT
34 	{
35 		int on = 1;
36 
37 		if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_BSDCOMPAT,
38 			(char *)&on, sizeof(on)) != 0)
39 		{
40 			purple_debug_warning("zephyr", "couldn't setsockopt\n");
41 		}
42 	}
43 #endif
44 
45     bindin.sin_family = AF_INET;
46 
47     if (port && *port)
48 	bindin.sin_port = *port;
49     else
50 	bindin.sin_port = 0;
51 
52     bindin.sin_addr.s_addr = INADDR_ANY;
53 
54     if (bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)) < 0) {
55 	if (errno == EADDRINUSE && port && *port)
56 	    return (ZERR_PORTINUSE);
57 	else
58 	    return (errno);
59     }
60 
61     if (!bindin.sin_port) {
62 	len = sizeof(bindin);
63 	if (getsockname(__Zephyr_fd, (struct sockaddr *)&bindin, &len))
64 	    return (errno);
65     }
66 
67     __Zephyr_port = bindin.sin_port;
68     __Zephyr_open = 1;
69 
70     if (port)
71 	*port = bindin.sin_port;
72 
73     return (ZERR_NONE);
74 }
75