// TODO: use this
r = mkdir("/tmp/bash", 0700); | |
if(r != 0) | |
{ | |
NSLog(@"Failed to create /tmp/bash: %s", strerror(errno)); | |
goto out; | |
} | |
pid_t pid = fork(); | |
if(pid == -1) | |
{ | |
NSLog(@"fork: %s", strerror(errno)); | |
goto out; | |
} | |
else if(pid == 0) | |
{ | |
r = setenv("SHELL", "/tmp/bootstrap/bin/bash", 1); | |
if(r == 0) | |
{ | |
r = setenv("TERM", "xterm-256color", 1); | |
if(r == 0) | |
{ | |
r = setenv("USER", "root", 1); | |
if(r == 0) | |
{ | |
r = setenv("LOGNAME", "root", 1); | |
if(r == 0) | |
{ | |
r = setenv("HOME", "/tmp/bash", 1); | |
if(r == 0) | |
{ | |
r = setenv("PATH", "/tmp/bootstrap/bin:/tmp/bootstrap/sbin:/usr/bin:/bin:/usr/sbin:/sbin", 1); | |
if(r == 0) | |
{ | |
r = setenv("PS1", "\\h:\\W \\u\\$ ", 1); | |
} | |
} | |
} | |
} | |
} | |
} | |
if(r != 0) | |
{ | |
NSLog(@"setenv: %s", strerror(errno)); | |
exit(-1); | |
} | |
int sock = socket(AF_INET, SOCK_STREAM, 0); | |
if(sock == -1) | |
{ | |
NSLog(@"socket: %s", strerror(errno)); | |
exit(-1); | |
} | |
int one = 1; | |
r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); | |
if(r != 0) | |
{ | |
NSLog(@"setsockopt: %s", strerror(errno)); | |
exit(-1); | |
} | |
struct sockaddr_in addr = | |
{ | |
.sin_family = AF_INET, | |
.sin_port = htons(44), | |
.sin_addr = | |
{ | |
.s_addr = INADDR_ANY, | |
}, | |
}; | |
r = bind(sock, (struct sockaddr*)&addr, sizeof(addr)); | |
if(r != 0) | |
{ | |
NSLog(@"bind: %s", strerror(errno)); | |
exit(-1); | |
} | |
r = listen(sock, 0); | |
if(r != 0) | |
{ | |
NSLog(@"listen: %s", strerror(errno)); | |
exit(-1); | |
} | |
while(1) | |
{ | |
int conn = accept(sock, NULL, NULL); | |
pid = fork(); | |
if(pid == -1) | |
{ | |
NSLog(@"fork: %s", strerror(errno)); | |
exit(-1); | |
} | |
else if(pid == 0) | |
{ | |
int master = -1; | |
pid = forkpty(&master, NULL, NULL, NULL); | |
if(pid == -1) | |
{ | |
NSLog(@"forkpty: %s", strerror(errno)); | |
exit(-1); | |
} | |
else if(pid == 0) | |
{ | |
execve("/tmp/bootstrap/bin/bash", (char *const[]){ "/tmp/bootstrap/bin/bash", "--noprofile", "--norc", "-i", NULL }, environ); | |
} | |
else | |
{ | |
// XXX | |
struct termios tio; | |
tcgetattr(master, &tio); | |
NSLog(@"c_iflag: %016lx", tio.c_iflag); | |
NSLog(@"c_oflag: %016lx", tio.c_oflag); | |
NSLog(@"c_cflag: %016lx", tio.c_cflag); | |
NSLog(@"c_lflag: %016lx", tio.c_lflag); | |
for(size_t i = 0; i < NCCS; ++i) | |
{ | |
NSLog(@"c_cc[%lu]: %02x", i, tio.c_cc[i]); | |
} | |
NSLog(@"c_ispeed: %016lx", tio.c_ispeed); | |
NSLog(@"c_ospeed: %016lx", tio.c_ospeed); | |
// XXX | |
fd_conn_t rarg = | |
{ | |
.from = master, | |
.to = conn, | |
}; | |
fd_conn_t warg = | |
{ | |
.from = conn, | |
.to = master, | |
}; | |
pthread_t rthrd, | |
wthrd; | |
r = pthread_create(&rthrd, NULL, fd_conn, &rarg); | |
if(r != 0) | |
{ | |
NSLog(@"pthread_create: %s", strerror(r)); | |
exit(-1); | |
} | |
r = pthread_create(&wthrd, NULL, fd_conn, &warg); | |
if(r != 0) | |
{ | |
NSLog(@"pthread_create: %s", strerror(r)); | |
exit(-1); | |
} | |
waitpid(pid, NULL, 0); | |
exit(0); | |
} | |
} | |
else | |
{ | |
close(conn); | |
} | |
} | |
} | |
typedef struct | |
{ | |
int from; | |
int to; | |
} fd_conn_t; | |
void* fd_conn(void *arg) | |
{ | |
const fd_conn_t *desc = arg; | |
int from = desc->from, | |
to = desc->to; | |
while(1) | |
{ | |
char buf[1024]; | |
ssize_t num = read(from, buf, sizeof(buf)); | |
if(num < 0) | |
{ | |
NSLog(@"read: %s", strerror(errno)); | |
exit(-1); | |
} | |
if(num == 0) | |
{ | |
exit(0); | |
} | |
ssize_t n = 0; | |
while(n < num) | |
{ | |
n += write(to, buf + n, num - n); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment