17dd7cddfSDavid du Colombier /* invoked from /netlib/pub/search.html */ 27dd7cddfSDavid du Colombier 37dd7cddfSDavid du Colombier #include <u.h> 47dd7cddfSDavid du Colombier #include <libc.h> 57dd7cddfSDavid du Colombier #include <bio.h> 67dd7cddfSDavid du Colombier #include "httpd.h" 77dd7cddfSDavid du Colombier 87dd7cddfSDavid du Colombier void bib_fmt(char*,char*); 97dd7cddfSDavid du Colombier void index_fmt(char*,char*); 107dd7cddfSDavid du Colombier void no_fmt(char*,char*); 117dd7cddfSDavid du Colombier void send(Connect*); 127dd7cddfSDavid du Colombier 137dd7cddfSDavid du Colombier Hio *hout; 147dd7cddfSDavid du Colombier 157dd7cddfSDavid du Colombier /********** table of databases ************/ 167dd7cddfSDavid du Colombier 177dd7cddfSDavid du Colombier typedef struct DB DB; 187dd7cddfSDavid du Colombier struct DB 197dd7cddfSDavid du Colombier { 207dd7cddfSDavid du Colombier int SELECT; /* value from search.html */ 217dd7cddfSDavid du Colombier char *log; /* abbreviation for logfile */ 227dd7cddfSDavid du Colombier int maxhit; /* maximum number of hits to return */ 237dd7cddfSDavid du Colombier char *file; /* searchfs database */ 247dd7cddfSDavid du Colombier void (*fmt)(char*,char*); /* convert one record to HTML */ 257dd7cddfSDavid du Colombier char *postlude; /* trailer text */ 267dd7cddfSDavid du Colombier }; 277dd7cddfSDavid du Colombier 287dd7cddfSDavid du Colombier DB db[] = 297dd7cddfSDavid du Colombier { 307dd7cddfSDavid du Colombier {0, "netlib", 250, "/srv/netlib_DEFAULT", index_fmt, 317dd7cddfSDavid du Colombier "<HR><A HREF=\"/netlib/master\">browse netlib</A></BODY>\r\n"}, 327dd7cddfSDavid du Colombier {1, "BibNet", 250, "/srv/netlib_bibnet", bib_fmt, 337dd7cddfSDavid du Colombier "<HR><A HREF=\"/netlib/bibnet\">browse BibNet</A></BODY>\r\n"}, 347dd7cddfSDavid du Colombier {2, "compgeom", 250, "/srv/netlib_compgeom", no_fmt, "</BODY>\r\n"}, 357dd7cddfSDavid du Colombier {3, "approx", 250, "/srv/netlib_approximation", no_fmt, 367dd7cddfSDavid du Colombier "<HR><A HREF=\"/netlib/a/catalog.html.gz\">hierarchical catalog</A></BODY>\r\n"}, 377dd7cddfSDavid du Colombier {4, "siam", 50, "/srv/netlib_siam-Secret", no_fmt, "</BODY>\r\n"}, 387dd7cddfSDavid du Colombier {-1,"",0,"",no_fmt,""} 397dd7cddfSDavid du Colombier }; 407dd7cddfSDavid du Colombier 417dd7cddfSDavid du Colombier 427dd7cddfSDavid du Colombier 437dd7cddfSDavid du Colombier /********** reformat database record as HTML ************/ 447dd7cddfSDavid du Colombier 457dd7cddfSDavid du Colombier void /* tr '\015' '\012' ("uncombline") */ 467dd7cddfSDavid du Colombier no_fmt(char*s,char*e) 477dd7cddfSDavid du Colombier { 487dd7cddfSDavid du Colombier /* s = start, e = (one past) end of database record */ 497dd7cddfSDavid du Colombier char *p; 507dd7cddfSDavid du Colombier for(p = s; p<e; p++) 517dd7cddfSDavid du Colombier if(*p=='\r'){ 527dd7cddfSDavid du Colombier hwrite(hout, s,p-s); 537dd7cddfSDavid du Colombier hprint(hout, "\n"); 547dd7cddfSDavid du Colombier s = p+1; 557dd7cddfSDavid du Colombier } 567dd7cddfSDavid du Colombier } 577dd7cddfSDavid du Colombier 587dd7cddfSDavid du Colombier int /* should the filename have .gz appended? */ 597dd7cddfSDavid du Colombier suffix(char*filename) 607dd7cddfSDavid du Colombier { 617dd7cddfSDavid du Colombier int n; 627dd7cddfSDavid du Colombier char *z; 637dd7cddfSDavid du Colombier 647dd7cddfSDavid du Colombier if(!filename || *filename==0) 657dd7cddfSDavid du Colombier return(0); 667dd7cddfSDavid du Colombier n = strlen(filename); 677dd7cddfSDavid du Colombier if(strncmp(".html",filename+n-5,5)==0) 687dd7cddfSDavid du Colombier return(0); 697dd7cddfSDavid du Colombier z = malloc(n+50); 707dd7cddfSDavid du Colombier if(z == nil) 717dd7cddfSDavid du Colombier return(0); 727dd7cddfSDavid du Colombier strcpy(z,"/netlib/pub/"); 737dd7cddfSDavid du Colombier strcat(z,filename); 747dd7cddfSDavid du Colombier strcat(z,".gz"); 757dd7cddfSDavid du Colombier if(access(z,4)==0){ 767dd7cddfSDavid du Colombier free(z); 777dd7cddfSDavid du Colombier return(1); 787dd7cddfSDavid du Colombier } 797dd7cddfSDavid du Colombier free(z); 807dd7cddfSDavid du Colombier return(0); 817dd7cddfSDavid du Colombier } 827dd7cddfSDavid du Colombier 837dd7cddfSDavid du Colombier void /* add HREF to "file:" lines */ 847dd7cddfSDavid du Colombier index_fmt(char*s,char*e) 857dd7cddfSDavid du Colombier { 867dd7cddfSDavid du Colombier char *p, *filename; 877dd7cddfSDavid du Colombier if(strncmp(s,"file",4)==0 && (s[4]==' '||s[4]=='\t')){ 887dd7cddfSDavid du Colombier for(filename = s+4; strchr(" \t",*filename); filename++){} 897dd7cddfSDavid du Colombier for(s = filename; *s && strchr("\r\n",*s)==nil; s++){} 907dd7cddfSDavid du Colombier *s++ = '\0'; 917dd7cddfSDavid du Colombier if(*s=='\n') s++; 927dd7cddfSDavid du Colombier hprint(hout, "file: <A HREF=\"/netlib/%s",filename); 937dd7cddfSDavid du Colombier if(suffix(filename)) 947dd7cddfSDavid du Colombier hprint(hout, ".gz"); 957dd7cddfSDavid du Colombier hprint(hout, "\">%s</A>\r\n",filename); 967dd7cddfSDavid du Colombier for(p = s; p<e; p++) 977dd7cddfSDavid du Colombier if(*p=='\r'){ 987dd7cddfSDavid du Colombier hwrite(hout, s,p-s); 997dd7cddfSDavid du Colombier hprint(hout, "\n"); 1007dd7cddfSDavid du Colombier s = p+1; 1017dd7cddfSDavid du Colombier } 1027dd7cddfSDavid du Colombier }else if(strncmp(s,"lib",3)==0 && (s[3]==' '||s[3]=='\t')){ 1037dd7cddfSDavid du Colombier for(filename = s+3; strchr(" \t",*filename); filename++){} 1047dd7cddfSDavid du Colombier for(s = filename; *s && strchr("\r\n",*s)==nil; s++){} 1057dd7cddfSDavid du Colombier *s++ = '\0'; 1067dd7cddfSDavid du Colombier if(*s=='\n') s++; 1077dd7cddfSDavid du Colombier hprint(hout, "lib: <A HREF=\"/netlib/%s",filename); 1087dd7cddfSDavid du Colombier hprint(hout, "\">%s</A>\r\n",filename); 1097dd7cddfSDavid du Colombier for(p = s; p<e; p++) 1107dd7cddfSDavid du Colombier if(*p=='\r'){ 1117dd7cddfSDavid du Colombier hwrite(hout, s,p-s); 1127dd7cddfSDavid du Colombier hprint(hout, "\n"); 1137dd7cddfSDavid du Colombier s = p+1; 1147dd7cddfSDavid du Colombier } 1157dd7cddfSDavid du Colombier }else{ 1167dd7cddfSDavid du Colombier no_fmt(s,e); 1177dd7cddfSDavid du Colombier } 1187dd7cddfSDavid du Colombier } 1197dd7cddfSDavid du Colombier 1207dd7cddfSDavid du Colombier void /* add HREF to "URL" lines */ 1217dd7cddfSDavid du Colombier bib_fmt(char*s,char*e) 1227dd7cddfSDavid du Colombier { 1237dd7cddfSDavid du Colombier char *p, *filename; 1247dd7cddfSDavid du Colombier for(p = s; p<e; p++) 1257dd7cddfSDavid du Colombier if(*p=='\r'){ 1267dd7cddfSDavid du Colombier hwrite(hout, s,p-s); 1277dd7cddfSDavid du Colombier hprint(hout, "\n"); 1287dd7cddfSDavid du Colombier s = p+1; 1297dd7cddfSDavid du Colombier if(strncmp(s," URL =",6)==0 && 1307dd7cddfSDavid du Colombier (filename = strchr(s+6,'"'))!=nil){ 1317dd7cddfSDavid du Colombier filename++; 1327dd7cddfSDavid du Colombier for(s = filename; *s && strchr("\"\r\n",*s)==nil; s++){} 1337dd7cddfSDavid du Colombier *s++ = '\0'; 1347dd7cddfSDavid du Colombier p = s; 1357dd7cddfSDavid du Colombier hprint(hout, " URL =<A HREF=\"%s\">%s</A>", 1367dd7cddfSDavid du Colombier filename,filename); 1377dd7cddfSDavid du Colombier } 1387dd7cddfSDavid du Colombier } 1397dd7cddfSDavid du Colombier } 1407dd7cddfSDavid du Colombier 1417dd7cddfSDavid du Colombier 1427dd7cddfSDavid du Colombier /********** main() calls httpheadget() calls send() ************/ 1437dd7cddfSDavid du Colombier 1447dd7cddfSDavid du Colombier void 1457dd7cddfSDavid du Colombier main(int argc, char **argv) 1467dd7cddfSDavid du Colombier { 1477dd7cddfSDavid du Colombier Connect *c; 1487dd7cddfSDavid du Colombier 1497dd7cddfSDavid du Colombier c = init(argc, argv); 1507dd7cddfSDavid du Colombier hout = &c->hout; 1517dd7cddfSDavid du Colombier httpheaders(c); 1527dd7cddfSDavid du Colombier send(c); 1537dd7cddfSDavid du Colombier exits(nil); 1547dd7cddfSDavid du Colombier } 1557dd7cddfSDavid du Colombier 1567dd7cddfSDavid du Colombier Biobuf Blist; 1577dd7cddfSDavid du Colombier 1587dd7cddfSDavid du Colombier Biobuf* 1597dd7cddfSDavid du Colombier init800fs(char*name,char*pat) 1607dd7cddfSDavid du Colombier { 1617dd7cddfSDavid du Colombier int fd800fs, n; 1627dd7cddfSDavid du Colombier char*search; 1637dd7cddfSDavid du Colombier 1647dd7cddfSDavid du Colombier fd800fs = open(name, ORDWR); 1657dd7cddfSDavid du Colombier if(fd800fs < 0) 1667dd7cddfSDavid du Colombier exits("can't connect to 800fs server"); 1677dd7cddfSDavid du Colombier if(mount(fd800fs, "/mnt", MREPL, "") < 0) 1687dd7cddfSDavid du Colombier exits("can't mount /mnt"); 1697dd7cddfSDavid du Colombier fd800fs = open("/mnt/search", ORDWR); 1707dd7cddfSDavid du Colombier n = strlen("search=")+strlen(pat)+1; 1717dd7cddfSDavid du Colombier search = ezalloc(n); 1727dd7cddfSDavid du Colombier strcpy(search,"search="); 1737dd7cddfSDavid du Colombier strcat(search,pat); 1747dd7cddfSDavid du Colombier write(fd800fs,search,n); 1757dd7cddfSDavid du Colombier free(search); 1767dd7cddfSDavid du Colombier Binit(&Blist, fd800fs,OREAD); 1777dd7cddfSDavid du Colombier return(&Blist); 1787dd7cddfSDavid du Colombier } 1797dd7cddfSDavid du Colombier 1807dd7cddfSDavid du Colombier 1817dd7cddfSDavid du Colombier void 1827dd7cddfSDavid du Colombier send(Connect *c) 1837dd7cddfSDavid du Colombier { 1847dd7cddfSDavid du Colombier Biobuf*blist; 1857dd7cddfSDavid du Colombier int m, n, dbi, nmatch; 1867dd7cddfSDavid du Colombier char *pat, *s, *e; 1877dd7cddfSDavid du Colombier SPairs *q; 1887dd7cddfSDavid du Colombier 1897dd7cddfSDavid du Colombier if(strcmp(c->req.meth, "GET") != 0 && strcmp(c->req.meth, "HEAD") != 0) 1907dd7cddfSDavid du Colombier unallowed(c, "GET, HEAD"); 1917dd7cddfSDavid du Colombier if(c->head.expectother || c->head.expectcont) 1927dd7cddfSDavid du Colombier fail(c, ExpectFail, nil); 1937dd7cddfSDavid du Colombier if(c->req.search == nil || !*c->req.search) 1947dd7cddfSDavid du Colombier fail(c, NoData, "netlib_find"); 1957dd7cddfSDavid du Colombier s = c->req.search; 1967dd7cddfSDavid du Colombier while((s = strchr(s, '+')) != nil) 1977dd7cddfSDavid du Colombier *s++ = ' '; 1987dd7cddfSDavid du Colombier dbi = -1; 1997dd7cddfSDavid du Colombier pat = nil; 2007dd7cddfSDavid du Colombier for(q = parsequery(hstrdup(c->req.search)); q; q = q->next){ 2017dd7cddfSDavid du Colombier if(strcmp(q->s, "db") == 0){ 2027dd7cddfSDavid du Colombier m = atoi(q->t); 2037dd7cddfSDavid du Colombier for(dbi = 0; m!=db[dbi].SELECT; dbi++) 2047dd7cddfSDavid du Colombier if(db[dbi].SELECT<0) 2057dd7cddfSDavid du Colombier exits("unrecognized db"); 2067dd7cddfSDavid du Colombier }else if(strcmp(q->s, "pat") == 0){ 2077dd7cddfSDavid du Colombier pat = q->t; 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier } 2107dd7cddfSDavid du Colombier if(dbi < 0) 2117dd7cddfSDavid du Colombier exits("missing db field in query"); 2127dd7cddfSDavid du Colombier if(pat == nil) 2137dd7cddfSDavid du Colombier exits("missing pat field in query"); 2147dd7cddfSDavid du Colombier logit(c, "netlib_find %s %s", db[dbi].log,pat); 2157dd7cddfSDavid du Colombier 2167dd7cddfSDavid du Colombier blist = init800fs(db[dbi].file,pat); 2177dd7cddfSDavid du Colombier 2187dd7cddfSDavid du Colombier if(c->req.vermaj){ 2197dd7cddfSDavid du Colombier okheaders(c); 2207dd7cddfSDavid du Colombier hprint(hout, "Content-type: text/html\r\n"); 2217dd7cddfSDavid du Colombier hprint(hout, "\r\n"); 2227dd7cddfSDavid du Colombier } 223*14414594SDavid du Colombier if(strcmp(c->req.meth, "HEAD") == 0){ 224*14414594SDavid du Colombier writelog(c, "Reply: 200 netlib_find 0\n"); 2257dd7cddfSDavid du Colombier exits(nil); 226*14414594SDavid du Colombier } 2277dd7cddfSDavid du Colombier 2287dd7cddfSDavid du Colombier hprint(hout, "<HEAD><TITLE>%s/%s</TITLE></HEAD>\r\n<BODY>\r\n", 2297dd7cddfSDavid du Colombier db[dbi].log,pat); 2307dd7cddfSDavid du Colombier nmatch = 0; 2317dd7cddfSDavid du Colombier 2327dd7cddfSDavid du Colombier while(s = Brdline(blist, '\n')){ /* get next database record */ 2337dd7cddfSDavid du Colombier n = Blinelen(blist); 2347dd7cddfSDavid du Colombier e = s+n; 2357dd7cddfSDavid du Colombier hprint(hout, "<PRE>"); 2367dd7cddfSDavid du Colombier (*db[dbi].fmt)(s,e); 2377dd7cddfSDavid du Colombier hprint(hout, "</PRE>\r\n"); 2387dd7cddfSDavid du Colombier if(nmatch++>=db[dbi].maxhit){ 2397dd7cddfSDavid du Colombier hprint(hout, "<H4>reached limit at %d hits</H4>\n\r",nmatch); 2407dd7cddfSDavid du Colombier break; 2417dd7cddfSDavid du Colombier } 2427dd7cddfSDavid du Colombier } 2437dd7cddfSDavid du Colombier if(nmatch==0) 2447dd7cddfSDavid du Colombier hprint(hout, "<H4>Nothing Found.</H4>\r\n"); 2457dd7cddfSDavid du Colombier hprint(hout, db[dbi].postlude); 246*14414594SDavid du Colombier hflush(hout); 247*14414594SDavid du Colombier writelog(c, "Reply: 200 netlib_find %ld %ld\n", hout->seek, hout->seek); 2487dd7cddfSDavid du Colombier exits(nil); 2497dd7cddfSDavid du Colombier } 250