1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
5 * Copyright (C) 2001-2003, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
44 struct mk_config
*mk_config_create(char *path
)
49 char *key
=0, *val
=0, *last
=0;
50 struct mk_config
*cnf
=0, *new, *p
;
52 if((f
=fopen(path
, "r")) == NULL
) {
53 fprintf(stderr
, "\nConfig Error: I can't open %s file\n\n", path
);
57 /* looking for configuration directives */
58 while(fgets(buf
, 255, f
)){
60 if(buf
[len
-1] == '\n') {
62 if(len
&& buf
[len
-1] == '\r')
66 if(!buf
[0] || buf
[0] == '#')
69 key
= strtok_r(buf
, "\"\t ", &last
);
70 val
= strtok_r(NULL
, "\"\t ", &last
);
76 /* Allow new entry found */
77 new = mk_mem_malloc(sizeof(struct mk_config
));
78 new->key
= mk_string_dup(key
);
79 new->val
= mk_string_dup(val
);
82 /* Link to main list */
99 void mk_config_free(struct mk_config
*cnf
)
101 struct mk_config
*prev
=0, *target
;
107 target
= target
->next
;
120 void *mk_config_getval(struct mk_config
*cnf
, char *key
, int mode
)
127 if(strcasecmp(p
->key
, key
) == 0){
129 case MK_CONFIG_VAL_STR
:
130 return (void *) p
->val
;
131 case MK_CONFIG_VAL_NUM
:
132 return (void *) atoi(p
->val
);
133 case MK_CONFIG_VAL_BOOL
:
134 on
= strcasecmp(p
->val
, VALUE_ON
);
135 off
= strcasecmp(p
->val
,VALUE_OFF
);
141 return (void *) VAR_ON
;
144 return (void *) VAR_OFF
;
155 /* Read configuration files */
156 void mk_config_read_files(char *path_conf
, char *file_conf
)
161 struct stat checkdir
;
162 struct mk_config
*cnf
;
164 config
->serverconf
= mk_string_dup(path_conf
);
165 config
->workers
= MK_WORKERS_DEFAULT
;
167 if(stat(config
->serverconf
, &checkdir
)==-1){
168 fprintf(stderr
, "ERROR: Invalid path to configuration files.");
172 m_build_buffer(&path
, &len
, "%s/%s", path_conf
, file_conf
);
174 cnf
= mk_config_create(path
);
176 /* Connection port */
177 config
->serverport
= (int) mk_config_getval(cnf
,
180 if(!config
->serverport
>=1 && !config
->serverport
<=65535){
181 mk_config_print_error_msg("Port", path
);
184 /* Number of thread workers */
185 config
->workers
= (int) mk_config_getval(cnf
,
188 if(config
->maxclients
< 1){
189 mk_config_print_error_msg("Workers", path
);
193 config
->timeout
= (int) mk_config_getval(cnf
,
196 if(config
->timeout
< 1){
197 mk_config_print_error_msg("Timeout", path
);
201 config
->keep_alive
= (int) mk_config_getval(cnf
,
204 if(config
->keep_alive
== VAR_ERR
){
205 mk_config_print_error_msg("KeepAlive", path
);
208 /* MaxKeepAliveRequest */
209 config
->max_keep_alive_request
= (int) mk_config_getval(cnf
,
210 "MaxKeepAliveRequest",
212 if(config
->max_keep_alive_request
== 0){
213 mk_config_print_error_msg("MaxKeepAliveRequest", path
);
216 /* KeepAliveTimeout */
217 config
->keep_alive_timeout
= (int) mk_config_getval(cnf
,
220 if(config
->keep_alive_timeout
== 0){
221 mk_config_print_error_msg("KeepAliveTimeout", path
);
225 config
->pid_file_path
= mk_config_getval(cnf
,
229 /* Home user's directory /~ */
230 config
->user_dir
= mk_config_getval(cnf
, "UserDir", MK_CONFIG_VAL_STR
);
234 aux
= index
= mk_config_getval(cnf
, "Indexfile", MK_CONFIG_VAL_STR
);
236 mk_config_add_index(aux
);
237 aux
=strtok_r(NULL
,"\"\t ", &last
);
240 /* HideVersion Variable */
241 config
->hideversion
= (int) mk_config_getval(cnf
,
244 if(config
->hideversion
== VAR_ERR
){
245 mk_config_print_error_msg("HideVersion", path
);
249 config
->user
= mk_config_getval(cnf
, "User", MK_CONFIG_VAL_STR
);
252 config
->resume
= (int) mk_config_getval(cnf
,
255 if(config
->resume
== VAR_ERR
){
256 mk_config_print_error_msg("Resume", path
);
260 config
->symlink
= (int) mk_config_getval(cnf
,
263 if(config
->symlink
== VAR_ERR
){
264 mk_config_print_error_msg("SymLink", path
);
268 /* Monkey Palm Servers */
270 palm
= mk_config_getval(cnf
, "Palm", MK_CONFIG_VAL_STR
);
272 struct palm
*new, *p
;
274 new = mk_mem_malloc(sizeof(struct palm
));
275 new->ext
= strdup(strtok_r(NULL
, "\"\t ", &last
));
276 new->mimetype
= strdup(strtok_r(NULL
,"\"\t ", &last
));
277 new->host
= strdup(strtok_r(NULL
,"\"\t ", &last
));
278 new->port
= atoi(strtok_r(NULL
, "\"\t ", &last
));
295 mk_config_read_hosts(path_conf
);
298 void mk_config_read_hosts(char *path
)
304 struct host
*p_host
, *new_host
; /* debug */
307 m_build_buffer(&buf
, &len
, "%s/sites/default", path
);
308 config
->hosts
= mk_config_get_host(buf
);
314 printf("\nError parsing main configuration file 'default'\n");
318 m_build_buffer(&buf
, &len
, "%s/sites/", path
);
319 if (!(dir
= opendir(buf
)))
323 p_host
= config
->hosts
;
325 /* Reading content */
326 while ((ent
= readdir(dir
)) != NULL
)
328 if (strcmp((char *) ent
->d_name
, "." ) == 0) continue;
329 if (strcmp((char *) ent
->d_name
, ".." ) == 0) continue;
330 if (strcasecmp((char *) ent
->d_name
, "default" ) == 0) continue;
332 m_build_buffer(&file
, &len
, "%s/sites/%s", path
, ent
->d_name
);
334 new_host
= (struct host
*) mk_config_get_host(file
);
341 p_host
->next
= new_host
;
351 printf("*** HOST ***\n");
352 printf(" [servername]\t\t%s\n", h->servername);
353 printf(" [documentroot]\t\t%s\n", h->documentroot);
354 printf(" [conf file]\t\t%s\n", h->file);
355 printf(" [access log]\t\t%s\n", h->access_log_path);
356 printf(" [error log]\t\t%s\n", h->error_log_path);
357 printf(" [script alias]\t\t%s %s\n", h->scriptalias[0], h->scriptalias[1]);
358 printf(" [get dir]\t\t%i\n", h->getdir);
359 printf(" [header file]\t\t%s\n", h->header_file);
360 printf(" [footer file]\t\t%s\n\n", h->footer_file);
368 struct host
*mk_config_get_host(char *path
)
371 struct stat checkdir
;
373 struct mk_config
*cnf
;
375 cnf
= mk_config_create(path
);
377 host
= mk_mem_malloc_z(sizeof(struct host
));
378 host
->servername
= 0;
379 host
->file
= mk_string_dup(path
);
381 host
->servername
= mk_config_getval(cnf
, "Servername", MK_CONFIG_VAL_STR
);
382 host
->documentroot
.data
= mk_config_getval(cnf
,
385 host
->documentroot
.len
= strlen(host
->documentroot
.data
);
386 if(stat(host
->documentroot
.data
, &checkdir
)==-1) {
388 "ERROR: Invalid path to Server_root in %s\n\n",
392 else if(!(checkdir
.st_mode
& S_IFDIR
)) {
394 "ERROR: DocumentRoot variable in %s has an invalid directory path\n\n",
400 host
->access_log_path
= mk_config_getval(cnf
,
404 host
->error_log_path
= mk_config_getval(cnf
,
409 host
->getdir
= (int) mk_config_getval(cnf
, "GetDir", MK_CONFIG_VAL_BOOL
);
410 if(host
->getdir
== VAR_ERR
){
411 mk_config_print_error_msg("GetDir", path
);
414 if(!host
->servername
){
419 /* Server Signature */
420 if(config
->hideversion
==VAR_OFF
){
421 m_build_buffer(&host
->host_signature
, &len
,
422 "Monkey/%s Server (Host: %s, Port: %i)",
423 VERSION
, host
->servername
, config
->serverport
);
426 m_build_buffer(&host
->host_signature
, &len
,
427 "Monkey Server (Host: %s, Port: %i)",
428 host
->servername
, config
->serverport
);
430 m_build_buffer(&host
->header_host_signature
.data
,
431 &host
->header_host_signature
.len
,
432 "Server: %s", host
->host_signature
);
434 if(pipe(host
->log_access
)<0){
438 if(pipe(host
->log_error
)<0){
442 fcntl(host
->log_access
[1], F_SETFL
, O_NONBLOCK
);
443 fcntl(host
->log_error
[1], F_SETFL
, O_NONBLOCK
);
450 /* Imprime error de configuracion y cierra */
451 void mk_config_print_error_msg(char *variable
, char *path
)
453 fprintf(stderr
, "\nError: %s variable in %s has an invalid value.\n", variable
, path
);
458 /* Agrega distintos index.xxx */
459 void mk_config_add_index(char *indexname
)
461 struct indexfile
*new_index
=0, *aux_index
;
463 new_index
= (struct indexfile
*) malloc(sizeof(struct indexfile
));
464 strncpy(new_index
->indexname
,indexname
,MAX_INDEX_NOMBRE
- 1);
465 new_index
->indexname
[MAX_INDEX_NOMBRE
- 1]='\0';
466 new_index
->next
=NULL
;
468 if(first_index
==NULL
) {
469 first_index
=new_index
;
472 aux_index
=first_index
;
473 while(aux_index
->next
!=NULL
)
474 aux_index
=aux_index
->next
;
475 aux_index
->next
=new_index
;
479 void mk_config_set_init_values(void)
481 /* Valores iniciales */
483 config
->hideversion
=VAR_OFF
;
484 config
->keep_alive
=VAR_ON
;
485 config
->keep_alive_timeout
=15;
486 config
->max_keep_alive_request
=50;
487 config
->maxclients
=150;
489 config
->resume
=VAR_ON
;
490 config
->standard_port
=80;
491 config
->serverport
=2001;
492 config
->symlink
=VAR_OFF
;
495 config
->open_flags
= O_RDONLY
| O_NONBLOCK
;
498 config
->plugins
= mk_mem_malloc_z(sizeof(struct plugin_stages
));
501 /* read main configuration from monkey.conf */
502 void mk_config_start_configure(void)
506 mk_config_set_init_values();
507 mk_config_read_files(config
->file_config
, M_DEFAULT_CONFIG_FILE
);
509 /* if not index names defined, set default */
510 if(first_index
==NULL
){
511 mk_config_add_index("index.html");
515 mk_mimetype_read_config();
517 /* Basic server information */
518 if(config
->hideversion
==VAR_OFF
)
520 m_build_buffer(&config
->server_software
.data
,
521 &len
, "Monkey/%s (%s)",VERSION
,OS
);
522 config
->server_software
.len
= len
;
526 m_build_buffer(&config
->server_software
.data
, &len
,
528 config
->server_software
.len
= len
;
532 struct host
*mk_config_host_find(mk_pointer host
)
534 struct host
*aux_host
;
536 aux_host
= config
->hosts
;
539 if(strncasecmp(aux_host
->servername
, host
.data
, host
.len
)==0)
542 aux_host
=aux_host
->next
;
548 void mk_config_sanity_check()
550 /* Check O_NOATIME for current user, flag will just be used
551 * if running user is allowed to.
553 int fd
, flags
=config
->open_flags
;
556 fd
= open(config
->file_config
, flags
);
559 config
->open_flags
= flags
;