blob: 2421a649896d4f6a6a3eda1cb863d03c338311af [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <ctype.h>
static int
isme(char *uid)
{
int n;
char *p;
n = strtol(uid, &p, 10);
if(*p == 0 && p > uid)
return n == getuid();
return strcmp(getuser(), uid) == 0;
}
/*
* 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)
{
int fd;
Dir *d;
char *disp, *p;
if((disp = getenv("DISPLAY")) == nil){
#ifdef __APPLE__
// Might be running native GUI on OS X.
disp = strdup(":0.0");
if(disp == nil)
return nil;
#else
werrstr("$DISPLAY not set");
return nil;
#endif
}
/* canonicalize: xxx:0.0 => xxx:0 */
p = strrchr(disp, ':');
if(p){
p++;
while(isdigit((uchar)*p))
p++;
if(strcmp(p, ".0") == 0)
*p = 0;
}
/* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */
for(p=disp; *p; p++)
if(*p == '/')
*p = '_';
p = smprint("/tmp/ns.%s.%s", getuser(), disp);
free(disp);
if(p == nil){
werrstr("out of memory");
return p;
}
if((fd=create(p, OREAD, DMDIR|0700)) >= 0){
close(fd);
return p;
}
if((d = dirstat(p)) == nil){
free(d);
werrstr("stat %s: %r", p);
free(p);
return nil;
}
if((d->mode&0777) != 0700 || !isme(d->uid)){
werrstr("bad name space dir %s", p);
free(p);
free(d);
return nil;
}
free(d);
return p;
}
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;
}