Tizen 2.1 base
[platform/framework/web/download-provider.git] / provider / download-provider-socket.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20
21 #include <pthread.h>
22
23 #include <time.h>
24 #include <sys/time.h>
25
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sys/stat.h>
29
30 #include <signal.h>
31
32 #include "download-provider.h"
33 #include "download-provider-log.h"
34 #include "download-provider-socket.h"
35
36 //////////////////////////////////////////////////////////////////////////
37 /// @brief write the error to socket
38 /// @return if success, return 0
39 int dp_ipc_send_errorcode(int fd, dp_error_type errorcode)
40 {
41         if (fd < 0) {
42                 TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
43                 return -1;
44         }
45
46         if (fd >= 0 && write(fd, &errorcode, sizeof(dp_error_type)) <= 0) {
47                 TRACE_STRERROR("[ERROR] write FD[%d]", fd);
48                 return -1;
49         }
50         return 0;
51 }
52
53 //////////////////////////////////////////////////////////////////////////
54 /// @brief write the progressinfo to socket
55 /// @return if success, return 0
56 int dp_ipc_send_event(int fd, int id, dp_state_type state,
57         dp_error_type errorcode, unsigned long long received_size)
58 {
59         if (fd < 0) {
60                 TRACE_ERROR("[ERROR][%d] CHECK FD[%d]", id, fd);
61                 return -1;
62         }
63
64         dp_event_info eventinfo;
65         eventinfo.id = id;
66         eventinfo.state = state;
67         eventinfo.err = errorcode;
68         eventinfo.received_size = received_size;
69
70         // write
71         if (fd >= 0 && write(fd, &eventinfo, sizeof(dp_event_info)) <= 0) {
72                 TRACE_STRERROR("[ERROR][%d] write FD[%d]", id, fd);
73                 return -1;
74         }
75         return 0;
76 }
77
78 // keep the order/ unsigned , str
79 char *dp_ipc_read_string(int fd)
80 {
81         unsigned length = 0;
82         char *str = NULL;
83
84         if (fd < 0) {
85                 TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
86                 return NULL;
87         }
88
89         // read flexible URL from client.
90         if (read(fd, &length, sizeof(unsigned)) < 0) {
91                 TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
92                 return NULL;
93         }
94         if (length < 1 || length > DP_MAX_URL_LEN) {
95                 TRACE_ERROR("[STRING LEGNTH] [%d]", length);
96                 return NULL;
97         }
98         str = (char *)calloc((length + 1), sizeof(char));
99         if (read(fd, str, length * sizeof(char)) < 0) {
100                 TRACE_STRERROR("[ERROR] read FD[%d]", fd);
101                 free(str);
102                 str = NULL;
103                 return NULL;
104         }
105         str[length] = '\0';
106         return str;
107 }
108
109 // keep the order/ unsigned , str
110 int dp_ipc_send_string(int fd, const char *str)
111 {
112         unsigned length = 0;
113
114         if (fd < 0) {
115                 TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
116                 return -1;
117         }
118         if (!str) {
119                 TRACE_ERROR("[ERROR] CHECK STRING FD[%d]", fd);
120                 return -1;
121         }
122
123         length = strlen(str);
124         if (length < 1) {
125                 TRACE_ERROR("[ERROR] CHECK LENGTH FD[%d]", fd);
126                 return -1;
127         }
128         if (fd >= 0 && write(fd, &length, sizeof(unsigned)) <= 0) {
129                 TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
130                 return -1;
131         }
132         if (fd >= 0 && write(fd, str, length * sizeof(char)) <= 0) {
133                 TRACE_STRERROR("[ERROR] write FD[%d]", fd);
134                 return -1;
135         }
136         return 0;
137 }
138
139 int dp_ipc_send_custom_type(int fd, void *value, size_t type_size)
140 {
141         if (fd < 0) {
142                 TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
143                 return -1;
144         }
145         if (!value) {
146                 TRACE_ERROR("[ERROR] CHECK VALUE FD[%d]", fd);
147                 return -1;
148         }
149         if (fd >= 0 && write(fd, value, type_size) <= 0) {
150                 TRACE_STRERROR("[ERROR] write FD[%d]", fd);
151                 return -1;
152         }
153         return 0;
154 }
155
156 int dp_ipc_read_custom_type(int fd, void *value, size_t type_size)
157 {
158         if (fd < 0) {
159                 TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
160                 return -1;
161         }
162
163         if (read(fd, value, type_size) < 0) {
164                 TRACE_STRERROR("[ERROR] read FD[%d]", fd);
165                 return -1;
166         }
167         return 0;
168 }
169
170 int dp_accept_socket_new()
171 {
172         int sockfd = -1;
173         struct sockaddr_un listenaddr;
174
175         if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
176                 TRACE_STRERROR("failed to create socket");
177                 return -1;
178         }
179
180         bzero(&listenaddr, sizeof(listenaddr));
181         listenaddr.sun_family = AF_UNIX;
182         strcpy(listenaddr.sun_path, DP_IPC);
183
184         if (bind(sockfd, (struct sockaddr *)&listenaddr, sizeof listenaddr) !=
185                 0) {
186                 TRACE_STRERROR("[CRITICAL] bind");
187                 close(sockfd);
188                 return -1;
189         }
190
191         if (chmod(listenaddr.sun_path, 0777) < 0) {
192                 TRACE_STRERROR("[CRITICAL] chmod");
193                 close(sockfd);
194                 return -1;
195         }
196
197         // need 3 socket per a group
198         if (listen(sockfd, DP_MAX_GROUP * 3) != 0) {
199                 TRACE_STRERROR("[CRITICAL] listen");
200                 close(sockfd);
201                 return -1;
202         }
203         return sockfd;
204 }
205
206 int dp_socket_free(int sockfd)
207 {
208         TRACE_INFO("[%d]", sockfd);
209         if (sockfd < 0)
210                 return -1;
211         shutdown(sockfd, 0);
212         close(sockfd);
213         return 0;
214 }