diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/posix-factotum.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/posix-factotum.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/posix-factotum.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/posix-factotum.c b/sys/src/cmd/unix/drawterm/posix-factotum.c new file mode 100755 index 000000000..728131bb5 --- /dev/null +++ b/sys/src/cmd/unix/drawterm/posix-factotum.c @@ -0,0 +1,106 @@ +#include <u.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <ctype.h> +#include <pwd.h> +#include <libc.h> +#include <auth.h> +#include <fcall.h> +#include <authsrv.h> +#include <libsec.h> +#include "drawterm.h" + +#undef socket +#undef connect +#undef getenv +#undef access + +char* +getuser(void) +{ + static char user[64]; + struct passwd *pw; + + pw = getpwuid(getuid()); + if(pw == nil) + return "none"; + strecpy(user, user+sizeof user, pw->pw_name); + return user; +} +/* + * Absent other hints, it works reasonably well to use + * the X11 display name as the name space identifier. + * This is how sam's B has worked since the early days. + * Since most programs using name spaces are also using X, + * this still seems reasonable. Terminal-only sessions + * can set $NAMESPACE. + */ +static char* +nsfromdisplay(void) +{ + char *disp, *p; + + if((disp = getenv("DISPLAY")) == nil){ + werrstr("$DISPLAY not set"); + return nil; + } + + /* canonicalize: xxx:0.0 => xxx:0 */ + p = strrchr(disp, ':'); + if(p){ + p++; + while(isdigit((uchar)*p)) + p++; + if(strcmp(p, ".0") == 0) + *p = 0; + } + + return smprint("/tmp/ns.%s.%s", getuser(), disp); +} + +char* +getns(void) +{ + char *ns; + + ns = getenv("NAMESPACE"); + if(ns == nil) + ns = nsfromdisplay(); + if(ns == nil){ + werrstr("$NAMESPACE not set, %r"); + return nil; + } + return ns; +} + +int +dialfactotum(void) +{ + int fd; + struct sockaddr_un su; + char *name; + + name = smprint("%s/factotum", getns()); + + if(name == nil || access(name, 0) < 0) + return -1; + memset(&su, 0, sizeof su); + su.sun_family = AF_UNIX; + if(strlen(name)+1 > sizeof su.sun_path){ + werrstr("socket name too long"); + return -1; + } + strcpy(su.sun_path, name); + if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ + werrstr("socket: %r"); + return -1; + } + if(connect(fd, (struct sockaddr*)&su, sizeof su) < 0){ + werrstr("connect %s: %r", name); + close(fd); + return -1; + } + + return lfdfd(fd); +} + |