getns.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 }