9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

getns.c (1702B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <ctype.h>
      4 
      5 static int
      6 isme(char *uid)
      7 {
      8 	int n;
      9 	char *p;
     10 
     11 	n = strtol(uid, &p, 10);
     12 	if(*p == 0 && p > uid)
     13 		return n == getuid();
     14 	return strcmp(getuser(), uid) == 0;
     15 }
     16 /*
     17  * Absent other hints, it works reasonably well to use
     18  * the X11 display name as the name space identifier.
     19  * This is how sam's B has worked since the early days.
     20  * Since most programs using name spaces are also using X,
     21  * this still seems reasonable.  Terminal-only sessions
     22  * can set $NAMESPACE.
     23  */
     24 static char*
     25 nsfromdisplay(void)
     26 {
     27 	int fd;
     28 	Dir *d;
     29 	char *disp, *p;
     30 
     31 	if((disp = getenv("DISPLAY")) == nil){
     32 #ifdef __APPLE__
     33 		// Might be running native GUI on OS X.
     34 		disp = strdup(":0.0");
     35 		if(disp == nil)
     36 			return nil;
     37 #else
     38 		werrstr("$DISPLAY not set");
     39 		return nil;
     40 #endif
     41 	}
     42 
     43 	/* canonicalize: xxx:0.0 => xxx:0 */
     44 	p = strrchr(disp, ':');
     45 	if(p){
     46 		p++;
     47 		while(isdigit((uchar)*p))
     48 			p++;
     49 		if(strcmp(p, ".0") == 0)
     50 			*p = 0;
     51 	}
     52 	
     53 	/* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */
     54 	for(p=disp; *p; p++)
     55 		if(*p == '/')
     56 			*p = '_';
     57 
     58 	p = smprint("/tmp/ns.%s.%s", getuser(), disp);
     59 	free(disp);
     60 	if(p == nil){
     61 		werrstr("out of memory");
     62 		return p;
     63 	}
     64 	if((fd=create(p, OREAD, DMDIR|0700)) >= 0){
     65 		close(fd);
     66 		return p;
     67 	}
     68 	if((d = dirstat(p)) == nil){
     69 		free(d);
     70 		werrstr("stat %s: %r", p);
     71 		free(p);
     72 		return nil;
     73 	}
     74 	if((d->mode&0777) != 0700 || !isme(d->uid)){
     75 		werrstr("bad name space dir %s", p);
     76 		free(p);
     77 		free(d);
     78 		return nil;
     79 	}
     80 	free(d);
     81 	return p;
     82 }
     83 
     84 char*
     85 getns(void)
     86 {
     87 	char *ns;
     88 
     89 	ns = getenv("NAMESPACE");
     90 	if(ns == nil)
     91 		ns = nsfromdisplay();
     92 	if(ns == nil){
     93 		werrstr("$NAMESPACE not set, %r");
     94 		return nil;
     95 	}
     96 	return ns;
     97 }