636 lines
17 KiB
C
636 lines
17 KiB
C
|
/*
|
|||
|
goahead.c -- Main program for GoAhead
|
|||
|
|
|||
|
Usage: goahead [options] [documents] [IP][:port] ...
|
|||
|
Options:
|
|||
|
--auth authFile # User and role configuration
|
|||
|
--background # Run as a Linux daemon
|
|||
|
--home directory # Change to directory to run
|
|||
|
--log logFile:level # Log to file file at verbosity level
|
|||
|
--route routeFile # Route configuration file
|
|||
|
--verbose # Same as --log stdout:2
|
|||
|
--version # Output version information
|
|||
|
|
|||
|
Copyright (c) All Rights Reserved. See details at the end of the file.
|
|||
|
*/
|
|||
|
|
|||
|
/********************************* Includes ***********************************/
|
|||
|
|
|||
|
#include "goahead.h"
|
|||
|
#include "js.h"
|
|||
|
|
|||
|
/********************************* Defines ************************************/
|
|||
|
|
|||
|
static int finished = 0;
|
|||
|
|
|||
|
#undef ME_GOAHEAD_LISTEN
|
|||
|
/*
|
|||
|
These must match TOP.es.set
|
|||
|
*/
|
|||
|
#if TEST_IPV6
|
|||
|
#if ME_COM_SSL
|
|||
|
#define ME_GOAHEAD_LISTEN "http://127.0.0.1:18080, https://127.0.0.1:14443, http://[::1]:18090, https://[::1]:14453"
|
|||
|
#else
|
|||
|
#define ME_GOAHEAD_LISTEN "http://127.0.0.1:18080, http://[::1]:18090"
|
|||
|
#endif
|
|||
|
#else
|
|||
|
#if ME_COM_SSL
|
|||
|
#define ME_GOAHEAD_LISTEN "http://192.168.2.133:80, https://192.168.2.133:443"
|
|||
|
#else
|
|||
|
#define ME_GOAHEAD_LISTEN "http://192.168.2.133:80"
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
/********************************* Forwards ***********************************/
|
|||
|
|
|||
|
static void initPlatform(void);
|
|||
|
static void logHeader(void);
|
|||
|
static void usage(void);
|
|||
|
|
|||
|
#if WINDOWS
|
|||
|
static void windowsClose();
|
|||
|
static int windowsInit();
|
|||
|
static LRESULT CALLBACK websWindProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp);
|
|||
|
#endif
|
|||
|
|
|||
|
static bool testHandler(Webs *wp);
|
|||
|
#if ME_GOAHEAD_JAVASCRIPT
|
|||
|
static int aspTest(int eid, Webs *wp, int argc, char **argv);
|
|||
|
static int bigTest(int eid, Webs *wp, int argc, char **argv);
|
|||
|
#endif
|
|||
|
static void actionTest(Webs *wp);
|
|||
|
static void sessionTest(Webs *wp);
|
|||
|
static void showTest(Webs *wp);
|
|||
|
// 测试action函数
|
|||
|
static void on_led_set(Webs *wp);
|
|||
|
static void on_buzzer_set(Webs *wp);
|
|||
|
|
|||
|
#if ME_GOAHEAD_UPLOAD && !ME_ROM
|
|||
|
static void uploadTest(Webs *wp);
|
|||
|
#endif
|
|||
|
#if ME_GOAHEAD_LEGACY
|
|||
|
static int legacyTest(Webs *wp, char *prefix, char *dir, int flags);
|
|||
|
#endif
|
|||
|
|
|||
|
#if ME_UNIX_LIKE
|
|||
|
static void sigHandler(int signo);
|
|||
|
#endif
|
|||
|
|
|||
|
static void exitProc(void *data, int id);
|
|||
|
|
|||
|
/*********************************** Code *************************************/
|
|||
|
|
|||
|
MAIN(goahead, int argc, char **argv, char **envp)
|
|||
|
{
|
|||
|
char *argp, *home, *documents, *endpoints, *endpoint, *route, *auth, *tok, *lspec;
|
|||
|
int argind, duration;
|
|||
|
|
|||
|
#if WINDOWS
|
|||
|
if (windowsInit() < 0) {
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
route = "route.txt";
|
|||
|
auth = "auth.txt";
|
|||
|
duration = 0;
|
|||
|
|
|||
|
// 命令行解析
|
|||
|
for (argind = 1; argind < argc; argind++) {
|
|||
|
argp = argv[argind];
|
|||
|
if (*argp != '-') {
|
|||
|
break;
|
|||
|
|
|||
|
} else if (smatch(argp, "--auth") || smatch(argp, "-a")) {
|
|||
|
if (argind >= argc) usage();
|
|||
|
auth = argv[++argind];
|
|||
|
|
|||
|
#if ME_UNIX_LIKE && !MACOSX
|
|||
|
} else if (smatch(argp, "--background") || smatch(argp, "-b")) {
|
|||
|
websSetBackground(1);
|
|||
|
#endif
|
|||
|
|
|||
|
} else if (smatch(argp, "--debugger") || smatch(argp, "-d") || smatch(argp, "-D")) {
|
|||
|
websSetDebug(1);
|
|||
|
|
|||
|
} else if (smatch(argp, "--duration")) {
|
|||
|
if (argind >= argc) usage();
|
|||
|
duration = atoi(argv[++argind]);
|
|||
|
|
|||
|
} else if (smatch(argp, "--home")) {
|
|||
|
if (argind >= argc) usage();
|
|||
|
home = argv[++argind];
|
|||
|
if (chdir(home) < 0) {
|
|||
|
error("Cannot change directory to %s", home);
|
|||
|
exit(-1);
|
|||
|
}
|
|||
|
} else if (smatch(argp, "--log") || smatch(argp, "-l")) {
|
|||
|
if (argind >= argc) usage();
|
|||
|
logSetPath(argv[++argind]);
|
|||
|
|
|||
|
} else if (smatch(argp, "--verbose") || smatch(argp, "-v")) {
|
|||
|
logSetPath("stdout:2");
|
|||
|
|
|||
|
} else if (smatch(argp, "--route") || smatch(argp, "-r")) {
|
|||
|
route = argv[++argind];
|
|||
|
|
|||
|
} else if (smatch(argp, "--version") || smatch(argp, "-V")) {
|
|||
|
printf("%s\n", ME_VERSION);
|
|||
|
exit(0);
|
|||
|
|
|||
|
} else if (*argp == '-' && isdigit((uchar) argp[1])) {
|
|||
|
lspec = sfmt("stdout:%s", &argp[1]);
|
|||
|
logSetPath(lspec);
|
|||
|
wfree(lspec);
|
|||
|
|
|||
|
} else {
|
|||
|
usage();
|
|||
|
}
|
|||
|
}
|
|||
|
documents = ME_GOAHEAD_DOCUMENTS;
|
|||
|
if (argc > argind) {
|
|||
|
documents = argv[argind++];
|
|||
|
}
|
|||
|
initPlatform(); // 平台初始化,注册信号处理函数
|
|||
|
if (websOpen(documents, route) < 0) // 初始化服务器
|
|||
|
{
|
|||
|
error("Cannot initialize server. Exiting.");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
#if ME_GOAHEAD_AUTH // 加载路径和鉴权配置文件
|
|||
|
if (websLoad(auth) < 0)
|
|||
|
{
|
|||
|
error("Cannot load %s", auth);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
#endif
|
|||
|
logHeader(); // 打印web服务器基本信息
|
|||
|
if (argind < argc) {
|
|||
|
while (argind < argc) {
|
|||
|
endpoint = argv[argind++]; // 参数中指定了服务器的endpoint 如./goahead -v ./web/ 192.168.10.111:80
|
|||
|
// WEB端口监听
|
|||
|
if (websListen(endpoint) < 0) {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
endpoints = sclone(ME_GOAHEAD_LISTEN);
|
|||
|
for (endpoint = stok(endpoints, ", \t", &tok); endpoint; endpoint = stok(NULL, ", \t,", &tok)) {
|
|||
|
#if !ME_COM_SSL
|
|||
|
if (strstr(endpoint, "https")) continue;
|
|||
|
#endif
|
|||
|
if (websListen(endpoint) < 0) {
|
|||
|
wfree(endpoints);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
wfree(endpoints);
|
|||
|
}
|
|||
|
|
|||
|
#if ME_ROM && KEEP // 采用web文件ROM化
|
|||
|
/*
|
|||
|
If not using a route/auth config files, then manually create the routes like this:
|
|||
|
If custom matching is required, use websSetRouteMatch. If authentication is required, use websSetRouteAuth.
|
|||
|
*/
|
|||
|
websAddRoute("/", "file", 0);
|
|||
|
#endif
|
|||
|
#ifdef GOAHEAD_INIT
|
|||
|
/*
|
|||
|
Define your init function in main.me goahead.init, or
|
|||
|
configure with DFLAGS=GOAHEAD_INIT=myInitFunction
|
|||
|
*/
|
|||
|
{
|
|||
|
extern int GOAHEAD_INIT();
|
|||
|
|
|||
|
if (GOAHEAD_INIT() < 0) {
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
websDefineHandler("test", testHandler, 0, 0, 0); // 定义一个请求处理程序
|
|||
|
websAddRoute("/test", "test", 0);
|
|||
|
#if ME_GOAHEAD_LEGACY
|
|||
|
// 表示对 /goform 的请求都交给 websFormHandler 函数处理。函数的参数列表如下
|
|||
|
websUrlHandlerDefine("/legacy/", 0, 0, legacyTest, 0); // 设置form方式调用时候的文件位置
|
|||
|
// websFormDefine(T("odbc_form_web_login"), odbc_form_web_login); // 定义form方式调用接口函数字符对应的函数名称
|
|||
|
#endif
|
|||
|
#if ME_GOAHEAD_JAVASCRIPT
|
|||
|
websDefineJst("aspTest", aspTest); // 定义一个js本地函数
|
|||
|
websDefineJst("bigTest", bigTest);
|
|||
|
#endif
|
|||
|
websDefineAction("test", actionTest); // goAction定义,在asp文件中调用C函数
|
|||
|
websDefineAction("sessionTest", sessionTest);
|
|||
|
websDefineAction("showTest", showTest);
|
|||
|
|
|||
|
websDefineAction("led", on_led_set);
|
|||
|
websDefineAction("buzzer", on_buzzer_set);
|
|||
|
|
|||
|
#if ME_GOAHEAD_UPLOAD && !ME_ROM
|
|||
|
websDefineAction("uploadTest", uploadTest);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
#if ME_UNIX_LIKE && !MACOSX
|
|||
|
/*
|
|||
|
Service events till terminated
|
|||
|
*/
|
|||
|
if (websGetBackground()) {
|
|||
|
if (daemon(0, 0) < 0) {
|
|||
|
error("Cannot run as daemon");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (duration) {
|
|||
|
printf("Running for %d secs\n", duration);
|
|||
|
websStartEvent(duration * 1000, (WebsEventProc) exitProc, 0);
|
|||
|
}
|
|||
|
websServiceEvents(&finished);
|
|||
|
logmsg(1, "Instructed to exit\n");
|
|||
|
websClose();
|
|||
|
|
|||
|
#if WINDOWS
|
|||
|
windowsClose();
|
|||
|
#endif
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void exitProc(void *data, int id)
|
|||
|
{
|
|||
|
websStopEvent(id);
|
|||
|
finished = 1;
|
|||
|
}
|
|||
|
|
|||
|
static void logHeader(void)
|
|||
|
{
|
|||
|
char home[ME_GOAHEAD_LIMIT_STRING];
|
|||
|
|
|||
|
getcwd(home, sizeof(home));
|
|||
|
logmsg(2, "Configuration for %s", ME_TITLE);
|
|||
|
logmsg(2, "---------------------------------------------");
|
|||
|
logmsg(2, "Version: %s", ME_VERSION);
|
|||
|
logmsg(2, "BuildType: %s", ME_DEBUG ? "Debug" : "Release");
|
|||
|
logmsg(2, "CPU: %s", ME_CPU);
|
|||
|
logmsg(2, "OS: %s", ME_OS);
|
|||
|
logmsg(2, "Host: %s", websGetServer());
|
|||
|
logmsg(2, "Directory: %s", home);
|
|||
|
logmsg(2, "Documents: %s", websGetDocuments());
|
|||
|
logmsg(2, "Configure: %s", ME_CONFIG_CMD);
|
|||
|
logmsg(2, "---------------------------------------------");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void usage(void) {
|
|||
|
fprintf(stderr, "\n%s Usage:\n\n"
|
|||
|
" %s [options] [documents] [[IPaddress][:port] ...]\n\n"
|
|||
|
" Options:\n"
|
|||
|
#if ME_GOAHEAD_AUTH
|
|||
|
" --auth authFile # User and role configuration\n"
|
|||
|
#endif
|
|||
|
#if ME_UNIX_LIKE && !MACOSX
|
|||
|
" --background # Run as a Unix daemon\n"
|
|||
|
#endif
|
|||
|
" --debugger # Run in debug mode\n"
|
|||
|
" --home directory # Change to directory to run\n"
|
|||
|
" --log logFile:level # Log to file file at verbosity level\n"
|
|||
|
" --route routeFile # Route configuration file\n"
|
|||
|
" --verbose # Same as --log stdout:2\n"
|
|||
|
" --version # Output version information\n\n",
|
|||
|
ME_TITLE, ME_NAME);
|
|||
|
exit(-1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void initPlatform(void)
|
|||
|
{
|
|||
|
#if ME_UNIX_LIKE
|
|||
|
signal(SIGINT, sigHandler);
|
|||
|
signal(SIGTERM, sigHandler);
|
|||
|
signal(SIGKILL, sigHandler); // 增加退出信号处理
|
|||
|
#ifdef SIGPIPE
|
|||
|
signal(SIGPIPE, SIG_IGN);
|
|||
|
#endif
|
|||
|
#elif ME_WIN_LIKE
|
|||
|
_fmode=_O_BINARY;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if ME_UNIX_LIKE
|
|||
|
static void sigHandler(int signo)
|
|||
|
{
|
|||
|
finished = 1;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Simple handler and route test
|
|||
|
Note: Accesses to "/" are normally remapped automatically to /index.html
|
|||
|
*/
|
|||
|
static bool testHandler(Webs *wp)
|
|||
|
{
|
|||
|
if (smatch(wp->path, "/")) {
|
|||
|
websRewriteRequest(wp, "/home.html");
|
|||
|
/* Fall through */
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if ME_GOAHEAD_JAVASCRIPT
|
|||
|
/*
|
|||
|
Parse the form variables: name, address and echo back
|
|||
|
*/
|
|||
|
static int aspTest(int eid, Webs *wp, int argc, char **argv)
|
|||
|
{
|
|||
|
char *name, *address;
|
|||
|
|
|||
|
if (jsArgs(argc, argv, "%s %s", &name, &address) < 2) {
|
|||
|
websError(wp, 400, "Insufficient args\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
return (int) websWrite(wp, "Name: %s, Address %s", name, address);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Generate a large response
|
|||
|
*/
|
|||
|
static int bigTest(int eid, Webs *wp, int argc, char **argv)
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
websSetStatus(wp, 200);
|
|||
|
websWriteHeaders(wp, -1, 0);
|
|||
|
websWriteEndHeaders(wp);
|
|||
|
websWrite(wp, "<html>\n");
|
|||
|
for (i = 0; i < 800; i++) {
|
|||
|
websWrite(wp, " Line: %05d %s", i, "aaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccccddddddd<br/>\n");
|
|||
|
}
|
|||
|
websWrite(wp, "</html>\n");
|
|||
|
websDone(wp);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Implement /action/actionTest. Parse the form variables: name, address and echo back.
|
|||
|
*/
|
|||
|
static void actionTest(Webs *wp)
|
|||
|
{
|
|||
|
cchar *name, *address;
|
|||
|
|
|||
|
name = websGetVar(wp, "name", NULL);
|
|||
|
address = websGetVar(wp, "address", NULL);
|
|||
|
websSetStatus(wp, 200);
|
|||
|
websWriteHeaders(wp, -1, 0);
|
|||
|
websWriteEndHeaders(wp);
|
|||
|
websWrite(wp, "<html><body><h2>name: %s, address: %s</h2></body></html>\n", name, address);
|
|||
|
websFlush(wp, 0);
|
|||
|
websDone(wp);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void sessionTest(Webs *wp)
|
|||
|
{
|
|||
|
cchar *number;
|
|||
|
|
|||
|
if (scaselessmatch(wp->method, "POST")) {
|
|||
|
number = websGetVar(wp, "number", 0);
|
|||
|
websSetSessionVar(wp, "number", number);
|
|||
|
} else {
|
|||
|
number = websGetSessionVar(wp, "number", 0);
|
|||
|
}
|
|||
|
websSetStatus(wp, 200);
|
|||
|
websWriteHeaders(wp, -1, 0);
|
|||
|
websWriteEndHeaders(wp);
|
|||
|
websWrite(wp, "<html><body><p>Number %s</p></body></html>\n", number);
|
|||
|
websDone(wp);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void showTest(Webs *wp)
|
|||
|
{
|
|||
|
WebsKey *s;
|
|||
|
|
|||
|
websSetStatus(wp, 200);
|
|||
|
websWriteHeaders(wp, -1, 0);
|
|||
|
websWriteEndHeaders(wp);
|
|||
|
websWrite(wp, "<html><body><pre>\n");
|
|||
|
for (s = hashFirst(wp->vars); s; s = hashNext(wp->vars, s)) {
|
|||
|
websWrite(wp, "%s=%s\n", s->name.value.string, s->content.value.string);
|
|||
|
}
|
|||
|
websWrite(wp, "</pre></body></html>\n");
|
|||
|
websDone(wp);
|
|||
|
}
|
|||
|
|
|||
|
// led控制
|
|||
|
static void on_led_set(Webs *wp)
|
|||
|
{
|
|||
|
// get the input value in query stream
|
|||
|
// char *io_val;
|
|||
|
//
|
|||
|
// io_val = websGetVar(wp, "val_led", NULL);
|
|||
|
// if(io_val)
|
|||
|
// system("echo 1 > /sys/class/leds/led-err/brightness");
|
|||
|
// else
|
|||
|
// system("echo 0 > /sys/class/leds/led-err/brightness");
|
|||
|
}
|
|||
|
|
|||
|
// 蜂鸣器控制
|
|||
|
static void on_buzzer_set(Webs *wp)
|
|||
|
{
|
|||
|
// char *io_val;
|
|||
|
//
|
|||
|
// io_val = websGetVar(wp, "val_buz", NULL);
|
|||
|
// if(io_val)
|
|||
|
// system("echo 1 > /sys/class/leds/beep/brightness");
|
|||
|
// else
|
|||
|
// system("echo 0 > /sys/class/leds/beep/brightness");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if ME_GOAHEAD_UPLOAD && !ME_ROM
|
|||
|
/*
|
|||
|
Dump the file upload details. Don't actually do anything with the uploaded file.
|
|||
|
*/
|
|||
|
static void uploadTest(Webs *wp)
|
|||
|
{
|
|||
|
WebsKey *s;
|
|||
|
WebsUpload *up;
|
|||
|
char *upfile;
|
|||
|
|
|||
|
websSetStatus(wp, 200);
|
|||
|
websWriteHeaders(wp, -1, 0);
|
|||
|
websWriteHeader(wp, "Content-Type", "text/plain");
|
|||
|
websWriteEndHeaders(wp);
|
|||
|
if (scaselessmatch(wp->method, "POST")) {
|
|||
|
for (s = hashFirst(wp->files); s; s = hashNext(wp->files, s)) {
|
|||
|
up = s->content.value.symbol;
|
|||
|
websWrite(wp, "FILE: %s\r\n", s->name.value.string);
|
|||
|
websWrite(wp, "FILENAME=%s\r\n", up->filename);
|
|||
|
websWrite(wp, "CLIENT=%s\r\n", up->clientFilename);
|
|||
|
websWrite(wp, "TYPE=%s\r\n", up->contentType);
|
|||
|
websWrite(wp, "SIZE=%d\r\n", up->size);
|
|||
|
upfile = sfmt("%s/tmp/%s", websGetDocuments(), up->clientFilename);
|
|||
|
if (rename(up->filename, upfile) < 0) {
|
|||
|
error("Cannot rename uploaded file: %s to %s, errno %d", up->filename, upfile, errno);
|
|||
|
}
|
|||
|
wfree(upfile);
|
|||
|
}
|
|||
|
websWrite(wp, "\r\nVARS:\r\n");
|
|||
|
for (s = hashFirst(wp->vars); s; s = hashNext(wp->vars, s)) {
|
|||
|
websWrite(wp, "%s=%s\r\n", s->name.value.string, s->content.value.string);
|
|||
|
}
|
|||
|
}
|
|||
|
websDone(wp);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
#if ME_GOAHEAD_LEGACY
|
|||
|
/*
|
|||
|
Legacy handler with old parameter sequence
|
|||
|
*/
|
|||
|
static int legacyTest(Webs *wp, char *prefix, char *dir, int flags)
|
|||
|
{
|
|||
|
websSetStatus(wp, 200);
|
|||
|
websWriteHeaders(wp, -1, 0);
|
|||
|
websWriteHeader(wp, "Content-Type", "text/plain");
|
|||
|
websWriteEndHeaders(wp);
|
|||
|
websWrite(wp, "Hello Legacy World\n");
|
|||
|
websDone(wp);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#if WINDOWS
|
|||
|
/*
|
|||
|
Create a taskbar entry. Register the window class and create a window
|
|||
|
*/
|
|||
|
static int windowsInit()
|
|||
|
{
|
|||
|
HINSTANCE inst;
|
|||
|
WNDCLASS wc; /* Window class */
|
|||
|
HMENU hSysMenu;
|
|||
|
HWND hwnd;
|
|||
|
|
|||
|
inst = websGetInst();
|
|||
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|||
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
|||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|||
|
wc.cbClsExtra = 0;
|
|||
|
wc.cbWndExtra = 0;
|
|||
|
wc.hInstance = inst;
|
|||
|
wc.hIcon = NULL;
|
|||
|
wc.lpfnWndProc = (WNDPROC) websWindProc;
|
|||
|
wc.lpszMenuName = wc.lpszClassName = ME_NAME;
|
|||
|
if (! RegisterClass(&wc)) {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
/*
|
|||
|
Create a window just so we can have a taskbar to close this web server
|
|||
|
*/
|
|||
|
hwnd = CreateWindow(ME_NAME, ME_TITLE, WS_MINIMIZE | WS_POPUPWINDOW, CW_USEDEFAULT,
|
|||
|
0, 0, 0, NULL, NULL, inst, NULL);
|
|||
|
if (hwnd == NULL) {
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
Add the about box menu item to the system menu
|
|||
|
*/
|
|||
|
hSysMenu = GetSystemMenu(hwnd, FALSE);
|
|||
|
if (hSysMenu != NULL) {
|
|||
|
AppendMenu(hSysMenu, MF_SEPARATOR, 0, NULL);
|
|||
|
}
|
|||
|
ShowWindow(hwnd, SW_SHOWNORMAL);
|
|||
|
UpdateWindow(hwnd);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void windowsClose()
|
|||
|
{
|
|||
|
HINSTANCE inst;
|
|||
|
|
|||
|
inst = websGetInst();
|
|||
|
UnregisterClass(ME_NAME, inst);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Main menu window message handler.
|
|||
|
*/
|
|||
|
static LRESULT CALLBACK websWindProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp)
|
|||
|
{
|
|||
|
switch (msg) {
|
|||
|
case WM_DESTROY:
|
|||
|
PostQuitMessage(0);
|
|||
|
finished++;
|
|||
|
return 0;
|
|||
|
|
|||
|
case WM_SYSCOMMAND:
|
|||
|
break;
|
|||
|
}
|
|||
|
return DefWindowProc(hwnd, msg, wp, lp);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Check for Windows Messages
|
|||
|
*/
|
|||
|
WPARAM checkWindowsMsgLoop()
|
|||
|
{
|
|||
|
MSG msg;
|
|||
|
|
|||
|
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
|||
|
if (!GetMessage(&msg, NULL, 0, 0) || msg.message == WM_QUIT) {
|
|||
|
return msg.wParam;
|
|||
|
}
|
|||
|
TranslateMessage(&msg);
|
|||
|
DispatchMessage(&msg);
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Windows message handler
|
|||
|
*/
|
|||
|
static LRESULT CALLBACK websAboutProc(HWND hwndDlg, uint msg, uint wp, long lp)
|
|||
|
{
|
|||
|
LRESULT lResult;
|
|||
|
|
|||
|
lResult = DefWindowProc(hwndDlg, msg, wp, lp);
|
|||
|
|
|||
|
switch (msg) {
|
|||
|
case WM_CREATE:
|
|||
|
break;
|
|||
|
case WM_DESTROY:
|
|||
|
break;
|
|||
|
case WM_COMMAND:
|
|||
|
break;
|
|||
|
}
|
|||
|
return lResult;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
/*
|
|||
|
Copyright (c) Embedthis Software. All Rights Reserved.
|
|||
|
This software is distributed under commercial and open source licenses.
|
|||
|
You may use the Embedthis GoAhead open source license or you may acquire
|
|||
|
a commercial license from Embedthis Software. You agree to be fully bound
|
|||
|
by the terms of either license. Consult the LICENSE.md distributed with
|
|||
|
this software for full details and other copyrights.
|
|||
|
*/
|