about summary refs log tree commit diff stats
path: root/src/main.c
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2024-12-31 02:18:40 -0600
committerRen Kararou <[email protected]>2024-12-31 02:18:40 -0600
commitf6b4ac41eec72a25c703c63f43bd1104049a405c (patch)
tree6fc60798944ac010c22ede4e2e9e33d6b97d39e0 /src/main.c
parent810de0a90148d5dc7fe5919949220a00d14f6447 (diff)
downloadnbtpd-f6b4ac41eec72a25c703c63f43bd1104049a405c.tar.gz
nbtpd-f6b4ac41eec72a25c703c63f43bd1104049a405c.tar.bz2
nbtpd-f6b4ac41eec72a25c703c63f43bd1104049a405c.zip
complete setup code; complete initial packet handling
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c105
1 files changed, 82 insertions, 23 deletions
diff --git a/src/main.c b/src/main.c
index 3701c79..0264050 100644
--- a/src/main.c
+++ b/src/main.c
@@ -17,11 +17,17 @@
 
 #include "packet.h"
 #include "netascii.h"
+#include "handlers.h"
 
-static int stop = 0;
+int nbtpd_stop = 0;
 
-void stop_handler() {
-	stop = 1;
+void stop_handler(int i) {
+	syslog(LOG_ERR, "caught shutdown signal, cleaning up.");
+	if (i != 0) {
+		nbtpd_stop = i;
+	} else {
+		nbtpd_stop = 1;
+	}
 	return;
 }
 
@@ -89,6 +95,8 @@ int main(int argc, char **argv) {
 	setlogmask(LOG_UPTO(LOG_INFO));
 	openlog(argv[0], LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_FTP);
 	syslog(LOG_INFO, "starting up...");
+	signal(SIGTERM, &stop_handler);
+	signal(SIGINT, &stop_handler);
 
 	if (daemonize) {
 		if (daemon(1, 0)) {
@@ -127,16 +135,18 @@ int main(int argc, char **argv) {
 	}
 	syslog(LOG_INFO, "socket bind success");
 
-	//TODO: use getpwnam_r() and getgrnam_r()
-	struct passwd *u = getpwnam((const char *)&user);
-	if (setuid((*u).pw_uid) == -1) {
-		syslog(LOG_ERR, "failed to drop user privileges");
-		return -1;
-	}
-	struct group *g = getgrnam((const char *)&group);
-	if (setgid((*g).gr_gid) == -1) {
-		syslog(LOG_ERR, "failed to drop group privileges");
-		return -1;
+	if (daemonize) {
+		//TODO: use getpwnam_r() and getgrnam_r()
+		struct group *g = getgrnam((const char *)&group);
+		if (setgid((*g).gr_gid) == -1) {
+			syslog(LOG_ERR, "failed to drop group privileges");
+			return -1;
+		}
+		struct passwd *u = getpwnam((const char *)&user);
+		if (setuid((*u).pw_uid) == -1) {
+			syslog(LOG_ERR, "failed to drop user privileges");
+			return -1;
+		}
 	}
 
 	// create persistent buffer
@@ -147,21 +157,70 @@ int main(int argc, char **argv) {
 		close(s);
 		return -1;
 	}
-	while (!stop) {
+	while (!nbtpd_stop) {
 		struct sockaddr_in caddr;
 		unsigned int clen = sizeof(caddr);
 		memset(buf, '\0', 1024);
-		if (recvfrom(s, buf, 1024, 0, (struct sockaddr*)&caddr, &clen) < 0) {
-			syslog(LOG_ERR,
-					"got a client connection, but unable to receive data!");
-			free(buf);
+		ssize_t recvd_bytes = 0;
+		if ((recvd_bytes = recvfrom(s, buf, 1024, 0, 
+				(struct sockaddr *)&caddr, &clen)) < 0) {
+			syslog(
+				LOG_ERR,
+				"got a client connection, but unable to receive data!"
+			);
 			continue;
 		}
-		//TODO: process packet
-
-		// we will never actually join on this thread, and don't care to keep it around.
-		//pthread_t *_thread; // since this hasn't been implemented yet, clang is complaining
-
+		if (recvd_bytes < 4) {
+			syslog(LOG_ERR, "ignoring invalid packet.");
+			continue;
+		}
+		nbd_nbtpd_args *args = malloc(sizeof(nbd_nbtpd_args));
+		if (args == NULL) {
+			syslog(LOG_CRIT, "unable to allocate memory");
+			continue;
+		}
+		nbd_tftp_opcode oc = ntohs(((uint16_t)buf[0] << 8) + buf[1]);
+		(*args).client = caddr;
+		(*args).err = 0;
+		memset((*args).path, '\0', 768);
+		memset((*args).mode, '\0', 32);
+		int i;
+		for(i = 2; buf[i] != 0 && i < recvd_bytes && (i - 2) < 768; i++) {
+			(*args).path[i - 2] = buf[i];
+		}
+		int s = i + 1;
+		if (s >= recvd_bytes) {
+			oc = 0;
+		} else {
+			for(i = s; buf[i] != 0 && i < recvd_bytes && (i - s) < 32; i++) {
+				(*args).mode[i - s] = buf[i];
+			}
+		}
+		pthread_t *_thread = malloc(sizeof(pthread_t));
+		if (_thread == NULL) {
+			syslog(LOG_CRIT, "unable to allocate memory");
+			free(args);
+			continue;
+		}
+		void *(*func)(void *);
+		switch (oc) {
+			case RRQ:
+				func = &read_req_resp;
+				break;
+			case WRQ:
+				func = &write_req_resp;
+				break;
+			default:
+				(*args).err = 4;
+				func = &nbd_nbtpd_resp_error;
+		}
+		if (pthread_create(_thread, 0, func, (void *)args) != 0) {
+			syslog(
+				LOG_CRIT,
+				"unable to handle request: cannot create thread!"
+			);
+			free(args);
+		}
 	}
 
 	// free our persistent buffer