Removed graph, httpd and webserver
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9757 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
287219ad0d
commit
7390d2d950
@ -4,6 +4,7 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2007/01/31
|
||||
* Removed graph, httpd and webserver
|
||||
* Wiped out the old night code (use svn if you want it) [ultramage]
|
||||
2007/01/30
|
||||
* 'Long Range Attacked' mob skill conditions will no longer trigger on
|
||||
|
5
Makefile
5
Makefile
@ -109,7 +109,7 @@ MKDEF = CC="$(CC)" CFLAGS="$(CFLAGS)" LIB_S="$(LIBS)"
|
||||
endif
|
||||
|
||||
.PHONY: txt sql common login login_sql char char_sql map map_sql ladmin converters \
|
||||
addons plugins tools webserver clean zlib depend
|
||||
addons plugins tools clean zlib depend
|
||||
|
||||
txt : Makefile.cache conf common login char map ladmin
|
||||
|
||||
@ -153,9 +153,6 @@ ladmin: src/ladmin/GNUmakefile common
|
||||
plugins addons: src/plugins/GNUmakefile common
|
||||
$(MAKE) -C src/plugins $(MKDEF)
|
||||
|
||||
webserver:
|
||||
$(MAKE) -C src/$@ $(MKDEF)
|
||||
|
||||
tools:
|
||||
$(MAKE) -C src/tool $(MKDEF)
|
||||
|
||||
|
@ -25,8 +25,5 @@ plugin: upnp
|
||||
// Process id logging
|
||||
//plugin: pid
|
||||
|
||||
// Built-in webserver
|
||||
//plugin: httpd
|
||||
|
||||
// Console parser
|
||||
//plugin: console
|
||||
|
@ -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) $<
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 \
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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"));
|
@ -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.
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
@ -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>";
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)));
|
||||
}
|
@ -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;
|
||||
}
|
@ -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");
|
||||
}
|
@ -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>");
|
||||
}
|
@ -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");
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -82,14 +82,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -84,14 +84,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -82,14 +82,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -82,14 +82,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -83,14 +83,6 @@ SOURCE=..\..\src\common\ers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\graph.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\common\grfio.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -151,9 +151,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c">
|
||||
</File>
|
||||
@ -236,9 +233,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\db.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h">
|
||||
</File>
|
||||
|
@ -149,9 +149,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c">
|
||||
</File>
|
||||
@ -228,9 +225,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\db.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h">
|
||||
</File>
|
||||
|
@ -150,9 +150,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c">
|
||||
</File>
|
||||
@ -208,9 +205,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\db.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h">
|
||||
</File>
|
||||
|
@ -152,9 +152,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c">
|
||||
</File>
|
||||
@ -210,9 +207,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\db.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h">
|
||||
</File>
|
||||
|
@ -173,9 +173,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c">
|
||||
</File>
|
||||
@ -324,9 +321,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h">
|
||||
</File>
|
||||
|
@ -174,9 +174,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c">
|
||||
</File>
|
||||
@ -325,9 +322,6 @@
|
||||
<File
|
||||
RelativePath="..\src\common\ers.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h">
|
||||
</File>
|
||||
|
@ -219,10 +219,6 @@
|
||||
RelativePath="..\src\common\ers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c"
|
||||
>
|
||||
@ -323,10 +319,6 @@
|
||||
RelativePath="..\src\common\db.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h"
|
||||
>
|
||||
|
@ -218,10 +218,6 @@
|
||||
RelativePath="..\src\common\ers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c"
|
||||
>
|
||||
@ -322,10 +318,6 @@
|
||||
RelativePath="..\src\common\db.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h"
|
||||
>
|
||||
|
@ -212,10 +212,6 @@
|
||||
RelativePath="..\src\common\ers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c"
|
||||
>
|
||||
@ -288,10 +284,6 @@
|
||||
RelativePath="..\src\common\db.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h"
|
||||
>
|
||||
|
@ -219,10 +219,6 @@
|
||||
RelativePath="..\src\common\ers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c"
|
||||
>
|
||||
@ -295,10 +291,6 @@
|
||||
RelativePath="..\src\common\db.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h"
|
||||
>
|
||||
|
@ -245,10 +245,6 @@
|
||||
RelativePath="..\src\common\ers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c"
|
||||
>
|
||||
@ -445,10 +441,6 @@
|
||||
RelativePath="..\src\common\ers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h"
|
||||
>
|
||||
|
@ -247,10 +247,6 @@
|
||||
RelativePath="..\src\common\ers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.c"
|
||||
>
|
||||
@ -447,10 +443,6 @@
|
||||
RelativePath="..\src\common\ers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\graph.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\common\grfio.h"
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user