/*creates a multi-level linked list structure representing the namespaces of specified processes. Selects and outputs information from this structure in various ways. Inteded to be used as component of other namespace tools such as graphical namespace mapper and grid namespace game */
#include <u.h>
#include <libc.h>
#include <bio.h>
struct nsline {
struct nsline *next;
char *tokens[5];
char *fulline;
} ;
struct nslist {
struct nsline *first;
struct nsline *current;
struct nsline *new;
} ;
struct listolists {
struct listolists *next;
struct nslist targlist;
int nsof;
} ;
struct nslist makenslist(char *);
void printline(char *[]);
void findbind(char *, char*[]);
int main(int argc, char *argv[]){
char *targdir = nil;
char mode = 'z';
ARGBEGIN {
case 'd':
targdir = ARGF();
mode = 'd';
break;
default:
break;
} ARGEND
if (argc < 1){
char defpid[256];
sprint(defpid, "%d", getpid());
argv[0]=strdup(defpid);
}
struct listolists *lolfirst = nil;
struct listolists *lolcurrent=nil;
struct listolists *lolnew=nil;
lolfirst=(struct listolists *) malloc (sizeof (struct listolists));
lolfirst->nsof=atoi(argv[0]);
lolfirst->targlist = makenslist(argv[0]);
lolfirst->next=(struct listolists *) malloc (sizeof (struct listolists));
lolcurrent=lolfirst->next;
for (int i=1; i<argc; i++){
lolcurrent->nsof=atoi(argv[i]);
lolcurrent->targlist=makenslist(argv[i]);
lolcurrent->next=(struct listolists *) malloc (sizeof(struct listolists));
lolcurrent=lolcurrent->next;
}
lolcurrent->next=nil;
if(mode=='d'){
lolcurrent=lolfirst;
while (lolcurrent->next !=nil){
while (lolcurrent->targlist.current==nil)
if (lolcurrent->next !=nil)
lolcurrent=lolcurrent->next;
else goto breakout;
print("\nprocess %d\n", lolcurrent->nsof);
lolcurrent->targlist.current=lolcurrent->targlist.first;
while (lolcurrent->targlist.current->next !=nil){
findbind(targdir, lolcurrent->targlist.current->tokens);
lolcurrent->targlist.current=lolcurrent->targlist.current->next;
}
lolcurrent=lolcurrent->next;
}
breakout:
;
}
if(mode=='z'){
lolcurrent=lolfirst;
while (lolcurrent->next !=nil){
while (lolcurrent->targlist.current==nil)
if (lolcurrent->next !=nil)
lolcurrent=lolcurrent->next;
else goto theend;
print("\nprocess %d\n", lolcurrent->nsof);
while (lolcurrent->targlist.current->next !=nil){
printline(lolcurrent->targlist.current->tokens);
lolcurrent->targlist.current=lolcurrent->targlist.current->next;
}
lolcurrent=lolcurrent->next;
}
theend:
;
}
return 0;
}
/* more human-readable output than ns. makes flags into prepositional phrases. */
void printline(char *nstok[5]){
if ((*nstok[0]) == 'm')
print("-");
print("%-8s",nstok[0]);
/* print("%-8s",nstok[1]); */
print("%-28s",nstok[2]);
if ((*nstok[0]) != 'c') {
char c = (*(nstok[1] + 1));
switch (c) {
case 'b':
print("ON TOP OF ");
break;
case 'a':
print("UNDERNEATH ");
break;
default:
print("REPLACING ");
break;
}
} else
print("%-8s", nstok[1]);
print("%-4s",nstok[3]);
print("\n");
return;
}
/* finds matching mountpoints to a given directory string */
void findbind(char *incoming, char *nstok[5]){
if (strncmp(nstok[3], incoming, 3) == 0) {
print("%s\n", nstok[2]);
}
return;
}
/* fills a linked list with a tokenized process namespace structure */
struct nslist makenslist(char *targns){
Biobuf nsbuf;
char buf[1024];
char *line = nil;
int indcounter = 0;
struct nsline *first = nil;
struct nsline *current = nil;
struct nsline *new = nil;
int nsfd;
sprint(buf, "/proc/%s/ns", targns);
if ((nsfd = open(buf, OREAD)) == -1){
/* print("cant open proc %s ", targns); */
struct nslist returnstruct = nil;
return returnstruct;
}
Binit(&nsbuf, nsfd, OREAD);
first = (struct nsline *) malloc(sizeof(struct nsline));
line = Brdstr(&nsbuf, '\n', 1);
first->fulline=(char *) malloc((sizeof(char))*strlen(line)+1);
strcpy(first->fulline, line);
tokenize(line, first->tokens, 5);
if((*(first->tokens[1]) != '-') && (*(first->tokens[0]) != 'c')){
first->tokens[3]=strdup(first->tokens[2]);
first->tokens[2]=strdup(first->tokens[1]);
first->tokens[1]=" ";
}
if (*(first->tokens[0]) == 'c'){
first->tokens[2]=" ";
first->tokens[3]=" ";
}
first->next = (struct nsline *) malloc(sizeof(struct nsline));
current = first->next;
while((line = Brdstr(&nsbuf, '\n', 1)) != nil) {
current->fulline = (char *) malloc((sizeof(char)) * strlen(line) + 1);
strcpy(current->fulline, line);
tokenize(line, current->tokens, 5);
if((*(current->tokens[1]) != '-') && (*(current->tokens[0]) != 'c')){
current->tokens[3]=strdup(current->tokens[2]);
current->tokens[2]=strdup(current->tokens[1]);
current->tokens[1]=" ";
}
if (*(current->tokens[0]) == 'c'){
current->tokens[2]=" ";
current->tokens[3]=" ";
}
new = (struct nsline *) malloc(sizeof(struct nsline));
current->next=new;
current=new;
indcounter++;
}
current->next=nil;
current=first;
Bterm(&nsbuf);
close(nsfd);
struct nslist returnstruct;
returnstruct.first=first;
returnstruct.current=current;
returnstruct.new=new;
return returnstruct;
}
|