/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <bio.h>#include <auth.h>#include <fcall.h> #pragma varargck type "P" char* int nsrv;Dir *srv;Biobuf stdout; typedef struct Mount Mount; struct Mount{ char *cmd; char *flag; char *new; char *old; char *spec;}; void xlatemnt(Mount*);char *quote(char*); int rflag; voidusage(void){ fprint(2, "usage: ns [-r] [pid]\n"); exits("usage");} voidmain(int argc, char **argv){ Mount *m; int line, fd, n, pid; char buf[1024], *av[5]; ARGBEGIN{ case 'r': rflag++; break; default: usage(); }ARGEND if(argc > 1) usage(); if(argc == 1){ pid = atoi(argv[0]); if(pid == 0) usage(); }else pid = getpid(); Binit(&stdout, 1, OWRITE); sprint(buf, "/proc/%d/ns", pid); fd = open(buf, OREAD); if(fd < 0) { fprint(2, "ns: open %s: %r\n", buf); exits("open ns"); } for(line=1; ; line++) { n = read(fd, buf, sizeof(buf)); if(n == sizeof(buf)) { fprint(2, "ns: ns string too long\n"); exits("read ns"); } if(n < 0) { fprint(2, "ns: read %r\n"); exits("read ns"); } if(n == 0) break; buf[n] = '\0'; m = mallocz(sizeof(Mount), 1); if(m == nil) { fprint(2, "ns: no memory: %r\n"); exits("no memory"); } n = tokenize(buf, av, 5); switch(n){ case 2: if(strcmp(av[0], "cd") == 0){ Bprint(&stdout, "%s %s\n", av[0], av[1]); continue; } /* fall through */ default: fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line); exits("format"); case 5: m->cmd = strdup(av[0]); m->flag = strdup(av[1]); m->new = strdup(av[2]); m->old = strdup(av[3]); m->spec = strdup(av[4]); break; case 4: if(av[1][0] == '-'){ m->cmd = strdup(av[0]); m->flag = strdup(av[1]); m->new = strdup(av[2]); m->old = strdup(av[3]); m->spec = strdup(""); }else{ m->cmd = strdup(av[0]); m->flag = strdup(""); m->new = strdup(av[1]); m->old = strdup(av[2]); m->spec = strdup(av[3]); } break; case 3: m->cmd = strdup(av[0]); m->flag = strdup(""); m->new = strdup(av[1]); m->old = strdup(av[2]); m->spec = strdup(""); break; } if(!rflag && strcmp(m->cmd, "mount")==0) xlatemnt(m); Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag, quote(m->new), quote(m->old), quote(m->spec)); free(m->cmd); free(m->flag); free(m->new); free(m->old); free(m->spec); free(m); } exits(nil);} voidxlatemnt(Mount *m){ int n, fd; char *s, *t, *net, *port; char buf[256]; if(strncmp(m->new, "/net/", 5) != 0) return; s = strdup(m->new); net = s+5; for(t=net; *t!='/'; t++) if(*t == '\0') goto Return; *t = '\0'; port = t+1; for(t=port; *t!='/'; t++) if(*t == '\0') goto Return; *t = '\0'; if(strcmp(t+1, "data") != 0) goto Return; snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port); fd = open(buf, OREAD); if(fd < 0) goto Return; n = read(fd, buf, sizeof buf); close(fd); if(n<=1 || n>sizeof buf) goto Return; if(buf[n-1] == '\n') --n; buf[n] = '\0'; t = malloc(strlen(net)+1+n+1); if(t == nil) goto Return; sprint(t, "%s!%s", net, buf); free(m->new); m->new = t; Return: free(s);} char*quote(char *s){ static char buf[3][1024]; static int i; char *p, *ep; if(strpbrk(s, " '\\\t#$") == nil) return s; i = (i+1)%3; p = &buf[i][0]; ep = &buf[i][1024]; *p++ = '\''; while(p < ep-5){ switch(*s){ case '\0': goto out; case '\'': *p++ = '\''; break; } *p++ = *s++; } out: *p++ = '\''; *p = '\0'; return buf[i];}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <auth.h>
#include <fcall.h>
#pragma varargck type "P" char*
int nsrv;
Dir *srv;
Biobuf stdout;
typedef struct Mount Mount;
struct Mount
{
char *cmd;
char *flag;
char *new;
char *old;
char *spec;
};
void xlatemnt(Mount*);
char *quote(char*);
int rflag;
void
usage(void)
{
fprint(2, "usage: ns [-r] [pid]\n");
exits("usage");
}
void
main(int argc, char **argv)
{
Mount *m;
int line, fd, n, pid;
char buf[1024], *av[5];
ARGBEGIN{
case 'r':
rflag++;
break;
default:
usage();
}ARGEND
if(argc > 1)
usage();
if(argc == 1){
pid = atoi(argv[0]);
if(pid == 0)
usage();
}else
pid = getpid();
Binit(&stdout, 1, OWRITE);
sprint(buf, "/proc/%d/ns", pid);
fd = open(buf, OREAD);
if(fd < 0) {
fprint(2, "ns: open %s: %r\n", buf);
exits("open ns");
}
for(line=1; ; line++) {
n = read(fd, buf, sizeof(buf));
if(n == sizeof(buf)) {
fprint(2, "ns: ns string too long\n");
exits("read ns");
}
if(n < 0) {
fprint(2, "ns: read %r\n");
exits("read ns");
}
if(n == 0)
break;
buf[n] = '\0';
m = mallocz(sizeof(Mount), 1);
if(m == nil) {
fprint(2, "ns: no memory: %r\n");
exits("no memory");
}
n = tokenize(buf, av, 5);
switch(n){
case 2:
if(strcmp(av[0], "cd") == 0){
Bprint(&stdout, "%s %s\n", av[0], av[1]);
continue;
}
/* fall through */
default:
fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line);
exits("format");
case 5:
m->cmd = strdup(av[0]);
m->flag = strdup(av[1]);
m->new = strdup(av[2]);
m->old = strdup(av[3]);
m->spec = strdup(av[4]);
break;
case 4:
if(av[1][0] == '-'){
m->cmd = strdup(av[0]);
m->flag = strdup(av[1]);
m->new = strdup(av[2]);
m->old = strdup(av[3]);
m->spec = strdup("");
}else{
m->cmd = strdup(av[0]);
m->flag = strdup("");
m->new = strdup(av[1]);
m->old = strdup(av[2]);
m->spec = strdup(av[3]);
}
break;
case 3:
m->cmd = strdup(av[0]);
m->flag = strdup("");
m->new = strdup(av[1]);
m->old = strdup(av[2]);
m->spec = strdup("");
break;
}
if(!rflag && strcmp(m->cmd, "mount")==0)
xlatemnt(m);
Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag,
quote(m->new), quote(m->old), quote(m->spec));
free(m->cmd);
free(m->flag);
free(m->new);
free(m->old);
free(m->spec);
free(m);
}
exits(nil);
}
void
xlatemnt(Mount *m)
{
int n, fd;
char *s, *t, *net, *port;
char buf[256];
if(strncmp(m->new, "/net/", 5) != 0)
return;
s = strdup(m->new);
net = s+5;
for(t=net; *t!='/'; t++)
if(*t == '\0')
goto Return;
*t = '\0';
port = t+1;
for(t=port; *t!='/'; t++)
if(*t == '\0')
goto Return;
*t = '\0';
if(strcmp(t+1, "data") != 0)
goto Return;
snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port);
fd = open(buf, OREAD);
if(fd < 0)
goto Return;
n = read(fd, buf, sizeof buf);
close(fd);
if(n<=1 || n>sizeof buf)
goto Return;
if(buf[n-1] == '\n')
--n;
buf[n] = '\0';
t = malloc(strlen(net)+1+n+1);
if(t == nil)
goto Return;
sprint(t, "%s!%s", net, buf);
free(m->new);
m->new = t;
Return:
free(s);
}
char*
quote(char *s)
{
static char buf[3][1024];
static int i;
char *p, *ep;
if(strpbrk(s, " '\\\t#$") == nil)
return s;
i = (i+1)%3;
p = &buf[i][0];
ep = &buf[i][1024];
*p++ = '\'';
while(p < ep-5){
switch(*s){
case '\0':
goto out;
case '\'':
*p++ = '\'';
break;
}
*p++ = *s++;
}
out:
*p++ = '\'';
*p = '\0';
return buf[i];
}