Update Copyright date in files
[MonkeyD.git] / src / utils.c
blob236e9083190745a37cfea45e2ce6dc8800dbc693
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.
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 = 50;
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;
205 char *get_real_string(mk_pointer uri)
208 int i, hex_result, aux_char;
209 int buf_idx = 0;
210 char *buf;
211 char hex[3];
213 if ((i = mk_string_char_search(uri.data, '%', uri.len)) < 0) {
214 return NULL;
217 buf = mk_mem_malloc_z(uri.len);
220 if (i > 0) {
221 strncpy(buf, uri.data, i);
222 buf_idx = i;
225 while (i < uri.len) {
226 if (uri.data[i] == '%' && i + 2 < uri.len) {
227 memset(hex, '\0', sizeof(hex));
228 strncpy(hex, uri.data + i + 1, 2);
229 hex[2] = '\0';
231 if ((hex_result = hex2int(hex)) <= 127) {
232 buf[buf_idx] = toascii(hex_result);
234 else {
235 if ((aux_char = get_char(hex_result)) != -1) {
236 buf[buf_idx] = aux_char;
238 else {
239 mk_mem_free(buf);
240 return NULL;
243 i += 2;
245 else {
246 buf[buf_idx] = uri.data[i];
248 i++;
249 buf_idx++;
251 buf[buf_idx] = '\0';
253 return buf;
256 void mk_utils_toupper(char *string)
258 int i, len;
260 len = strlen(string);
261 for (i = 0; i < len; i++) {
262 string[i] = toupper(string[i]);
266 mk_pointer mk_utils_int2mkp(int n)
268 mk_pointer p;
269 char *buf;
270 unsigned long len;
271 int size = 32;
273 buf = mk_mem_malloc(size);
274 len = snprintf(buf, 32, "%i", n);
276 p.data = buf;
277 p.len = len;
279 return p;
282 #ifdef TRACE
283 #include <sys/time.h>
284 void mk_utils_trace(const char *component, int color, const char *function,
285 char *file, int line, const char* format, ...)
287 va_list args;
288 char *color_function = NULL;
289 char *color_fileline = NULL;
291 struct timeval tv;
292 struct timezone tz;
294 gettimeofday(&tv, &tz);
296 /* Switch message color */
297 switch(color) {
298 case MK_TRACE_CORE:
299 color_function = ANSI_YELLOW;
300 color_fileline = ANSI_WHITE;
301 break;
302 case MK_TRACE_PLUGIN:
303 color_function = ANSI_BLUE;
304 color_fileline = ANSI_WHITE;
305 break;
308 va_start( args, format );
310 fprintf(stderr, "~ %s%2i.%i%s %s%s[%s%s%s%s%s|%s:%i%s] %s%s():%s ",
311 ANSI_CYAN, (tv.tv_sec - monkey_init_time), tv.tv_usec, ANSI_RESET,
312 ANSI_MAGENTA, ANSI_BOLD,
313 ANSI_RESET, ANSI_BOLD, ANSI_GREEN, component, color_fileline, file,
314 line, ANSI_MAGENTA,
315 color_function, function, ANSI_RED);
316 vfprintf( stderr, format, args );
317 va_end( args );
318 fprintf( stderr, "%s\n", ANSI_RESET);
320 #endif