initial revision
[ucgine.git] / lib / cmd / ucg_cmd_socket.c
1 /*
2  * Copyright (c) 2009-2015, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /*-
29  * Copyright (c) <2010>, Intel Corporation
30  * All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * - Redistributions of source code must retain the above copyright
37  *   notice, this list of conditions and the following disclaimer.
38  *
39  * - Redistributions in binary form must reproduce the above copyright
40  *   notice, this list of conditions and the following disclaimer in
41  *   the documentation and/or other materials provided with the
42  *   distribution.
43  *
44  * - Neither the name of Intel Corporation nor the names of its
45  *   contributors may be used to endorse or promote products derived
46  *   from this software without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
54  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
55  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59  * OF THE POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 #include <stdio.h>
63 #include <string.h>
64 #include <unistd.h>
65 #include <stdlib.h>
66 #include <stdarg.h>
67 #include <inttypes.h>
68 #include <fcntl.h>
69 #ifdef UCG_CMD_HAVE_TERMIOS
70 #include <termios.h>
71 #endif
72
73 #ifdef UCG_CMD_HAVE_SOCKET
74 #include <sys/socket.h>
75 #include <netinet/in.h>
76 #include <sys/socket.h>
77 #include <sys/un.h>
78 #endif
79
80 #include "ucg_cmd_parse.h"
81 #include "ucg_cmd_rdline.h"
82 #include "ucg_cmd_socket.h"
83 #include "ucg_cmd.h"
84
85 #ifdef UCG_CMD_HAVE_SOCKET
86 int
87 ucg_cmd_tcpv4_listen(in_addr_t addr, uint16_t port)
88 {
89         int s;
90         struct sockaddr_in sin_ci;
91         int optval = 1;
92
93         s = socket(PF_INET, SOCK_STREAM, 0);
94         if (s < 0)
95                 return s;
96
97         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
98                         &optval, sizeof(optval)) == -1)
99                 goto end;
100
101         memset(&sin_ci, 0, sizeof(sin_ci));
102         sin_ci.sin_family = AF_INET;
103         sin_ci.sin_addr.s_addr = addr;
104         sin_ci.sin_port = htons(port);
105 #ifndef __linux__
106         sin_ci.sin_len = sizeof(sin_ci);
107 #endif
108         if (bind(s, (struct sockaddr *)&sin_ci, sizeof(sin_ci)) < 0)
109                 goto end;
110
111         if (listen(s, 1) < 0)
112                 goto end;
113
114         return s;
115  end:
116         close(s);
117         return -1;
118 }
119
120 int
121 ucg_cmd_tcpv6_listen(const struct in6_addr *addr6, uint16_t port)
122 {
123         int s;
124         struct sockaddr_in6 sin6_ci;
125
126         s = socket(PF_INET6, SOCK_STREAM, 0);
127         if (s < 0)
128                 return s;
129
130         bzero(&sin6_ci, sizeof(sin6_ci));
131         sin6_ci.sin6_family = AF_INET6;
132 #ifndef __linux__
133         sin6_ci.sin6_len = sizeof(sin6_ci);
134 #endif
135         memcpy(&sin6_ci.sin6_addr, addr6, sizeof(sin6_ci.sin6_addr));
136         sin6_ci.sin6_port = htons(port);
137         if (bind(s, (struct sockaddr *) &sin6_ci, sizeof(sin6_ci)) < 0)
138                 goto end;
139
140         if (listen(s, 1) < 0)
141                 goto end;
142
143         return s;
144  end:
145         close(s);
146         return -1;
147 }
148
149 int
150 ucg_cmd_unix_listen(const char *filename)
151 {
152         int s;
153         struct sockaddr_un servAddr;
154
155         s = socket(AF_UNIX, SOCK_STREAM, 0);
156         if (s < 0)
157                 return s;
158
159         bzero(&servAddr, sizeof(servAddr));
160         servAddr.sun_family = AF_UNIX;
161         memcpy(servAddr.sun_path, filename , strlen(filename));
162
163         unlink(filename);
164         if(bind(s, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
165                 goto end;
166
167         if (listen(s, 1) < 0)
168                 goto end;
169
170         return s;
171  end:
172         close(s);
173         return -1;
174 }
175
176 struct ucg_cmd *
177 ucg_cmd_accept(ucg_cmd_ctx_t *ctx, const char *prompt, int s)
178 {
179         FILE *f;
180         int s2;
181         struct sockaddr sin;
182         socklen_t sinlen;
183
184         sinlen = sizeof(struct sockaddr);
185
186         if ((s2 = accept(s, &sin, &sinlen)) < 0)
187                 return NULL;
188
189         f = fdopen(s2, "r+");
190         if (f == NULL) {
191                 close(s2);
192                 return NULL;
193         }
194         return (ucg_cmd_new(ctx, prompt, f, f));
195 }
196 #endif