/* * $Id; stfufs-server.c $ * * Author: Tomi Ollila -- too ät iki piste fi * * Copyright (c) 2007 tomi Ollila * All rights reserved * * Created: Sun 26 Aug 2007 08:18:39 AM EEST too * Last modified: Wed Jan 30 21:43:02 EET 2008 too */ #include #include #include #include #include "util.h" #include "pretocol.h" #include "random.h" #define STFUFS_SERVER 1 #include "stfufs.h" static int srv_doaccept(unsigned char * buf, int port) { int ssd; unsigned char msg[10]; memcpy(msg, buf, 4); if (port == 0) { int i; for (i = -500; i < 500; i += 10) { port = 14168 + i; ssd = dobindandlisten(port, false); if (ssd >= 0) break; } if (ssd < 0) die("Can not find suitable port where to bind"); /* else */ } else ssd = dobindandlisten(port, true); /* currently a big hacky, let's see if ever changed. */ memcpy(msg, buf, 4); msg[4] = port >> 8; msg[5] = port; msg[6] = 0; msg[7] = 0; msg[8] = 128; msg[9] = 0; /* 32768 */ writehsmsg(1, msg, 10); return doaccept(buf, ssd); } static int srv_doconnect(unsigned char * buf, int port, char * host) { char hostbuf[256]; char c; if (host[0] == '\0') { char * ssh_client, *p; ssh_client = getenv("SSH_CLIENT"); if (ssh_client == null) die("SSH_CLIENT environment variable undefined"); p = strchr(ssh_client, ' '); if (p == null) die("Unexpected SSH_CLIENT environment variable value"); if ((size_t)(p - ssh_client) >= sizeof hostbuf) die("Remote host part of SSH_CLIENT environment variable too long"); memcpy(hostbuf, ssh_client, p - ssh_client); hostbuf[p - ssh_client] = '\0'; host = hostbuf; } writehsmsg(1, buf, 6); readwt(1, &c, 1, 10 * 1000); return doconnect(buf, host, port); } static int create_connection(void) { unsigned char buf[260]; int i; char c; sendident(1); randombytes(buf, 4); i = recvident(1, 10 * 1000); if (i < 0) readwt(1, &c, 1, 10 * 1000); /* consume ack */ else c = i; d0(("%d %d", c, i)); if (c != 0) die("Client did not accept our ident"); write(1, "", 1); /* our ack, '\0'-byte */ /* read directory to be mounted */ i = readhsmsg(1, buf + 4); if (i > 1 && chdir(U2S(buf, char, [], *) + 4) < 0) die("Can not chdir to '%s': %s", buf, strerror(errno)); write(1, "", 1); /* ack again */ i = readhsmsg(1, buf + 4); if (i < 6) die("Too short message from client"); if (i == 6) return srv_doaccept(buf, (buf[8] << 8) + buf[9]); else return srv_doconnect(buf, (buf[8] << 8) + buf[9], U2S(buf, char, [], *) + 10); } int main(void) { int fd, fd2; util_init("Server"); fd2 = fd = create_connection(); switch (fork()) { case -1: die("fork failed"); case 0: break; default: return 0; /* parent */ } #if DEBUG fd2 = 2; #endif /* child */ dup2(fd, 0); dup2(fd, 1); dup2(fd2, 2); setsid(); if (fd > 2) close(fd); stfufs_server(); return 0; } /* * Local variables: * mode: c * c-file-style: "stroustrup" * tab-width: 8 * End: */