a1ad681998-01-16Fredrik Hübinette (Hubbe) #!/usr/local/bin/pike
6e41622000-09-01Henrik Grubbström (Grubba) /* -*- Pike -*- */
a1ad681998-01-16Fredrik Hübinette (Hubbe)  inherit Stdio.Port;
dd990d1998-12-31Fredrik Hübinette (Hubbe) #if !constant(Stdio.PROP_IPC) #define NO_IPC #endif
facd311998-08-05Fredrik Hübinette (Hubbe) // Bugfix for some older versions of Pike.. string combine_path(string s, string ... rest) { for(int e=0;e<sizeof(rest);e++) { if(sscanf(rest[e],"%*[a-zA-Z]:%*s")==2) { s=rest[e]; }else{ s=predef::combine_path(s,rest[e]); } } return s; } // Bugfix for some older versions of Pike.. #define BLOCK 65536 int cp(string from, string to) { if(!Stdio.cp(from,to)) { werror("Backup cp function in effect.\n"); string data; object tmp=Stdio.File(); if(!tmp->open(from,"r")) {
af263a1999-05-07Fredrik Hübinette (Hubbe)  werror(sprintf("Open %s for reading failed.\n",from));
facd311998-08-05Fredrik Hübinette (Hubbe)  return 0; } function r=tmp->read; tmp=Stdio.File(); if(!tmp->open(to,"wct")) {
af263a1999-05-07Fredrik Hübinette (Hubbe)  werror(sprintf("Open %s for writing failed.\n",to));
facd311998-08-05Fredrik Hübinette (Hubbe)  return 0; } function w=tmp->write; do { data=r(BLOCK); if(!data) { werror("Read failed.\n"); return 0; } if(w(data)!=strlen(data)) { werror("Write failed.\n"); return 0; } }while(strlen(data) == BLOCK); } return 1; }
d6a1a81998-01-25Fredrik Hübinette (Hubbe) void monitor(object(Stdio.File) io, object proc) { proc->wait();
80e7ad1998-07-26Fredrik Hübinette (Hubbe)  if(io) { io->close("rw"); io->close(); destruct(io); }
d6a1a81998-01-25Fredrik Hübinette (Hubbe) }
5e01c61999-08-24Fredrik Hübinette (Hubbe) string opt_path(string p1, string p2) { return ( ( ((p1||"") + ";" + (p2||"")) / ";" ) - ({""}) ) * ";"; }
a1ad681998-01-16Fredrik Hübinette (Hubbe) void handle_incoming_connection(object(Stdio.File) io) { object p;
5e01c61999-08-24Fredrik Hübinette (Hubbe)  mapping env=copy_value(getenv());
a1ad681998-01-16Fredrik Hübinette (Hubbe)  sscanf(io->read(4),"%4c",int args); string *cmd=allocate(args); for(int e=0;e<args;e++) { sscanf(io->read(4),"%4c",int len); cmd[e]=io->read(len); } object pi=Stdio.File();
dd990d1998-12-31Fredrik Hübinette (Hubbe) #ifdef NO_IPC
a1ad681998-01-16Fredrik Hübinette (Hubbe)  object p2=pi->pipe();
dd990d1998-12-31Fredrik Hübinette (Hubbe) #else object p2=pi->pipe(Stdio.PROP_IPC);
5a7ab61998-01-31Fredrik Hübinette (Hubbe) #endif
a1ad681998-01-16Fredrik Hübinette (Hubbe)  string dir=cmd[0]; cmd=cmd[1..];
3b0b561999-08-06Fredrik Hübinette (Hubbe)  while(sscanf(cmd[0],"%s=%s",string key, string val)) {
5e01c61999-08-24Fredrik Hübinette (Hubbe)  // 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; }
b3d5a42000-01-09Fredrik Hübinette (Hubbe)  werror("%s = %s\n",key,env[key]);
3b0b561999-08-06Fredrik Hübinette (Hubbe)  cmd=cmd[1..]; }
b3d5a42000-01-09Fredrik Hübinette (Hubbe)  write("Doing %s in %s\n",cmd*" ",dir);
47a5f41998-01-21Fredrik Hübinette (Hubbe)  switch(lower_case(cmd[0]))
a1ad681998-01-16Fredrik Hübinette (Hubbe)  {
47a5f41998-01-21Fredrik Hübinette (Hubbe)  case "mkdir": {
af263a1999-05-07Fredrik Hübinette (Hubbe)  string dir=combine_path(combine_path(getcwd(),dir),cmd[1]); int ret; if(Stdio.file_size(dir)!=-2) ret=mkdir(dir); else ret=1; if(!ret) { string x=sprintf("MKDIR %s failed, errno=%d\n",dir,errno()); io->write(sprintf("%4c%s",strlen(x),x)); }
47a5f41998-01-21Fredrik Hübinette (Hubbe)  io->write(sprintf("%4c",0));
af263a1999-05-07Fredrik Hübinette (Hubbe)  io->write(sprintf("%4c",!ret));
47a5f41998-01-21Fredrik Hübinette (Hubbe)  break; } case "copy": { string from=combine_path(combine_path(getcwd(),dir),cmd[1]); string to=combine_path(combine_path(getcwd(),dir),cmd[2]); if(mixed stat=file_stat(to))
5a7ab61998-01-31Fredrik Hübinette (Hubbe)  {
47a5f41998-01-21Fredrik Hübinette (Hubbe)  if(stat[1]==-2)
5a7ab61998-01-31Fredrik Hübinette (Hubbe)  { to=combine_path(to,basename(cmd[1])); } }
47a5f41998-01-21Fredrik Hübinette (Hubbe) 
5a7ab61998-01-31Fredrik Hübinette (Hubbe) 
facd311998-08-05Fredrik Hübinette (Hubbe)  int ret=cp(from,to);
5a7ab61998-01-31Fredrik Hübinette (Hubbe)  if(!ret) { string x=sprintf("Errno is %d\n" "CWD=%s\n" "from=%s\n" "to=%s\n" "dir=%s (%s)\n", errno(), getcwd(), from, to, dir, combine_path(getcwd(),dir)); io->write(sprintf("%4c%s",strlen(x),x)); }
47a5f41998-01-21Fredrik Hübinette (Hubbe)  io->write(sprintf("%4c",0));
5a7ab61998-01-31Fredrik Hübinette (Hubbe)  io->write(sprintf("%4c",!ret));
47a5f41998-01-21Fredrik Hübinette (Hubbe)  break; }
a1ad681998-01-16Fredrik Hübinette (Hubbe)  case "getenv": {
5e01c61999-08-24Fredrik Hübinette (Hubbe)  string s; if(sizeof(cmd)<2) { s=""; foreach(indices(env), string x) s+=sprintf("%s=%s\n",x,env[x]); }else{ s=(env[cmd[1]] || "")+"\n"; }
a1ad681998-01-16Fredrik Hübinette (Hubbe)  io->write(sprintf("%4c%s",strlen(s),s)); io->write(sprintf("%4c",0)); io->write(sprintf("%4c",0)); break; } default:
dd990d1998-12-31Fredrik Hübinette (Hubbe) #ifdef WINE
25f6bc2000-06-28Fredrik Hübinette (Hubbe)  void my_proxy(Stdio.File from, Stdio.File to) { while(string s=from->read(128,1)) if(to->write(s)!=strlen(s)) return; if(p) p->kill(9); /* DIE! */ }
dd990d1998-12-31Fredrik Hübinette (Hubbe)  { werror("Proxying.....\n"); object p3=Stdio.File(); #ifdef NO_IPC object p4=p3->pipe(); #else object p4=p3->pipe(Stdio.PROP_IPC); #endif thread_create(my_proxy,io,p4); io=p3; } #endif
25f6bc2000-06-28Fredrik Hübinette (Hubbe) #if __VERSION__ >= 0.699999 write("Trapping OOB\n"); if(io->read_oob) { thread_create(lambda() { while(1) { string tmp=io->read_oob(1); if(!tmp || !sizeof(tmp)) return; werror("**Interrupt received, killing child.\n"); p->kill(9); } }); } #endif
a1ad681998-01-16Fredrik Hübinette (Hubbe)  mixed err=catch { p=Process.create_process(cmd, ([
dd990d1998-12-31Fredrik Hübinette (Hubbe) #ifndef WINE
a1ad681998-01-16Fredrik Hübinette (Hubbe)  "stdin":io, "stdout":p2, "stderr":p2,
dd990d1998-12-31Fredrik Hübinette (Hubbe) #endif
a1ad681998-01-16Fredrik Hübinette (Hubbe)  "cwd":dir,
3b0b561999-08-06Fredrik Hübinette (Hubbe)  "env":env,
d6a1a81998-01-25Fredrik Hübinette (Hubbe)  ])); };
80e7ad1998-07-26Fredrik Hübinette (Hubbe)  destruct(p2);
a1ad681998-01-16Fredrik Hübinette (Hubbe)  if(!err) {
dd990d1998-12-31Fredrik Hübinette (Hubbe) #ifdef NO_IPC
d6a1a81998-01-25Fredrik Hübinette (Hubbe)  thread_create(monitor,p2,p);
5a7ab61998-01-31Fredrik Hübinette (Hubbe) #endif
a1ad681998-01-16Fredrik Hübinette (Hubbe)  while(1) { string s=pi->read(1000,1); if(!s || !strlen(s)) break; io->write(sprintf("%4c%s",strlen(s),s)); } io->write(sprintf("%4c",0));
6e41622000-09-01Henrik Grubbström (Grubba)  int code; if (catch { code = p->wait(); }) { // wait() failed. io->write(sprintf("%4c", -1)); } else { io->write(sprintf("%4c", code)); }
a1ad681998-01-16Fredrik Hübinette (Hubbe)  }else{
af263a1999-05-07Fredrik Hübinette (Hubbe)  werror("dir=%s\n",dir);
dd990d1998-12-31Fredrik Hübinette (Hubbe)  werror(master()->describe_backtrace(err));
d6a1a81998-01-25Fredrik Hübinette (Hubbe)  destruct(p2);
a1ad681998-01-16Fredrik Hübinette (Hubbe)  io->write(sprintf("%4c",0)); io->write(sprintf("%4c",69)); } }
af263a1999-05-07Fredrik Hübinette (Hubbe) #ifdef WINE io->close("rw"); #else
a1ad681998-01-16Fredrik Hübinette (Hubbe)  io->close("w");
af263a1999-05-07Fredrik Hübinette (Hubbe) #endif
a1ad681998-01-16Fredrik Hübinette (Hubbe)  destruct(io); }
dd990d1998-12-31Fredrik Hübinette (Hubbe) void handle_connections(string *hosts) { while(1) { if(object io=accept()) {
b29cd32000-05-16Fredrik Hübinette (Hubbe)  int ok=0;
dd990d1998-12-31Fredrik Hübinette (Hubbe)  sscanf(io->query_address(),"%s ",string ip);
b29cd32000-05-16Fredrik Hübinette (Hubbe)  foreach(hosts, string host) ok+=glob(host, ip); if(!ok)
dd990d1998-12-31Fredrik Hübinette (Hubbe)  {
5e01c61999-08-24Fredrik Hübinette (Hubbe)  werror("Connection from %s denied!!\n",ip);
dd990d1998-12-31Fredrik Hübinette (Hubbe)  destruct(io); continue; } thread_create(handle_incoming_connection,io); }else{ werror("Accept failed "+errno()+"\n"); } } }
a1ad681998-01-16Fredrik Hübinette (Hubbe) int main(int argc, string *argv) {
dd990d1998-12-31Fredrik Hübinette (Hubbe) #ifdef WINE werror("Running in WINE mode.\n"); #endif
d95dc91998-01-19Fredrik Hübinette (Hubbe)  if(argc<2)
a1ad681998-01-16Fredrik Hübinette (Hubbe)  {
542d6d1998-02-24Fredrik Hübinette (Hubbe)  werror("Usage: sprshd <port> <hosts to accept connections from>\n");
a1ad681998-01-16Fredrik Hübinette (Hubbe)  exit(1); } if(!bind((int)argv[1])) { werror("Failed to bind port.\n"); exit(1); }
542d6d1998-02-24Fredrik Hübinette (Hubbe)  string *hosts=({}); for(int e=2;e<sizeof(argv);e++) { if(sscanf(argv[e],"%*d.%*d")==2) {
0e1ad41998-10-17Per Hedbor  hosts+=({argv[e]});
542d6d1998-02-24Fredrik Hübinette (Hubbe)  continue; } mixed tmp=gethostbyname(argv[e]); if(!tmp) { werror("Gethostbyname("+argv[e]+") failed.\n"); exit(1); } hosts+=tmp[1]; }
a1ad681998-01-16Fredrik Hübinette (Hubbe) 
facd311998-08-05Fredrik Hübinette (Hubbe)  write("Ready ("+version()+").\n");
dd990d1998-12-31Fredrik Hübinette (Hubbe)  #ifdef WINE thread_create(handle_connections,hosts); werror("main returning...\n"); return -1; #else
2879411999-02-04Fredrik Hübinette (Hubbe)  handle_connections(hosts);
dd990d1998-12-31Fredrik Hübinette (Hubbe)  return 0; #endif
a1ad681998-01-16Fredrik Hübinette (Hubbe) }