#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;
}