2 * Copyright (C) Joerg Lenneis 2003
3 * All Rights Reserved. See COPYING.
8 #endif /* HAVE_CONFIG_H */
16 #endif /* HAVE_UNISTD_H */
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
23 #ifdef HAVE_SYS_TYPES_H
24 #include <sys/types.h>
25 #endif /* HAVE_SYS_TYPES_H */
26 #ifdef HAVE_SYS_TIME_H
28 #endif /* HAVE_SYS_TIME_H */
31 #include <atalk/logger.h>
32 #include <atalk/compat.h>
35 #include <sys/select.h>
37 int usockfd_create(char *usock_fn, mode_t mode, int backlog)
40 struct sockaddr_un addr;
43 if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
44 LOG(log_error, logtype_cnid, "error in socket call: %s",
49 if (unlink(usock_fn) < 0 && errno != ENOENT) {
50 LOG(log_error, logtype_cnid, "error unlinking unix socket file %s: %s",
51 usock_fn, strerror(errno));
54 memset((char *) &addr, 0, sizeof(struct sockaddr_un));
55 addr.sun_family = AF_UNIX;
56 strncpy(addr.sun_path, usock_fn, sizeof(addr.sun_path) - 1);
57 if (bind(sockfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) {
58 LOG(log_error, logtype_cnid, "error binding to socket for %s: %s",
59 usock_fn, strerror(errno));
63 if (listen(sockfd, backlog) < 0) {
64 LOG(log_error, logtype_cnid, "error in listen for %s: %s",
65 usock_fn, strerror(errno));
72 if (chmod(usock_fn, mode) < 0) {
73 LOG(log_error, logtype_cnid, "error changing permissions for %s: %s",
74 usock_fn, strerror(errno));
85 int tsockfd_create(char *host, char *port, int backlog)
87 int sockfd, flag, ret;
88 struct addrinfo hints, *servinfo, *p;
90 /* Prepare hint for getaddrinfo */
91 memset(&hints, 0, sizeof hints);
92 hints.ai_family = AF_UNSPEC;
93 hints.ai_socktype = SOCK_STREAM;
95 if ((ret = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
96 LOG(log_error, logtype_default, "tsockfd_create: getaddrinfo: %s\n", gai_strerror(ret));
100 /* create a socket */
101 /* loop through all the results and bind to the first we can */
102 for (p = servinfo; p != NULL; p = p->ai_next) {
103 if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
104 LOG(log_info, logtype_default, "tsockfd_create: socket: %s", strerror(errno));
109 * Set some socket options:
110 * SO_REUSEADDR deals w/ quick close/opens
111 * TCP_NODELAY diables Nagle
115 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
118 #ifdef USE_TCP_NODELAY
120 #define SOL_TCP IPPROTO_TCP
123 setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
124 #endif /* USE_TCP_NODELAY */
126 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
128 LOG(log_info, logtype_default, "tsockfd_create: bind: %s\n", strerror(errno));
132 if (listen(sockfd, backlog) < 0) {
134 LOG(log_info, logtype_default, "tsockfd_create: listen: %s\n", strerror(errno));
138 /* We got a socket */
143 LOG(log_error, logtype_default, "tsockfd_create: no suitable network config %s:%s", host, port);
144 freeaddrinfo(servinfo);
148 freeaddrinfo(servinfo);
152 /* --------------------- */
153 int usockfd_check(int sockfd, const sigset_t *sigset)
161 FD_SET(sockfd, &readfds);
163 if ((ret = pselect(sockfd + 1, &readfds, NULL, NULL, NULL, sigset)) < 0) {
166 LOG(log_error, logtype_cnid, "error in select: %s",
173 if ((fd = accept(sockfd, NULL, &size)) < 0) {
176 LOG(log_error, logtype_cnid, "error in accept: %s",