Add MK_PLUGIN_STAGE_00 to plugin stages
[MonkeyD.git] / plugins / cheetah / cheetah.c
bloba6989ccaadc4d68fb6a728f09ffa5e5dd0295780
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
3 /* Monkey HTTP Daemon
4 * ------------------
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.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <pwd.h>
28 #include <time.h>
30 #include "monkey.h"
31 #include "config.h"
32 #include "scheduler.h"
33 #include "info.h"
34 #include "request.h"
35 #include "str.h"
36 #include "plugin.h"
37 #include "worker.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;
71 time_t init_time;
72 struct plugin_api *mk_api;
74 void mk_cheetah_print_worker_memory_usage(pid_t pid)
76 int last, init, n, c = 0;
77 int s = 1024;
78 char *buf;
79 char *value;
80 pid_t ppid;
81 FILE *f;
83 ppid = getpid();
84 buf = mk_api->mem_alloc(s);
85 sprintf(buf, MK_CHEETAH_PROC_TASK, ppid, pid);
87 f = fopen(buf, "r");
88 if(!f){
89 printf("Cannot get details\n");
90 return;
93 buf = fgets(buf, s, f);
94 if(!buf){
95 printf("Cannot format details\n");
96 return;
98 fclose(f);
100 last = 0;
101 init = 0;
103 printf("\n");
104 return;
106 while((n = mk_string_search(buf+last, " ")) > 0){
107 if(c == 23){
108 value = mk_string_copy_substr(buf, init, last+n);
109 printf("%s\n", value);
110 mk_mem_free(buf);
111 mk_mem_free(value);
112 return;
114 init = last+n+1;
115 last += n +1;
116 c++;
120 void mk_cheetah_print_running_user()
122 struct passwd pwd;
123 struct passwd *result;
124 char *buf;
125 size_t bufsize;
126 uid_t uid;
128 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
129 if (bufsize == -1){
130 bufsize = 16384;
133 buf = malloc(bufsize);
134 uid = getuid();
135 getpwuid_r(uid, &pwd, buf, bufsize, &result);
137 printf("%s\n", pwd.pw_name);
138 free(buf);
141 void mk_cheetah_cmd_uptime()
143 int days; int hours; int minutes; int seconds;
144 long int upmind;
145 long int upminh;
146 long int uptime;
148 /* uptime in seconds */
149 uptime = time(NULL) - init_time;
151 /* days */
152 days = uptime / MK_CHEETAH_ONEDAY;
153 upmind = uptime - (days * MK_CHEETAH_ONEDAY);
155 /* hours */
156 hours = upmind / MK_CHEETAH_ONEHOUR;
157 upminh = upmind - hours * MK_CHEETAH_ONEHOUR;
159 /* minutes */
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)
172 struct plugin *p;
174 if(!list){
175 return;
178 p = list;
179 printf("* %s", stage);
180 printf("\n Loaded plugins on this stage");
181 printf("\n ----------------------------");
182 while(p){
183 printf("\n %s v%s on \"%s\"", p->name, p->version, p->path);
184 p = p->next;
187 printf("\n\n");
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()
205 struct host *host;
207 host = mk_api->config->hosts;
209 while(host){
210 printf("* VHost '%s'\n", host->servername);
211 printf(" - Configuration Path : %s\n",
212 host->file);
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");
221 host = host->next;
225 void mk_cheetah_cmd_workers()
227 struct sched_list_node *sl;
228 sl = *mk_api->sched_list;
230 while(sl){
231 printf("* Worker %i\n", sl->idx);
232 printf(" - Task ID : %i\n", sl->pid);
234 /* Memory Usage */
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);
242 sl = sl->next;
246 void mk_cheetah_cmd_quit()
248 printf("Cheeta says: Good Bye!\n");
249 fflush(stdout);
250 pthread_exit(NULL);
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)
269 int nthreads = 0;
270 struct sched_list_node *sl;
273 sl = *mk_api->sched_list;
274 while(sl){
275 nthreads++;
276 sl = sl->next;
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",
290 nthreads,
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){
318 return;
320 else{
321 printf("Invalid command, type 'help' for a list of available commands\n");
324 printf("\n");
325 fflush(stdout);
328 void mk_cheetah_loop()
330 int len;
331 char cmd[200];
332 char line[200];
333 char *rcmd;
335 printf("\n*** Welcome to Cheetah!, the Monkey Shell :) ***\n");
336 printf("\nType 'help' for a list of available commands\n\n");
337 fflush(stdout);
339 while(1){
340 printf("%s", MK_CHEETAH_PROMPT);
341 rcmd = fgets(line, sizeof(line), stdin);
343 len = strlen(line);
344 strncpy(cmd, line, len-1);
345 cmd[len-1] = '\0';
347 mk_cheetah_cmd(cmd);
348 bzero(line, sizeof(line));
352 void *mk_cheetah_init(void *args)
354 init_time = time(NULL);
355 mk_cheetah_loop();
356 return 0;
359 /* This function is called when the plugin is loaded, it must
360 * return
362 int _mk_plugin_init(void **api)
364 mk_api = *api;
365 return 0;
368 int _mk_plugin_stage_10(struct server_config *config)
370 pthread_t tid;
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");
378 exit(1);
381 return 0;