about summary refs log tree commit diff stats
path: root/src/handlers.c
blob: 10599a336233ccd6ca75eabd64bea9d141bc7aa4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888 } /* Comment */
.highlight .err { color: #A61717; background-color: #E3D2D2 } /* Error */
.highlight .k { color: #080; font-weight: bold } /* Keyword */
.highlight .ch { color: #888 } /* Comment.Hashbang */
.highlight .cm { color: #888 } /* Comment.Multiline */
.highlight .cp { color: #C00; font-weight: bold } /* Comment
#ifdef __linux__
#define _POSIX_C_SOURCE 200809L
#define _DEFAULT_SOURCE
#endif

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <syslog.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#ifdef __FreeBSD__
#include <sys/param.h>
#endif

#include "handlers.h"
#include "packet.h"
#include "netascii.h"

typedef enum opmode {
	NOT_FOUND,
	NETASCII,
	OCTAL,
	MAIL
// any additional modes
} nbd_opmode;

nbd_opmode get_mode(char *mode) {
	nbd_opmode opmode;
	if (strncmp((const char *)mode, (const char *)&"netascii", NBD_NBTPD_ARGS_MODE_MAX) == 0) {
		opmode = NETASCII;
	} else if (strncmp((const char *)mode, (const char *)&"octal", NBD_NBTPD_ARGS_MODE_MAX) == 0) {
		opmode = OCTAL;
	} else if (strncmp((const char *)mode, (const char *)&"mail", NBD_NBTPD_ARGS_MODE_MAX) == 0) {
		opmode = MAIL;
	} else {
		opmode = NOT_FOUND;
	}
	return opmode;
}

void *read_req_resp(void *args) {
	char *fname = NULL, *wd = NULL, *buf = NULL;
	FILE *fp = NULL;
	nbd_nbtpd_args *argptr = (nbd_nbtpd_args *)args;
	if (!is_netascii_str((char *)&argptr->path)) {
		argptr->err = 1;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	fname = realpath((char *)&argptr->path, NULL);
	if (fname == NULL) {
		syslog(LOG_ERR, "unable to get real path: %s", strerror(errno));
		argptr->err = 1;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	/*
	 * POSIX does not define what happens when getcwd() is given NULL.
	 * This means that illumos libc and GNU libc both return a newly
	 * malloc()'d string, while FreeBSD libc does not.  Also, FreeBSD uses
	 * constant MAXPATHLEN defined in <sys/param.h> rather than PATH_MAX.
	 */
#ifdef __FreeBSD__
	wd = malloc(MAXPATHLEN);
	if (wd == NULL) {
		syslog(LOG_ERR, "unable to allocate PATH_MAX memory: %s", strerror(errno));
		argptr->err = 0;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	if (getcwd(wd, MAXPATHLEN) == NULL) {
		argptr->err = 0;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
#else
	if ((wd = getcwd(NULL, PATH_MAX)) == NULL) {
		argptr->err = 0;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
#endif
	if (!strncmp(wd, fname, sizeof(wd) - 1)) {
		argptr->err = 2;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	if (!is_netascii_str((char *)&argptr->mode)) {
		argptr->err = 4;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	nbd_opmode opmode = get_mode((char *)&argptr->mode);
	switch (opmode) {
		case NETASCII:
			break;
		case OCTAL:
			break;
		default:
			argptr->err = 4;
			goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	fp = fopen(fname, "r");

	buf = malloc(512);
	if (buf == NULL) {
		syslog(
			LOG_CRIT,
			"failed to allocate memory: %s",
			strerror(errno)
		);
		argptr->err = 0;
		goto nbd_nbtpd_thread_read_cleanup_ps;
	}
	memset(buf, '\0', 512);
	int s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s <= 0) {
		syslog(LOG_ERR, "unable to define socket: %s", strerror(errno));
		goto nbd_nbtpd_thread_read_cleanup;
	}

	close(s);
nbd_nbtpd_thread_read_cleanup:
	fclose(fp);
	free(buf);
	free(fname);
	free(wd);
	free(args);
	return (void *)NULL;
nbd_nbtpd_thread_read_cleanup_ps:
	if (fp != NULL) {
		fclose(fp);
	}
	free(buf);
	free(fname);
	free(wd);
	return nbd_nbtpd_resp_error(args);
}

void *write_req_resp(void *args) {
	free(args);
	return (void *)NULL;
}

void *nbd_nbtpd_resp_error(void *args) {
	//TODO: open socket and scream error, then cleanup.
	free(args);
	return (void *)NULL;
}