1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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.
37 #include <sys/types.h>
38 #include <sys/socket.h>
43 #include <sys/sendfile.h>
60 const char *mk_date_wd
[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
61 const char *mk_date_ym
[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
62 "Aug", "Sep", "Oct", "Nov", "Dec"};
64 /* This function given a unix time, set in a mk_pointer
65 * the date in the RFC1123 format like:
67 * Wed, 23 Jun 2010 22:32:01 GMT
69 * it also adds a 'CRLF' at the end
71 int mk_utils_utime2gmt(mk_pointer
**p
, time_t date
)
79 if ((date
= time(NULL
)) == -1) {
84 /* Convert unix time to struct tm */
85 gtm
= (struct tm
*) gmtime(&date
);
90 /* struct tm -> tm_year counts number of years after 1900 */
91 year
= gtm
->tm_year
+ 1900;
93 /* Compose template */
97 *buf
++ = mk_date_wd
[gtm
->tm_wday
][0];
98 *buf
++ = mk_date_wd
[gtm
->tm_wday
][1];
99 *buf
++ = mk_date_wd
[gtm
->tm_wday
][2];
103 /* Day of the month */
104 *buf
++ = ('0' + (gtm
->tm_mday
/ 10));
105 *buf
++ = ('0' + (gtm
->tm_mday
% 10));
109 *buf
++ = mk_date_ym
[gtm
->tm_mon
][0];
110 *buf
++ = mk_date_ym
[gtm
->tm_mon
][1];
111 *buf
++ = mk_date_ym
[gtm
->tm_mon
][2];
115 *buf
++ = ('0' + (year
/ 1000) % 10);
116 *buf
++ = ('0' + (year
/ 100) % 10);
117 *buf
++ = ('0' + (year
/ 10) % 10);
118 *buf
++ = ('0' + (year
% 10));
122 *buf
++ = ('0' + (gtm
->tm_hour
/ 10));
123 *buf
++ = ('0' + (gtm
->tm_hour
% 10));
127 *buf
++ = ('0' + (gtm
->tm_min
/ 10));
128 *buf
++ = ('0' + (gtm
->tm_min
% 10));
132 *buf
++ = ('0' + (gtm
->tm_sec
/ 10));
133 *buf
++ = ('0' + (gtm
->tm_sec
% 10));
136 /* GMT Time zone + CRLF */
144 /* Set mk_pointer data len */
150 time_t PutDate_unix(char *date
)
152 time_t new_unix_time
;
155 if (!strptime(date
, GMT_DATEFORMAT
, (struct tm
*) &t_data
)) {
159 new_unix_time
= mktime((struct tm
*) &t_data
);
161 return (new_unix_time
);
164 int mk_buffer_cat(mk_pointer
*p
, char *buf1
, int len1
, char *buf2
, int len2
)
166 /* Validate lengths */
167 if (len1
< 0 || len2
< 0) {
172 p
->data
= (char *) mk_mem_malloc(len1
+ len2
+ 1);
175 memcpy(p
->data
, buf1
, len1
);
176 memcpy(p
->data
+ len1
, buf2
, len2
);
177 p
->data
[len1
+ len2
] = '\0';
180 p
->len
= len1
+ len2
;
185 /* Run current process in background mode (daemon, evil Monkey >:) */
186 int mk_utils_set_daemon()
195 exit(0); /* Success */
198 setsid(); /* Create new session */
205 /* If the URI contains hexa format characters it will return
206 * convert the Hexa values to ASCII character
208 char *mk_utils_hexuri_to_ascii(mk_pointer uri
)
211 int i
, hex_result
, aux_char
;
216 if ((i
= mk_string_char_search(uri
.data
, '%', uri
.len
)) < 0) {
220 buf
= mk_mem_malloc_z(uri
.len
);
224 strncpy(buf
, uri
.data
, i
);
228 while (i
< uri
.len
) {
229 if (uri
.data
[i
] == '%' && i
+ 2 < uri
.len
) {
230 memset(hex
, '\0', sizeof(hex
));
231 strncpy(hex
, uri
.data
+ i
+ 1, 2);
234 if ((hex_result
= hex2int(hex
)) <= 127) {
235 buf
[buf_idx
] = toascii(hex_result
);
238 if ((aux_char
= get_char(hex_result
)) != -1) {
239 buf
[buf_idx
] = aux_char
;
249 buf
[buf_idx
] = uri
.data
[i
];
260 #include <sys/time.h>
261 void mk_utils_trace(const char *component
, int color
, const char *function
,
262 char *file
, int line
, const char* format
, ...)
265 char *color_function
= NULL
;
266 char *color_fileline
= NULL
;
272 if (!strstr(envtrace
, file
)) {
278 pthread_mutex_lock(&mutex_trace
);
280 gettimeofday(&tv
, &tz
);
282 /* Switch message color */
285 color_function
= ANSI_YELLOW
;
286 color_fileline
= ANSI_WHITE
;
288 case MK_TRACE_PLUGIN
:
289 color_function
= ANSI_BLUE
;
290 color_fileline
= ANSI_WHITE
;
294 va_start( args
, format
);
296 fprintf(stderr
, "~ %s%2i.%i%s %s%s[%s%s%s%s%s|%s:%i%s] %s%s():%s ",
297 ANSI_CYAN
, (int) (tv
.tv_sec
- monkey_init_time
), (int) tv
.tv_usec
, ANSI_RESET
,
298 ANSI_MAGENTA
, ANSI_BOLD
,
299 ANSI_RESET
, ANSI_BOLD
, ANSI_GREEN
, component
, color_fileline
, file
,
301 color_function
, function
, ANSI_RED
);
302 vfprintf( stderr
, format
, args
);
304 fprintf( stderr
, "%s\n", ANSI_RESET
);
307 pthread_mutex_unlock(&mutex_trace
);
312 /* Get SOMAXCONN value. Based on sysctl manpage */
313 int mk_utils_get_somaxconn()
315 /* sysctl() is deprecated in some systems, you can notice that with some system
318 * '(warning: process `monkey' used the deprecated sysctl system call...'
320 * In order to avoid that problem, this function will check the proc filesystem,
321 * if it still fails, we will use the default value defined for somaxconn for years...
327 f
= fopen("/proc/sys/net/core/somaxconn", "r");
328 if(f
&& fgets(buf
, 16, f
)) {
329 somaxconn
= atoi(buf
);
336 /* Write Monkey's PID */
337 int mk_utils_register_pid()
341 remove(config
->pid_file_path
);
342 config
->pid_status
= VAR_OFF
;
344 if ((pid_file
= fopen(config
->pid_file_path
, "w")) == NULL
) {
345 puts("Error: I can't log pid of monkey");
349 fprintf(pid_file
, "%i", getpid());
351 config
->pid_status
= VAR_ON
;
356 /* Remove PID file */
357 int mk_utils_remove_pid()
359 mk_user_undo_uidgid();
360 return remove(config
->pid_file_path
);