Fix mimetype add overflow
[MonkeyD.git] / src / utils.c
blobf6658aa337565345423b7ffb941d210344d168c5
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Monkey HTTP Daemon
4 * ------------------
5 * Copyright (C) 2001-2010, Eduardo Silva P. <edsiper@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #define _GNU_SOURCE
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <assert.h>
28 #include <errno.h>
29 #include <limits.h>
31 #include <ctype.h>
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <signal.h>
43 #include <sys/sendfile.h>
45 #include <time.h>
47 #include "monkey.h"
48 #include "memory.h"
49 #include "utils.h"
50 #include "str.h"
51 #include "config.h"
52 #include "chars.h"
53 #include "socket.h"
54 #include "clock.h"
56 int SendFile(int socket, struct client_request *cr, struct request *sr)
58 long int nbytes = 0;
60 nbytes = sendfile(socket, sr->fd_file, &sr->bytes_offset,
61 sr->bytes_to_send);
63 if (nbytes > 0 && sr->loop == 0) {
64 mk_socket_set_cork_flag(socket, TCP_CORK_OFF);
67 if (nbytes == -1) {
68 fprintf(stderr, "error from sendfile: %s\n", strerror(errno));
69 return -1;
71 else {
72 sr->bytes_to_send -= nbytes;
75 sr->loop++;
76 return sr->bytes_to_send;
79 /* Devuelve la fecha para enviarla
80 en el header */
81 mk_pointer PutDate_string(time_t date)
83 int n, size = 32;
84 mk_pointer date_gmt;
85 struct tm *gmt_tm;
87 mk_pointer_reset(&date_gmt);
89 if (date == 0) {
90 if ((date = time(NULL)) == -1) {
91 return date_gmt;
95 date_gmt.data = mk_mem_malloc(size);
96 gmt_tm = (struct tm *) gmtime(&date);
97 n = strftime(date_gmt.data, size - 1, GMT_DATEFORMAT, gmt_tm);
98 date_gmt.data[n] = '\0';
99 date_gmt.len = n;
101 return date_gmt;
104 time_t PutDate_unix(char *date)
106 time_t new_unix_time;
107 struct tm t_data;
109 if (!strptime(date, GMT_DATEFORMAT, (struct tm *) &t_data)) {
110 return -1;
113 new_unix_time = mktime((struct tm *) &t_data);
115 return (new_unix_time);
118 int mk_buffer_cat(mk_pointer * p, char *buf1, char *buf2)
121 int len1, len2;
123 len1 = strlen(buf1);
124 len2 = strlen(buf2);
126 /* alloc space */
127 p->data = (char *) mk_mem_malloc(len1 + len2 + 1);
129 /* copy data */
130 memcpy(p->data, buf1, len1);
131 memcpy(p->data + len1, buf2, len2);
132 p->data[len1 + len2] = '\0';
134 /* assign len */
135 p->len = len1 + len2;
137 return 0;
140 char *m_build_buffer(char **buffer, unsigned long *len, const char *format,
141 ...)
143 va_list ap;
144 int length;
145 char *ptr;
146 static size_t _mem_alloc = 64;
147 size_t alloc = 0;
149 /* *buffer *must* be an empty/NULL buffer */
151 *buffer = (char *) mk_mem_malloc(_mem_alloc);
152 if (!*buffer) {
153 return NULL;
155 alloc = _mem_alloc;
157 va_start(ap, format);
158 length = vsnprintf(*buffer, alloc, format, ap);
160 if (length >= alloc) {
161 ptr = realloc(*buffer, length + 1);
162 if (!ptr) {
163 va_end(ap);
164 return NULL;
166 *buffer = ptr;
167 alloc = length + 1;
168 length = vsnprintf(*buffer, alloc, format, ap);
170 va_end(ap);
172 if (length < 0) {
173 return NULL;
176 ptr = *buffer;
177 ptr[length] = '\0';
178 *len = length;
180 return *buffer;
183 /* Run current process in background mode (daemon, evil Monkey >:) */
184 int mk_utils_set_daemon()
186 switch (fork()) {
187 case 0:
188 break;
189 case -1:
190 exit(1);
191 break; /* Error */
192 default:
193 exit(0); /* Success */
196 setsid(); /* Create new session */
197 fclose(stdin); /* close screen outputs */
198 fclose(stderr);
199 fclose(stdout);
201 return 0;
204 /* If the URI contains hexa format characters it will return
205 * convert the Hexa values to ASCII character
207 char *mk_utils_hexuri_to_ascii(mk_pointer uri)
210 int i, hex_result, aux_char;
211 int buf_idx = 0;
212 char *buf;
213 char hex[3];
215 if ((i = mk_string_char_search(uri.data, '%', uri.len)) < 0) {
216 return NULL;
219 buf = mk_mem_malloc_z(uri.len);
222 if (i > 0) {
223 strncpy(buf, uri.data, i);
224 buf_idx = i;
227 while (i < uri.len) {
228 if (uri.data[i] == '%' && i + 2 < uri.len) {
229 memset(hex, '\0', sizeof(hex));
230 strncpy(hex, uri.data + i + 1, 2);
231 hex[2] = '\0';
233 if ((hex_result = hex2int(hex)) <= 127) {
234 buf[buf_idx] = toascii(hex_result);
236 else {
237 if ((aux_char = get_char(hex_result)) != -1) {
238 buf[buf_idx] = aux_char;
240 else {
241 mk_mem_free(buf);
242 return NULL;
245 i += 2;
247 else {
248 buf[buf_idx] = uri.data[i];
250 i++;
251 buf_idx++;
253 buf[buf_idx] = '\0';
255 return buf;
258 void mk_utils_toupper(char *string)
260 int i, len;
262 len = strlen(string);
263 for (i = 0; i < len; i++) {
264 string[i] = toupper(string[i]);
268 mk_pointer mk_utils_int2mkp(int n)
270 mk_pointer p;
271 char *buf;
272 unsigned long len;
273 int size = 32;
275 buf = mk_mem_malloc(size);
276 len = snprintf(buf, size, "%i\r\n", n);
278 p.data = buf;
279 p.len = len;
281 return p;
284 #ifdef TRACE
285 #include <sys/time.h>
286 void mk_utils_trace(const char *component, int color, const char *function,
287 char *file, int line, const char* format, ...)
289 va_list args;
290 char *color_function = NULL;
291 char *color_fileline = NULL;
293 struct timeval tv;
294 struct timezone tz;
296 gettimeofday(&tv, &tz);
298 /* Switch message color */
299 switch(color) {
300 case MK_TRACE_CORE:
301 color_function = ANSI_YELLOW;
302 color_fileline = ANSI_WHITE;
303 break;
304 case MK_TRACE_PLUGIN:
305 color_function = ANSI_BLUE;
306 color_fileline = ANSI_WHITE;
307 break;
310 va_start( args, format );
312 fprintf(stderr, "~ %s%2i.%i%s %s%s[%s%s%s%s%s|%s:%i%s] %s%s():%s ",
313 ANSI_CYAN, (int) (tv.tv_sec - monkey_init_time), (int) tv.tv_usec, ANSI_RESET,
314 ANSI_MAGENTA, ANSI_BOLD,
315 ANSI_RESET, ANSI_BOLD, ANSI_GREEN, component, color_fileline, file,
316 line, ANSI_MAGENTA,
317 color_function, function, ANSI_RED);
318 vfprintf( stderr, format, args );
319 va_end( args );
320 fprintf( stderr, "%s\n", ANSI_RESET);
322 #endif