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