#ifdef __linux__ #define _POSIX_C_SOURCE 200809L #define _DEFAULT_SOURCE #endif #include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #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 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; }