1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
5 * Copyright (C) 2001-2009, 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.
25 #include <sys/types.h>
32 #include "scheduler.h"
39 #define MK_CHEETAH_STATUS "status"
40 #define MK_CHEETAH_STATUS_SC "\\s"
42 #define MK_CHEETAH_HELP "help"
43 #define MK_CHEETAH_HELP_SC "\\h"
45 #define MK_CHEETAH_UPTIME "uptime"
46 #define MK_CHEETAH_UPTIME_SC "\\u"
48 #define MK_CHEETAH_PLUGINS "plugins"
49 #define MK_CHEETAH_PLUGINS_SC "\\g"
51 #define MK_CHEETAH_VHOSTS "vhosts"
52 #define MK_CHEETAH_VHOSTS_SC "\\v"
54 #define MK_CHEETAH_WORKERS "workers"
55 #define MK_CHEETAH_WORKERS_SC "\\w"
57 #define MK_CHEETAH_QUIT "quit"
58 #define MK_CHEETAH_QUIT_SC "\\q"
60 #define MK_CHEETAH_PROMPT "cheetah> "
61 #define MK_CHEETAH_PROC_TASK "/proc/%i/task/%i/stat"
62 #define MK_CHEETAH_ONEDAY 86400
63 #define MK_CHEETAH_ONEHOUR 3600
64 #define MK_CHEETAH_ONEMINUTE 60
66 /* Plugin data for register */
67 mk_plugin_data_t _name
= "Cheetah";
68 mk_plugin_data_t _version
= "1.0";
69 mk_plugin_stage_t _stages
= MK_PLUGIN_STAGE_10
;
72 struct plugin_api
*mk_api
;
74 void mk_cheetah_print_worker_memory_usage(pid_t pid
)
76 int last
, init
, n
, c
= 0;
84 buf
= mk_api
->mem_alloc(s
);
85 sprintf(buf
, MK_CHEETAH_PROC_TASK
, ppid
, pid
);
89 printf("Cannot get details\n");
93 buf
= fgets(buf
, s
, f
);
95 printf("Cannot format details\n");
106 while((n
= mk_string_search(buf
+last
, " ")) > 0){
108 value
= mk_string_copy_substr(buf
, init
, last
+n
);
109 printf("%s\n", value
);
120 void mk_cheetah_print_running_user()
123 struct passwd
*result
;
128 bufsize
= sysconf(_SC_GETPW_R_SIZE_MAX
);
133 buf
= malloc(bufsize
);
135 getpwuid_r(uid
, &pwd
, buf
, bufsize
, &result
);
137 printf("%s\n", pwd
.pw_name
);
141 void mk_cheetah_cmd_uptime()
143 int days
; int hours
; int minutes
; int seconds
;
148 /* uptime in seconds */
149 uptime
= time(NULL
) - init_time
;
152 days
= uptime
/ MK_CHEETAH_ONEDAY
;
153 upmind
= uptime
- (days
* MK_CHEETAH_ONEDAY
);
156 hours
= upmind
/ MK_CHEETAH_ONEHOUR
;
157 upminh
= upmind
- hours
* MK_CHEETAH_ONEHOUR
;
160 minutes
= upminh
/ MK_CHEETAH_ONEMINUTE
;
161 seconds
= upminh
- minutes
* MK_CHEETAH_ONEMINUTE
;
163 printf("Server has been running: %i day%s, %i hour%s, %i minute%s and %i second%s\n",
164 days
, (days
> 1) ? "s" : "",
165 hours
, (hours
> 1) ? "s" : "",
166 minutes
, (minutes
> 1) ? "s" : "",
167 seconds
, (seconds
> 1) ? "s" : "");
170 void mk_cheetah_cmd_plugins_print(struct plugin
*list
, const char *stage
)
179 printf("* %s", stage
);
180 printf("\n Loaded plugins on this stage");
181 printf("\n ----------------------------");
183 printf("\n %s v%s on \"%s\"", p
->name
, p
->version
, p
->path
);
190 void mk_cheetah_cmd_plugins()
192 struct plugin_stages
*p
= mk_api
->config
->plugins
;
194 mk_cheetah_cmd_plugins_print(p
->stage_10
, "STAGE_10");
195 mk_cheetah_cmd_plugins_print(p
->stage_20
, "STAGE_20");
196 mk_cheetah_cmd_plugins_print(p
->stage_30
, "STAGE_30");
197 mk_cheetah_cmd_plugins_print(p
->stage_40
, "STAGE_40");
198 mk_cheetah_cmd_plugins_print(p
->stage_50
, "STAGE_50");
199 mk_cheetah_cmd_plugins_print(p
->stage_60
, "STAGE_60");
202 void mk_cheetah_cmd_vhosts()
206 host
= mk_api
->config
->hosts
;
209 printf("* VHost '%s'\n", host
->servername
);
210 printf(" - Configuration Path : %s\n",
212 printf(" - Document Root : %s\n",
213 host
->documentroot
.data
);
214 printf(" - Access Log : %s\n",
215 host
->access_log_path
);
216 printf(" - Error Log : %s\n",
217 host
->error_log_path
);
218 printf(" - List Directory Content : %s",
219 (host
->getdir
== VAR_ON
) ? "Yes" : "No");
224 void mk_cheetah_cmd_workers()
226 struct sched_list_node
*sl
;
227 sl
= *mk_api
->sched_list
;
230 printf("* Worker %i\n", sl
->idx
);
231 printf(" - Task ID : %i\n", sl
->pid
);
234 printf(" - Memory usage : ");
235 mk_cheetah_print_worker_memory_usage(sl
->pid
);
237 printf(" - Active Requests : %i\n",
238 sl
->active_requests
);
239 printf(" - Closed Requests : %i\n",
240 sl
->closed_requests
);
245 void mk_cheetah_cmd_quit()
247 printf("Cheeta says: Good Bye!\n");
252 void mk_cheetah_cmd_help()
254 printf("\nList of available commands for Cheetah Shell\n");
255 printf("\ncommand shortcut description");
256 printf("\n----------------------------------------------------");
257 printf("\nhelp (\\h) Print this help");
258 printf("\nstatus (\\s) Display general web server information");
259 printf("\nuptime (\\u) Display how long the web server has been running");
260 printf("\nplugins (\\g) List loaded plugins and associated stages");
261 printf("\nvhosts (\\v) List virtual hosts configured");
262 printf("\nworkers (\\w) Show thread workers information");
263 printf("\nquit (\\q) Exit Cheetah shell :_(\n");
266 void mk_cheetah_cmd(char *cmd
)
269 struct sched_list_node
*sl
;
272 sl
= *mk_api
->sched_list
;
278 if(strcmp(cmd
, MK_CHEETAH_STATUS
) == 0 ||
279 strcmp(cmd
, MK_CHEETAH_STATUS_SC
) == 0){
280 printf("\nMonkey Version : %s\n", VERSION
);
281 printf("Configutarion path : %s\n", mk_api
->config
->serverconf
);
282 printf("Process ID : %i\n", getpid());
284 printf("Process User : ");
285 mk_cheetah_print_running_user();
287 printf("Server Port : %i\n", mk_api
->config
->serverport
);
288 printf("Worker Threads : %i (per configuration: %i)\n",
290 mk_api
->config
->workers
);
292 else if(strcmp(cmd
, MK_CHEETAH_UPTIME
) == 0 ||
293 strcmp(cmd
, MK_CHEETAH_UPTIME_SC
) == 0){
294 mk_cheetah_cmd_uptime();
296 else if(strcmp(cmd
, MK_CHEETAH_PLUGINS
) == 0 ||
297 strcmp(cmd
, MK_CHEETAH_PLUGINS_SC
) == 0){
298 mk_cheetah_cmd_plugins();
300 else if(strcmp(cmd
, MK_CHEETAH_WORKERS
) == 0 ||
301 strcmp(cmd
, MK_CHEETAH_WORKERS_SC
) == 0){
302 mk_cheetah_cmd_workers();
304 else if(strcmp(cmd
, MK_CHEETAH_VHOSTS
) == 0 ||
305 strcmp(cmd
, MK_CHEETAH_VHOSTS_SC
) == 0){
306 mk_cheetah_cmd_vhosts();
308 else if(strcmp(cmd
, MK_CHEETAH_HELP
) == 0 ||
309 strcmp(cmd
, MK_CHEETAH_HELP_SC
) == 0){
310 mk_cheetah_cmd_help();
312 else if(strcmp(cmd
, MK_CHEETAH_QUIT
) == 0 ||
313 strcmp(cmd
, MK_CHEETAH_QUIT_SC
) == 0){
314 mk_cheetah_cmd_quit();
316 else if(strlen(cmd
) == 0){
320 printf("Invalid command, type 'help' for a list of available commands\n");
327 void mk_cheetah_loop()
334 printf("\n*** Welcome to Cheetah!, the Monkey Shell :) ***\n");
335 printf("\nType 'help' for a list of available commands\n\n");
339 printf("%s", MK_CHEETAH_PROMPT
);
340 rcmd
= fgets(line
, sizeof(line
), stdin
);
343 strncpy(cmd
, line
, len
-1);
347 bzero(line
, sizeof(line
));
351 void *mk_cheetah_init(void *args
)
353 init_time
= time(NULL
);
358 /* This function is called when the plugin is loaded, it must
361 int _mk_plugin_init(void **api
)
367 int _mk_plugin_stage_10(struct server_config
*config
)
370 pthread_attr_t thread_attr
;
372 pthread_attr_init(&thread_attr
);
373 pthread_attr_setdetachstate(&thread_attr
, PTHREAD_CREATE_DETACHED
);
374 if(pthread_create(&tid
, &thread_attr
, (void *) mk_cheetah_init
, config
)<0)
376 perror("pthread_create");