Added signal handling to smtp, nailed many memory leaks on SearchTree, WorkerThread...
[fmail.git] / src / posixsocket.cpp
blob2ec70846d96ac647a78f30f195d5d2b6307b778c
1 /*
2 libfmail: Socket abstraction, Posix Implementation
4 Copyright (C) 2007 Carlos Daniel Ruvalcaba Valenzuela <clsdaniel@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <malloc.h>
25 #include <sys/types.h>
26 #include <sys/uio.h>
27 #include <unistd.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <sys/socket.h>
31 #include <sys/time.h>
32 #include <sys/ioctl.h>
33 #include <poll.h>
34 #include <fcntl.h>
36 #include <libfmail/socket.h>
38 /* TODO: Add proper Unix socket support
39 * TODO: Add better Poll implementation
40 * TODO: Add proper NONBLOCK implementation
41 * */
42 class PosixSocket : public Socket {
43 private:
44 int sock;
45 int sock_port;
46 struct sockaddr_in * sock_addr;
47 struct pollfd sock_poll;
48 public:
49 PosixSocket(int socktype, int options){
50 int family;
51 int flags;
53 if (socktype == SOCKET_INET){
54 family = AF_INET;
55 } else if (socktype == SOCKET_UNIX){
56 family = AF_UNIX;
59 sock = socket(family, SOCK_STREAM, 0);
60 sock_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
61 memset(sock_addr, 0, sizeof(*sock_addr));
62 sock_addr->sin_family = family;
63 sock_poll.fd = sock;
65 if (options | SOCKET_NONBLOCK){
66 flags = fcntl(sock, F_GETFL, 0);
67 fcntl(sock, F_SETFL, flags|O_NONBLOCK);
71 PosixSocket(int s, struct sockaddr_in * addr){
72 sock = s;
73 sock_addr = addr;
76 ~PosixSocket(){
77 free(sock_addr);
80 void setPort(int port){
81 sock_port = port;
82 sock_addr->sin_port = htons(port);
85 int getPort(){
86 return sock_port;
89 void setAddress(const char * addr){
90 if (addr == 0){
91 sock_addr->sin_addr.s_addr = htonl(INADDR_ANY);
92 } else{
93 inet_pton(AF_INET, addr, &(sock_addr->sin_addr));
97 char *getAddress(){
98 char * addr;
99 addr = (char *)malloc(sizeof(char) * 17);
100 if (!addr)
101 return 0;
102 inet_ntop(AF_INET, &(sock_addr->sin_addr), addr, 17);
103 return addr;
106 int Connect(){
107 size_t slen;
109 slen = sizeof(struct sockaddr_in);
110 return connect(sock, (struct sockaddr *)(sock_addr), slen);
113 int Bind(){
114 int slen;
116 slen = sizeof(struct sockaddr_in);
117 return bind(sock, (struct sockaddr *)sock_addr, slen);
120 int Listen(int queue){
121 return listen(sock, queue);
124 int Write(const char * buffer, int len){
125 return write(sock, buffer, len);
128 int Read(char * buffer, int len){
129 return read(sock, buffer, len);
132 Socket *Accept(){
133 int client_socket;
134 struct sockaddr_in * client;
135 socklen_t clen;
136 Socket * s;
138 client = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
139 if (!client)
140 return 0;
141 clen = sizeof(struct sockaddr_in);
143 client_socket = accept(sock, (struct sockaddr *)client, &clen);
145 if (client_socket == -1)
146 return 0;
147 s = new PosixSocket(client_socket, client);
148 return s;
151 int Close(){
152 return close(sock);
155 int Poll(int ms, int mode){
156 int ret;
158 ret = 0;
159 sock_poll.fd = sock;
160 sock_poll.events = 0;
162 if (mode & SOCKET_POLL_READ)
163 sock_poll.events |= POLLIN;
164 if (mode & SOCKET_POLL_WRITE)
165 sock_poll.events |= POLLOUT;
166 if (mode & SOCKET_POLL_ERROR)
167 sock_poll.events |= POLLERR;
169 ret = poll(&sock_poll, 1, ms);
170 if (ret == -1) {
171 ret |= SOCKET_POLL_ERROR;
172 return ret;
175 if (sock_poll.revents & POLLIN)
176 ret |= SOCKET_POLL_READ;
177 if (sock_poll.revents & POLLOUT)
178 ret |= SOCKET_POLL_WRITE;
179 if (sock_poll.revents & POLLERR)
180 ret |= SOCKET_POLL_ERROR;
182 return ret;
186 Socket * Socket::CreateSocket(int socktype, int options){
187 return new PosixSocket(socktype, options);