5e1cbd1998-02-24Fredrik Hübinette (Hubbe) #if !constant(strerror) #define strerror(X) X #endif
41ee482000-02-28Fredrik Hübinette (Hubbe) #ifdef __NT__ void exece(string cmd, array(string) args) { exit(Process.create_process( ({ cmd }) + args )->wait()); } #endif
7eb6942000-11-30Fredrik Hübinette (Hubbe) string follow_symlinks(string s)
5e1cbd1998-02-24Fredrik Hübinette (Hubbe) {
43a3c42000-11-08Fredrik Noring  mixed st;
7eb6942000-11-30Fredrik Hübinette (Hubbe)  string x=s;
5bf94b2000-10-31Henrik Grubbström (Grubba)  while ((st = file_stat(s, 1)) && (st[1] == -3)) { string new_s = readlink(s); if (new_s == s) { werror(sprintf("%O is a symlink to itself!\n", s)); exit(1); }
7eb6942000-11-30Fredrik Hübinette (Hubbe)  s = combine_path(getcwd(),dirname(s),new_s);
5bf94b2000-10-31Henrik Grubbström (Grubba)  }
7eb6942000-11-30Fredrik Hübinette (Hubbe) // werror("Follow symlink %O -> %O\n",x,s); return s; } string fixpath(string s) { string mnt=getenv("NTMOUNT"); s=follow_symlinks(s);
5e1cbd1998-02-24Fredrik Hübinette (Hubbe)  if(mnt && strlen(mnt)) s=replace(s,mnt,""); return replace(s,"/","\\"); } string fixabspath(string s) { return replace(s,"/","\\"); }
41ee482000-02-28Fredrik Hübinette (Hubbe) string opt_path(string p1, string p2) { return ( ( ((p1||"") + ";" + (p2||"")) / ";" ) - ({""}) ) * ";"; }
ef359c1998-03-21Fredrik Hübinette (Hubbe) int silent_do_cmd(string *cmd, mixed|void filter, int|void silent)
5e1cbd1998-02-24Fredrik Hübinette (Hubbe) {
7eb6942000-11-30Fredrik Hübinette (Hubbe) // werror("%O\n",cmd);
5e1cbd1998-02-24Fredrik Hübinette (Hubbe)  string ret="";
da5cd91998-11-05Fredrik Hübinette (Hubbe)  object(Stdio.File) f=Stdio.File(); switch(getenv("REMOTE_METHOD"))
5e1cbd1998-02-24Fredrik Hübinette (Hubbe)  {
da5cd91998-11-05Fredrik Hübinette (Hubbe)  default: werror("Unknown REMOTE method %s\n",getenv("REMOTE_METHOD")); break; case "wine": case "WINE": #if 0 if(!silent && !filter) { return Process.create_process(({"wine",cmd*" "}))->wait(); } else #endif { object o=f->pipe(Stdio.PROP_BIDIRECTIONAL | Stdio.PROP_IPC);
dd990d1998-12-31Fredrik Hübinette (Hubbe)  cmd=({"wine", "-winver","win95",
41ee482000-02-28Fredrik Hübinette (Hubbe)  "-debugmsg","fixme-all",
dd990d1998-12-31Fredrik Hübinette (Hubbe)  "-debugmsg","trace+all", "-debugmsg","+relay", cmd*" "}); // werror("WINE %O\n",cmd);
41ee482000-02-28Fredrik Hübinette (Hubbe)  object proc=Process.create_process(cmd, (["stdout":o]) ); destruct(o); while(1) { string s=f->read(8192,1); if(!s || !strlen(s)) break; s=replace(s,"\r\n","\n"); if(!silent) write(s); ret+=s; } if(filter) filter(ret); destruct(f); return proc->wait(); } case "cygwin": case "CYGWIN": { mapping env=copy_value(getenv()); if(string tmp=getenv("REMOTE_VARIABLES")) { foreach(tmp/"\n",string var) { if(search(var,"=")!=-1 && sscanf(var,"%s=%s",string key, string val)) { // Magic if(!env[key]) { if(env[lower_case(key)]) key=lower_case(key); else if(env[upper_case(key)]) key=upper_case(key); else { foreach(indices(env), string x) { if(lower_case(x) == lower_case(key)) { key=x; break; } } } } if(val[0]==';') { env[key]=opt_path(env[key], val); } else if(val[-1]==';') { env[key]=opt_path(val, env[key]); } else { env[key]=val; } // werror("%s = %s\n",key,env[key]); } } } string mnt=getenv("NTMOUNT"); #if 1 /* Experimental */ if(mnt && strlen(mnt)>1) { for(int e=1;e<sizeof(cmd);e++) cmd[e]=replace(cmd[e],mnt,getenv("NTDRIVE")); } #endif object o=f->pipe(Stdio.PROP_IPC); object proc=Process.create_process(cmd, (["stdout":o,"env":env]));
da5cd91998-11-05Fredrik Hübinette (Hubbe)  destruct(o); while(1) { string s=f->read(8192,1); if(!s || !strlen(s)) break; s=replace(s,"\r\n","\n"); if(!silent) write(s); ret+=s; } if(filter) filter(ret); destruct(f); return proc->wait(); } case 0: case "sprsh": case "SPRSH":
7ce0441999-08-24Fredrik Hübinette (Hubbe)  if(string tmp=getenv("REMOTE_VARIABLES")) {
c93e072000-12-26Fredrik Hübinette (Hubbe)  array vars=({"__handles_stderr=1"});
7ce0441999-08-24Fredrik Hübinette (Hubbe)  foreach(tmp/"\n",string var) if(search(var,"=")!=-1) vars+=({var}); cmd=vars+cmd; }
da5cd91998-11-05Fredrik Hübinette (Hubbe)  string tmp=getcwd(); string mnt=getenv("NTMOUNT");
41ee482000-02-28Fredrik Hübinette (Hubbe)  if(mnt && strlen(mnt)) tmp=replace(tmp,mnt,getenv("NTDRIVE")); else tmp=getenv("NTDRIVE")+tmp; tmp=replace(tmp,"/","\\"); cmd=({ tmp })+cmd;
fbb55b2000-02-02Fredrik Hübinette (Hubbe)  #if 1 /* Experimental */ if(mnt && strlen(mnt)>1) { for(int e=1;e<sizeof(cmd);e++) cmd[e]=replace(cmd[e],mnt,getenv("NTDRIVE")); } #endif
da5cd91998-11-05Fredrik Hübinette (Hubbe)  if(!f->connect(getenv("NTHOST"),(int)getenv("NTPORT"))) {
6ae3c22000-08-29Peter Bortas  werror("Failed to connect to "+getenv("NTHOST")+":"+getenv("NTPORT") +" "+strerror(errno())+".\n");
da5cd91998-11-05Fredrik Hübinette (Hubbe)  exit(1);
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  } class SimpleInOut { object o=Stdio.File("stdin"); string read() { string s=o->read(1000,1); if(!strlen(s)) return 0; return s;
da5cd91998-11-05Fredrik Hübinette (Hubbe)  }
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  int write(string s) { return Stdio.stdout->write(s); }
c93e072000-12-26Fredrik Hübinette (Hubbe)  int werr(string s) { return Stdio.stderr->write(s); }
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  }; object inout; #if __VERSION__ > 0.699999 && constant(thread_create) class RLInOut { Thread.Mutex m=Thread.Mutex(); object rl=Stdio.Readline(); string prompt="";
6dc2772000-07-28Fredrik Hübinette (Hubbe)  array from_handler= ({"\r\n","\n\r","\n"}); array to_handler= ({"\n\r","\n\r","\n\r"});
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  string read() { string tmp=rl->read(); if(tmp) { tmp+="\n"; prompt=""; } return tmp; } int write(string s) {
6dc2772000-07-28Fredrik Hübinette (Hubbe)  /* This provides some very basic terminal emulation */ /* We need to understand \r, \n, and \b */ // werror("%O\n",s); s=replace(prompt+s,from_handler,to_handler); array tmp=s/"/b"; array lines=s/"\r"; foreach(lines, string l) { if(strlen(l) && l[-1]=='\n') { rl->write(l); prompt=""; }else{ prompt=l; } } rl->set_prompt(prompt);
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  return strlen(s); }
c93e072000-12-26Fredrik Hübinette (Hubbe)  int werr(string s) { return write(s); }
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  void create() { rl->enable_history(512);
6dc2772000-07-28Fredrik Hübinette (Hubbe)  for(int e=0;e<256;e++) { switch(e) { case '\n': case '\r': break; default: from_handler+=({ sprintf("%c\b",e) }); to_handler+=({ sprintf("") }); } }
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  } };
9077572000-06-30Fredrik Hübinette (Hubbe)  if(!silent && !!Stdio.stdin->tcgetattr() && !!Stdio.stdout->tcgetattr())
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  { inout=RLInOut(); }else #endif inout=SimpleInOut();
da5cd91998-11-05Fredrik Hübinette (Hubbe)  f->write(sprintf("%4c",sizeof(cmd))); for(int e=0;e<sizeof(cmd);e++) f->write(sprintf("%4c%s",strlen(cmd[e]),cmd[e]));
fb24932000-01-27Fredrik Hübinette (Hubbe) // if(f->proxy) // f->proxy(Stdio.File("stdin")); // else // werror("FNORD\n");
da5cd91998-11-05Fredrik Hübinette (Hubbe)  thread_create(lambda(object f) {
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  int killed;
6dc2772000-07-28Fredrik Hübinette (Hubbe)  int last_killed;
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  void killme() {
6dc2772000-07-28Fredrik Hübinette (Hubbe)  if(last_killed == time()) return; last_killed=time(); werror("\r\n** Interupted\r\n"); if(!killed || killed+5 > time())
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  { f->write_oob("x");
6dc2772000-07-28Fredrik Hübinette (Hubbe)  if(!killed) killed=time(); }else{ exit(1);
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  } }; if(f->write_oob)
fb24932000-01-27Fredrik Hübinette (Hubbe)  {
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  signal(signum("SIGINT"), killme);
fb24932000-01-27Fredrik Hübinette (Hubbe)  }
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  while(string s=inout->read()) f->write(s); signal(signum("SIGINT"), 0);
fb24932000-01-27Fredrik Hübinette (Hubbe)  f->close("w");
da5cd91998-11-05Fredrik Hübinette (Hubbe)  },f); while(1) {
be24952000-06-28Henrik Grubbström (Grubba)  string s = f->read(4); if (!s) { werror("Connection closed!\n"); exit(1); }
c93e072000-12-26Fredrik Hübinette (Hubbe)  sscanf(s,"%c%3c",int channel, int len);
da5cd91998-11-05Fredrik Hübinette (Hubbe)  if(!len) break; s=f->read(len); s=replace(s,"\r\n","\n");
c93e072000-12-26Fredrik Hübinette (Hubbe)  if(!silent) { switch(channel) { case 0: /* Backwards compatibility */ case 1: inout->write(s); break; // stdout case 2: inout->werr(s); break; // stderr } }
ac77cc2000-06-28Fredrik Hübinette (Hubbe)  if(filter) ret+=s;
da5cd91998-11-05Fredrik Hübinette (Hubbe)  } if(filter) filter(ret); sscanf(f->read(4),"%4c",int code); f->close("r");
fb24932000-01-27Fredrik Hübinette (Hubbe) // f->close("w"); // werror("Closing stdout.\n");
da5cd91998-11-05Fredrik Hübinette (Hubbe)  destruct(f);
0b854c2000-12-19Fredrik Hübinette (Hubbe)  if(code > 127) {
80412d2000-12-19Henrik Grubbström (Grubba)  werror("Software failure. Press left mouse button to continue.\r\n"
0b854c2000-12-19Fredrik Hübinette (Hubbe)  " Guru meditation #%s\r\n", sprintf("%016X",code)/8*"."); code=127; }
da5cd91998-11-05Fredrik Hübinette (Hubbe)  return code;
5e1cbd1998-02-24Fredrik Hübinette (Hubbe)  } }
ef359c1998-03-21Fredrik Hübinette (Hubbe) string tmp; string popen_cmd(string *cmd) { tmp=""; silent_do_cmd(cmd,lambda(string x) { tmp=x; }, 1); return tmp; }
5e1cbd1998-02-24Fredrik Hübinette (Hubbe) string getntenv(string var) { string s="";
da5cd91998-11-05Fredrik Hübinette (Hubbe)  switch(getenv("REMOTE_METHOD"))
5e1cbd1998-02-24Fredrik Hübinette (Hubbe)  {
da5cd91998-11-05Fredrik Hübinette (Hubbe)  default: werror("Unknown REMOTE method %s\n",getenv("REMOTE_METHOD")); break; case "wine": case "WINE": return getenv(var) || getenv(lower_case(var)); case 0: case "sprsh": case "SPRSH": return popen_cmd( ({"getenv",var}) );
5e1cbd1998-02-24Fredrik Hübinette (Hubbe)  } } int do_cmd(string *cmd, mixed|void filter) { return silent_do_cmd(cmd,filter); } string find_lib_location() { return __FILE__; }
c064061998-05-27Fredrik Hübinette (Hubbe)  string find_next_in_path(string argv0,string cmd) { argv0=combine_path(getcwd(),argv0); if(file_stat(argv0)) { foreach((getenv("PATH")||"")/":",string x) { string fname=combine_path(getcwd(),x,cmd);
43a3c42000-11-08Fredrik Noring  if(mixed s=file_stat(fname))
c064061998-05-27Fredrik Hübinette (Hubbe)  { if(argv0) {
686ed61998-09-01Fredrik Hübinette (Hubbe)  if(argv0==fname)
c064061998-05-27Fredrik Hübinette (Hubbe)  argv0=0; }else{ return fname; } } } }else{ foreach((getenv("PATH")||"")/":",string x) { string fname=combine_path(getcwd(),x,cmd);
43a3c42000-11-08Fredrik Noring  if(mixed s=file_stat(fname))
c064061998-05-27Fredrik Hübinette (Hubbe)  { if(Stdio.File(fname,"r")->read(2)=="#!") continue; return fname; } } } foreach((getenv("PATH")||"")/":",string x) { string fname=combine_path(getcwd(),x,cmd);
43a3c42000-11-08Fredrik Noring  if(mixed s=file_stat(fname))
c064061998-05-27Fredrik Hübinette (Hubbe)  return fname; } return "/bin/"+cmd; }