⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smb.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
				while (p > url && !isdigit(*p)) p--;				if (p == url) goto print_as_is;				/* FIXME: Use parse_date()? */				/* year */				while (p > url && isdigit(*p)) p--;				if (p == url || !isspace(*p)) goto print_as_is;				while (p > url && isspace(*p)) p--;				/* seconds */				while (p > url && isdigit(*p)) p--;				if (p == url || *p != ':') goto print_as_is;				p--;				/* minutes */				while (p > url && isdigit(*p)) p--;				if (p == url || *p != ':') goto print_as_is;				p--;				/* hours */				while (p > url && isdigit(*p)) p--;				if (p == url || !isspace(*p)) goto print_as_is;				p--;				/* day as number */				while (p > url && isdigit(*p)) p--;				while (p > url && isspace(*p)) p--;				if (p == url) goto print_as_is;				/* month */				while (p > url && !isspace(*p)) p--;				if (p == url || !isspace(*p)) goto print_as_is;				p--;				/* day name */				while (p > url && !isspace(*p)) p--;				if (p == url || !isspace(*p)) goto print_as_is;				while (p > url && isspace(*p)) p--;				/* file size */				if (p == url || !isdigit(*p)) goto print_as_is;				if (*p == '0' && isspace(*(p - 1))) may_be_dir = 1;				while (p > url && isdigit(*p)) p--;				if (p == url) goto print_as_is;				/* Magic to determine if we have a				 * filename or a dirname. Thanks to				 * smbclient ambiguous output. */				{					unsigned char *pp = p;					while (pp > url && isspace(*pp)) pp--;					if (p - pp <= 8) {						while (pp > url						       && (*pp == 'D'							  || *pp == 'H'							  || *pp == 'A'							  || *pp == 'S'						          || *pp == 'R'							  || *pp == 'V')) {						        if (*pp == 'D' && may_be_dir)								dir = 1;							pp--;						}					}					while (pp > url && isspace(*pp)) pp--;					p = pp;				}				/* Don't display '.' directory */				if (p == url && *url == '.') goto ignored;				p++;				add_to_string(page, "  <a href=\"");				add_bytes_to_string(page, url, p - url);				if (dir) add_char_to_string(page, '/');				add_to_string(page, "\">");				add_bytes_to_string(page, url, p - url);				add_to_string(page, "</a>");				add_bytes_to_string(page, p, line_end - p);			} else {				goto print_as_is;			}		} else {print_as_is:			add_bytes_to_string(page, line_start, line_len);		}		add_char_to_string(page, ASCII_LF);ignored:		line_start = line_end + start_offset + 1;	}	add_to_string(page, "</pre></body></html>");}static voidend_smb_connection(struct connection *conn){	struct smb_connection_info *si = conn->info;	struct uri *uri;	enum connection_state state = S_OK;	if (smb_get_cache(conn)) return;	if (conn->from) {		truncate_entry(conn->cached, conn->from, 1);		conn->cached->incomplete = 0;		goto bye;	}	/* Ensure termination by LF + NUL chars, memory for this	 * was reserved by smb_read_text(). */	if (si->textlen && si->text[si->textlen - 1] != ASCII_LF)		si->text[si->textlen++] = ASCII_LF;	si->text[si->textlen] = '\0';	uri = conn->uri;	if (uri->datalen	    && uri->data[uri->datalen - 1] != '/'	    && uri->data[uri->datalen - 1] != '\\'	    && (strstr(si->text, "NT_STATUS_FILE_IS_A_DIRECTORY")		|| strstr(si->text, "NT_STATUS_ACCESS_DENIED")		|| strstr(si->text, "ERRbadfile"))) {		redirect_cache(conn->cached, "/", 1, 0);	} else {		struct string page;		if (!init_string(&page)) {			state = S_OUT_OF_MEM;			goto bye;		}		parse_smbclient_output(uri, si, &page);		add_fragment(conn->cached, 0, page.source, page.length);		conn->from += page.length;		truncate_entry(conn->cached, page.length, 1);		conn->cached->incomplete = 0;		done_string(&page);		mem_free_set(&conn->cached->content_type, stracpy("text/html"));	}bye:	close_socket(conn, &conn->socket);	close_socket(conn, &conn->data_socket);	abort_conn_with_state(conn, state);}/* Close all non-terminal file descriptors. */static voidclose_all_non_term_fd(void){	int n;	int max = 1024;#ifdef RLIMIT_NOFILE	struct rlimit lim;	if (!getrlimit(RLIMIT_NOFILE, &lim))		max = lim.rlim_max;#endif	for (n = 3; n < max; n++)		close(n);}voidsmb_protocol_handler(struct connection *conn){	int out_pipe[2] = { -1, -1 };	int err_pipe[2] = { -1, -1 };	unsigned char *share, *dir;	unsigned char *p;	pid_t cpid;	int dirlen;	struct smb_connection_info *si;	struct uri *uri;	si = mem_calloc(1, sizeof(*si) + 2);	if (!si) {		abort_conn_with_state(conn, S_OUT_OF_MEM);		return;	}	conn->info = si;	uri = conn->uri;	p = strchr(uri->data, '/');	if (p && p - uri->data < uri->datalen) {		share = memacpy(uri->data, p - uri->data);		dir = p + 1;		/* FIXME: ensure @dir do not contain dangerous chars. --Zas */	} else if (uri->datalen) {		if (smb_get_cache(conn)) return;		redirect_cache(conn->cached, "/", 1, 0);		abort_conn_with_state(conn, S_OK);		return;	} else {		share = stracpy("");		dir = "";	}	if (!share) {		abort_conn_with_state(conn, S_OUT_OF_MEM);		return;	}	dirlen = strlen(dir);	if (!*share) {		si->list_type = SMB_LIST_SHARES;	} else if (!dirlen || dir[dirlen - 1] == '/'		   || dir[dirlen - 1] == '\\') {		si->list_type = SMB_LIST_DIR;	}	if (c_pipe(out_pipe) || c_pipe(err_pipe)) {		int s_errno = errno;		if (out_pipe[0] >= 0) close(out_pipe[0]);		if (out_pipe[1] >= 0) close(out_pipe[1]);		mem_free(share);		abort_conn_with_state(conn, -s_errno);		return;	}	conn->from = 0;	cpid = fork();	if (cpid == -1) {		int s_errno = errno;		close(out_pipe[0]);		close(out_pipe[1]);		close(err_pipe[0]);		close(err_pipe[1]);		mem_free(share);		retry_conn_with_state(conn, -s_errno);		return;	}	if (!cpid) {#define SMBCLIENT "smbclient"#define MAX_SMBCLIENT_ARGS 32		int n = 0;		unsigned char *v[MAX_SMBCLIENT_ARGS];		unsigned char *optstr;		close(1);		dup2(out_pipe[1], 1);		close(2);		dup2(err_pipe[1], 2);		close(0);		dup2(open("/dev/null", O_RDONLY), 0);		close_all_non_term_fd();		close(out_pipe[0]);		close(err_pipe[0]);		/* Usage: smbclient service <password> [options] */		v[n++] = SMBCLIENT;		/* FIXME: handle alloc failures. */		/* At this point, we are the child process.		 * Maybe we just don't care if the child kills itself		 * dereferencing a NULL pointer... -- Miciah */		/* Leaving random core files after itself is not what a nice		 * program does. Also, the user might also want to know, why		 * the hell does he see nothing on the screen. --pasky */		if (*share) {			/* Construct service path. */			asprintf((char **) &v[n++], "//%.*s/%s",				 uri->hostlen, uri->host, share);			/* Add password if any. */			if (uri->passwordlen && !uri->userlen) {				v[n++] = memacpy(uri->password, uri->passwordlen);			}		} else {			/* Get a list of shares available on a host. */			v[n++] = "-L";			v[n++] = memacpy(uri->host, uri->hostlen);		}		v[n++] = "-N";		/* Don't ask for a password. */		v[n++] = "-E";		/* Write messages to stderr instead of stdout. */		v[n++] = "-d 0";	/* Disable debug mode. */		if (uri->portlen) {			/* Connect to the specified port. */			v[n++] = "-p";			v[n++] = memacpy(uri->port, uri->portlen);		}		if (uri->userlen) {			/* Set the network username. */			v[n++] = "-U";			if (!uri->passwordlen) {				/* No password. */				v[n++] = memacpy(uri->user, uri->userlen);			} else {				/* With password. */				asprintf((char **) &v[n++], "%.*s%%%.*s",					 uri->userlen, uri->user,					 uri->passwordlen, uri->password);			}		}		if (*share) {			/* FIXME: use si->list_type here ?? --Zas */			if (!dirlen || dir[dirlen - 1] == '/' || dir[dirlen - 1] == '\\') {				if (dirlen) {					/* Initial directory. */					v[n++] = "-D";					v[n++] = dir;				}				v[n++] = "-c"; /* Execute semicolon separated commands. */				v[n++] = "ls"; /* List files. */			} else {				/* Copy remote file to stdout. */				unsigned char *s = straconcat("get \"", dir, "\" -", NULL);				unsigned char *ss = s;				v[n++] = "-c"; /* Execute semicolon separated commands. */				while ((ss = strchr(ss, '/'))) *ss = '\\'; /* Escape '/' */				v[n++] = s;			}		}		/* Optionally add SMB credentials file. */		optstr = get_opt_str("protocol.smb.credentials");		if (optstr[0]) {			v[n++] = "-A";			v[n++] = optstr;		}		v[n++] = NULL;	/* End of arguments list. */		assert(n < MAX_SMBCLIENT_ARGS);		execvp(SMBCLIENT, (char **) v);		/* FIXME: this message will never be displayed, since execvp()		 * failed. */		fprintf(stderr, SMBCLIENT " not found in $PATH");		_exit(1);#undef MAX_SMBCLIENT_ARGS#undef SMBCLIENT	}	mem_free(share);	conn->data_socket.fd = out_pipe[0];	conn->socket.fd = err_pipe[0];	close(out_pipe[1]);	close(err_pipe[1]);	set_handlers(out_pipe[0], (void (*)(void *)) smb_got_data, NULL, NULL, conn);	set_handlers(err_pipe[0], (void (*)(void *)) smb_got_text, NULL, NULL, conn);	set_connection_state(conn, S_CONN);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -