4 | 6 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,49 @@ |
1 |
+#!/bin/sh |
|
2 |
+rm -f gen_res.c gen_res.h |
|
3 |
+cat >> gen_res.c <<'EoF' |
|
4 |
+/* DO NOT EDIT. Automatically generated file. */ |
|
5 |
+typedef struct resindex { char *name; unsigned char *data; int len; } resindex; |
|
6 |
+EoF |
|
7 |
+cp gen_res.c gen_res.h |
|
8 |
+cat >> gen_res.h <<'EoF' |
|
9 |
+extern resindex *resindexdata; |
|
10 |
+resindex *res_find(resindex *index, char *name); |
|
11 |
+EoF |
|
12 |
+cat >> gen_res.c <<'EoF' |
|
13 |
+#include <string.h> |
|
14 |
+EoF |
|
15 |
+# generate the contents |
|
16 |
+ls -1 | grep -v "^gen.sh\$\|^gen_res.c\$\|^gen_res.h\$" | while read f ; do |
|
17 |
+ name=`echo $f | tr -c "a-zA-Z0-9" "_" | sed "s/^\([0-9]\)/_\1/g"` |
|
18 |
+ echo "static unsigned char $name[]={\"\\" >> gen_res.c |
|
19 |
+ cat $f | hexdump -v -e '"\\""x" 1/1 "%02X"' | sed "s/\(....................................................................\)/\1#@/g" | tr '#@' '\\ |
|
20 |
+' >> gen_res.c |
|
21 |
+ echo '"};' >> gen_res.c |
|
22 |
+done |
|
23 |
+# generate the listing |
|
24 |
+( |
|
25 |
+echo "" |
|
26 |
+echo "static resindex resindexstaticdata[]={" |
|
27 |
+ls -1 | grep -v "^gen.sh\$\|^gen_res.c\$\|^gen_res.h\$" | while read f ; do |
|
28 |
+ name=`echo $f | tr -c "a-zA-Z0-9" "_" | sed "s/^\([0-9]\)/_\1/g"` |
|
29 |
+ echo "{\"$f\",$name,`wc -c $f | cut -d ' ' -f 1`}," |
|
30 |
+done |
|
31 |
+echo "{NULL,NULL,0}};" |
|
32 |
+) >> gen_res.c |
|
33 |
+echo "resindex *resindexdata=resindexstaticdata;" >> gen_res.c |
|
34 |
+cat >>gen_res.c <<'EoF' |
|
35 |
+resindex * |
|
36 |
+res_find(resindex *index, char *name) |
|
37 |
+{ |
|
38 |
+ int i; |
|
39 |
+ if(index==NULL || name==NULL) |
|
40 |
+ return(NULL); |
|
41 |
+ for(i=0;index[i].name!=NULL;i++) { |
|
42 |
+ if(strcmp(index[i].name,name)==0) |
|
43 |
+ return(index+i); |
|
44 |
+ } |
|
45 |
+ return(NULL); |
|
46 |
+} |
|
47 |
+EoF |
|
48 |
+ |
|
49 |
+exit 0 |
0 | 50 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,15 @@ |
1 |
+<!DOCTYPE html> |
|
2 |
+<html> |
|
3 |
+<head><title>kakumei login</title> |
|
4 |
+ <link rel="stylesheet" type="text/css" href="style.css"> |
|
5 |
+</head> |
|
6 |
+<body> |
|
7 |
+ <div class="centered"> |
|
8 |
+ <p class='title'>Acceso restringido</p> |
|
9 |
+ <p><span class='label'>Usuario</span> <input class='rounded' id='user' type ='input' value=''/></p> |
|
10 |
+ <p><span class='label'>Clave</span> <input class='rounded' id='pass' type ='password' value=''/></p> |
|
11 |
+ <span class='centeredbutton'><input class='rounded' id='dologin' type ='button' value='Acceder'/></span> |
|
12 |
+ </div> |
|
13 |
+ <script src='script.js'></script> |
|
14 |
+</body> |
|
15 |
+</html> |
0 | 16 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,25 @@ |
1 |
+(function () { |
|
2 |
+"use strict"; |
|
3 |
+ |
|
4 |
+function request(querytext, func, errorfunc) { |
|
5 |
+ var req = new XMLHttpRequest(); |
|
6 |
+ req.onreadystatechange = function() { |
|
7 |
+ if (req.readyState !== 4) { |
|
8 |
+ return; |
|
9 |
+ } |
|
10 |
+ if (req.status !== 200) { |
|
11 |
+ errorfunc(); |
|
12 |
+ return; |
|
13 |
+ } |
|
14 |
+ func(req.responseText); |
|
15 |
+ }; |
|
16 |
+ req.open("GET",querytext); |
|
17 |
+ req.send(); |
|
18 |
+} |
|
19 |
+ |
|
20 |
+dologin.onclick = function(e) { |
|
21 |
+ request("/doLogin?u="+encodeURIComponent(user.value)+"&p="+encodeURIComponent(pass.value),function(r) { |
|
22 |
+ newpage(r);},function() {}); |
|
23 |
+}; |
|
24 |
+ |
|
25 |
+}()); |
0 | 26 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,49 @@ |
1 |
+body { |
|
2 |
+ font-family: Sans; |
|
3 |
+ color: #8080a5; |
|
4 |
+ padding: 80px 0px 0px 0px; |
|
5 |
+} |
|
6 |
+ |
|
7 |
+input.rounded { |
|
8 |
+ border: 1px solid #ccc; |
|
9 |
+ -moz-border-radius: 10px; |
|
10 |
+ -webkit-border-radius: 10px; |
|
11 |
+ border-radius: 10px; |
|
12 |
+ -moz-box-shadow: 2px 2px 3px #666; |
|
13 |
+ -webkit-box-shadow: 2px 2px 3px #666; |
|
14 |
+ box-shadow: 2px 2px 3px #666; |
|
15 |
+ font-size: 20px; |
|
16 |
+ padding: 4px 7px; |
|
17 |
+ outline: 0; |
|
18 |
+ -webkit-appearance: none; |
|
19 |
+} |
|
20 |
+input.rounded:focus { |
|
21 |
+ border-color: #339933; |
|
22 |
+} |
|
23 |
+div.centered { |
|
24 |
+ background-color: #cede91; |
|
25 |
+ border: 1px solid #ccc; |
|
26 |
+ -moz-border-radius: 20px; |
|
27 |
+ -webkit-border-radius: 20px; |
|
28 |
+ border-radius: 20px; |
|
29 |
+ -moz-box-shadow: 2px 2px 3px #666; |
|
30 |
+ -webkit-box-shadow: 2px 2px 3px #666; |
|
31 |
+ box-shadow: 2px 2px 3px #666; |
|
32 |
+ font-size: 20px; |
|
33 |
+ padding: 16px 24px; |
|
34 |
+ outline: 0; |
|
35 |
+ -webkit-appearance: none; |
|
36 |
+} |
|
37 |
+ |
|
38 |
+div.centered { |
|
39 |
+ text-align: center; |
|
40 |
+ width: 450px; |
|
41 |
+ margin-left: auto; |
|
42 |
+ margin-right: auto; |
|
43 |
+} |
|
44 |
+ |
|
45 |
+p.title { |
|
46 |
+ font-size: 28px; |
|
47 |
+ padding: 0px 0px 20px 0px; |
|
48 |
+} |
|
49 |
+ |
... | ... |
@@ -1,19 +1,25 @@ |
1 | 1 |
WEBKERNEL=../../webkernel/src |
2 | 2 |
CC=gcc |
3 |
-CFLAGS=-g -Wall -I$(WEBKERNEL) |
|
3 |
+CFLAGS=-g -Wall -I$(WEBKERNEL) -I../res |
|
4 | 4 |
LDFLAGS= |
5 | 5 |
|
6 | 6 |
all: kakumei |
7 | 7 |
|
8 | 8 |
clean: |
9 |
- rm -f *.o kakumei |
|
9 |
+ rm -f *.o kakumei ../res/gen_res.[ch] |
|
10 | 10 |
|
11 | 11 |
kakumei: kakumei.o loglib.o parselib.o sbuf.o \ |
12 |
- socklib.o webkernel.o |
|
12 |
+ socklib.o webkernel.o gen_res.o |
|
13 | 13 |
$(CC) $(LDFLAGS) kakumei.o loglib.o parselib.o sbuf.o \ |
14 |
- socklib.o webkernel.o -o kakumei |
|
14 |
+ socklib.o webkernel.o gen_res.o -o kakumei |
|
15 | 15 |
|
16 |
-kakumei.o: kakumei.c |
|
16 |
+kakumei.o: kakumei.c ../src/gen_res.c |
|
17 |
+ |
|
18 |
+../src/gen_res.c: ../res/index.html ../res/script.js ../res/style.css |
|
19 |
+ ( cd ../res && ./gen.sh ) |
|
20 |
+ |
|
21 |
+gen_res.o: ../src/gen_res.c |
|
22 |
+ $(CC) $(CFLAGS) -c ../res/gen_res.c -o gen_res.o |
|
17 | 23 |
|
18 | 24 |
loglib.o: $(WEBKERNEL)/loglib.c |
19 | 25 |
$(CC) $(CFLAGS) -c $(WEBKERNEL)/loglib.c -o loglib.o |
... | ... |
@@ -7,8 +7,95 @@ |
7 | 7 |
* This progran is licensed under the terms of the Affero GPL v1+ |
8 | 8 |
*/ |
9 | 9 |
|
10 |
+#include <stdio.h> |
|
11 |
+#include <stdlib.h> |
|
12 |
+#include <unistd.h> |
|
13 |
+#include <string.h> |
|
14 |
+#include <signal.h> |
|
15 |
+#include "gen_res.h" |
|
16 |
+#include "socklib.h" |
|
17 |
+#include "webkernel.h" |
|
18 |
+ |
|
19 |
+typedef struct kakumei { |
|
20 |
+ sselect *ssel; |
|
21 |
+ wk *web; |
|
22 |
+} kakumei; |
|
23 |
+ |
|
24 |
+ |
|
25 |
+static int signal_init(int signum, void (*fn)(int)); |
|
26 |
+static void sigint(int signum); |
|
27 |
+volatile int sigint_flag=0; |
|
28 |
+ |
|
29 |
+wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
|
30 |
+ |
|
10 | 31 |
int |
11 | 32 |
main(int argc, char *argv[]) |
12 | 33 |
{ |
34 |
+ int port; |
|
35 |
+ int timeout=500; |
|
36 |
+ kakumei *ka,kastore; |
|
37 |
+ memset(&kastore,0,sizeof(kastore)); |
|
38 |
+ ka=&kastore; |
|
39 |
+ if(argc!=2) { |
|
40 |
+ printf("Syntax: %s port\n",argv[0]); |
|
41 |
+ return(1); |
|
42 |
+ } |
|
43 |
+ port=atoi(argv[1]); |
|
44 |
+ if((ka->ssel=sselect_init())==NULL) { |
|
45 |
+ fprintf(stderr,"ERROR: insufficient memory\n"); |
|
46 |
+ return(1); |
|
47 |
+ } |
|
48 |
+ if((ka->web=wk_init(port,ka->ssel,NULL,callback_http,NULL,ka))==NULL) { |
|
49 |
+ sselect_free(ka->ssel),ka->ssel=NULL; |
|
50 |
+ fprintf(stderr,"ERROR: couldn't init web server\n"); |
|
51 |
+ return(2); |
|
52 |
+ } |
|
53 |
+ sigint_flag=0; |
|
54 |
+ signal_init(SIGINT,sigint); |
|
55 |
+ while(!sigint_flag) { |
|
56 |
+ sselect_wait(ka->ssel,timeout); |
|
57 |
+ wk_service(ka->web); |
|
58 |
+ } |
|
59 |
+ wk_free(ka->web),ka->web=NULL; |
|
60 |
+ sselect_free(ka->ssel),ka->ssel=NULL; |
|
13 | 61 |
return(0); |
14 | 62 |
} |
63 |
+ |
|
64 |
+wk_action |
|
65 |
+callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
|
66 |
+{ |
|
67 |
+ kakumei *ka=(kakumei *)userptr; |
|
68 |
+ resindex *res; |
|
69 |
+ if(ka==NULL) |
|
70 |
+ return(wkact_finished); |
|
71 |
+ if((strcmp(uri->path,"/")==0 && (res=res_find(resindexdata,"index.html"))!=NULL) || |
|
72 |
+ (uri->path[0]=='/' && (res=res_find(resindexdata,uri->path+1))!=NULL)) { |
|
73 |
+ wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
74 |
+ return(wkact_finished); |
|
75 |
+ } |
|
76 |
+ if(memcmp(uri->path,"/doLogin?",9)==0) { |
|
77 |
+ printf("Login: %s\n",uri->path+9); |
|
78 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
79 |
+ return(wkact_finished); |
|
80 |
+ } |
|
81 |
+ printf("URI not found: %s\n",uri->path); |
|
82 |
+ wk_serve_error(web,connid,wkerr_notfound); |
|
83 |
+ return(wkact_finished); |
|
84 |
+} |
|
85 |
+ |
|
86 |
+static int |
|
87 |
+signal_init(int signum, void (*fn)(int)) |
|
88 |
+{ |
|
89 |
+ struct sigaction sa; |
|
90 |
+ sa.sa_handler=fn; |
|
91 |
+ sigemptyset(&sa.sa_mask); |
|
92 |
+ sa.sa_flags=0; |
|
93 |
+ return(sigaction(signum,&sa,0)); |
|
94 |
+} |
|
95 |
+ |
|
96 |
+static void |
|
97 |
+sigint(int signum) |
|
98 |
+{ |
|
99 |
+ sigint_flag=1; |
|
100 |
+} |
|
101 |
+ |