17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <auth.h>
57dd7cddfSDavid du Colombier #include <fcall.h>
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier #pragma varargck type "P" char*
87dd7cddfSDavid du Colombier
97dd7cddfSDavid du Colombier int nsrv;
107dd7cddfSDavid du Colombier Dir *srv;
117dd7cddfSDavid du Colombier Biobuf stdout;
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier typedef struct Mount Mount;
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier struct Mount
167dd7cddfSDavid du Colombier {
177dd7cddfSDavid du Colombier char *cmd;
187dd7cddfSDavid du Colombier char *flag;
197dd7cddfSDavid du Colombier char *new;
207dd7cddfSDavid du Colombier char *old;
217dd7cddfSDavid du Colombier char *spec;
227dd7cddfSDavid du Colombier };
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier void xlatemnt(Mount*);
257dd7cddfSDavid du Colombier char *quote(char*);
267dd7cddfSDavid du Colombier
277dd7cddfSDavid du Colombier int rflag;
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier void
usage(void)307dd7cddfSDavid du Colombier usage(void)
317dd7cddfSDavid du Colombier {
327dd7cddfSDavid du Colombier fprint(2, "usage: ns [-r] [pid]\n");
337dd7cddfSDavid du Colombier exits("usage");
347dd7cddfSDavid du Colombier }
357dd7cddfSDavid du Colombier
367dd7cddfSDavid du Colombier void
main(int argc,char ** argv)377dd7cddfSDavid du Colombier main(int argc, char **argv)
387dd7cddfSDavid du Colombier {
397dd7cddfSDavid du Colombier Mount *m;
407dd7cddfSDavid du Colombier int line, fd, n, pid;
417dd7cddfSDavid du Colombier char buf[1024], *av[5];
427dd7cddfSDavid du Colombier
437dd7cddfSDavid du Colombier ARGBEGIN{
447dd7cddfSDavid du Colombier case 'r':
457dd7cddfSDavid du Colombier rflag++;
467dd7cddfSDavid du Colombier break;
477dd7cddfSDavid du Colombier default:
487dd7cddfSDavid du Colombier usage();
497dd7cddfSDavid du Colombier }ARGEND
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier if(argc > 1)
527dd7cddfSDavid du Colombier usage();
537dd7cddfSDavid du Colombier if(argc == 1){
547dd7cddfSDavid du Colombier pid = atoi(argv[0]);
557dd7cddfSDavid du Colombier if(pid == 0)
567dd7cddfSDavid du Colombier usage();
577dd7cddfSDavid du Colombier }else
587dd7cddfSDavid du Colombier pid = getpid();
597dd7cddfSDavid du Colombier
607dd7cddfSDavid du Colombier Binit(&stdout, 1, OWRITE);
617dd7cddfSDavid du Colombier
627dd7cddfSDavid du Colombier sprint(buf, "/proc/%d/ns", pid);
637dd7cddfSDavid du Colombier fd = open(buf, OREAD);
647dd7cddfSDavid du Colombier if(fd < 0) {
657dd7cddfSDavid du Colombier fprint(2, "ns: open %s: %r\n", buf);
667dd7cddfSDavid du Colombier exits("open ns");
677dd7cddfSDavid du Colombier }
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier for(line=1; ; line++) {
707dd7cddfSDavid du Colombier n = read(fd, buf, sizeof(buf));
71*80ee5cbfSDavid du Colombier if(n == sizeof(buf)) {
72*80ee5cbfSDavid du Colombier fprint(2, "ns: ns string too long\n");
73*80ee5cbfSDavid du Colombier exits("read ns");
74*80ee5cbfSDavid du Colombier }
757dd7cddfSDavid du Colombier if(n < 0) {
767dd7cddfSDavid du Colombier fprint(2, "ns: read %r\n");
777dd7cddfSDavid du Colombier exits("read ns");
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier if(n == 0)
807dd7cddfSDavid du Colombier break;
817dd7cddfSDavid du Colombier buf[n] = '\0';
827dd7cddfSDavid du Colombier
837dd7cddfSDavid du Colombier m = mallocz(sizeof(Mount), 1);
847dd7cddfSDavid du Colombier if(m == nil) {
857dd7cddfSDavid du Colombier fprint(2, "ns: no memory: %r\n");
867dd7cddfSDavid du Colombier exits("no memory");
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier n = tokenize(buf, av, 5);
907dd7cddfSDavid du Colombier switch(n){
917dd7cddfSDavid du Colombier case 2:
927dd7cddfSDavid du Colombier if(strcmp(av[0], "cd") == 0){
937dd7cddfSDavid du Colombier Bprint(&stdout, "%s %s\n", av[0], av[1]);
947dd7cddfSDavid du Colombier continue;
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier /* fall through */
977dd7cddfSDavid du Colombier default:
987dd7cddfSDavid du Colombier fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line);
997dd7cddfSDavid du Colombier exits("format");
1007dd7cddfSDavid du Colombier case 5:
1017dd7cddfSDavid du Colombier m->cmd = strdup(av[0]);
1027dd7cddfSDavid du Colombier m->flag = strdup(av[1]);
1037dd7cddfSDavid du Colombier m->new = strdup(av[2]);
1047dd7cddfSDavid du Colombier m->old = strdup(av[3]);
1057dd7cddfSDavid du Colombier m->spec = strdup(av[4]);
1067dd7cddfSDavid du Colombier break;
1077dd7cddfSDavid du Colombier case 4:
1087dd7cddfSDavid du Colombier if(av[1][0] == '-'){
1097dd7cddfSDavid du Colombier m->cmd = strdup(av[0]);
1107dd7cddfSDavid du Colombier m->flag = strdup(av[1]);
1117dd7cddfSDavid du Colombier m->new = strdup(av[2]);
1127dd7cddfSDavid du Colombier m->old = strdup(av[3]);
1137dd7cddfSDavid du Colombier m->spec = strdup("");
1147dd7cddfSDavid du Colombier }else{
1157dd7cddfSDavid du Colombier m->cmd = strdup(av[0]);
1167dd7cddfSDavid du Colombier m->flag = strdup("");
1177dd7cddfSDavid du Colombier m->new = strdup(av[1]);
1187dd7cddfSDavid du Colombier m->old = strdup(av[2]);
1197dd7cddfSDavid du Colombier m->spec = strdup(av[3]);
1207dd7cddfSDavid du Colombier }
1217dd7cddfSDavid du Colombier break;
1227dd7cddfSDavid du Colombier case 3:
1237dd7cddfSDavid du Colombier m->cmd = strdup(av[0]);
1247dd7cddfSDavid du Colombier m->flag = strdup("");
1257dd7cddfSDavid du Colombier m->new = strdup(av[1]);
1267dd7cddfSDavid du Colombier m->old = strdup(av[2]);
1277dd7cddfSDavid du Colombier m->spec = strdup("");
1287dd7cddfSDavid du Colombier break;
1297dd7cddfSDavid du Colombier }
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier if(!rflag && strcmp(m->cmd, "mount")==0)
1327dd7cddfSDavid du Colombier xlatemnt(m);
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag,
1357dd7cddfSDavid du Colombier quote(m->new), quote(m->old), quote(m->spec));
1367dd7cddfSDavid du Colombier
1377dd7cddfSDavid du Colombier free(m->cmd);
1387dd7cddfSDavid du Colombier free(m->flag);
1397dd7cddfSDavid du Colombier free(m->new);
1407dd7cddfSDavid du Colombier free(m->old);
1417dd7cddfSDavid du Colombier free(m->spec);
1427dd7cddfSDavid du Colombier free(m);
1437dd7cddfSDavid du Colombier }
1447dd7cddfSDavid du Colombier
1457dd7cddfSDavid du Colombier exits(nil);
1467dd7cddfSDavid du Colombier }
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier void
xlatemnt(Mount * m)1497dd7cddfSDavid du Colombier xlatemnt(Mount *m)
1507dd7cddfSDavid du Colombier {
1517dd7cddfSDavid du Colombier int n, fd;
1527dd7cddfSDavid du Colombier char *s, *t, *net, *port;
1537dd7cddfSDavid du Colombier char buf[256];
1547dd7cddfSDavid du Colombier
1557dd7cddfSDavid du Colombier if(strncmp(m->new, "/net/", 5) != 0)
1567dd7cddfSDavid du Colombier return;
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier s = strdup(m->new);
1597dd7cddfSDavid du Colombier net = s+5;
1607dd7cddfSDavid du Colombier for(t=net; *t!='/'; t++)
1617dd7cddfSDavid du Colombier if(*t == '\0')
1627dd7cddfSDavid du Colombier goto Return;
1637dd7cddfSDavid du Colombier *t = '\0';
1647dd7cddfSDavid du Colombier port = t+1;
1657dd7cddfSDavid du Colombier for(t=port; *t!='/'; t++)
1667dd7cddfSDavid du Colombier if(*t == '\0')
1677dd7cddfSDavid du Colombier goto Return;
1687dd7cddfSDavid du Colombier *t = '\0';
1697dd7cddfSDavid du Colombier if(strcmp(t+1, "data") != 0)
1707dd7cddfSDavid du Colombier goto Return;
1717dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port);
1727dd7cddfSDavid du Colombier fd = open(buf, OREAD);
1737dd7cddfSDavid du Colombier if(fd < 0)
1747dd7cddfSDavid du Colombier goto Return;
1757dd7cddfSDavid du Colombier n = read(fd, buf, sizeof buf);
1767dd7cddfSDavid du Colombier close(fd);
1777dd7cddfSDavid du Colombier if(n<=1 || n>sizeof buf)
1787dd7cddfSDavid du Colombier goto Return;
1797dd7cddfSDavid du Colombier if(buf[n-1] == '\n')
1807dd7cddfSDavid du Colombier --n;
1817dd7cddfSDavid du Colombier buf[n] = '\0';
1827dd7cddfSDavid du Colombier t = malloc(strlen(net)+1+n+1);
1837dd7cddfSDavid du Colombier if(t == nil)
1847dd7cddfSDavid du Colombier goto Return;
1857dd7cddfSDavid du Colombier sprint(t, "%s!%s", net, buf);
1867dd7cddfSDavid du Colombier free(m->new);
1877dd7cddfSDavid du Colombier m->new = t;
1887dd7cddfSDavid du Colombier
1897dd7cddfSDavid du Colombier Return:
1907dd7cddfSDavid du Colombier free(s);
1917dd7cddfSDavid du Colombier }
1927dd7cddfSDavid du Colombier
1937dd7cddfSDavid du Colombier char*
quote(char * s)1947dd7cddfSDavid du Colombier quote(char *s)
1957dd7cddfSDavid du Colombier {
1967dd7cddfSDavid du Colombier static char buf[3][1024];
1977dd7cddfSDavid du Colombier static int i;
1987dd7cddfSDavid du Colombier char *p, *ep;
1997dd7cddfSDavid du Colombier
2007dd7cddfSDavid du Colombier if(strpbrk(s, " '\\\t#$") == nil)
2017dd7cddfSDavid du Colombier return s;
2027dd7cddfSDavid du Colombier i = (i+1)%3;
2037dd7cddfSDavid du Colombier p = &buf[i][0];
2047dd7cddfSDavid du Colombier ep = &buf[i][1024];
2057dd7cddfSDavid du Colombier *p++ = '\'';
2067dd7cddfSDavid du Colombier while(p < ep-5){
2077dd7cddfSDavid du Colombier switch(*s){
2087dd7cddfSDavid du Colombier case '\0':
2097dd7cddfSDavid du Colombier goto out;
2107dd7cddfSDavid du Colombier case '\'':
2117dd7cddfSDavid du Colombier *p++ = '\'';
2127dd7cddfSDavid du Colombier break;
2137dd7cddfSDavid du Colombier }
2147dd7cddfSDavid du Colombier *p++ = *s++;
2157dd7cddfSDavid du Colombier }
2167dd7cddfSDavid du Colombier out:
2177dd7cddfSDavid du Colombier *p++ = '\'';
2187dd7cddfSDavid du Colombier *p = '\0';
2197dd7cddfSDavid du Colombier return buf[i];
2207dd7cddfSDavid du Colombier }
221