about summary refs log tree commit diff stats
path: root/src/main.c
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2025-01-26 03:41:25 -0600
committerRen Kararou <[email protected]>2025-01-26 03:41:25 -0600
commit1bcf3de7f521d83185cce580db2dea6d50a617b6 (patch)
treec06850c6c0df9bdc9ca395ecc9ebe67b7c9dfb86 /src/main.c
parent9ec8d6d9dc03791f6ab1e3ad108c8d705d355696 (diff)
downloadnbtpd-bazel.tar.gz
nbtpd-bazel.tar.bz2
nbtpd-bazel.zip
try bazel bazel
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c313
1 files changed, 0 insertions, 313 deletions
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 7114cc7..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,313 +0,0 @@
-#ifdef __linux__
-#define _POSIX_C_SOURCE 2
-#define _DEFAULT_SOURCE
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <pwd.h>
-#include <grp.h>
-#include <errno.h>
-#include <signal.h>
-//TODO: use threads.h instead
-#include <pthread.h>
-
-// illumos-only headers
-#ifdef __illumos__
-#include <priv.h>
-#endif
-
-#include "packet.h"
-#include "netascii.h"
-#include "handlers.h"
-
-int nbtpd_stop = 0;
-
-void stop_handler(int i) {
-	syslog(LOG_ERR, "caught shutdown signal, cleaning up and awaiting threads");
-	if (i != 0) {
-		nbtpd_stop = i;
-	} else {
-		nbtpd_stop = 1;
-	}
-	return;
-}
-
-void usage(char *name) {
-	//TODO: print to stderr; cleanup to be compliant
-	fprintf(stderr,
-		"usage: %s -h [-d [-u USER] [-g GROUP]] [-a INET_ADDRESS] [-p PORT] [-l LEVEL]\n",
-		name
-	);
-	fprintf(stderr, "\td: daemonize.\n");
-	fprintf(stderr,
-		"\tu: username to run as (default: nobody).  Must be specified after -d.\n"
-	);
-	fprintf(stderr,
-		"\tg: group to run as (default: nobody).  Must be specified after -d.\n"
-	);
-	fprintf(stderr, "\ta: address to bind to (default: 127.0.0.1)\n");
-	fprintf(stderr, "\tp: port to bind to (default: 69)\n");
-	fprintf(stderr, "\tl: log level; one of:\n");
-	fprintf(stderr, "\t\temerg\n\t\talert\n\t\tcrit\n\t\terr\n\t\twarn\n");
-	fprintf(stderr, "\t\tnotice\n\t\tinfo (default)\n\t\tdebug\n");
-}
-
-int set_loglevel(char *level) {
-	if (strncmp("emerg", level, 6) == 0) {
-		setlogmask(LOG_UPTO(LOG_EMERG));
-		return 0;
-	}
-	if (strncmp("alert", level, 6) == 0) {
-		setlogmask(LOG_UPTO(LOG_ALERT));
-		return 0;
-	}
-	if (strncmp("crit", level, 5) == 0) {
-		setlogmask(LOG_UPTO(LOG_CRIT));
-		return 0;
-	}
-	if (strncmp("err", level, 4) == 0) {
-		setlogmask(LOG_UPTO(LOG_ERR));
-		return 0;
-	}
-	if (strncmp("warn", level, 5) == 0) {
-		setlogmask(LOG_UPTO(LOG_WARNING));
-		return 0;
-	}
-	if (strncmp("notice", level, 7) == 0) {
-		setlogmask(LOG_UPTO(LOG_NOTICE));
-		return 0;
-	}
-	if (strncmp("info", level, 5) == 0) {
-		setlogmask(LOG_UPTO(LOG_INFO));
-		return 0;
-	}
-	if (strncmp("debug", level, 6) == 0) {
-		setlogmask(LOG_UPTO(LOG_DEBUG));
-		return 0;
-	}
-	return -1;
-}
-
-int main(int argc, char **argv) {
-	int retme = 0;
-	int daemonize = 0, loglevset = 0;
-	char addr[17], user[32], group[32];
-	memset(addr, '\0', sizeof(addr));
-	memset(user, '\0', sizeof(user));
-	memset(group, '\0', sizeof(group));
-	strcpy(addr, "127.0.0.1");
-	strcpy(user, "nobody");
-	strcpy(group, "nobody");
-	int port = 69;
-	int ch = 0;
-	while ((ch = getopt(argc, argv, "da:p:u:g:l:h")) != -1) {
-		switch (ch) {
-			case 'a':
-				strncpy(addr, optarg, sizeof(addr) - 1);
-				break;
-			case 'p':
-				port = atoi(optarg);
-				if ((port <= 0) || (port >= 65536)) {
-					fprintf(stderr, "invalid port specified.\n");
-					return -1;
-				}
-				break;
-			case 'd':
-				daemonize = 1;
-				break;
-			case 'g':
-				if (daemonize) {
-					strncpy(group, optarg, sizeof(group) - 1);
-				} else {
-					fprintf(stderr, "-g requires -d\n");
-					return -1;
-				}
-				break;
-			case 'u':
-				if (daemonize) {
-					strncpy(user, optarg, sizeof(user) - 1);
-				} else {
-					fprintf(stderr, "-u requires -d\n");
-					return -1;
-				}
-				break;
-			case 'l':
-				loglevset = 1;
-				if (set_loglevel(optarg)) {
-					fprintf(stderr, "invalid option for -l\n");
-					usage(argv[0]);
-					return -1;
-				}
-				break;
-			 case 'h': case '?':
-				usage(argv[0]);
-				return -1;
-		}
-	}
-	if (!loglevset) {
-		setlogmask(LOG_UPTO(LOG_INFO));
-	}
-#ifdef __illumos__
-	openlog(argv[0], LOG_PID | LOG_NDELAY, LOG_FTP);
-#else
-	openlog(argv[0], LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_FTP);
-#endif
-	syslog(LOG_INFO, "starting up...");
-	signal(SIGTERM, &stop_handler);
-	signal(SIGINT, &stop_handler);
-	char *buf = NULL;
-	int s = socket(AF_INET, SOCK_DGRAM, 0);
-	if (s <= 0) {
-		syslog(LOG_ERR, "unable to bind socket!");
-		return -1;
-	}
-	if (daemonize) {
-		if (daemon(1, 0)) {
-			syslog(LOG_ERR, "failed to daemonize: %s", strerror(errno));
-			retme = -1;
-			goto cleanup;
-		} else {
-			syslog(LOG_INFO, "daemonized");
-		}
-	}
-	struct timeval timeout = { 30, 0 };
-	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
-		syslog(LOG_ERR, "unable to set socket timeout: %s", strerror(errno));
-		retme = -1;
-		goto cleanup;
-	}
-	struct sockaddr_in saddr;
-	saddr.sin_family = AF_INET;
-	saddr.sin_port = htons(port);
-	saddr.sin_addr.s_addr = inet_addr(addr);
-	if (bind(s, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) {
-		syslog(LOG_ERR, "socket bind failed: %s", strerror(errno));
-		retme = -1;
-		goto cleanup;
-	}
-	syslog(LOG_DEBUG, "socket bind success");
-	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: %s",
-				strerror(errno)
-			);
-			retme = -1;
-			goto cleanup;
-		}
-		struct passwd *u = getpwnam((const char *)&user);
-		if (setuid((*u).pw_uid) == -1) {
-			syslog(
-				LOG_ERR,
-				"failed to drop user privileges: %s",
-				strerror(errno)
-			);
-			retme = -1;
-			goto cleanup;
-		}
-	}
-#ifdef __illumos__
-	//TODO: illumos priv.h privdrop
-#endif
-	buf = malloc(1024);
-	if (buf == NULL) {
-		syslog(LOG_CRIT, "unable to allocate memory: %s", strerror(errno));
-		retme = -1;
-		goto cleanup;
-	}
-	while (!nbtpd_stop) {
-		struct sockaddr_in caddr;
-		unsigned int clen = sizeof(caddr);
-		memset(buf, '\0', 1024);
-		ssize_t recvd_bytes = 0;
-		if ((recvd_bytes = recvfrom(s, buf, 1024, 0,
-				(struct sockaddr *)&caddr, &clen)) < 0) {
-			continue;
-		}
-		if (recvd_bytes < 4) {
-			syslog(
-				LOG_ERR,
-				"ignoring invalid packet from %s.",
-				inet_ntoa(caddr.sin_addr)
-			);
-			continue;
-		}
-		syslog(
-			LOG_INFO,
-			"got connection from %s:%d",
-			inet_ntoa(caddr.sin_addr),
-			ntohs(caddr.sin_port)
-		);
-		nbd_nbtpd_args *args = malloc(sizeof(nbd_nbtpd_args));
-		if (args == NULL) {
-			syslog(
-				LOG_CRIT,
-				"unable to allocate memory: %s",
-				strerror(errno)
-			);
-			continue;
-		}
-		nbd_tftp_opcode oc = ((uint16_t)buf[0] << 8) + buf[1];
-		args->client = caddr;
-		args->err = 0;
-		memset(args->path, '\0', NBD_NBTPD_ARGS_PATH_MAX);
-		memset(args->mode, '\0', NBD_NBTPD_ARGS_MODE_MAX);
-		int i;
-		for(i = 2; buf[i] != 0 && i < recvd_bytes && (i - 2) < (NBD_NBTPD_ARGS_PATH_MAX - 1); 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) < (NBD_NBTPD_ARGS_MODE_MAX - 1); i++) {
-				args->mode[i - s] = buf[i];
-			}
-		}
-		//TODO: use std threads
-		pthread_t _thread;
-		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;
-		}
-		//TODO: use std threads
-		int e;
-		syslog(LOG_ERR, "spawning thread for %s", inet_ntoa(caddr.sin_addr));
-		if ((e = pthread_create(&_thread, 0, func, (void *)args)) != 0) {
-			syslog(
-				LOG_CRIT,
-				"unable to spawn thread: %s",
-				strerror(e)
-			);
-			free(args);
-		}
-	}
-cleanup:
-	free(buf);
-	close(s);
-	pthread_exit(NULL);
-	return retme;
-}
-