| 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 #ifdef WIN32 |
|
| 13 #include <winsock2.h> |
|
| 14 #else |
|
| 15 #include <sys/socket.h> |
|
| 16 #endif |
|
| 17 |
|
| 18 Code_t ZOpenPort(port) |
|
| 19 unsigned short *port; |
|
| 20 { |
|
| 21 struct sockaddr_in bindin; |
|
| 22 socklen_t len; |
|
| 23 |
|
| 24 (void) ZClosePort(); |
|
| 25 |
|
| 26 if ((__Zephyr_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
|
| 27 __Zephyr_fd = -1; |
|
| 28 return (errno); |
|
| 29 } |
|
| 30 |
|
| 31 #ifdef SO_BSDCOMPAT |
|
| 32 { |
|
| 33 int on = 1; |
|
| 34 |
|
| 35 setsockopt(__Zephyr_fd, SOL_SOCKET, SO_BSDCOMPAT, (char *)&on, |
|
| 36 sizeof(on)); |
|
| 37 } |
|
| 38 #endif |
|
| 39 |
|
| 40 bindin.sin_family = AF_INET; |
|
| 41 |
|
| 42 if (port && *port) |
|
| 43 bindin.sin_port = *port; |
|
| 44 else |
|
| 45 bindin.sin_port = 0; |
|
| 46 |
|
| 47 bindin.sin_addr.s_addr = INADDR_ANY; |
|
| 48 |
|
| 49 if (bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)) < 0) { |
|
| 50 if (errno == EADDRINUSE && port && *port) |
|
| 51 return (ZERR_PORTINUSE); |
|
| 52 else |
|
| 53 return (errno); |
|
| 54 } |
|
| 55 |
|
| 56 if (!bindin.sin_port) { |
|
| 57 len = sizeof(bindin); |
|
| 58 if (getsockname(__Zephyr_fd, (struct sockaddr *)&bindin, &len)) |
|
| 59 return (errno); |
|
| 60 } |
|
| 61 |
|
| 62 __Zephyr_port = bindin.sin_port; |
|
| 63 __Zephyr_open = 1; |
|
| 64 |
|
| 65 if (port) |
|
| 66 *port = bindin.sin_port; |
|
| 67 |
|
| 68 return (ZERR_NONE); |
|
| 69 } |
|