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_00
, "STAGE_00");
195 mk_cheetah_cmd_plugins_print(p
->stage_10
, "STAGE_10");
196 mk_cheetah_cmd_plugins_print(p
->stage_20
, "STAGE_20");
197 mk_cheetah_cmd_plugins_print(p
->stage_30
, "STAGE_30");
198 mk_cheetah_cmd_plugins_print(p
->stage_40
, "STAGE_40");
199 mk_cheetah_cmd_plugins_print(p
->stage_50
, "STAGE_50");
200 mk_cheetah_cmd_plugins_print(p
->stage_60
, "STAGE_60");
203 void mk_cheetah_cmd_vhosts()
207 host
= mk_api
->config
->hosts
;
210 printf("* VHost '%s'\n", host
->servername
);
211 printf(" - Configuration Path : %s\n",
213 printf(" - Document Root : %s\n",
214 host
->documentroot
.data
);
215 printf(" - Access Log : %s\n",
216 host
->access_log_path
);
217 printf(" - Error Log : %s\n",
218 host
->error_log_path
);
219 printf(" - List Directory Content : %s",
220 (host
->getdir
== VAR_ON
) ? "Yes" : "No");
225 void mk_cheetah_cmd_workers()
227 struct sched_list_node
*sl
;
228 sl
= *mk_api
->sched_list
;
231 printf("* Worker %i\n", sl
->idx
);
232 printf(" - Task ID : %i\n", sl
->pid
);
235 printf(" - Memory usage : ");
236 mk_cheetah_print_worker_memory_usage(sl
->pid
);
238 printf(" - Active Requests : %i\n",
239 sl
->active_requests
);
240 printf(" - Closed Requests : %i\n",
241 sl
->closed_requests
);
246 void mk_cheetah_cmd_quit()
248 printf("Cheeta says: Good Bye!\n");
253 void mk_cheetah_cmd_help()
255 printf("\nList of available commands for Cheetah Shell\n");
256 printf("\ncommand shortcut description");
257 printf("\n----------------------------------------------------");
258 printf("\nhelp (\\h) Print this help");
259 printf("\nstatus (\\s) Display general web server information");
260 printf("\nuptime (\\u) Display how long the web server has been running");
261 printf("\nplugins (\\g) List loaded plugins and associated stages");
262 printf("\nvhosts (\\v) List virtual hosts configured");
263 printf("\nworkers (\\w) Show thread workers information");
264 printf("\nquit (\\q) Exit Cheetah shell :_(\n");
267 void mk_cheetah_cmd(char *cmd
)
270 struct sched_list_node
*sl
;
273 sl
= *mk_api
->sched_list
;
279 if(strcmp(cmd
, MK_CHEETAH_STATUS
) == 0 ||
280 strcmp(cmd
, MK_CHEETAH_STATUS_SC
) == 0){
281 printf("\nMonkey Version : %s\n", VERSION
);
282 printf("Configutarion path : %s\n", mk_api
->config
->serverconf
);
283 printf("Process ID : %i\n", getpid());
285 printf("Process User : ");
286 mk_cheetah_print_running_user();
288 printf("Server Port : %i\n", mk_api
->config
->serverport
);
289 printf("Worker Threads : %i (per configuration: %i)\n",
291 mk_api
->config
->workers
);
293 else if(strcmp(cmd
, MK_CHEETAH_UPTIME
) == 0 ||
294 strcmp(cmd
, MK_CHEETAH_UPTIME_SC
) == 0){
295 mk_cheetah_cmd_uptime();
297 else if(strcmp(cmd
, MK_CHEETAH_PLUGINS
) == 0 ||
298 strcmp(cmd
, MK_CHEETAH_PLUGINS_SC
) == 0){
299 mk_cheetah_cmd_plugins();
301 else if(strcmp(cmd
, MK_CHEETAH_WORKERS
) == 0 ||
302 strcmp(cmd
, MK_CHEETAH_WORKERS_SC
) == 0){
303 mk_cheetah_cmd_workers();
305 else if(strcmp(cmd
, MK_CHEETAH_VHOSTS
) == 0 ||
306 strcmp(cmd
, MK_CHEETAH_VHOSTS_SC
) == 0){
307 mk_cheetah_cmd_vhosts();
309 else if(strcmp(cmd
, MK_CHEETAH_HELP
) == 0 ||
310 strcmp(cmd
, MK_CHEETAH_HELP_SC
) == 0){
311 mk_cheetah_cmd_help();
313 else if(strcmp(cmd
, MK_CHEETAH_QUIT
) == 0 ||
314 strcmp(cmd
, MK_CHEETAH_QUIT_SC
) == 0){
315 mk_cheetah_cmd_quit();
317 else if(strlen(cmd
) == 0){
321 printf("Invalid command, type 'help' for a list of available commands\n");
328 void mk_cheetah_loop()
335 printf("\n*** Welcome to Cheetah!, the Monkey Shell :) ***\n");
336 printf("\nType 'help' for a list of available commands\n\n");
340 printf("%s", MK_CHEETAH_PROMPT
);
341 rcmd
= fgets(line
, sizeof(line
), stdin
);
344 strncpy(cmd
, line
, len
-1);
348 bzero(line
, sizeof(line
));
352 void *mk_cheetah_init(void *args
)
354 init_time
= time(NULL
);
359 /* This function is called when the plugin is loaded, it must
362 int _mk_plugin_init(void **api
)
368 int _mk_plugin_stage_10(struct server_config
*config
)
371 pthread_attr_t thread_attr
;
373 pthread_attr_init(&thread_attr
);
374 pthread_attr_setdetachstate(&thread_attr
, PTHREAD_CREATE_DETACHED
);
375 if(pthread_create(&tid
, &thread_attr
, (void *) mk_cheetah_init
, config
)<0)
377 perror("pthread_create");