mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
The SMB protocol handling using libsmbclient.
This commit is contained in:
parent
927f08ec6a
commit
d399c809f7
40
configure.in
40
configure.in
@ -277,7 +277,7 @@ AC_PROG_GCC_TRADITIONAL
|
|||||||
AC_FUNC_MEMCMP
|
AC_FUNC_MEMCMP
|
||||||
AC_FUNC_MMAP
|
AC_FUNC_MMAP
|
||||||
AC_FUNC_STRFTIME
|
AC_FUNC_STRFTIME
|
||||||
AC_CHECK_FUNCS(cfmakeraw gethostbyaddr herror strerror)
|
AC_CHECK_FUNCS(atoll cfmakeraw gethostbyaddr herror strerror)
|
||||||
AC_CHECK_FUNCS(popen uname access chmod alarm timegm mremap)
|
AC_CHECK_FUNCS(popen uname access chmod alarm timegm mremap)
|
||||||
AC_CHECK_FUNCS(strcasecmp strncasecmp strcasestr strstr strchr strrchr)
|
AC_CHECK_FUNCS(strcasecmp strncasecmp strcasestr strstr strchr strrchr)
|
||||||
AC_CHECK_FUNCS(memmove bcopy stpcpy strdup index isdigit mempcpy memrchr)
|
AC_CHECK_FUNCS(memmove bcopy stpcpy strdup index isdigit mempcpy memrchr)
|
||||||
@ -1161,13 +1161,6 @@ AC_CHECK_HEADERS(execinfo.h, HAVE_EXECINFO=yes, HAVE_EXECINFO=no)
|
|||||||
# possible checks for other system-specific means go here
|
# possible checks for other system-specific means go here
|
||||||
|
|
||||||
|
|
||||||
dnl ===================================================================
|
|
||||||
dnl SMB protocol support.
|
|
||||||
dnl ===================================================================
|
|
||||||
|
|
||||||
AC_CHECK_PROG(HAVE_SMBCLIENT, smbclient, yes, no)
|
|
||||||
|
|
||||||
|
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
dnl Gettext grey zone. Beware.
|
dnl Gettext grey zone. Beware.
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
@ -1260,17 +1253,28 @@ EL_ARG_ENABLE(CONFIG_GOPHER, gopher, [Gopher protocol],
|
|||||||
EL_ARG_ENABLE(CONFIG_NNTP, nntp, [NNTP protocol],
|
EL_ARG_ENABLE(CONFIG_NNTP, nntp, [NNTP protocol],
|
||||||
[ --enable-nntp enable nntp protocol support])
|
[ --enable-nntp enable nntp protocol support])
|
||||||
|
|
||||||
dnl Force disable SMB before EL_ARG_DEPEND so that it logs the correct value.
|
dnl ===================================================================
|
||||||
if test "${enable_smb-no}" != no || test "${CONFIG_SMB-no}" != no; then
|
dnl SMB protocol support.
|
||||||
AC_MSG_WARN([Forcing --disable-smb because of vulnerability CVE-2006-5925.
|
dnl ===================================================================
|
||||||
If you want to use SMB, please see bug 844.])
|
EL_SAVE_FLAGS
|
||||||
|
|
||||||
|
if test "x${enable_smb}" != xno; then
|
||||||
|
AC_CHECK_HEADERS(libsmbclient.h, HAVE_SMBCLIENT=yes, HAVE_SMBCLIENT=no)
|
||||||
|
|
||||||
|
if test "$HAVE_SMBCLIENT" = yes; then
|
||||||
|
AC_CHECK_LIB(smbclient, smbc_init, HAVE_SMBCLIENT=yes, HAVE_SMBCLIENT=no)
|
||||||
|
if test "$HAVE_SMBCLIENT" = yes; then
|
||||||
|
LIBS="$LIBS -lsmbclient"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
EL_ARG_DEPEND(CONFIG_SMB, smb, [HAVE_SMBCLIENT:yes], [Samba protocol],
|
||||||
|
[ --enable-smb enable Samba protocol support])
|
||||||
|
|
||||||
|
if test "x$CONFIG_SMB" = xno; then
|
||||||
|
EL_RESTORE_FLAGS
|
||||||
fi
|
fi
|
||||||
enable_smb=no
|
|
||||||
CONFIG_SMB=no
|
|
||||||
EL_ARG_DEPEND(CONFIG_SMB, smb, [HAVE_SMBCLIENT:yes], [SMB protocol],
|
|
||||||
[ --enable-smb not currently allowed])
|
|
||||||
dnl EL_ARG_DEPEND(CONFIG_SMB, smb, [HAVE_SMBCLIENT:yes], [SMB protocol],
|
|
||||||
dnl [ --disable-smb disable SMB protocol support (requires smbclient)])
|
|
||||||
|
|
||||||
|
|
||||||
EL_ARG_ENABLE(CONFIG_MOUSE, mouse, [Mouse handling],
|
EL_ARG_ENABLE(CONFIG_MOUSE, mouse, [Mouse handling],
|
||||||
|
@ -109,6 +109,9 @@ init_directory_listing(struct string *page, struct uri *uri)
|
|||||||
case PROTOCOL_GOPHER:
|
case PROTOCOL_GOPHER:
|
||||||
info = "Gopher";
|
info = "Gopher";
|
||||||
break;
|
break;
|
||||||
|
case PROTOCOL_SMB:
|
||||||
|
info = "Samba";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
info = "?";
|
info = "?";
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
top_builddir=../../..
|
top_builddir=../../..
|
||||||
include $(top_builddir)/Makefile.config
|
include $(top_builddir)/Makefile.config
|
||||||
|
|
||||||
OBJS = smb.o
|
OBJS = smb2.o
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.lib
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
452
src/protocol/smb/smb2.c
Normal file
452
src/protocol/smb/smb2.c
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
/* SMB protocol implementation */
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE /* Needed for asprintf() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef HAVE_LIBSMBCLIENT_H
|
||||||
|
#include <libsmbclient.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h> /* OS/2 needs this after sys/types.h */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include "cache/cache.h"
|
||||||
|
#include "config/options.h"
|
||||||
|
#include "intl/gettext/libintl.h"
|
||||||
|
#include "main/module.h"
|
||||||
|
#include "main/select.h"
|
||||||
|
#include "network/connection.h"
|
||||||
|
#include "network/socket.h"
|
||||||
|
#include "osdep/osdep.h"
|
||||||
|
#include "protocol/auth/auth.h"
|
||||||
|
#include "protocol/common.h"
|
||||||
|
#include "protocol/protocol.h"
|
||||||
|
#include "protocol/smb/smb.h"
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "util/conv.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/snprintf.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
/* These options are not used. */
|
||||||
|
struct option_info smb_options[] = {
|
||||||
|
INIT_OPT_TREE("protocol", N_("SMB"),
|
||||||
|
"smb", 0,
|
||||||
|
N_("SAMBA specific options.")),
|
||||||
|
|
||||||
|
INIT_OPT_STRING("protocol.smb", N_("Credentials"),
|
||||||
|
"credentials", 0, "",
|
||||||
|
N_("Credentials file passed to smbclient via -A option.")),
|
||||||
|
|
||||||
|
NULL_OPTION_INFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct module smb_protocol_module = struct_module(
|
||||||
|
/* name: */ N_("SMB"),
|
||||||
|
/* options: */ smb_options,
|
||||||
|
/* hooks: */ NULL,
|
||||||
|
/* submodules: */ NULL,
|
||||||
|
/* data: */ NULL,
|
||||||
|
/* init: */ NULL,
|
||||||
|
/* done: */ NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
static void
|
||||||
|
smb_error(int error)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "text/x-error");
|
||||||
|
printf("%d\n", error);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const struct smbc_dirent **da = (const struct smbc_dirent **)a;
|
||||||
|
const struct smbc_dirent **db = (const struct smbc_dirent **)b;
|
||||||
|
int res = (*da)->smbc_type - (*db)->smbc_type;
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return strcmp((*da)->name, (*db)->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_entry(struct smbc_dirent *entry, unsigned char dircolor[])
|
||||||
|
{
|
||||||
|
switch (entry->smbc_type) {
|
||||||
|
case SMBC_WORKGROUP:
|
||||||
|
printf("<a href=\"%s\">", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("<font color=\"%s\"><b>", dircolor);
|
||||||
|
}
|
||||||
|
printf("%s", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("</b></font>");
|
||||||
|
}
|
||||||
|
puts("</a> WORKGROUP");
|
||||||
|
break;
|
||||||
|
case SMBC_SERVER:
|
||||||
|
printf("<a href=\"%s\">", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("<font color=\"%s\"><b>", dircolor);
|
||||||
|
}
|
||||||
|
printf("%s", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("</b></font>");
|
||||||
|
}
|
||||||
|
puts("</a> SERVER");
|
||||||
|
break;
|
||||||
|
case SMBC_FILE_SHARE:
|
||||||
|
printf("<a href=\"%s\">", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("<font color=\"%s\"><b>", dircolor);
|
||||||
|
}
|
||||||
|
printf("%s", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("</b></font>");
|
||||||
|
}
|
||||||
|
puts("</a> FILE SHARE");
|
||||||
|
case SMBC_PRINTER_SHARE:
|
||||||
|
printf("%s PRINTER\n", entry->name);
|
||||||
|
break;
|
||||||
|
case SMBC_COMMS_SHARE:
|
||||||
|
printf("%s COMM\n", entry->name);
|
||||||
|
break;
|
||||||
|
case SMBC_IPC_SHARE:
|
||||||
|
printf("%s IPC\n", entry->name);
|
||||||
|
break;
|
||||||
|
case SMBC_DIR:
|
||||||
|
printf("<a href=\"%s\">", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("<font color=\"%s\"><b>", dircolor);
|
||||||
|
}
|
||||||
|
printf("%s", entry->name);
|
||||||
|
if (*dircolor) {
|
||||||
|
printf("</b></font>");
|
||||||
|
}
|
||||||
|
puts("</a>");
|
||||||
|
break;
|
||||||
|
case SMBC_LINK:
|
||||||
|
printf("<a href=\"%s\">%s</a> Link\n", entry->name, entry->name);
|
||||||
|
break;
|
||||||
|
case SMBC_FILE:
|
||||||
|
printf("<a href=\"%s\">%s</a>\n", entry->name, entry->name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* unknown type */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sort_and_display_entries(int dir, unsigned char dircolor[])
|
||||||
|
{
|
||||||
|
struct smbc_dirent *fentry, **table = NULL;
|
||||||
|
int size = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while ((fentry = smbc_readdir(dir))) {
|
||||||
|
struct smbc_dirent **new_table, *new_entry;
|
||||||
|
int length = sizeof(*fentry) + fentry->namelen;
|
||||||
|
|
||||||
|
if (!strcmp(fentry->name, "."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
new_entry = mem_alloc(length);
|
||||||
|
if (!new_entry)
|
||||||
|
continue;
|
||||||
|
new_table = mem_realloc(table, (size + 1) * sizeof(*table));
|
||||||
|
if (!new_table)
|
||||||
|
continue;
|
||||||
|
memcpy(new_entry, fentry, length);
|
||||||
|
table = new_table;
|
||||||
|
table[size] = new_entry;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
qsort(table, size, sizeof(*table),
|
||||||
|
(int (*)(const void *, const void *)) compare);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
display_entry(table[i], dircolor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smb_directory(int dir, struct uri *uri)
|
||||||
|
{
|
||||||
|
struct string buf;
|
||||||
|
unsigned char dircolor[8] = "";
|
||||||
|
|
||||||
|
if (init_directory_listing(&buf, uri) != S_OK) {
|
||||||
|
smb_error(-S_OUT_OF_MEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "text/html");
|
||||||
|
fclose(stderr);
|
||||||
|
|
||||||
|
puts(buf.source);
|
||||||
|
|
||||||
|
if (get_opt_bool("document.browse.links.color_dirs")) {
|
||||||
|
color_to_string(get_opt_color("document.colors.dirs"),
|
||||||
|
(unsigned char *) &dircolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_and_display_entries(dir, dircolor);
|
||||||
|
puts("</pre><hr/></body></html>");
|
||||||
|
smbc_closedir(dir);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smb_auth(const char *srv, const char *shr, char *wg, int wglen, char *un,
|
||||||
|
int unlen, char *pw, int pwlen)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
#define READ_SIZE 4096
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_smb(struct connection *conn)
|
||||||
|
{
|
||||||
|
unsigned char url_data[1024];
|
||||||
|
struct uri *uri = conn->uri;
|
||||||
|
struct auth_entry *auth = find_auth(uri);
|
||||||
|
unsigned char *url;
|
||||||
|
int dir;
|
||||||
|
|
||||||
|
if ((uri->userlen && uri->passwordlen) || !auth || !auth->valid) {
|
||||||
|
url = get_uri_string(uri, URI_BASE);
|
||||||
|
} else {
|
||||||
|
snprintf(url_data, 1024, "smb://%s:%s@%s", auth->user, auth->password,
|
||||||
|
get_uri_string(uri, URI_HOST | URI_PORT | URI_DATA));
|
||||||
|
url = url_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
smb_error(-S_OUT_OF_MEM);
|
||||||
|
}
|
||||||
|
if (smbc_init(smb_auth, 0)) {
|
||||||
|
smb_error(errno);
|
||||||
|
};
|
||||||
|
dir = smbc_opendir(url);
|
||||||
|
if (dir >= 0) {
|
||||||
|
smb_directory(dir, conn->uri);
|
||||||
|
} else {
|
||||||
|
char buf[READ_SIZE];
|
||||||
|
struct stat sb;
|
||||||
|
int r, res;
|
||||||
|
int file = smbc_open(url, O_RDONLY, 0);
|
||||||
|
|
||||||
|
if (file < 0) {
|
||||||
|
smb_error(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = smbc_fstat(file, &sb);
|
||||||
|
if (res) {
|
||||||
|
smb_error(res);
|
||||||
|
}
|
||||||
|
/* filesize */
|
||||||
|
fprintf(stderr, "%" OFF_T_FORMAT, sb.st_size);
|
||||||
|
fclose(stderr);
|
||||||
|
|
||||||
|
while ((r = smbc_read(file, buf, READ_SIZE)) > 0) {
|
||||||
|
if (safe_write(STDOUT_FILENO, buf, r) <= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
smbc_close(file);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef READ_SIZE
|
||||||
|
|
||||||
|
/* Kill the current connection and ask for a username/password for the next
|
||||||
|
* try. */
|
||||||
|
static void
|
||||||
|
prompt_username_pw(struct connection *conn)
|
||||||
|
{
|
||||||
|
add_auth_entry(conn->uri, "Samba", NULL, NULL, 0);
|
||||||
|
abort_connection(conn, S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smb_got_error(struct socket *socket, struct read_buffer *rb)
|
||||||
|
{
|
||||||
|
int len = rb->length;
|
||||||
|
struct connection *conn = socket->conn;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
abort_connection(conn, -errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb->data[len] = '\0';
|
||||||
|
error = atoi(rb->data);
|
||||||
|
kill_buffer_data(rb, len);
|
||||||
|
switch (error) {
|
||||||
|
case EACCES:
|
||||||
|
prompt_username_pw(conn);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort_connection(conn, -error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smb_got_data(struct socket *socket, struct read_buffer *rb)
|
||||||
|
{
|
||||||
|
int len = rb->length;
|
||||||
|
struct connection *conn = socket->conn;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
abort_connection(conn, -errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
abort_connection(conn, S_OK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket->state = SOCKET_END_ONCLOSE;
|
||||||
|
conn->received += len;
|
||||||
|
if (add_fragment(conn->cached, conn->from, rb->data, len) == 1)
|
||||||
|
conn->tries = 0;
|
||||||
|
conn->from += len;
|
||||||
|
kill_buffer_data(rb, len);
|
||||||
|
|
||||||
|
read_from_socket(socket, rb, S_TRANS, smb_got_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smb_got_header(struct socket *socket, struct read_buffer *rb)
|
||||||
|
{
|
||||||
|
struct connection *conn = socket->conn;
|
||||||
|
struct read_buffer *buf;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
conn->cached = get_cache_entry(conn->uri);
|
||||||
|
if (!conn->cached) {
|
||||||
|
close(socket->fd);
|
||||||
|
close(conn->data_socket->fd);
|
||||||
|
abort_connection(conn, S_OUT_OF_MEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket->state = SOCKET_END_ONCLOSE;
|
||||||
|
|
||||||
|
if (rb->length > 0) {
|
||||||
|
unsigned char *ctype = memacpy(rb->data, rb->length);
|
||||||
|
|
||||||
|
if (ctype && *ctype) {
|
||||||
|
if (!strcmp(ctype, "text/x-error")) {
|
||||||
|
error = 1;
|
||||||
|
mem_free(ctype);
|
||||||
|
} else {
|
||||||
|
if (ctype[0] >= '0' && ctype[0] <= '9') {
|
||||||
|
#ifdef HAVE_ATOLL
|
||||||
|
conn->est_length = (off_t)atoll(ctype);
|
||||||
|
#else
|
||||||
|
conn->est_length = (off_t)atoi(ctype);
|
||||||
|
#endif
|
||||||
|
mem_free(ctype);
|
||||||
|
}
|
||||||
|
else mem_free_set(&conn->cached->content_type, ctype);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mem_free_if(ctype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = alloc_read_buffer(conn->data_socket);
|
||||||
|
if (!buf) {
|
||||||
|
close(socket->fd);
|
||||||
|
close(conn->data_socket->fd);
|
||||||
|
abort_connection(conn, S_OUT_OF_MEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
mem_free_set(&conn->cached->content_type, stracpy("text/html"));
|
||||||
|
read_from_socket(conn->data_socket, buf, S_CONN, smb_got_error);
|
||||||
|
} else {
|
||||||
|
read_from_socket(conn->data_socket, buf, S_CONN, smb_got_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
smb_protocol_handler(struct connection *conn)
|
||||||
|
{
|
||||||
|
int smb_pipe[2] = { -1, -1 };
|
||||||
|
int header_pipe[2] = { -1, -1 };
|
||||||
|
pid_t cpid;
|
||||||
|
|
||||||
|
if (c_pipe(smb_pipe) || c_pipe(header_pipe)) {
|
||||||
|
int s_errno = errno;
|
||||||
|
|
||||||
|
if (smb_pipe[0] >= 0) close(smb_pipe[0]);
|
||||||
|
if (smb_pipe[1] >= 0) close(smb_pipe[1]);
|
||||||
|
if (header_pipe[0] >= 0) close(header_pipe[0]);
|
||||||
|
if (header_pipe[1] >= 0) close(header_pipe[1]);
|
||||||
|
abort_connection(conn, -s_errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
conn->from = 0;
|
||||||
|
conn->unrestartable = 1;
|
||||||
|
|
||||||
|
cpid = fork();
|
||||||
|
if (cpid == -1) {
|
||||||
|
int s_errno = errno;
|
||||||
|
|
||||||
|
close(smb_pipe[0]);
|
||||||
|
close(smb_pipe[1]);
|
||||||
|
close(header_pipe[0]);
|
||||||
|
close(header_pipe[1]);
|
||||||
|
retry_connection(conn, -s_errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cpid) {
|
||||||
|
dup2(smb_pipe[1], 1);
|
||||||
|
dup2(open("/dev/null", O_RDONLY), 0);
|
||||||
|
dup2(header_pipe[1], 2);
|
||||||
|
close(smb_pipe[0]);
|
||||||
|
close(header_pipe[0]);
|
||||||
|
|
||||||
|
close_all_non_term_fd();
|
||||||
|
do_smb(conn);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
struct read_buffer *buf2;
|
||||||
|
|
||||||
|
conn->data_socket->fd = smb_pipe[0];
|
||||||
|
conn->socket->fd = header_pipe[0];
|
||||||
|
close(smb_pipe[1]);
|
||||||
|
close(header_pipe[1]);
|
||||||
|
buf2 = alloc_read_buffer(conn->socket);
|
||||||
|
if (!buf2) {
|
||||||
|
close(smb_pipe[0]);
|
||||||
|
close(header_pipe[0]);
|
||||||
|
abort_connection(conn, S_OUT_OF_MEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
read_from_socket(conn->socket, buf2, S_CONN, smb_got_header);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user