/* * simple www client for even simpler lookups * does nothing yet, just dump the html source all at once * Hint: I think it's a driver bug. When using victim->more(array); * fro within read_callback or close_callback, it doesn't work. In * any other place it does. What's more : * void bogus() { return 1;} doesn't barf while * void bogus() { return find_player("leto");} does... Boggle. * So, for now, no more. just dump :( * Leto 12/6/95 (Work in progress !!) * Leto 12/7/95 (Still work in progress !!) done: better parsing * Todo: fix the ALT in IMG SRC loop */ // ansi is temp :) #include <ansi.h> #include <mudlib.h> #include <config.h> #include <net/socket.h> #include <socket.h> #include <uid.h> #define HREF "<A HREF" #define HREFC "</A>" static mapping services; static int debug_level; static object www_socket; object victim; // Prototypes :) void create(); int www(string argh); string parse_data(mixed info); void send_packet(string data); //#define SOCKET "/std/socket/socket.c" //#define WWW_SERVER "131.174.8.16 6667" #define WWW_SERVER "127.0.0.1 2217" inherit OBJECT; int read_callback(object socket, mixed info){ if(interactive(environment(this_object()))) { info = explode(replace_string(info, "\r", ""), "\n"); victim = environment(this_object()); /* * the more doesn't work for some reason. The input_to in there * doesn't get called, and i have NO clue whatsoever after 3 hours * of debugging why. For now, i won't use more */ message("network",parse_data(info),victim); //victim->more(explode(parse_data(info),"\n")); // Driver bug prevents this ?? } else { message("network",parse_data(info),environment(this_object())); } return 1; } int close_callback(object socket){ socket->remove(); remove(); // If it doesn't work, use brute force :) if(this_object()) destruct(this_object()); return 1; } void send_packet(string data){ www_socket->send(data); } void process_error(mixed *info){ message("network","WWW Error:"+dump_variable(info),environment(this_object())); } void create(){ // if(!clonep()) return; if(!this_player()) destruct(this_object()); // Leto: tsk tsk tsk Drizzt, remember uids ? :) seteuid(ROOT_UID); // message("network","Initiating www connection.\n",environment(this_object()) ); set("short","A simple www client"); set("long","A very simple www client, featuring Deathblade's socket.c"); set("mass",0); set("bulk",0); set("id", ({ "www","www client","client" }) ); // set("undroppable",1); // ? } void get_page(string url) { string type,site,page; int parsed; parsed = sscanf(url,"%s://%s/%s",type,site,page); if(parsed <1) { message("error",sprintf("invalid URL,attempting http://%s\n",url), environment(this_object()) ); get_page(sprintf("http://%s",url)); // No we won't recurse indefinetly :) return; } if(parsed == 1) // Bozo's didn't gave the trailing '/', must be netscape users { get_page(url+"/"); return; } if(parsed ==2) // No specified page, use index.html page = page+"index.html"; // Now we're ready to handle the request. switch(type) { case("telnet") : { message("error", "Telnet is not supported. Wizards can use the terminal for that.\n", environment(this_object()) ); break; } case("ftp") : { message("error", "Ftp is not supported. Get real !!!\n", environment(this_object()) ); break; } case("gopher") : { message("error", "Gopher is not supported. This is a simple www client!\n", environment(this_object()) ); break; } case("http"): { // check site for ":" if(strsrch(site,":")==-1) site = site + " 80" ; // default port else site = replace_string(site,":"," "); // make it a valid string for // MudOS sockets if(sscanf(site,"%*s.%*s.%*s.%*s %*s")!=5) { message("error", sprintf("Error in site format for %s. Shit, I prob need to resolve the name you gave me, giving up for now.\n",site), environment(this_object()) ); break; } www_socket = clone_object(SOCKET, SKT_STYLE_CONNECT, site, (: read_callback :), (: close_callback :) ); if(!www_socket) { message("error", sprintf("Can't connect to %s.\n",site), environment(this_object()) ); break; } write(sprintf("Conection established, attempting to get %s...\n",page)); send_packet(sprintf("GET /%s HTTP/1.0\n",page)); write("Waiting for answer...\n"); break; } default : { message("error", "Never heard of an URL like that.\n", environment(this_object()) ); break; } } } void init() { add_action("www","www"); // add protection for client being dropped here } void remove(){ if(www_socket) www_socket->remove(); destruct(this_object()); } //int move() { return 1; } // not allowed, for Tmi-2 like muds } int www(string argh) { if(!argh || argh=="") { notify_fail("No url specified.\n"); return 0; } get_page(argh); return 1; // Let the command hook handle whatever it is. } string parse_data(string *info) { string contents,tmp1,tmp2,tmp3, *tmp4; int open,close,done,cols,lines,i,debug; // Parse the bloody html here :) //First implode it all to a big string. if(pointerp(info)) contents = implode(info," "); else return "Bogus type of:"+typeof(contents); //Silently remove <HTML> and </HTML> contents = replace_string(contents,"<HTML>",""); contents = replace_string(contents,"</HTML>",""); rm("tmp/half"); write_file("tmp/half",contents); // Same for everything in HEAD open = strsrch(contents,"<HEAD>"); if(open!=-1) { close = strsrch(contents,"</HEAD>"); if(close==-1) { // No appr. closing tag, eat opentag. write("Missing </HEAD> tag, attempting to fix lousy html...\n"); contents= replace_string(contents,"<HEAD>","\n"); } else contents = contents[0..open-1]+contents[close+strlen("</HEAD>")..] ; } // Same for everything in HEADER (sigh!!) open = strsrch(contents,"<HEADER>"); if(open!=-1) { close = strsrch(contents,"</HEADER>"); if(close==-1) { // No appr. closing tag, eat opentag. write("Missing </HEADER> tag, attempting to fix lousy html...\n"); contents= replace_string(contents,"<HEADER>","\n"); } else contents = contents[0..open-1]+contents[close+strlen("</HEADER>")..] ; } // remove body tags contents = replace_string(contents,"<BODY>","\n"); // People assume we start contents = replace_string(contents,"</BODY>","\n"); // a new line // Try and interpret the CENTER tags while(1) { open = strsrch(contents,"<CENTER>"); if(open!=-1) { close = strsrch(contents,"</CENTER>"); if(close<open) say("Barfed on CENTER tag\n"); else { // need to know how much room we have to center in cols = environment(this_object())->getenv("COLUMNS") ? to_int(environment(this_object())->getenv("COLUMNS")) : 78; //cols = 78; tmp1 = contents[0..open-1]+"\n"; tmp2 = contents[open+8..close-1]; tmp3 = "\n"+ contents[close+9..]; while(tmp2[0]==' ') tmp2= tmp2[1..];// Strip leading spaces while(tmp2[<1]==' ') tmp2= tmp2[0..<2];// Strip trailing spaces tmp2 = sprintf("%|"+cols+"s", tmp2); contents = tmp1+tmp2+tmp3 ; } } else break; } // Now translate a few one-on-one tags contents = replace_string(contents," "," "); contents = replace_string(contents,"<P>","\n\n"); contents = replace_string(contents,"<p>","\n\n"); contents = replace_string(contents,"</P>",""); contents = replace_string(contents,"</p>",""); contents = replace_string(contents,"<b>",BOLD); contents = replace_string(contents,"</b>",NOR); contents = replace_string(contents,"<BR>","\n--\n"); contents = replace_string(contents,"<br>","\n--\n"); contents = replace_string(contents,"<HR>","\n--\n"); contents = replace_string(contents,"<hr>","\n--\n"); contents = replace_string(contents,"<B>",BOLD); contents = replace_string(contents,"</B>",NOR); // Change picture refs into [INLINE] done = 2; #define IMGTAG "<IMG" while( (done!=0) && (debug<10) ) { string alt,alttmp; debug++; // First the open tag open = strsrch(contents,(done==2) ?IMGTAG : lower_case(IMGTAG)); if(open!=-1 ) { tmp1 = contents[0..open-1]; tmp2 = contents[open..]; close = strsrch(tmp2,">"); if(close==-1) { say("Bad html IMG tag\n"); break; } else { /* ALT: the next line seems to cause an infinite loop for some reason That's why the max of 10 loops has been added. alt=(tmp2[0..close+1]; if(alt && alt!="") alt = replace_string(alt,"ALT","alt"); if(strsrch(alt,"alt")!=-1) { say("Found alt string\n"); if (!(sscanf(alt,"%*salt=%s ",alttmp)==2) ) if (!(sscanf(alt,"%*salt=%s>",alttmp)==2) ) alt= "[INLINE]"; } else alt = alttmp; END ALT */ //say("loop\n"); tmp2=tmp2[close+1..]; // contents = tmp1 + alt +tmp2; This should work when loop probs are gone contents = tmp1 + "[INLINE]" +tmp2; alt=""; } } else done--; } // the <a hrefs>foo</a> tags done = 2; while(done!=0) { // First the open tag open = strsrch(contents,(done==2) ? HREF : lower_case(HREF)); if(open!=-1) { tmp1 = contents[0..open-1]; tmp2 = contents[open..]; close = strsrch(tmp2,">"); if(close==-1) { say("Bad html a href tag\n"); break; } tmp2=tmp2[close+1..]; contents = tmp1 + " " + BLU +tmp2; contents = replace_string(contents, ((done==2) ? HREFC : lower_case(HREFC))," "+NOR,1); } else done--;; } // Remove whitespace while(strsrch(contents," ")!=-1) contents = replace_string(contents," "," "); // And the H tags... contents = replace_string(contents,"<h1>","\n\n"+RED); contents = replace_string(contents,"<H1>","\n\n"+RED); contents = replace_string(contents,"</H1>","\n\n"+NOR); contents = replace_string(contents,"</h1>","\n\n"+NOR); contents = replace_string(contents,"<h2>","\n\n"+GRN); contents = replace_string(contents,"<H2>","\n\n"+GRN); contents = replace_string(contents,"</H2>","\n\n"+NOR); contents = replace_string(contents,"</h2>","\n\n"+NOR); contents = replace_string(contents,"<h3>","\n\n"+GRN); contents = replace_string(contents,"<H3>","\n\n"+GRN); contents = replace_string(contents,"</H3>","\n\n"+NOR); contents = replace_string(contents,"</h3>","\n\n"+NOR); contents = replace_string(contents,"<UL>","\n\n"); contents = replace_string(contents,"<ul>","\n\n"); contents = replace_string(contents,"</UL>","\n\n"); contents = replace_string(contents,"</ul>","\n\n"); contents = replace_string(contents,"<LI>",BOLD+"\no "+NOR); contents = replace_string(contents,"<li>",BOLD+"\no "+NOR); if(contents[<1]!='\n') contents = contents +"\n"; // Now we do an indent trick. We explode the string to an array with \n // then we break up cols longer then COLUMNS or 78 chars, and add as much // white space to the second half as the first half has. Simple ident. rm("/tmp/unwrapped"); write_file("/tmp/unwrapped",contents); tmp4 = explode(contents,"\n"); //determine the amount of cols. cols = environment(this_object())->getenv("COLUMNS") ? to_int(environment(this_object())->getenv("COLUMNS")) : 78; lines = sizeof(tmp4); while(i<lines) { if(strlen(tmp4[i])>cols) { // Take the first space from cols-- to wrap tmp1 = tmp4[i][0..cols]; open = strsrch(tmp1," ",-1); if(open==-1) open = cols-1 ; // We tried... tmp1 = tmp1[0..open-1]; tmp2=""; // ident remainder of line. while(tmp4[i][0]==' ') { tmp2 += " " ; tmp4[i]=tmp4[i][1..]; } tmp2 += tmp1[open+1..] + tmp4[i][cols+1..]; tmp4 = tmp4[0..i-1] + ({ tmp1 }) + ({ tmp2 }) + tmp4[i+1..] ; } else i++; } contents = implode(tmp4,"\n"); while(strsrch(contents," ")!=-1) contents = replace_string(contents," "," "); rm("/tmp/wrapped"); write_file("/tmp/wrapped",contents); return contents; } void leto(string foo){ send_packet(foo+"\n"); }