• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.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#ifdef HAVE_UNISTD_H
15#include <unistd.h>
16#endif /* HAVE_UNISTD_H */
17#include <sys/un.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <netdb.h>
22
23#ifdef HAVE_SYS_TYPES_H
24#include <sys/types.h>
25#endif /* HAVE_SYS_TYPES_H */
26#ifdef HAVE_SYS_TIME_H
27#include <sys/time.h>
28#endif /* HAVE_SYS_TIME_H */
29
30
31#include <atalk/logger.h>
32#include <atalk/compat.h>
33#include "usockfd.h"
34
35#include <sys/select.h>
36
37int usockfd_create(char *usock_fn, mode_t mode, int backlog)
38{
39    int sockfd;
40    struct sockaddr_un addr;
41
42
43    if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
44        LOG(log_error, logtype_cnid, "error in socket call: %s",
45            strerror(errno));
46        return -1;
47    }
48
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));
52        return -1;
53    }
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));
60        return -1;
61    }
62
63    if (listen(sockfd, backlog) < 0) {
64        LOG(log_error, logtype_cnid, "error in listen for %s: %s",
65            usock_fn, strerror(errno));
66        return -1;
67    }
68
69#ifdef chmod
70#undef chmod
71#endif
72    if (chmod(usock_fn, mode) < 0) {
73        LOG(log_error, logtype_cnid, "error changing permissions for %s: %s",
74            usock_fn, strerror(errno));
75        close(sockfd);
76        return -1;
77    }
78
79    return sockfd;
80}
81
82/* ---------------
83 * create a tcp socket
84 */
85int tsockfd_create(char *host, char *port, int backlog)
86{
87    int sockfd, flag, ret;
88    struct addrinfo hints, *servinfo, *p;
89
90    /* Prepare hint for getaddrinfo */
91    memset(&hints, 0, sizeof hints);
92    hints.ai_family = AF_UNSPEC;
93    hints.ai_socktype = SOCK_STREAM;
94
95    if ((ret = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
96        LOG(log_error, logtype_default, "tsockfd_create: getaddrinfo: %s\n", gai_strerror(ret));
97        return 0;
98    }
99
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));
105            continue;
106        }
107
108        /*
109         * Set some socket options:
110         * SO_REUSEADDR deals w/ quick close/opens
111         * TCP_NODELAY diables Nagle
112         */
113#ifdef SO_REUSEADDR
114        flag = 1;
115        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
116#endif
117
118#ifdef USE_TCP_NODELAY
119#ifndef SOL_TCP
120#define SOL_TCP IPPROTO_TCP
121#endif
122        flag = 1;
123        setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
124#endif /* USE_TCP_NODELAY */
125
126        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
127            close(sockfd);
128            LOG(log_info, logtype_default, "tsockfd_create: bind: %s\n", strerror(errno));
129            continue;
130        }
131
132        if (listen(sockfd, backlog) < 0) {
133            close(sockfd);
134            LOG(log_info, logtype_default, "tsockfd_create: listen: %s\n", strerror(errno));
135            continue;
136        }
137
138        /* We got a socket */
139        break;
140    }
141
142    if (p == NULL)  {
143        LOG(log_error, logtype_default, "tsockfd_create: no suitable network config %s:%s", host, port);
144        freeaddrinfo(servinfo);
145        return -1;
146    }
147
148    freeaddrinfo(servinfo);
149    return sockfd;
150}
151
152/* --------------------- */
153int usockfd_check(int sockfd, const sigset_t *sigset)
154{
155    int fd;
156    socklen_t size;
157    fd_set readfds;
158    int ret;
159
160    FD_ZERO(&readfds);
161    FD_SET(sockfd, &readfds);
162
163    if ((ret = pselect(sockfd + 1, &readfds, NULL, NULL, NULL, sigset)) < 0) {
164        if (errno == EINTR)
165            return 0;
166        LOG(log_error, logtype_cnid, "error in select: %s",
167            strerror(errno));
168        return -1;
169    }
170
171    if (ret) {
172        size = 0;
173        if ((fd = accept(sockfd, NULL, &size)) < 0) {
174            if (errno == EINTR)
175                return 0;
176            LOG(log_error, logtype_cnid, "error in accept: %s",
177                strerror(errno));
178            return -1;
179        }
180        return fd;
181    } else
182        return 0;
183}
184