aaef2a1997-03-02Henrik Grubbström (Grubba) import files;
660b961996-11-30Niels Möller void perror(string format,mixed ... args);
aaef2a1997-03-02Henrik Grubbström (Grubba) #if !efun(error) #define error(X) do{array Y=backtrace();throw(({(X),Y[..sizeof(Y)-2]}));}while(0) #endif /* !error */
19104e1996-12-07Per Hedbor string popen(string s, void|mapping env, int|void uid, int|void gid)
5e4ede1996-11-12Per Hedbor { object p,p2;
aaef2a1997-03-02Henrik Grubbström (Grubba)  p2 = file();
5e4ede1996-11-12Per Hedbor  p=p2->pipe(); if(!p) error("Popen failed. (couldn't create pipe)\n"); if(!fork()) {
19104e1996-12-07Per Hedbor  array (int) olduid = ({ -1, -1 });
5e4ede1996-11-12Per Hedbor  catch { if(p->query_fd() < 0) { perror("File to dup2 to closed!\n"); exit(99); }
aaef2a1997-03-02Henrik Grubbström (Grubba)  p->dup2(file("stdout"));
19104e1996-12-07Per Hedbor  if(uid || gid) { object privs = ((program)"privs")("Executing script as non-www user"); olduid = ({ uid, gid }); setgid(olduid[1]); setuid(olduid[0]); #if efun(initgroups) array pw = getpwuid((int)uid); if(pw) initgroups(pw[0], (int)olduid[0]);
5e4ede1996-11-12Per Hedbor #endif
19104e1996-12-07Per Hedbor  }
aaef2a1997-03-02Henrik Grubbström (Grubba)  catch(exece("/bin/sh", ({ "-c", s }), (env||getenv())));
5e4ede1996-11-12Per Hedbor  }; exit(69); }else{ string t; destruct(p);
19104e1996-12-07Per Hedbor  t=p2->read(0x7fffffff);
5e4ede1996-11-12Per Hedbor  destruct(p2); return t; } }
3ee80f1996-11-12Per Hedbor mapping make_mapping(string *f) { mapping foo=([ ]); string s, a, b; foreach(f, s) { sscanf(s, "%s=%s", a, b); foo[a]=b; } return foo; } int low_spawne(string s,string *args, mapping|array env, object stdin, object stdout, object stderr, void|string wd) { object p; int pid; string t; if(arrayp(env)) env = make_mapping(env); if(!mappingp(env)) env=([]);
aaef2a1997-03-02Henrik Grubbström (Grubba)  stdin->dup2(file("stdin")); stdout->dup2(file("stdout")); stderr->dup2(file("stderr"));
3ee80f1996-11-12Per Hedbor  if(stringp(wd) && sizeof(wd)) cd(wd); exece(s, args, env); perror(sprintf("Spawne: Failed to exece %s\n", s)); exit(0); } int spawne(string s,string *args, mapping|array env, object stdin, object stdout, object stderr, void|string wd, void|array (int) uid) { int pid, *olduid = allocate(2, "int");
19104e1996-12-07Per Hedbor  object privs; if(pid=fork()) return pid;
3ee80f1996-11-12Per Hedbor  if(arrayp(uid) && sizeof(uid) == 2) {
19104e1996-12-07Per Hedbor  privs = ((program)"privs")("Executing program as non-www user (outside roxen)");
3ee80f1996-11-12Per Hedbor  setgid(uid[1]); setuid(uid[0]);
19104e1996-12-07Per Hedbor  } catch(low_spawne(s, args, env, stdin, stdout, stderr, wd));
3ee80f1996-11-12Per Hedbor  exit(0); }
a683751996-11-20Mirar (Pontus Hagland) private static int perror_last_was_newline=1; void perror(string format,mixed ... args) { string s; int lwn; s=((args==({}))?format:sprintf(format,@args)); if (s=="") return; if ( (lwn = s[-1]=="\n") ) s=s[0..strlen(s)-2]; werror((perror_last_was_newline?getpid()+": ":"") +replace(s,"\n","\n"+getpid()+": ") +(lwn?"\n":"")); perror_last_was_newline=lwn; }
3ee80f1996-11-12Per Hedbor void create() { add_constant("spawne",spawne);
a683751996-11-20Mirar (Pontus Hagland)  add_constant("perror",perror);
5e4ede1996-11-12Per Hedbor  add_constant("popen",popen); }