17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include "httpd.h"
5*80ee5cbfSDavid du Colombier #include "httpsrv.h"
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier typedef struct Point Point;
87dd7cddfSDavid du Colombier typedef struct OkPoint OkPoint;
97dd7cddfSDavid du Colombier typedef struct Strings Strings;
107dd7cddfSDavid du Colombier
117dd7cddfSDavid du Colombier struct Point
127dd7cddfSDavid du Colombier {
137dd7cddfSDavid du Colombier int x;
147dd7cddfSDavid du Colombier int y;
157dd7cddfSDavid du Colombier };
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier struct OkPoint
187dd7cddfSDavid du Colombier {
197dd7cddfSDavid du Colombier Point p;
207dd7cddfSDavid du Colombier int ok;
217dd7cddfSDavid du Colombier };
227dd7cddfSDavid du Colombier
237dd7cddfSDavid du Colombier struct Strings
247dd7cddfSDavid du Colombier {
257dd7cddfSDavid du Colombier char *s1;
267dd7cddfSDavid du Colombier char *s2;
277dd7cddfSDavid du Colombier };
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier static char *me;
307dd7cddfSDavid du Colombier
317dd7cddfSDavid du Colombier int polytest(int, Point, Point, Point);
327dd7cddfSDavid du Colombier Strings getfield(char*);
337dd7cddfSDavid du Colombier OkPoint pt(char*);
34*80ee5cbfSDavid du Colombier char* translate(HConnect*, char*, char*);
357dd7cddfSDavid du Colombier Point sub(Point, Point);
367dd7cddfSDavid du Colombier float dist(Point, Point);
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier void
main(int argc,char ** argv)397dd7cddfSDavid du Colombier main(int argc, char **argv)
407dd7cddfSDavid du Colombier {
41*80ee5cbfSDavid du Colombier HConnect *c;
427dd7cddfSDavid du Colombier Hio *hout;
437dd7cddfSDavid du Colombier char *dest;
447dd7cddfSDavid du Colombier
457dd7cddfSDavid du Colombier me = "imagemap";
467dd7cddfSDavid du Colombier c = init(argc, argv);
477dd7cddfSDavid du Colombier hout = &c->hout;
48*80ee5cbfSDavid du Colombier if(hparseheaders(c, HSTIMEOUT) < 0)
49*80ee5cbfSDavid du Colombier exits("failed");
507dd7cddfSDavid du Colombier anonymous(c);
517dd7cddfSDavid du Colombier
52*80ee5cbfSDavid du Colombier if(strcmp(c->req.meth, "GET") != 0 && strcmp(c->req.meth, "HEAD") != 0){
53*80ee5cbfSDavid du Colombier hunallowed(c, "GET, HEAD");
54*80ee5cbfSDavid du Colombier exits("unallowed");
55*80ee5cbfSDavid du Colombier }
56*80ee5cbfSDavid du Colombier if(c->head.expectother || c->head.expectcont){
57*80ee5cbfSDavid du Colombier hfail(c, HExpectFail, nil);
58*80ee5cbfSDavid du Colombier exits("failed");
59*80ee5cbfSDavid du Colombier }
607dd7cddfSDavid du Colombier dest = translate(c, c->req.uri, c->req.search);
617dd7cddfSDavid du Colombier
627dd7cddfSDavid du Colombier if(dest == nil){
637dd7cddfSDavid du Colombier if(c->req.vermaj){
64*80ee5cbfSDavid du Colombier hokheaders(c);
657dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\r\n");
667dd7cddfSDavid du Colombier hprint(hout, "\r\n");
677dd7cddfSDavid du Colombier }
687dd7cddfSDavid du Colombier hprint(hout, "<head><title>Nothing Found</title></head><body>\n");
697dd7cddfSDavid du Colombier hprint(hout, "Nothing satisfying your search request could be found.\n</body>\n");
7014414594SDavid du Colombier hflush(hout);
7114414594SDavid du Colombier writelog(c, "Reply: 200 imagemap %ld %ld\n", hout->seek, hout->seek);
727dd7cddfSDavid du Colombier exits(nil);
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier if(http11(c) && strcmp(c->req.meth, "POST") == 0)
76*80ee5cbfSDavid du Colombier hredirected(c, "303 See Other", dest);
777dd7cddfSDavid du Colombier else
78*80ee5cbfSDavid du Colombier hredirected(c, "302 Found", dest);
797dd7cddfSDavid du Colombier exits(nil);
807dd7cddfSDavid du Colombier }
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier char*
translate(HConnect * c,char * uri,char * search)83*80ee5cbfSDavid du Colombier translate(HConnect *c, char *uri, char *search)
847dd7cddfSDavid du Colombier {
857dd7cddfSDavid du Colombier Biobuf *b;
867dd7cddfSDavid du Colombier Strings ss;
877dd7cddfSDavid du Colombier OkPoint okp;
887dd7cddfSDavid du Colombier Point p, cen, q, start;
897dd7cddfSDavid du Colombier float close, d;
907dd7cddfSDavid du Colombier char *line, *to, *def, *s, *dst;
917dd7cddfSDavid du Colombier int n, inside, r, ncsa;
927dd7cddfSDavid du Colombier
93*80ee5cbfSDavid du Colombier if(search == nil){
94*80ee5cbfSDavid du Colombier hfail(c, HNoData, me);
95*80ee5cbfSDavid du Colombier exits("failed");
96*80ee5cbfSDavid du Colombier }
977dd7cddfSDavid du Colombier okp = pt(search);
98*80ee5cbfSDavid du Colombier if(!okp.ok){
99*80ee5cbfSDavid du Colombier hfail(c, HBadSearch, me);
100*80ee5cbfSDavid du Colombier exits("failed");
101*80ee5cbfSDavid du Colombier }
1027dd7cddfSDavid du Colombier p = okp.p;
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier b = Bopen(uri, OREAD);
105*80ee5cbfSDavid du Colombier if(b == nil){
106*80ee5cbfSDavid du Colombier hfail(c, HNotFound, uri);
107*80ee5cbfSDavid du Colombier exits("failed");
108*80ee5cbfSDavid du Colombier }
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier to = nil;
1117dd7cddfSDavid du Colombier def = nil;
1127dd7cddfSDavid du Colombier dst = nil;
1137dd7cddfSDavid du Colombier close = 0.;
1147dd7cddfSDavid du Colombier ncsa = 1;
1157dd7cddfSDavid du Colombier while(line = Brdline(b, '\n')){
1167dd7cddfSDavid du Colombier line[Blinelen(b)-1] = 0;
1177dd7cddfSDavid du Colombier
1187dd7cddfSDavid du Colombier ss = getfield(line);
1197dd7cddfSDavid du Colombier s = ss.s1;
1207dd7cddfSDavid du Colombier line = ss.s2;
1217dd7cddfSDavid du Colombier if(ncsa){
1227dd7cddfSDavid du Colombier ss = getfield(line);
1237dd7cddfSDavid du Colombier dst = ss.s1;
1247dd7cddfSDavid du Colombier line = ss.s2;
1257dd7cddfSDavid du Colombier }
1267dd7cddfSDavid du Colombier if(strcmp(s, "#cern") == 0){
1277dd7cddfSDavid du Colombier ncsa = 0;
1287dd7cddfSDavid du Colombier continue;
1297dd7cddfSDavid du Colombier }
1307dd7cddfSDavid du Colombier if(strcmp(s, "rect") == 0){
1317dd7cddfSDavid du Colombier ss = getfield(line);
1327dd7cddfSDavid du Colombier s = ss.s1;
1337dd7cddfSDavid du Colombier line = ss.s2;
1347dd7cddfSDavid du Colombier okp = pt(s);
1357dd7cddfSDavid du Colombier q = okp.p;
1367dd7cddfSDavid du Colombier if(!okp.ok || q.x > p.x || q.y > p.y)
1377dd7cddfSDavid du Colombier continue;
1387dd7cddfSDavid du Colombier ss = getfield(line);
1397dd7cddfSDavid du Colombier s = ss.s1;
1407dd7cddfSDavid du Colombier line = ss.s2;
1417dd7cddfSDavid du Colombier okp = pt(s);
1427dd7cddfSDavid du Colombier q = okp.p;
1437dd7cddfSDavid du Colombier if(!okp.ok || q.x < p.x || q.y < p.y)
1447dd7cddfSDavid du Colombier continue;
1457dd7cddfSDavid du Colombier if(!ncsa){
1467dd7cddfSDavid du Colombier ss = getfield(line);
1477dd7cddfSDavid du Colombier dst = ss.s1;
1487dd7cddfSDavid du Colombier }
1497dd7cddfSDavid du Colombier return dst;
1507dd7cddfSDavid du Colombier }else if(strcmp(s, "circle") == 0){
1517dd7cddfSDavid du Colombier ss = getfield(line);
1527dd7cddfSDavid du Colombier s = ss.s1;
1537dd7cddfSDavid du Colombier line = ss.s2;
1547dd7cddfSDavid du Colombier okp = pt(s);
1557dd7cddfSDavid du Colombier cen = okp.p;
1567dd7cddfSDavid du Colombier if(!okp.ok)
1577dd7cddfSDavid du Colombier continue;
1587dd7cddfSDavid du Colombier ss = getfield(line);
1597dd7cddfSDavid du Colombier s = ss.s1;
1607dd7cddfSDavid du Colombier line = ss.s2;
1617dd7cddfSDavid du Colombier if(ncsa){
1627dd7cddfSDavid du Colombier okp = pt(s);
1637dd7cddfSDavid du Colombier if(!okp.ok)
1647dd7cddfSDavid du Colombier continue;
1657dd7cddfSDavid du Colombier if(dist(okp.p, cen) >= dist(p, cen))
1667dd7cddfSDavid du Colombier return dst;
1677dd7cddfSDavid du Colombier }else{
1687dd7cddfSDavid du Colombier r = strtol(s, nil, 10);
1697dd7cddfSDavid du Colombier ss = getfield(line);
1707dd7cddfSDavid du Colombier dst = ss.s1;
1717dd7cddfSDavid du Colombier d = (float)r * r;
1727dd7cddfSDavid du Colombier if(d >= dist(p, cen))
1737dd7cddfSDavid du Colombier return dst;
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier }else if(strcmp(s, "poly") == 0){
1767dd7cddfSDavid du Colombier ss = getfield(line);
1777dd7cddfSDavid du Colombier s = ss.s1;
1787dd7cddfSDavid du Colombier line = ss.s2;
1797dd7cddfSDavid du Colombier okp = pt(s);
1807dd7cddfSDavid du Colombier start = okp.p;
1817dd7cddfSDavid du Colombier if(!okp.ok)
1827dd7cddfSDavid du Colombier continue;
1837dd7cddfSDavid du Colombier inside = 0;
1847dd7cddfSDavid du Colombier cen = start;
1857dd7cddfSDavid du Colombier for(n = 1; ; n++){
1867dd7cddfSDavid du Colombier ss = getfield(line);
1877dd7cddfSDavid du Colombier s = ss.s1;
1887dd7cddfSDavid du Colombier line = ss.s2;
1897dd7cddfSDavid du Colombier okp = pt(s);
1907dd7cddfSDavid du Colombier q = okp.p;
1917dd7cddfSDavid du Colombier if(!okp.ok)
1927dd7cddfSDavid du Colombier break;
1937dd7cddfSDavid du Colombier inside = polytest(inside, p, cen, q);
1947dd7cddfSDavid du Colombier cen = q;
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier inside = polytest(inside, p, cen, start);
1977dd7cddfSDavid du Colombier if(!ncsa)
1987dd7cddfSDavid du Colombier dst = s;
1997dd7cddfSDavid du Colombier if(n >= 3 && inside)
2007dd7cddfSDavid du Colombier return dst;
2017dd7cddfSDavid du Colombier }else if(strcmp(s, "point") == 0){
2027dd7cddfSDavid du Colombier ss = getfield(line);
2037dd7cddfSDavid du Colombier s = ss.s1;
2047dd7cddfSDavid du Colombier line = ss.s2;
2057dd7cddfSDavid du Colombier okp = pt(s);
2067dd7cddfSDavid du Colombier q = okp.p;
2077dd7cddfSDavid du Colombier if(!okp.ok)
2087dd7cddfSDavid du Colombier continue;
2097dd7cddfSDavid du Colombier d = dist(p, q);
2107dd7cddfSDavid du Colombier if(!ncsa){
2117dd7cddfSDavid du Colombier ss = getfield(line);
2127dd7cddfSDavid du Colombier dst = ss.s1;
2137dd7cddfSDavid du Colombier }
2147dd7cddfSDavid du Colombier if(d == 0.)
2157dd7cddfSDavid du Colombier return dst;
2167dd7cddfSDavid du Colombier if(close == 0. || d < close){
2177dd7cddfSDavid du Colombier close = d;
2187dd7cddfSDavid du Colombier to = dst;
2197dd7cddfSDavid du Colombier }
2207dd7cddfSDavid du Colombier }else if(strcmp(s, "default") == 0){
2217dd7cddfSDavid du Colombier if(!ncsa){
2227dd7cddfSDavid du Colombier ss = getfield(line);
2237dd7cddfSDavid du Colombier dst = ss.s1;
2247dd7cddfSDavid du Colombier }
2257dd7cddfSDavid du Colombier def = dst;
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier }
2287dd7cddfSDavid du Colombier if(to == nil)
2297dd7cddfSDavid du Colombier to = def;
2307dd7cddfSDavid du Colombier return to;
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier int
polytest(int inside,Point p,Point b,Point a)2347dd7cddfSDavid du Colombier polytest(int inside, Point p, Point b, Point a)
2357dd7cddfSDavid du Colombier {
2367dd7cddfSDavid du Colombier Point pa, ba;
2377dd7cddfSDavid du Colombier
2387dd7cddfSDavid du Colombier if(b.y>a.y){
2397dd7cddfSDavid du Colombier pa=sub(p, a);
2407dd7cddfSDavid du Colombier ba=sub(b, a);
2417dd7cddfSDavid du Colombier }else{
2427dd7cddfSDavid du Colombier pa=sub(p, b);
2437dd7cddfSDavid du Colombier ba=sub(a, b);
2447dd7cddfSDavid du Colombier }
2457dd7cddfSDavid du Colombier if(0<=pa.y && pa.y<ba.y && pa.y*ba.x<=pa.x*ba.y)
2467dd7cddfSDavid du Colombier inside = !inside;
2477dd7cddfSDavid du Colombier return inside;
2487dd7cddfSDavid du Colombier }
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier Point
sub(Point p,Point q)2517dd7cddfSDavid du Colombier sub(Point p, Point q)
2527dd7cddfSDavid du Colombier {
2537dd7cddfSDavid du Colombier p.x -= q.x;
2547dd7cddfSDavid du Colombier p.y -= q.y;
2557dd7cddfSDavid du Colombier return p;
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier
2587dd7cddfSDavid du Colombier float
dist(Point p,Point q)2597dd7cddfSDavid du Colombier dist(Point p, Point q)
2607dd7cddfSDavid du Colombier {
2617dd7cddfSDavid du Colombier p.x -= q.x;
2627dd7cddfSDavid du Colombier p.y -= q.y;
2637dd7cddfSDavid du Colombier return (float)p.x * p.x + (float)p.y * p.y;
2647dd7cddfSDavid du Colombier }
2657dd7cddfSDavid du Colombier
2667dd7cddfSDavid du Colombier OkPoint
pt(char * s)2677dd7cddfSDavid du Colombier pt(char *s)
2687dd7cddfSDavid du Colombier {
2697dd7cddfSDavid du Colombier OkPoint okp;
2707dd7cddfSDavid du Colombier Point p;
2717dd7cddfSDavid du Colombier char *t, *e;
2727dd7cddfSDavid du Colombier
2737dd7cddfSDavid du Colombier if(*s == '(')
2747dd7cddfSDavid du Colombier s++;
2757dd7cddfSDavid du Colombier t = strchr(s, ')');
2767dd7cddfSDavid du Colombier if(t != nil)
2777dd7cddfSDavid du Colombier *t = 0;
2787dd7cddfSDavid du Colombier p.x = 0;
2797dd7cddfSDavid du Colombier p.y = 0;
2807dd7cddfSDavid du Colombier t = strchr(s, ',');
2817dd7cddfSDavid du Colombier if(t == nil){
2827dd7cddfSDavid du Colombier okp.p = p;
2837dd7cddfSDavid du Colombier okp.ok = 0;
2847dd7cddfSDavid du Colombier return okp;
2857dd7cddfSDavid du Colombier }
2867dd7cddfSDavid du Colombier e = nil;
2877dd7cddfSDavid du Colombier p.x = strtol(s, &e, 10);
2887dd7cddfSDavid du Colombier if(e != t){
2897dd7cddfSDavid du Colombier okp.p = p;
2907dd7cddfSDavid du Colombier okp.ok = 0;
2917dd7cddfSDavid du Colombier return okp;
2927dd7cddfSDavid du Colombier }
2937dd7cddfSDavid du Colombier p.y = strtol(t+1, &e, 10);
2947dd7cddfSDavid du Colombier if(e == nil || *e != 0){
2957dd7cddfSDavid du Colombier okp.p = p;
2967dd7cddfSDavid du Colombier okp.ok = 0;
2977dd7cddfSDavid du Colombier return okp;
2987dd7cddfSDavid du Colombier }
2997dd7cddfSDavid du Colombier okp.p = p;
3007dd7cddfSDavid du Colombier okp.ok = 1;
3017dd7cddfSDavid du Colombier return okp;
3027dd7cddfSDavid du Colombier }
3037dd7cddfSDavid du Colombier
3047dd7cddfSDavid du Colombier Strings
getfield(char * s)3057dd7cddfSDavid du Colombier getfield(char *s)
3067dd7cddfSDavid du Colombier {
3077dd7cddfSDavid du Colombier Strings ss;
3087dd7cddfSDavid du Colombier char *f;
3097dd7cddfSDavid du Colombier
3107dd7cddfSDavid du Colombier while(*s == '\t' || *s == ' ')
3117dd7cddfSDavid du Colombier s++;
3127dd7cddfSDavid du Colombier f = s;
3137dd7cddfSDavid du Colombier while(*s && *s != '\t' && *s != ' ')
3147dd7cddfSDavid du Colombier s++;
3157dd7cddfSDavid du Colombier if(*s)
3167dd7cddfSDavid du Colombier *s++ = 0;
3177dd7cddfSDavid du Colombier ss.s1 = f;
3187dd7cddfSDavid du Colombier ss.s2 = s;
3197dd7cddfSDavid du Colombier return ss;
3207dd7cddfSDavid du Colombier }
321