diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/Makefile | 4 | ||||
-rw-r--r-- | src/char_sql/Makefile | 4 | ||||
-rw-r--r-- | src/common/Makefile | 3 | ||||
-rw-r--r-- | src/common/core.c | 3 | ||||
-rw-r--r-- | src/common/graph.c | 318 | ||||
-rw-r--r-- | src/common/graph.h | 27 | ||||
-rw-r--r-- | src/login/Makefile | 4 | ||||
-rw-r--r-- | src/login_sql/Makefile | 4 | ||||
-rw-r--r-- | src/map/Makefile | 4 | ||||
-rw-r--r-- | src/plugins/Makefile | 10 | ||||
-rw-r--r-- | src/plugins/httpd.c | 751 | ||||
-rw-r--r-- | src/plugins/httpd.h | 107 | ||||
-rw-r--r-- | src/plugins/httpd.txt | 20 | ||||
-rw-r--r-- | src/webserver/Makefile | 20 | ||||
-rw-r--r-- | src/webserver/doc/API.txt | 50 | ||||
-rw-r--r-- | src/webserver/doc/README | 11 | ||||
-rw-r--r-- | src/webserver/generate.c | 38 | ||||
-rw-r--r-- | src/webserver/htmlstyle.c | 51 | ||||
-rw-r--r-- | src/webserver/logs.c | 8 | ||||
-rw-r--r-- | src/webserver/main.c | 142 | ||||
-rw-r--r-- | src/webserver/pages/about.c | 6 | ||||
-rw-r--r-- | src/webserver/pages/notdone.c | 5 | ||||
-rw-r--r-- | src/webserver/pages/sample.c | 24 | ||||
-rw-r--r-- | src/webserver/parse.c | 135 |
24 files changed, 12 insertions, 1737 deletions
diff --git a/src/char/Makefile b/src/char/Makefile index 6282926f6..2f6f77ffd 100644 --- a/src/char/Makefile +++ b/src/char/Makefile @@ -3,12 +3,12 @@ all txt: char-server COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \ ../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \ ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \ - ../common/obj/strlib.o ../common/obj/graph.o ../common/obj/grfio.o \ + ../common/obj/strlib.o ../common/obj/grfio.o \ ../common/obj/mapindex.o ../common/obj/ers.o ../zlib/unz.o COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \ ../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \ ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \ - ../common/graph.h ../common/grfio.h ../common/mapindex.h + ../common/grfio.h ../common/mapindex.h %.o: %.c $(COMPILE.c) -DTXT_ONLY $(OUTPUT_OPTION) $< diff --git a/src/char_sql/Makefile b/src/char_sql/Makefile index 651cec002..4d6772838 100644 --- a/src/char_sql/Makefile +++ b/src/char_sql/Makefile @@ -3,12 +3,12 @@ all sql: char-server_sql COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \ ../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \ ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \ - ../common/obj/strlib.o ../common/obj/graph.o ../common/obj/grfio.o \ + ../common/obj/strlib.o ../common/obj/grfio.o \ ../common/obj/mapindex.o ../common/obj/ers.o ../zlib/unz.o COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \ ../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \ ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \ - ../common/graph.h ../common/grfio.h ../common/mapindex.h + ../common/grfio.h ../common/mapindex.h char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o int_homun.o itemdb.o $(COMMON_OBJ) $(CC) -o ../../$@ $^ $(LIB_S) diff --git a/src/common/Makefile b/src/common/Makefile index 7c8f8065d..b310d7991 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -5,7 +5,7 @@ obj: common: obj/core.o obj/socket.o obj/timer.o obj/db.o obj/plugins.o obj/lock.o \ obj/nullpo.o obj/malloc.o obj/showmsg.o obj/strlib.o obj/utils.o \ - obj/graph.o obj/grfio.o obj/minicore.o obj/minisocket.o obj/minimalloc.o \ + obj/grfio.o obj/minicore.o obj/minisocket.o obj/minimalloc.o \ obj/mapindex.o obj/unz.o obj/ers.o obj/md5calc.o @@ -48,7 +48,6 @@ obj/ers.o: ers.c ers.h cbasetypes.h obj/db.o: db.c db.h showmsg.h ers.h obj/lock.o: lock.c lock.h showmsg.h obj/grfio.o: grfio.c grfio.h -obj/graph.o: graph.c graph.h obj/nullpo.o: nullpo.c nullpo.h showmsg.h obj/malloc.o: malloc.c malloc.h showmsg.h obj/plugins.o: plugins.c plugins.h plugin.h diff --git a/src/common/core.c b/src/common/core.c index b5db552e6..f0ab846d1 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -19,7 +19,6 @@ #include "../common/db.h" #include "../common/socket.h" #include "../common/timer.h" -#include "../common/graph.h" #include "../common/plugins.h" #endif @@ -258,7 +257,6 @@ int main (int argc, char **argv) plugins_init(); do_init(argc,argv); - graph_init(); plugin_event_trigger(EVENT_ATHENA_INIT); {// Main runtime cycle @@ -273,7 +271,6 @@ int main (int argc, char **argv) } plugin_event_trigger(EVENT_ATHENA_FINAL); - graph_final(); do_final(); timer_final(); diff --git a/src/common/graph.c b/src/common/graph.c deleted file mode 100644 index a13379a6b..000000000 --- a/src/common/graph.c +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder - -// graph creation is enabled -// #define ENABLE_GRAPH - -#ifdef ENABLE_GRAPH - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifndef _WIN32 - #include <unistd.h> -#endif -#ifdef MINGW - #include <io.h> -#endif - -#include "../common/core.h" -#include "../common/timer.h" -#include "../common/grfio.h" -#include "../common/malloc.h" -#include "graph.h" - -struct graph { - int width; - int height; - int pallet_count; - int png_len; - int png_dirty; - unsigned char* raw_data; - unsigned char* png_data; - int * graph_value; - int graph_max; -}; - -void graph_write_dword(unsigned char* p,unsigned int v) { - p[0] = (unsigned char)((v >> 24) & 0xFF); - p[1] = (unsigned char)((v >> 16) & 0xFF); - p[2] = (unsigned char)((v >> 8) & 0xFF); - p[3] = (unsigned char)(v & 0xFF); -} - -struct graph* graph_create(unsigned int x,unsigned int y) { - struct graph *g = (struct graph*)aCalloc(sizeof(struct graph),1); - if(g == NULL) return NULL; - // 256 * 3 : パレットデータ - // x * y * 2 : イメージのバッファ - // 256 : チャンクデータなどの予備 - g->png_data = (unsigned char *) aMalloc(4 * 256 + (x + 1) * y * 2); - g->raw_data = (unsigned char *) aCalloc( (x + 1) * y , 1); - memcpy( - g->png_data, - "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x08\x03\x00\x00\x00\xFF\xFF\xFF" - "\xFF\x00\x00\x00\x03\x50\x4C\x54\x45\xFF\xFF\xFF\xA7\xC4\x1B\xC8",0x30 - ); - graph_write_dword(g->png_data + 0x10,x); - graph_write_dword(g->png_data + 0x14,y); - graph_write_dword(g->png_data + 0x1D,grfio_crc32(g->png_data+0x0C,0x11)); - g->pallet_count = 1; - g->width = x; - g->height = y; - g->png_dirty = 1; - g->graph_value = (int *) aCalloc(x,sizeof(int)); - g->graph_max = 1; - return g; -} - -void graph_pallet(struct graph* g, int index,unsigned long c) { - if(g == NULL || c >= 256) return; - - if(g->pallet_count <= index) { - memset(g->png_data + 0x29 + 3 * g->pallet_count,0,(index - g->pallet_count) * 3); - g->pallet_count = index + 1; - } - g->png_data[0x29 + index * 3 ] = (unsigned char)((c >> 16) & 0xFF); // R - g->png_data[0x29 + index * 3 + 1] = (unsigned char)((c >> 8) & 0xFF); // G - g->png_data[0x29 + index * 3 + 2] = (unsigned char)( c & 0xFF); // B - graph_write_dword(g->png_data + 0x21,g->pallet_count * 3); - graph_write_dword( - g->png_data + 0x29 + g->pallet_count * 3, - grfio_crc32(g->png_data + 0x25,g->pallet_count * 3 + 4) - ); - g->png_dirty = 1; -} - -void graph_setpixel(struct graph* g,int x,int y,int color) { - if(g == NULL || color >= 256) { return; } - if(x < 0) x = 0; - if(y < 0) y = 0; - if(x >= g->width) { x = g->width - 1; } - if(y >= g->height) { y = g->height - 1; } - if(color >= g->pallet_count) { graph_pallet(g,color,graph_rgb(0,0,0)); } - - g->raw_data[y * (g->width + 1) + x + 1] = (unsigned char)color; - g->png_dirty = 1; -} - -int graph_getpixel(struct graph* g,int x,int y) { - if(x < 0) x = 0; - if(y < 0) y = 0; - if(x >= g->width) { x = g->width - 1; } - if(y >= g->height) { y = g->height - 1; } - return g->raw_data[y * (g->width + 1) + x + 1]; -} - -const unsigned char* graph_output(struct graph* g,int *len) { - unsigned long inflate_len; - unsigned char *p; - - if(g == NULL) return NULL; - if(g->png_dirty == 0) { - *len = g->png_len; - return g->png_data; - } - - p = g->png_data + 0x2D + 3 * g->pallet_count; - inflate_len = 2 * (g->width + 1) * g->height; - memcpy(p + 4,"IDAT",4); - encode_zip(p + 8,&inflate_len,g->raw_data,(g->width + 1) * g->height); - graph_write_dword(p,inflate_len); - graph_write_dword(p + 8 + inflate_len,grfio_crc32(p + 4, inflate_len + 4)); - - p += 0x0C + inflate_len; - memcpy(p,"\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82",0x0C); - p += 0x0C; - g->png_len = p - g->png_data; - g->png_dirty = 0; - *len = g->png_len; - return g->png_data; -} - -void graph_free(struct graph* g) { - if(g != NULL) { - aFree(g->png_data); - aFree(g->raw_data); - aFree(g->graph_value); - aFree(g); - } -} - -// とりあえず不効率版。後ほど書き直し予定 -void graph_square(struct graph* g,int x,int y,int xe,int ye,int color) { - int i,j; - if(g == NULL) return; - if(x < 0) { x = 0; } - if(y < 0) { y = 0; } - if(xe > g->width) { xe = g->width; } - if(ye > g->height) { ye = g->height; } - for(i = y;i < ye ; i++) { - for(j = x; j < xe ; j++) { - graph_setpixel(g,j,i,color); - } - } -} - -// とりあえず不効率版。後ほど書き直し予定 -void graph_scroll(struct graph* g,int n,int color) { - int x,y; - if(g == NULL) return; - for(y = 0; y < g->height; y++) { - for(x = 0; x < g->width - n; x++) { - graph_setpixel(g,x,y,graph_getpixel(g,x + n,y)); - } - for( ; x < g->width; x++) { - graph_setpixel(g,x,y,color); - } - } -} - -void graph_data(struct graph* g,int value) { - int i, j, start; - if(g == NULL) return; - memmove(&g->graph_value[0],&g->graph_value[1],sizeof(int) * (g->width - 1)); - g->graph_value[g->width - 1] = value; - if(value > g->graph_max) { - // 最大値を超えたので再描画 - g->graph_max = value; - graph_square(g,0,0,g->width,g->height,0); - start = 0; - } else { - // スクロールしてポイント打つ - graph_scroll(g,1,0); - start = g->width - 1; - } - for(i = start; i < g->width; i++) { - int h0 = (i == 0 ? 0 : g->graph_value[i - 1]) * g->height / g->graph_max; - int h1 = (g->graph_value[i] ) * g->height / g->graph_max; - int h2 = (h0 < h1 ? 1 : -1); - for(j = h0; j != h1; j += h2) { - graph_setpixel(g,i,g->height - 1 - j,1); - } - graph_setpixel(g,i,g->height - 1 - h1,1); - } -} - -// 上の関数群を利用して、自動的にグラフを作成するタイマー群 - -#define GRP_WIDTH 300 // グラフの幅 -#define GRP_HEIGHT 200 // グラフの高さ -#define GRP_COLOR graph_rgb(0,0,255) // グラフの色 -#define GRP_INTERVEL 60*1000 // グラフの更新間隔 - -#define GRP_PATH "httpd/" - -struct graph_sensor { - struct graph* graph; - char* str; - char hash[32]; - int scanid; - int drawid; - int interval; - unsigned int (*func)(void); -}; - -static struct graph_sensor *sensor; -static int sensor_max; - -static int graph_scan_timer(int tid,unsigned int tick,int id,int data) -{ - if(id >= 0 && id < sensor_max) - graph_data(sensor[id].graph,sensor[id].func()); - return 0; -} - -// modified by Celest -- i'm trying to separate it from httpd if possible ^^; -static int graph_draw_timer(int tid,unsigned int tick,int id,int data) -{ - char png_file[24]; - FILE *fp; - - // create/update the png file - do { - const char *png_data; - int len; - sprintf (png_file, GRP_PATH"%s.png", sensor[id].hash); - fp = fopen(png_file, "w"); - // if another png of the same hash exists - // (i.e 2nd login server with the same sensors) - // this will fail = not good >.< - if (fp == NULL) - break; - png_data = graph_output(sensor[id].graph, &len); - fwrite(png_data,1,len,fp); - fclose(fp); - } while (0); - - // create/update text snippet - do { - char buf[8192], *p; - p = buf; - sprintf (png_file, GRP_PATH"%s.graph", sensor[id].hash); - fp = fopen(png_file, "w"); - if (fp == NULL) - break; - p += sprintf(p,"<h2>%s</h2>\n\n", - sensor[id].str); - p += sprintf(p,"<p><img src=\"%s.png\" width=\"%d\" height=\"%d\"></p>\n", - sensor[id].hash, GRP_WIDTH,GRP_HEIGHT); - p += sprintf(p,"<p>Max: %d, Interval: %d sec</p>\n\n", - sensor[id].graph->graph_max, sensor[id].interval / 1000); - fprintf(fp, buf); - fclose(fp); - } while (0); - - return 0; -} - -void graph_add_sensor(const unsigned char* string, int interval, unsigned int (*callback_func)(void)) -{ - int draw_interval = interval * 2; - struct graph *g = graph_create(GRP_WIDTH,GRP_HEIGHT); - graph_pallet(g,1,GRP_COLOR); - - sensor = (struct graph_sensor *) aRealloc(sensor, sizeof(struct graph_sensor) * (sensor_max + 1)); - sensor[sensor_max].graph = g; - sensor[sensor_max].str = aStrdup(string); - // create crc32 hash of the sensor's name - sprintf (sensor[sensor_max].hash, "%lu%c", grfio_crc32(string,strlen(string)), 'a' + SERVER_TYPE); - sensor[sensor_max].func = callback_func; - sensor[sensor_max].scanid = add_timer_interval(gettick() + 500, graph_scan_timer, sensor_max, 0, interval); - sensor[sensor_max].drawid = add_timer_interval(gettick() + 1000, graph_draw_timer, sensor_max, 0, draw_interval < 60000 ? 60000 : draw_interval); - sensor[sensor_max].interval = interval; - sensor_max++; - -} - -void graph_final (void) -{ - int i; - for(i = 0; i < sensor_max; i++) { - char png_file[24]; - // remove the png and snippet file - sprintf (png_file, GRP_PATH"%s.png", sensor[i].hash); - unlink (png_file); - sprintf (png_file, GRP_PATH"%s.graph", sensor[i].hash); - unlink (png_file); - graph_free(sensor[i].graph); - aFree(sensor[i].str); - //delete_timer(sensor[i].scanid,graph_scan_timer); - //delete_timer(sensor[i].drawid,graph_draw_timer); - } - aFree(sensor); - sensor_max = 0; -} - -void graph_init (void) -{ - graph_add_sensor ("Memory Usage", 1000, malloc_usage); - add_timer_func_list(graph_scan_timer, "graph_scan_timer"); - add_timer_func_list(graph_draw_timer, "graph_draw_timer"); -} - -#else -void graph_init (void) {} -void graph_final (void) {} -#endif diff --git a/src/common/graph.h b/src/common/graph.h deleted file mode 100644 index 9c8b73580..000000000 --- a/src/common/graph.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder - -#ifndef _GRAPH_H_ -#define _GRAPH_H_ - -void graph_init (void); -void graph_final (void); - -struct graph* graph_create(unsigned int x,unsigned int y); -void graph_pallet(struct graph* g, int index,unsigned long c); -const unsigned char* graph_output(struct graph* g,int *len); -void graph_setpixel(struct graph* g,int x,int y,int color); -void graph_scroll(struct graph* g,int n,int color); -void graph_square(struct graph* g,int x,int y,int xe,int ye,int color); - -// athenaの状態を調査するセンサーを追加する。 -// string : センサーの名称(Login Users など) -// inetrval : センサーの値を所得する間隔(msec) -// callback_func : センサーの値を返す関数( unsigned int login_users(void); など) - -void graph_add_sensor(const char* string, int interval, unsigned int (*callback_func)(void)); - -#define graph_rgb(r,g,b) (((r) << 16) | ((g) << 8) | (b)) - -#endif - diff --git a/src/login/Makefile b/src/login/Makefile index 5471999d2..b98226e27 100644 --- a/src/login/Makefile +++ b/src/login/Makefile @@ -3,13 +3,13 @@ all txt: login-server COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \ ../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \ ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \ - ../common/obj/strlib.o ../common/obj/graph.o ../common/obj/grfio.o \ + ../common/obj/strlib.o ../common/obj/grfio.o \ ../common/obj/mapindex.o ../common/obj/ers.o ../common/obj/md5calc.o \ ../zlib/unz.o COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \ ../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \ ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \ - ../common/graph.h ../common/grfio.h ../common/mapindex.h \ + ../common/grfio.h ../common/mapindex.h \ ../common/md5calc.h %.o: %.c diff --git a/src/login_sql/Makefile b/src/login_sql/Makefile index c8f5f3358..4c9bb9b58 100644 --- a/src/login_sql/Makefile +++ b/src/login_sql/Makefile @@ -3,13 +3,13 @@ all sql: login-server_sql COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \ ../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \ ../common/obj/malloc.o ../common/obj/showmsg.o ../common/obj/utils.o \ - ../common/obj/strlib.o ../common/obj/graph.o ../common/obj/grfio.o \ + ../common/obj/strlib.o ../common/obj/grfio.o \ ../common/obj/mapindex.o ../common/obj/ers.o ../common/obj/md5calc.o \ ../zlib/unz.o COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h \ ../common/version.h ../common/db.h ../common/plugins.h ../common/lock.h \ ../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \ - ../common/graph.h ../common/grfio.h ../common/mapindex.h \ + ../common/grfio.h ../common/mapindex.h \ ../common/md5calc.h login-server_sql: login.o $(COMMON_OBJ) diff --git a/src/map/Makefile b/src/map/Makefile index 2345c7dd3..5f9f122e8 100644 --- a/src/map/Makefile +++ b/src/map/Makefile @@ -12,13 +12,13 @@ COMMON_OBJ = ../common/obj/core.o ../common/obj/socket.o ../common/obj/timer.o \ ../common/obj/db.o ../common/obj/plugins.o ../common/obj/lock.o \ ../common/obj/nullpo.o ../common/obj/malloc.o ../common/obj/showmsg.o \ ../common/obj/utils.o ../common/obj/strlib.o ../common/obj/grfio.o \ - ../common/obj/graph.o ../common/obj/mapindex.o ../common/obj/ers.o \ + ../common/obj/mapindex.o ../common/obj/ers.o \ ../zlib/unz.o COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/db.h \ ../common/plugins.h ../common/lock.h ../common/nullpo.h ../common/malloc.h \ ../common/showmsg.h ../common/utils.h ../common/strlib.h ../common/grfio.h \ - ../common/graph.h ../common/mapindex.h + ../common/mapindex.h OBJECTS = obj/map.o obj/chrif.o obj/clif.o obj/pc.o obj/status.o obj/npc.o \ obj/npc_chat.o obj/chat.o obj/path.o obj/itemdb.o obj/mob.o obj/script.o \ diff --git a/src/plugins/Makefile b/src/plugins/Makefile index 989ae0939..f576995f6 100644 --- a/src/plugins/Makefile +++ b/src/plugins/Makefile @@ -1,5 +1,5 @@ -OBJECTS = sample.dll sig.dll pid.dll gui.dll upnp.dll httpd.dll console.dll +OBJECTS = sample.dll sig.dll pid.dll gui.dll upnp.dll console.dll ifdef CYGWIN PLUGINEXT = dll @@ -16,12 +16,6 @@ txt sql all: $(PLUGINS) $(CC) $(CFLAGS) -shared -o ../../plugins/$@ $< @touch $@ -httpd.$(PLUGINEXT): httpd.c - $(CC) $(CFLAGS) -shared -o ../../plugins/$@ $< \ - ../common/obj/minimalloc.o ../common/obj/db.o ../common/obj/showmsg.o \ - ../common/obj/utils.o ../common/obj/ers.o - @touch $@ - sig.$(PLUGINEXT): sig.c $(CC) $(CFLAGS) -shared -o ../../plugins/$@ $< \ ../common/obj/showmsg.o ../common/obj/utils.o \ @@ -29,14 +23,12 @@ sig.$(PLUGINEXT): sig.c @touch $@ gui.$(PLUGINEXT): ../../plugins/gui.conf -httpd.$(PLUGINEXT): ../../plugins/httpd.conf upnp.$(PLUGINEXT): ../../plugins/upnp.conf ../../plugins/%.conf: %.txt cp -r $< $@ ../../plugins/gui.conf: gui.txt -../../plugins/httpd.conf: httpd.txt ../../plugins/upnp.conf: upnp.txt depend: diff --git a/src/plugins/httpd.c b/src/plugins/httpd.c deleted file mode 100644 index 5e88c7dfd..000000000 --- a/src/plugins/httpd.c +++ /dev/null @@ -1,751 +0,0 @@ - -#ifdef __WIN32 -#include <windows.h> -#else -#include <unistd.h> -#endif -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../common/db.h" -//mmo required for definition of stricmp -#include "../common/mmo.h" -#include "../common/utils.h" -#include "../common/malloc.h" -#include "../common/socket.h" -#include "../common/plugin.h" -//#include "httpd.h" - -/** Created by End_of_Exam, ported to plugin and modified by Celest **/ - -PLUGIN_INFO = { - "HttpDaemon", - PLUGIN_CORE, - "0.1", - PLUGIN_VERSION, - "HTTP Daemon" -}; - -PLUGIN_EVENTS_TABLE = { - { "do_init", "Plugin_Init" }, - { "do_final", "Plugin_Final" }, - { NULL, NULL } -}; - -enum HTTPD_STATUS { - HTTPD_REQUEST_WAIT = 0, // リクエスト待ち - HTTPD_REQUEST_WAIT_POST, // リクエスト待ち(post) - HTTPD_REQUEST_OK, // リクエスト解釈完了 - HTTPD_SEND_HEADER, // ヘッダ送信完了 - HTTPD_WAITING_SEND // データが送信し終わるまで待っている状態 -}; -enum { - HTTPD_METHOD_UNKNOWN = 0, - HTTPD_METHOD_GET, - HTTPD_METHOD_POST -}; - -struct httpd_session_data { - int fd; - int status; - int http_ver; - int header_len; - int data_len; - int method; - int persist; - int request_count; - unsigned int tick; - const unsigned char* url; - const unsigned char* query; -}; - -// undefine socket operations included from socket.h, -// since we are going to use 'sessiond' instead -#undef RFIFOP -#undef RFIFOREST -#undef WFIFOP - -#define RFIFOP(fd,pos) (sessiond[fd]->rdata+sessiond[fd]->rdata_pos+(pos)) -#define RFIFOREST(fd) (sessiond[fd]->rdata_size-sessiond[fd]->rdata_pos) -#define WFIFOP(fd,pos) (sessiond[fd]->wdata+sessiond[fd]->wdata_size+(pos)) - -struct socket_data **sessiond; -char *server_type; -unsigned int (*gettick)(); -int (*add_timer_interval)(unsigned int,int (*)(int,unsigned int,int,int),int,int,int); -int *max_fd; -int (*delete_sessiond)(int); -int (*_WFIFOSET)(int,int); -int (*_RFIFOSKIP)(int,int); - -static int max_persist_requests = 32; // 持続通信での最大リクエスト数 -static int request_timeout[] = { 2500, 60*1000 }; // タイムアウト(最初、持続) -static char document_root[256] = "./httpd/"; // ドキュメントルート - -// httpd に入っているページと、呼び出すコールバック関数の一覧 -struct dbt *httpd_files; - -void httpd_send(struct httpd_session_data*, int, const char *, int, const void *); - -int httpd_check (struct socket_data *sd) -{ - // httpd に回すどうかの判定がまだ行われてない - // 先頭2バイトが GE ならhttpd に回してみる - if (sd->rdata_size >= 2 && - sd->rdata[0] == 'G' && sd->rdata[1] == 'E') - return 1; - - return 0; -} - -int httpd_strcasencmp(const char *s1, const char *s2,int len) -{ - while(len-- && (*s1 || *s2) ) { - if((*s1 | 0x20) != (*s2 | 0x20)) { - return ((*s1 | 0x20) > (*s2 | 0x20) ? 1 : -1); - } - s1++; s2++; - } - return 0; -} - -// httpd にページを追加する -// for などでページ名を合成できるように、key はstrdup()したものを使う - -void httpd_pages (const char* url, void (*httpd_func)(struct httpd_session_data*, const char*)) -{ - if (strdb_get(httpd_files,(unsigned char*)(url+1)) == NULL) { - strdb_put(httpd_files, (unsigned char*)aStrdup(url+1), httpd_func); - } else { - strdb_put(httpd_files, (unsigned char*)(url+1), httpd_func); - } -} - -static void (*httpd_default)(struct httpd_session_data* sd,const char* url); - -const char *httpd_get_error( struct httpd_session_data* sd, int* status ) -{ - const char* msg; - // httpd のステータスを決める - switch(*status) { - case 200: msg = "OK"; break; - case 400: msg = "Bad Request"; break; - case 401: msg = "Unauthorized"; break; // 未使用 - case 403: msg = "Forbidden"; break; // 未使用 - case 404: msg = "Not Found"; break; - case 408: msg = "Request Timedout"; break; - case 411: msg = "Length Required"; break; - case 413: msg = "Request Entity Too Large"; break; - default: - *status = 500; msg = "Internal Server Error"; break; - } - return msg; -} - -void httpd_send_error(struct httpd_session_data* sd,int status) -{ - const char* msg = httpd_get_error( sd, &status ); - httpd_send(sd, status, "text/plain",strlen(msg),msg); -} - -void httpd_send_head (struct httpd_session_data* sd, int status, const char *content_type, int content_len) -{ - char head[256]; - int len; - const char* msg; - - if (sd->status != HTTPD_REQUEST_OK) - return; - msg = httpd_get_error( sd, &status ); - - if(content_len == -1 || ++sd->request_count >= max_persist_requests ) { - // 長さが分からない or リクエスト限界を超えたので切断する - len = sprintf( - head, - "HTTP/1.%d %d %s\r\nContent-Type: %s\r\nConnection: close\r\n\r\n", - sd->http_ver,status,msg,content_type - ); - sd->persist = 0; - len = sprintf( - head, - "HTTP/1.%d %d %s\r\nContent-Type: %s\r\n\r\n", - sd->http_ver,status,msg,content_type - ); - sd->http_ver = 0; // 長さが分からないので、HTTP/1.0 扱い(自動切断)にする - } else { - len = sprintf( - head, - "HTTP/1.%d %d %s\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n", - sd->http_ver,status,msg,content_type,content_len - ); - } - memcpy(WFIFOP(sd->fd,0),head,len); - _WFIFOSET(sd->fd,len); - sd->status = HTTPD_SEND_HEADER; - sd->data_len = content_len; -} - -void httpd_send_data (struct httpd_session_data* sd, int content_len, const void *data) -{ - const char* msg = (const char*)data; - if (sd->status == HTTPD_REQUEST_OK) { - // ヘッダの送信忘れているので、適当に補う - httpd_send_head(sd,200,"application/octet-stream",-1); - } else if(sd->status != HTTPD_SEND_HEADER && sd->status != HTTPD_WAITING_SEND) { - return; - } - sd->data_len -= content_len; - - // 巨大なサイズのファイルも送信出来るように分割して送る - while (content_len > 0) { - int send_byte = content_len; - if(send_byte > 12*1024) send_byte = 12*1024; - memcpy(WFIFOP(sd->fd,0),msg,send_byte); - _WFIFOSET(sd->fd,send_byte); - msg += send_byte; content_len -= send_byte; - } - sd->status = HTTPD_WAITING_SEND; -} - -void httpd_send (struct httpd_session_data* sd, int status, const char *content_type, int content_len, const void *data) -{ - httpd_send_head(sd,status,content_type,content_len); - httpd_send_data(sd,content_len,data); -} - -void httpd_parse_header(struct httpd_session_data* sd); -void httpd_parse_request_ok(struct httpd_session_data *sd); - -int httpd_parse (int fd) -{ - struct httpd_session_data *sd = (struct httpd_session_data *)sessiond[fd]->session_data2; - if (sessiond[fd]->eof) { - delete_sessiond(fd); - return 0; - } - if (sd == NULL) { - sd = (struct httpd_session_data*) aMalloc (sizeof(struct httpd_session_data)); - sd->fd = fd; - sessiond[fd]->session_data2 = sd; - sd->tick = gettick(); - sd->persist = 0; - sd->request_count = 0; - } - printf ("status %d\n", sd->status); - switch(sd->status) { - case HTTPD_REQUEST_WAIT: - // リクエスト待ち - if(RFIFOREST(fd) > 1024) { - // リクエストが長すぎるので、エラー扱いする - sd->status = HTTPD_REQUEST_OK; - httpd_send_error(sd,400); // Bad Request - } else if( (int)( gettick() - sd->tick ) > request_timeout[sd->persist] ) { - // リクエストに時間がかかりすぎているので、エラー扱いする - sd->status = HTTPD_REQUEST_OK; - httpd_send_error(sd,408); // Request Timeout - } else if(sd->header_len == RFIFOREST(fd)) { - // 状態が以前と同じなので、リクエストを再解析する必要は無い - } else { - int limit = RFIFOREST(fd); - unsigned char *req = RFIFOP(fd,0); - sd->header_len = RFIFOREST(fd); - do { - if(*req == '\n' && limit > 0) { - limit--; req++; - if(*req == '\r' && limit > 0) { limit--; req++; } - if(*req == '\n') { - // HTTPヘッダの終点を見つけた - *req = 0; - sd->header_len = (req - RFIFOP(fd,0)) + 1; - httpd_parse_header(sd); - break; - } - } - } while(req++,--limit > 0); - } - break; - case HTTPD_REQUEST_WAIT_POST: - if(RFIFOREST(sd->fd) >= sd->header_len) { - unsigned char temp = RFIFOB(sd->fd,sd->header_len); - RFIFOB(sd->fd,sd->header_len) = 0; - httpd_parse_request_ok(sd); - RFIFOB(sd->fd,sd->header_len) = temp; - } - break; - case HTTPD_REQUEST_OK: - case HTTPD_SEND_HEADER: - // リクエストが終わったまま何も送信されていない状態なので、 - // 強制切断 - printf ("httpd: eof\n"); - sessiond[fd]->eof = 1; - break; - case HTTPD_WAITING_SEND: - // データの送信が終わるまで待機 - //if(sessiond[fd]->wdata_size == sessiond[fd]->wdata_pos) { - // i *hope* this is correct o.o; - if(sessiond[fd]->wdata_size == 0) { - // HTTP/1.0は手動切断 -// if(sd->http_ver == 0) { - if(sd->persist == 0) { - printf ("httpd: eof\n"); - sessiond[fd]->eof = 1; - } - // RFIFO からリクエストデータの消去と構造体の初期化 - _RFIFOSKIP(fd,sd->header_len); - sd->status = HTTPD_REQUEST_WAIT; - sd->tick = gettick(); - sd->header_len = 0; - sd->query = NULL; -// sd->http_ver = 0; // ver は保持 - sd->method = HTTPD_METHOD_UNKNOWN; - printf("httpd_parse: [% 3d] request sended RFIFOREST:%d\n", fd, RFIFOREST(fd)); - } - break; - } - return 0; -} - -void httpd_parse_header_sub( struct httpd_session_data* sd, const char *p1, int* plen ) -{ - int len = 0; - // HTTPのバージョンを調査 - if(!strncmp(p1 ,"HTTP/1.1",8)) { - sd->http_ver = 1; - sd->persist = 1; - } else { - sd->http_ver = 0; - sd->persist = 0; - } - - p1 = strchr(p1,'\n'); - while(p1) { - // Content-Length: の調査 - if(!httpd_strcasencmp(p1+1,"Content-Length: ",16)) { - len = atoi(p1 + 17); - } - // Connection: の調査 - if(!httpd_strcasencmp(p1+1,"Connection: ",12)) { - if( httpd_strcasencmp(p1+13,"close",5)==0 && sd->http_ver==1 ) - sd->persist = 0; - if( httpd_strcasencmp(p1+13,"Keep-Alive",10)==0 && sd->http_ver==0 ) - sd->persist = 1; - } - p1 = strchr(p1+1,'\n'); - } - if(plen) *plen = len; - return; -} - -void httpd_parse_header(struct httpd_session_data* sd) -{ - int i; - int status = 400; // Bad Request - unsigned char* req = RFIFOP(sd->fd,0); - do { - if(!strncmp(req,"GET /",5)) { - // GET リクエスト - req += 5; - for(i = 0;req[i]; i++) { - if(req[i] == ' ' || req[i] == '?') break; - if(!isalnum(req[i]) && req[i] != '.' && req[i] != '_' && req[i] != '-') break; - } - if(req[i] == ' ') { - req[i] = 0; - sd->url = req; - sd->query = NULL; - sd->status = HTTPD_REQUEST_OK; - } else if(req[i] == '?') { - req[i] = 0; - sd->query = &req[++i]; - for(;req[i];i++) { - if( - isalnum(req[i]) || req[i] == '+' || req[i] == '%' || req[i] == '&' || - req[i] == '=' - ) { - continue; - } else { - break; - } - } - if(req[i] != ' ') { - break; - } - req[i] = 0; - sd->url = req; - } else { - break; - } - // ヘッダ解析 - httpd_parse_header_sub( sd, &req[i+1], NULL ); - - printf("httpd: request %s %s\n", sd->url, sd->query); - sd->method = HTTPD_METHOD_GET; - httpd_parse_request_ok(sd); - } else if(!strncmp(req,"POST /",6)) { - int len; - req += 6; status = 404; - for(i = 0;req[i]; i++) { - if(req[i] == ' ') break; - if(!isalnum(req[i]) && req[i] != '.' && req[i] != '_' && req[i] != '-') break; - } - if(req[i] != ' ') { - break; - } - req[i] = 0; - sd->url = req; - - // ヘッダ解析 - httpd_parse_header_sub( sd, &req[i+1], &len ); - - if(len <= 0 || len >= 32*1024) { - // とりあえず32KB以上のリクエストは不正扱い - status = ( len==0 )? 411 : ( len>32*1024 )? 413 : 400; - break; - } - - sd->query = RFIFOP(sd->fd,sd->header_len); - sd->method = HTTPD_METHOD_POST; - sd->header_len += len; - if(RFIFOREST(sd->fd) >= sd->header_len) { - unsigned char temp = RFIFOB(sd->fd,sd->header_len); - RFIFOB(sd->fd,sd->header_len) = 0; - httpd_parse_request_ok(sd); - RFIFOB(sd->fd,sd->header_len) = temp; - } else { - // POSTのデータが送られてくるのを待つ - sd->status = HTTPD_REQUEST_WAIT_POST; - } - } else { - break; - } - } while(0); - if(sd->status == HTTPD_REQUEST_WAIT) { - sd->status = HTTPD_REQUEST_OK; - httpd_send_error(sd,status); - } -} - -void httpd_parse_request_ok (struct httpd_session_data *sd) -{ - void (*httpd_parse_func)(struct httpd_session_data*,const char*); - sd->status = HTTPD_REQUEST_OK; - - // ファイル名が求まったので、ページが無いか検索する - // printf("httpd_parse: [% 3d] request /%s\n", fd, req); - httpd_parse_func = strdb_get(httpd_files,(unsigned char*)sd->url); - if(httpd_parse_func == NULL) { - httpd_parse_func = httpd_default; - } - if(httpd_parse_func == NULL) { - httpd_send_error(sd,404); // Not Found - } else { - httpd_parse_func(sd,sd->url); - if(sd->status == HTTPD_REQUEST_OK) { - httpd_send_error(sd,404); // Not Found - } - } - if(sd->persist == 1 && sd->data_len) { - // 長さが変なデータ(こんなの送るなよ…) - printf("httpd_parse: send size mismatch when parsing /%s\n", sd->url); - sessiond[sd->fd]->eof = 1; - } - if(sd->status == HTTPD_REQUEST_OK) { - httpd_send_error(sd,404); - } -} - -char* httpd_get_value(struct httpd_session_data* sd,const char* val) -{ - int src_len = strlen(val); - const unsigned char* src_p = sd->query; - if(src_p == NULL) return aStrdup(""); - - do { - if(!memcmp(src_p,val,src_len) && src_p[src_len] == '=') { - break; - } - src_p = strchr(src_p + 1,'&'); - if(src_p) src_p++; - } while(src_p); - - if(src_p != NULL) { - // 目的の文字列を見つけた - const unsigned char* p2; - int dest_len; - char* dest_p; - src_p += src_len + 1; - p2 = strchr(src_p,'&'); - if(p2 == NULL) { - src_len = strlen(src_p); - } else { - src_len = (p2 - src_p); - } - dest_p = aMalloc(src_len + 1); - dest_len = 0; - while(src_len > 0) { - if(*src_p == '%' && src_len > 2) { - int c1 = 0,c2 = 0; - if(src_p[1] >= '0' && src_p[1] <= '9') c1 = src_p[1] - '0'; - if(src_p[1] >= 'A' && src_p[1] <= 'F') c1 = src_p[1] - 'A' + 10; - if(src_p[1] >= 'a' && src_p[1] <= 'f') c1 = src_p[1] - 'a' + 10; - if(src_p[2] >= '0' && src_p[2] <= '9') c2 = src_p[2] - '0'; - if(src_p[2] >= 'A' && src_p[2] <= 'F') c2 = src_p[2] - 'A' + 10; - if(src_p[2] >= 'a' && src_p[2] <= 'f') c2 = src_p[2] - 'a' + 10; - dest_p[dest_len++] = (c1 << 4) | c2; - src_p += 3; src_len -= 3; - } else if(*src_p == '+') { - dest_p[dest_len++] = ' '; - src_p++; src_len--; - } else { - dest_p[dest_len++] = *(src_p++); src_len--; - } - } - dest_p[dest_len] = 0; - return dest_p; - } - return aStrdup(""); -} - -// MIMEタイプ判定。主要なものだけ判定して、残りはapplication/octet-stream -static const char* httpd_mimetype(const char* url) -{ - char *ext = strrchr(url,'.'); - if(ext) { - if(!strcmp(ext,".html")) return "text/html"; - if(!strcmp(ext,".htm")) return "text/html"; - if(!strcmp(ext,".css")) return "text/css"; - if(!strcmp(ext,".js")) return "text/javascript"; - if(!strcmp(ext,".txt")) return "text/plain"; - if(!strcmp(ext,".gif")) return "image/gif"; - if(!strcmp(ext,".jpg")) return "image/jpeg"; - if(!strcmp(ext,".jpeg")) return "image/jpeg"; - if(!strcmp(ext,".png")) return "image/png"; - if(!strcmp(ext,".xbm")) return "image/xbm"; - if(!strcmp(ext,".zip")) return "application/zip"; - } - return "application/octet-stream"; -} - -void httpd_send_file(struct httpd_session_data* sd, const char* url) -{ - FILE *fp; - int file_size; - char file_buf[8192]; - if(sd->status != HTTPD_REQUEST_OK) return; - if(url[0] == '\0') url = "index.html"; - - // url の最大長は約1010バイトなので、バッファオーバーフローの心配は無し - sprintf(file_buf, "%s%s", document_root, url); - - fp = fopen(file_buf,"rb"); - if(fp == NULL) { - httpd_send_error(sd,404); - } else { - fseek(fp,0,SEEK_END); - file_size = ftell(fp); - fseek(fp,0,SEEK_SET); - httpd_send_head(sd,200,httpd_mimetype(url),file_size); - while(file_size > 0) { - int read_byte = file_size; - if(file_size > 8192) read_byte = 8192; - fread(file_buf,1,read_byte,fp); - httpd_send_data(sd,read_byte,file_buf); - file_size -= read_byte; - } - fclose(fp); - } -} - - -char* httpd_binary_encode(const char* val) -{ - char *buf = aMalloc(strlen(val) * 3 + 1); - char *p = buf; - while(*val) { - if(isalnum((unsigned char)*val)) { - *(p++) = *(val++); - } else { - unsigned char c1 = *(val++); - unsigned char c2 = (c1 >> 4); - unsigned char c3 = (c1 & 0x0F); - *(p++) = '%'; - *(p++) = c2 + (c2 >= 10 ? 'A'-10 : '0'); - *(p++) = c3 + (c3 >= 10 ? 'A'-10 : '0'); - } - } - *p = 0; - return buf; -} - -char* httpd_quote_meta(const char* p1) -{ - char *buf = aMalloc(strlen(p1) * 6 + 1); - char *p2 = buf; - while(*p1) { - switch(*p1) { - case '<': memcpy(p2,"<",4); p2 += 4; p1++; break; - case '>': memcpy(p2,">",4); p2 += 4; p1++; break; - case '&': memcpy(p2,"&",5); p2 += 5; p1++; break; - case '"': memcpy(p2,""",6); p2 += 6; p1++; break; - default: *(p2++) = *(p1++); - } - } - *p2 = 0; - return buf; -} - -///////// Graph / HTML snippets functions ///////////////////////////// - -struct file_entry { - char *filename; - struct file_entry *next; -}; -struct file_entry *fileentry_head = NULL; - -static void httpd_graph_load (const char *filename) -{ - struct file_entry *entry; - char type = *server_type + 'a'; - int len = strlen(filename); - - if (len <= 7 || filename[len - 7] != type) - return; - - entry = fileentry_head; - while (entry) { - if (strcmpi(entry->filename, filename) == 0) - return; - entry = entry->next; - } - - entry = (struct file_entry *) aMalloc (sizeof(struct file_entry)); - entry->filename = aStrdup(filename); - entry->next = fileentry_head; - fileentry_head = entry; -} - -// scan for available html snippets -static int httpd_graph_find (int tid, unsigned int tick, int id, int data) -{ - findfile("httpd", ".graph", httpd_graph_load); - return 0; -} - -static void httpd_graph_parse (struct httpd_session_data *sd,const char* url) -{ - // output html - struct file_entry *entry = fileentry_head; - char buf[8192]; - char *p = buf; - FILE *fp; - - p += sprintf(p,"<html><head><title>Athena Sensors</title></head>\n\n<body>\n"); - p += sprintf(p,"<h1>Athena Sensors</h1>\n\n"); - - while (entry) { - // insert snippets into html - char line[1024]; - fp = fopen(entry->filename, "r"); - if (fp == NULL) { - entry = entry->next; - continue; - } - while(fgets(line, sizeof(line) -1, fp)) - p += sprintf(p, line); - fclose(fp); - entry = entry->next; - } - p += sprintf(p,"</body></html>\n"); - httpd_send(sd,200,"text/html",p - buf,buf); -} - -//////////////// Initialise / Finalise ///////////////////////////// - -void do_final (void) -{ - int fd; - struct file_entry *entry = fileentry_head, *entry2; - - // clear up graph entries - while (entry) { - entry2 = entry->next; - aFree(entry->filename); - aFree(entry); - entry = entry2; - } - // clear up existing http connections - for (fd = 0; fd < *max_fd; fd++) - if (sessiond[fd] && sessiond[fd]->type == SESSION_HTTP) - delete_sessiond(fd); - - httpd_files->destroy(httpd_files,NULL); - // clear up the database - db_final(); - // clear up allocated memory - // note: the memory manager, if enabled, would be - // separate from the parent program, which is also - // why we need to delete our http sessions - // separately above - malloc_final(); -} - -void do_init (void) -{ - struct func_parse_table *parse_table; - int enable_httpd = 1; - - do { - char line[1024], w1[1024], w2[1024]; - FILE *fp = fopen("plugins/httpd.conf","r"); - if (fp == NULL) - break; - - while(fgets(line, sizeof(line) -1, fp)) { - if (line[0] == '/' && line[1] == '/') - continue; - if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2) { - if(strcmpi(w1,"enable_httpd")==0){ - enable_httpd = atoi(w2); - } else if(strcmpi(w1,"document_root")==0){ - strcpy(document_root, w2); - } else if(strcmpi(w1,"request_timeout_first")==0){ - request_timeout[0] = atoi(w2); - } else if(strcmpi(w1,"request_timeout_persist")==0){ - request_timeout[1] = atoi(w2); - } else if(strcmpi(w1,"max_persist_request")==0){ - max_persist_requests = atoi(w2); - } - } - } - fclose(fp); - } while (0); - - if (!enable_httpd) - return; - - malloc_init(); - db_init(); - IMPORT_SYMBOL(server_type, 0); - IMPORT_SYMBOL(gettick, 5); - IMPORT_SYMBOL(add_timer_interval, 8); - IMPORT_SYMBOL(max_fd, 13); - IMPORT_SYMBOL(sessiond, 14); - IMPORT_SYMBOL(delete_sessiond, 15); - IMPORT_SYMBOL(_WFIFOSET, 16); - IMPORT_SYMBOL(_RFIFOSKIP, 17); - IMPORT_SYMBOL(parse_table, 18); - - // register http parsing function - parse_table[SESSION_HTTP].check = httpd_check; - parse_table[SESSION_HTTP].func = httpd_parse; - - httpd_files = db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_RELEASE_KEY,50); - httpd_default = httpd_send_file; - - httpd_pages ("/graph", httpd_graph_parse); - add_timer_interval(gettick()+10000,httpd_graph_find,0,0,10000); - - return; -} diff --git a/src/plugins/httpd.h b/src/plugins/httpd.h deleted file mode 100644 index aa6989421..000000000 --- a/src/plugins/httpd.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef _HTTPD_H_ -#define _HTTPD_H_ - -struct httpd_session_data; - -// NOTE by Celest: This file is not used by httpd.c, but included only as an API reference. - -// 注意 -// 1.athena内蔵のhttpd で大きなファイルを送信することはお勧めしません。 -// 200KB を超えるようなファイルは、別のソフトを利用することを勧めます。 -// 2.ファイル名に使える文字は、[A-Za-z0-9-_\.] です。他の文字を使うと、 -// BAD REQUEST で弾かれます。 - - - -void httpd_pages(const char* url,void(*httpd_func)(struct httpd_session_data* sd,const char* url)); - -// 指定されたURL に対するコールバック関数を設定する。この関数は、以下のように -// 実装する必要がある。 -// -// 1. URL は、先頭のスラッシュが省かれたファイル名です。例えば、"GET / HTTP/1.0" -// という風にリクエストされた時、URL には""(空文字)が入り、"GET /hoge HTTP/1.0" -// の時には、"hoge"が入ります。 -// 2. リクエストされたページが見つかったら、httpd_send() または、httpd_send_head() -// とhttpd_send_data() の組を呼び出し、データを出力する。 -// 3. httpd_send_file を指定すると、httpd/ 以下にあるファイルを出力する。ファイルに -// 空文字が指定された時は、index.htmlが指定されたものとみなされる。 - - - -char* httpd_get_value(struct httpd_session_data* sd,const char* val); - -// リクエストされたアドレスに渡されたフォームデータのうち、該当する文字列を返す。 -// 例えば、"GET /status/graph?image=users HTTP/1.0"というリクエストの場合、 -// httpd_get_value(sd,"image"); は、 "users"を返す。この関数の戻り値は、呼び出し元が -// 解放しなければならない。また、該当する文字列が無い時は、空の文字列を返す。 - -unsigned int httpd_get_ip(struct httpd_session_data *sd); - -// クライアントのIPを返す。 - - -void httpd_default_page(void(*httpd_func)(struct httpd_session_data* sd,const char* url)); - -// 指定されたURL が登録されていない時に呼び出す関数を設定する。この関数を呼び出さないか、 -// 関数の引数にNULLを指定すると、404 Not Found を返す。 - - - - -void httpd_send(struct httpd_session_data* sd,int status,const char *content_type,int content_len,const void *data); - -// HTTPヘッダ、データを組にして送信する。この関数を呼び出した後に、httpd_send_data を -// 呼び出してはならない。 -// -// sd : httpd_set_parse_func() に渡されたものをそのまま渡すこと。 -// status : HTTPヘッダに加えるstatus。通常は200。 -// content_type : 送信するデータのタイプ。text/html , image/jpeg など。 -// content_len : 送信するデータの長さ。 -// data : 送信するデータへのポインタ - - - -void httpd_send_head(struct httpd_session_data* sd,int status,const char *content_type,int content_len); - -// HTTPヘッダを送信する。 -// -// sd : 同上 -// status : 同上 -// content_type : 同上 -// content_len : content_lenを-1に指定することで、この関数が呼ばれた時点で -// 長さが分からないデータを送信することができる。この場合は -// 強制的にHTTP/1.0 接続となり、オーバーヘッドが大きくなるので、 -// あまりお勧めはしない。 - - - - -void httpd_send_data(struct httpd_session_data* sd,int content_len,const void *data); - -// データを送信する。この関数を、httpd_send_head() を呼び出す前に呼び出された場合、 -// content_type = application/octet-stream, content_len = -1 としてヘッダが送信される。 -// sd : 同上 -// content_len : 送信するデータのdata長さを指定する。 -// data : 送信するデータ - - - -void httpd_send_file(struct httpd_session_data* sd,const char* url); - -// ファイルを送信する。この関数は、httpd_send_head() を呼び出す前に呼び出さなければ -// ならない。ファイルに空文字が指定されたときは、index.htmlが指定されたと見なされる。 - - - -void httpd_send_error(struct httpd_session_data* sd,int status); - -// HTTPエラーメッセージを送信する。status はHTTPのエラーコードと同じ。 -// 400 Bad Request, 404 Not Found, 500 Internal Server Error など。 - -int httpd_parse(int fd); - -// 初期化処理 -void do_init_httpd(void); -void do_final_httpd(void); - -#endif diff --git a/src/plugins/httpd.txt b/src/plugins/httpd.txt deleted file mode 100644 index 5a575f680..000000000 --- a/src/plugins/httpd.txt +++ /dev/null @@ -1,20 +0,0 @@ -// -// HTTP Daemon Plugin Configuration -// - -// Enabled the http daemon? -enable_httpd: 1 - -// WWW Root path -//(The ending slash is required!) -document_root: httpd/ - -// Request timeout (first request) -// Both of the following are in milliseconds -request_timeout_first: 2500 - -// Request timeout (consequent requests) -request_timeout_persist: 60000 - -// Maximum persistent requests -max_persist_request: 32
\ No newline at end of file diff --git a/src/webserver/Makefile b/src/webserver/Makefile deleted file mode 100644 index 077b39980..000000000 --- a/src/webserver/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -all: - #Generate framework... - $(CC) -c parse.c - $(CC) -c generate.c - $(CC) -c htmlstyle.c - $(CC) -c logs.c - - #Generate "pages"... - cd pages && $(CC) -c about.c && cd .. - cd pages && $(CC) -c sample.c && cd .. - cd pages && $(CC) -c notdone.c && cd .. - - #Building the server... - $(CC) -o webserver main.c parse.o generate.o htmlstyle.o \ - logs.o pages/about.o pages/sample.o pages/notdone.o - -clean: - rm -f *.o - rm -f pages/*.o - rm -f webserver diff --git a/src/webserver/doc/API.txt b/src/webserver/doc/API.txt deleted file mode 100644 index c80f7bd44..000000000 --- a/src/webserver/doc/API.txt +++ /dev/null @@ -1,50 +0,0 @@ -Here's the webserver API, so you can work on the webserver. - -My personal goal is to make this interface simple, so that coding it -will be like coding in some scripting language... - - - -char *get_param(char in_string[500], char swhat[500]); - -This function simply returns various data from the query string. - *Pass get_param NOTHING longer than 500 in length! - - What do I pass where in_string is? - The query string. - - What do I pass where swhat is? - One of two things... - Either 0 for the path of the 'page' - or you can pass it the param you wish to lookup. - - - - - - -char *get_query(char *inquery); - -This function simply returns a query string from the raw server request. -This is used once in main, I doubt you'll need it. - - - - - -void web_send(int sockin, char *in_data); - -Super easy way of sending data to a webpage! -Simply put in the socket name and then the data. - - Ex: - web_send(socket, "I like cheese!\n"); - - - - -char *html_header(char* title); -Easy way to print the eAthena header for the server. - - Ex: - web_send(sockethere, html_header("About")); diff --git a/src/webserver/doc/README b/src/webserver/doc/README deleted file mode 100644 index 0e94ff2ae..000000000 --- a/src/webserver/doc/README +++ /dev/null @@ -1,11 +0,0 @@ -This readme is intended for the programmers of eAthena. - -This webserver's apis are in API.txt. - -To make this simple, generate.c should handle most of the work this sever does -in terms of what people see. - -When a request is made the server shoots it off to generate.c. - -You are welcome to create more functions used by generate.c to generate pages -though, so don't feel limited by that one file. diff --git a/src/webserver/generate.c b/src/webserver/generate.c deleted file mode 100644 index ad050db4c..000000000 --- a/src/webserver/generate.c +++ /dev/null @@ -1,38 +0,0 @@ - -void generate_page(char password[25], int sock_in, char *query, char *ip) -{ - char *page = get_param(query, 0); - char *ppass = get_param(query, "password"); - - - if ( (ppass == 0) || (strcmp(password, ppass) != 0) ) - { - web_send(sock_in, html_header("Enter your password")); - web_send(sock_in, "<H1>NOT LOGGED IN!</H1><form action=\"/\" method=\"GET\">\n"); - web_send(sock_in, "Enter your password:<br>\n<input type=\"text\" name=\"password\">\n"); - web_send(sock_in, "<input type=\"submit\" value=\"Login\">\n"); - } - else - { - - - //To make this simple, we will have a bunch of if statements - //that then shoot out data off into functions. - - - //The 'index' - if ( strcmp(page, "/") == 0 ) - generate_notdone(sock_in, query, ip); - - - //About page: - if ( strcmp(page, "/about.html") == 0 ) - generate_about(sock_in, query, ip); - - - //Test page: - if ( strcmp(page, "/testing/") == 0 ) - generate_sample(sock_in, query, ip); - - } -} diff --git a/src/webserver/htmlstyle.c b/src/webserver/htmlstyle.c deleted file mode 100644 index c3a4b927a..000000000 --- a/src/webserver/htmlstyle.c +++ /dev/null @@ -1,51 +0,0 @@ -char output[10000]; - -char *html_header(char *title) -{ - memset(output, 0x0, 10000); - char *text = "<body text=\"#000000\" bgcolor=\"#939393\" link=\"#0033FF\">\n" - "<br><table width=\"92%\" cellspacing=\"1\" cellpadding=\"0\" border=\"0\"\n" - "align=\"center\" class=\"bordercolor\"><tbody><tr><td class=\"bordercolor\" width=\"100%\">\n" - "<table bgcolor=\"#ffffff\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">\n" - "<tbody><tr><td><table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" bgcolor=\"#ffffff\">\n" - "<tbody><tr><img src=\"http://eathena.sourceforge.net/athena.jpg\" alt=\"Athena\">\n" - "<td bgcolor=\"#ffffff\"></td></tr></tbody></table></td></tr></tbody></table>\n" - "</td></tr><tr align=\"left\"><td class=\"bordercolor\"><table bgcolor=\"#c6c6c6\" width=\"100%\" cellspacing=\"0\"\n" - "cellpadding=\"0\" style=\"text-align: left; margin-right: auto; margin-left: 0px;\">\n"; - "<tbody><tr><td width=\"100%\" align=\"center\"><table border=\"0\" width=\"100%\" cellpadding=\"3\"\n" - "cellspacing=\"0\" bgcolor=\"#c6c6c6\" align=\"center\"><tbody><tr>" - "<td valign=\"middle\" bgcolor=\"#c6c6c6\" align=\"center\"><a href=\"/cgi-bin/forum/YaBB.cgi\">" - "<span style=\"text-decoration: underline;\"><span style=\"font-weight: bold;\">\n" - "To the Forum</span></span></a><br></td></tr></tbody></table></td></tr></tbody>\n" - "</table></td></tr><tr><td class=\"bordercolor\" align=\"center\">\n" - "<table bgcolor=\"#ffffff\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\">\n" - "<tbody><tr><td width=\"100%\" align=\"center\"><table border=\"0\" width=\"100%\" cellpadding=\"5\"\n" - "cellspacing=\"0\" bgcolor=\"#ffffff\" align=\"center\"><tbody><tr>\n" - "<td valign=\"middle\" bgcolor=\"#ffffff\" align=\"center\"><font size=\"2\" color=\"#6e94b7\">\n" - "<b>Athena</b> « Portal »</font></td></tr></tbody></table></td></tr></tbody>" - "</table></td></tr></tbody></table>\n"; - - sprintf(output, "<title>%s</title>\n%s\n", title, text); - - return output; -} - - - -char *html_start_form(char *location, char *action) -{ - memset(output, 0x0, 10000); - sprintf(output, "<form action=\"%s\" method=\"%s\">", location, action); - return output; - - -} - - -char *html_end_forum(void) -{ - return "</form>"; -} - - - diff --git a/src/webserver/logs.c b/src/webserver/logs.c deleted file mode 100644 index 405b4882b..000000000 --- a/src/webserver/logs.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <time.h> - -void log_visit(char *query, char *ip) -{ - time_t timer; - timer=time(NULL); - printf("%s - \"%s\" - %s", ip, query, asctime(localtime(&timer))); -} diff --git a/src/webserver/main.c b/src/webserver/main.c deleted file mode 100644 index 59362558e..000000000 --- a/src/webserver/main.c +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************** - description - ------------------- - author : (C) 2004 by Michael J. Flickinger - email : mjflick@cpan.org - - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/wait.h> -#include <signal.h> - -#define BLOG 10 - -char *header = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"; -char recvin[500], password[25]; -int s_port; - -void sigchld_handler(int s) -{ - while(wait(NULL) > 0); -} - -int main(int argc, char **argv) -{ - if (argc < 3) - { - printf("eAthena Web Server\n"); - printf("usage: %s [password] [port]\n", argv[0]); - exit(0); - } - - s_port = atoi(argv[2]); - - if ((s_port < 1) || (s_port > 65534)) - { - printf("Error: The port you choose is not valid port.\n"); - exit(0); - } - - if (strlen(argv[1]) > 25) - { - printf("Error: Your password is too long.\n"); - printf("It must be shorter than 25 characters.\n"); - exit(0); - } - - memset(password, 0x0, 25); - memcpy(password, argv[1], strlen(argv[1])); - - int sockfd, new_fd; - struct sockaddr_in my_addr; - struct sockaddr_in their_addr; - int sin_size; - - struct sigaction sa; - - int yes=1; - - if ((sockfd = socket(AF_INET, SOCK_STREAM,0)) == -1) - { - perror("Darn, this is broken."); - exit(0); - } - - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) - { - perror("Error... :-("); - } - - //Now we know we have a working socket. :-) - - my_addr.sin_family = AF_INET; - my_addr.sin_port = htons(s_port); - my_addr.sin_addr.s_addr = INADDR_ANY; - memset(&(my_addr.sin_zero), '\0', 8); - - if ( bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) - { - perror("can not bind to this port"); - exit(0); - } - - if ( listen(sockfd, BLOG) == -1) - { - perror("can not listen on port"); - exit(0); - } - - sa.sa_handler = sigchld_handler; - - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - - if (sigaction(SIGCHLD, &sa, NULL) == -1) - { - perror("sigaction sucks"); - exit(0); - } - - printf("The eAthena webserver is up and listening on port %i.\n", s_port); - - while(1) - { - sin_size = sizeof(struct sockaddr_in); - new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); - - if (!fork()) - { - close(sockfd); - memset(recvin, 0x0, 500); - recv(new_fd, recvin, 500, 0); - send(new_fd, header, strlen(header), 0); - generate_page(password, new_fd, get_query(recvin), inet_ntoa(their_addr.sin_addr)); - log_visit(get_query(recvin), inet_ntoa(their_addr.sin_addr)); - - close(new_fd); - exit(0); - } - close(new_fd); - } - - return 0; -} diff --git a/src/webserver/pages/about.c b/src/webserver/pages/about.c deleted file mode 100644 index 2b0002ad8..000000000 --- a/src/webserver/pages/about.c +++ /dev/null @@ -1,6 +0,0 @@ -void generate_about(int sock_in, char *query, char *ip) -{ -//printf("%s", html_header("About")); - web_send(sock_in, html_header("About")); - web_send(sock_in, "<center>eAthena Web Server!</center>\n"); -} diff --git a/src/webserver/pages/notdone.c b/src/webserver/pages/notdone.c deleted file mode 100644 index a6492e361..000000000 --- a/src/webserver/pages/notdone.c +++ /dev/null @@ -1,5 +0,0 @@ -void generate_notdone(int sock_in, char *query, char *ip) -{ - web_send(sock_in, "<title>Not here!</title>\n"); - web_send(sock_in, "<h2><center>This page/feature is not done yet.</center>\n</h2>"); -} diff --git a/src/webserver/pages/sample.c b/src/webserver/pages/sample.c deleted file mode 100644 index be900a1bf..000000000 --- a/src/webserver/pages/sample.c +++ /dev/null @@ -1,24 +0,0 @@ - - -void generate_sample(int sock_in, char *query, char *ip) -{ - - char *name = get_param(query, "name"); - - web_send(sock_in, "<title>SAMPLE</title>\n"); - - - //If a name was not entered... - if ( name == '\0' ) - { - web_send(sock_in, "<form action=\"/testing/\" method=\"GET\">\n"); - web_send(sock_in, "<input type=\"text\" name=\"name\">\n"); - web_send(sock_in, "<input type=\"submit\">\n"); - } - else - { - web_send(sock_in, "Your name is: "); - web_send(sock_in, get_param(query, "name")); - } -printf("OK!\n"); -} diff --git a/src/webserver/parse.c b/src/webserver/parse.c deleted file mode 100644 index 8e54a81de..000000000 --- a/src/webserver/parse.c +++ /dev/null @@ -1,135 +0,0 @@ -#include <stdlib.h> - -char filtered_query[2000]; -char rdata[500]; -char param_n[500]; -char param_d[500]; - - -char *get_query(char *inquery) -{ - memset(filtered_query, 0x0, 2000); - sscanf(inquery, "GET %s %[$]", filtered_query); - return(filtered_query); -} - -void web_send(int sockin, char *in_data) -{ - send(sockin, in_data, strlen(in_data), 0); -} - - -//THIS IS BAD CODE BE CAREFULL WITH IT! -//Watch out for buffer overflow... -//When using please make sure to check the string size. - -//Also note: -//I take no pride in this code, it is a really bad way of doing this... -char *get_param(char in_string[500], char swhat[500]) -{ - int i = 0; - int marker, iswitch, pint, dint; - char flux[500]; - memset(flux, 0x0, 500); - - //Get the path of out "page" - if (swhat == 0) - { - //while i is not equal to array size - while (i != 500) - { - //if there is a question mark, halt! - if (in_string[i] == '?') - { - i = 499; - } - else - rdata[i] = in_string[i]; - - i++; - } - return rdata; - } - else //so, we want a param... - { - //calculate where param begins - while (i != 500) - { - if (in_string[i] == '?') - { - marker = i + 1; - i = 499; - } - i++; - } - - i = 0; - - //keep morons from trying to crash this - if ((marker > 500)||(marker < 1)) - marker = 500; - - while(marker != 500) - { - if ((in_string[marker] != '&') && (in_string[marker] != '\0')) - { - flux[i] = in_string[marker]; - i++; - } - else - { - - //we have a param, now we must dig through it - - //clear temp vars - memset(param_n, 0x0, 500); - memset(param_d, 0x0, 500); - iswitch = 0; - pint = 0; - dint = 0; - i = 0; - - //split result into param_n and param_d - while(i != 500) - { - if ( (flux[i] != '=') && (flux[i] != '\0') ) - { - if (iswitch == 0) - { - param_n[pint] = flux[i]; - pint++; - } - else - { - param_d[dint] = flux[i]; - dint++; - } - } - else - { - iswitch = 1; - } - if (flux[i] == '\0') - i = 499; - - i++; - } - - if ( strcmp(param_n, swhat) == 0 ) - { - return param_d; - } - - i = 0; - } - - if (in_string[marker] == '\0') - { - marker = 499; - } - marker++; - } - return 0; - } -} - |