• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/netatalk-3.0.5/etc/cnid_dbd/
1/*
2 * Copyright (C) Joerg Lenneis 2003
3 * All Rights Reserved.  See COPYING.
4 */
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif /* HAVE_CONFIG_H */
9
10
11#include <stdlib.h>
12#include <string.h>
13#include <errno.h>
14#include <unistd.h>
15#include <sys/un.h>
16#include <sys/socket.h>
17#include <netinet/in.h>
18#include <arpa/inet.h>
19#include <netdb.h>
20#include <sys/types.h>
21#include <sys/time.h>
22
23#include <atalk/logger.h>
24#include <atalk/compat.h>
25#include "usockfd.h"
26
27#include <sys/select.h>
28
29int usockfd_create(char *usock_fn, mode_t mode, int backlog)
30{
31    int sockfd;
32    struct sockaddr_un addr;
33
34
35    if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
36        LOG(log_error, logtype_cnid, "error in socket call: %s",
37            strerror(errno));
38        return -1;
39    }
40
41    if (unlink(usock_fn) < 0 && errno != ENOENT) {
42        LOG(log_error, logtype_cnid, "error unlinking unix socket file %s: %s",
43            usock_fn, strerror(errno));
44        return -1;
45    }
46    memset((char *) &addr, 0, sizeof(struct sockaddr_un));
47    addr.sun_family = AF_UNIX;
48    strncpy(addr.sun_path, usock_fn, sizeof(addr.sun_path) - 1);
49    if (bind(sockfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) {
50        LOG(log_error, logtype_cnid, "error binding to socket for %s: %s",
51            usock_fn, strerror(errno));
52        return -1;
53    }
54
55    if (listen(sockfd, backlog) < 0) {
56        LOG(log_error, logtype_cnid, "error in listen for %s: %s",
57            usock_fn, strerror(errno));
58        return -1;
59    }
60
61#ifdef chmod
62#undef chmod
63#endif
64    if (chmod(usock_fn, mode) < 0) {
65        LOG(log_error, logtype_cnid, "error changing permissions for %s: %s",
66            usock_fn, strerror(errno));
67        close(sockfd);
68        return -1;
69    }
70
71    return sockfd;
72}
73
74/* ---------------
75 * create a tcp socket
76 */
77int tsockfd_create(char *host, char *port, int backlog)
78{
79    int sockfd, flag, ret;
80    struct addrinfo hints, *servinfo, *p;
81
82    /* Prepare hint for getaddrinfo */
83    memset(&hints, 0, sizeof hints);
84    hints.ai_family = AF_UNSPEC;
85    hints.ai_socktype = SOCK_STREAM;
86
87    if ((ret = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
88        LOG(log_error, logtype_cnid, "tsockfd_create: getaddrinfo: %s\n", gai_strerror(ret));
89        return 0;
90    }
91
92    /* create a socket */
93    /* loop through all the results and bind to the first we can */
94    for (p = servinfo; p != NULL; p = p->ai_next) {
95        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
96            LOG(log_info, logtype_cnid, "tsockfd_create: socket: %s", strerror(errno));
97            continue;
98        }
99
100        /*
101         * Set some socket options:
102         * SO_REUSEADDR deals w/ quick close/opens
103         * TCP_NODELAY diables Nagle
104         */
105#ifdef SO_REUSEADDR
106        flag = 1;
107        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
108#endif
109
110#ifdef USE_TCP_NODELAY
111#ifndef SOL_TCP
112#define SOL_TCP IPPROTO_TCP
113#endif
114        flag = 1;
115        setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
116#endif /* USE_TCP_NODELAY */
117
118        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
119            close(sockfd);
120            LOG(log_info, logtype_cnid, "tsockfd_create: bind: %s\n", strerror(errno));
121            continue;
122        }
123
124        if (listen(sockfd, backlog) < 0) {
125            close(sockfd);
126            LOG(log_info, logtype_cnid, "tsockfd_create: listen: %s\n", strerror(errno));
127            continue;
128        }
129
130        /* We got a socket */
131        break;
132    }
133
134    if (p == NULL)  {
135        LOG(log_error, logtype_cnid, "tsockfd_create: no suitable network config %s:%s", host, port);
136        freeaddrinfo(servinfo);
137        return -1;
138    }
139
140    freeaddrinfo(servinfo);
141    return sockfd;
142}
143
144/* --------------------- */
145int usockfd_check(int sockfd, const sigset_t *sigset)
146{
147    int fd;
148    socklen_t size;
149    fd_set readfds;
150    int ret;
151
152    FD_ZERO(&readfds);
153    FD_SET(sockfd, &readfds);
154
155    if ((ret = pselect(sockfd + 1, &readfds, NULL, NULL, NULL, sigset)) < 0) {
156        if (errno == EINTR)
157            return 0;
158        LOG(log_error, logtype_cnid, "error in select: %s",
159            strerror(errno));
160        return -1;
161    }
162
163    if (ret) {
164        size = 0;
165        if ((fd = accept(sockfd, NULL, &size)) < 0) {
166            if (errno == EINTR)
167                return 0;
168            LOG(log_error, logtype_cnid, "error in accept: %s",
169                strerror(errno));
170            return -1;
171        }
172        return fd;
173    } else
174        return 0;
175}
176