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

📄 smb.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "links.h"#ifndef DISABLE_SMB#define SMBCLIENT	0#define SMBC		1#define N_CLIENTS	2int smb_client = 0;struct smb_connection_info {	int client;	int list;	int cl;	int ntext;	unsigned char text[1];};void smb_got_data(struct connection *);void smb_got_text(struct connection *);void end_smb_connection(struct connection *);int smbc_get_num(unsigned char *, int *, off_t *);void smb_read_text(struct connection *, int);void smb_func(struct connection *c){	int i;	int po[2];	int pe[2];	unsigned char *host, *user, *pass, *port, *data1, *data, *share, *dir;	int datal;	unsigned char *p;	pid_t r;	struct smb_connection_info *si;	si = mem_alloc(sizeof(struct smb_connection_info) + 2);	memset(si, 0, sizeof(struct smb_connection_info));	c->info = si;	si->client = smb_client;	host = get_host_name(c->url);	if (!host) {		setcstate(c, S_INTERNAL);		abort_connection(c);		return;	}	if (!(user = get_user_name(c->url))) user = stracpy("");	if (!(pass = get_pass(c->url))) pass = stracpy("");	if (!(port = get_port_str(c->url))) port = stracpy("");	if (!(data1 = get_url_data(c->url))) data1 = "";	data = init_str(), datal = 0;	add_conv_str(&data, &datal, data1, strlen(data1), -2);	for (i = 0; data[i]; i++) if (data[i] < 32 || data[i] == ';' || (data[i] == '"' && smb_client == SMBCLIENT)) {/* ';' shouldn't cause security problems but samba doesn't like it *//* '"' is allowed for smbc */		mem_free(host);		mem_free(port);		mem_free(user);		mem_free(pass);		mem_free(data);		setcstate(c, S_BAD_URL);		abort_connection(c);		return;	}	if ((p = strchr(data, '/'))) share = memacpy(data, p - data), dir = p + 1;	else if (*data) {		if (!c->cache && get_cache_entry(c->url, &c->cache)) {			mem_free(host);			mem_free(port);			mem_free(user);			mem_free(pass);			mem_free(data);			setcstate(c, S_OUT_OF_MEM);			abort_connection(c);			return;		}		if (c->cache->redirect) mem_free(c->cache->redirect);		c->cache->redirect = stracpy(c->url);		c->cache->redirect_get = 1;		add_to_strn(&c->cache->redirect, "/");		c->cache->incomplete = 0;		mem_free(host);		mem_free(port);		mem_free(user);		mem_free(pass);		mem_free(data);		setcstate(c, S_OK);		abort_connection(c);		return;	} else share = stracpy(""), dir = "";	if (!*share) si->list = 1;	else if (!*dir || dir[strlen(dir) - 1] == '/' || dir[strlen(dir) - 1] == '\\') si->list = 2;	if (c_pipe(po)) {		mem_free(host);		mem_free(port);		mem_free(user);		mem_free(pass);		mem_free(share);		mem_free(data);		setcstate(c, -errno);		abort_connection(c);		return;	}	if (c_pipe(pe)) {		mem_free(host);		mem_free(port);		mem_free(user);		mem_free(pass);		mem_free(share);		mem_free(data);		close(po[0]);		close(po[1]);		setcstate(c, -errno);		abort_connection(c);		return;	}	c->from = 0;	r = fork();	if (r == -1) {		mem_free(host);		mem_free(port);		mem_free(user);		mem_free(pass);		mem_free(share);		mem_free(data);		close(po[0]);		close(po[1]);		close(pe[0]);		close(pe[1]);		setcstate(c, -errno);		retry_connection(c);		return;	}	if (!r) {		int n;		unsigned char *v[32];		unsigned char *uphp;		close_fork_tty();		close(1);		if (si->list) dup2(pe[1], 1);		else dup2(po[1], 1);		close(2);		dup2(pe[1], 2);		close(0);		open("/dev/null", O_RDONLY);		close(po[0]);		close(pe[0]);		close(po[1]);		close(pe[1]);		n = 0;		switch (si->client) {		case SMBCLIENT:			v[n++] = "smbclient";			if (!*share) {				v[n++] = "-L";				v[n++] = host;			} else {				unsigned char *s = stracpy("//");				add_to_strn(&s, host);				add_to_strn(&s, "/");				add_to_strn(&s, share);				v[n++] = s;				if (*pass && !*user) {					v[n++] = pass;				}			}			v[n++] = "-N";			v[n++] = "-E";			if (*port) {				v[n++] = "-p";				v[n++] = port;			}			if (*user) {				v[n++] = "-U";				if (!*pass) {					v[n++] = user;				} else {					unsigned char *s = stracpy(user);					add_to_strn(&s, "%");					add_to_strn(&s, pass);					v[n++] = s;				}			}			if (*share) {				if (!*dir || dir[strlen(dir) - 1] == '/' || dir[strlen(dir) - 1] == '\\') {					if (*dir) {						v[n++] = "-D";						v[n++] = dir;					}					v[n++] = "-c";					v[n++] = "ls";				} else {					unsigned char *ss;					unsigned char *s = stracpy("get \"");					add_to_strn(&s, dir);					add_to_strn(&s, "\" -");					while ((ss = strchr(s, '/'))) *ss = '\\';					v[n++] = "-c";					v[n++] = s;				}			}			break;		case SMBC:			v[n++] = "smbc";			uphp = stracpy("");			if (*user) {				add_to_strn(&uphp, user);				if (*pass) {					add_to_strn(&uphp, ":");					add_to_strn(&uphp, pass);				}				add_to_strn(&uphp, "@");			}			add_to_strn(&uphp, host);			if (*port) {				add_to_strn(&uphp, ":");				add_to_strn(&uphp, port);			}			if (!*share) {				v[n++] = "-L";				v[n++] = uphp;			} else {				add_to_strn(&uphp, "/");				add_to_strn(&uphp, share);				if (!*dir || dir[strlen(dir) - 1] == '/' || dir[strlen(dir) - 1] == '\\') {					add_to_strn(&uphp, "/");					add_to_strn(&uphp, dir);					v[n++] = uphp;					v[n++] = "-c";					v[n++] = "ls";				} else {					unsigned char *d = init_str();					int dl = 0;					unsigned char *dp = dir;					v[n++] = uphp;					v[n++] = "-c";					add_to_str(&d, &dl, "pipe cat ");					while (*dp) {						if (*dp <= ' ' || *dp == '\\' || *dp == '"' || *dp == '\'' || *dp == '*' || *dp == '?') add_chr_to_str(&d, &dl, '\\');						add_chr_to_str(&d, &dl, *dp);						dp++;					}					v[n++] = d;				}			}			break;		default:			internal("unsuported smb client");		}		v[n++] = NULL;		execvp(v[0], (char **)(void *)v);		fprintf(stderr, "client not found");		fflush(stderr);		_exit(1);	}	c->pid = r;	mem_free(host);	mem_free(port);	mem_free(user);	mem_free(pass);	mem_free(share);	mem_free(data);	c->sock1 = po[0];	c->sock2 = pe[0];	close(po[1]);	close(pe[1]);	set_handlers(po[0], (void (*)(void *))smb_got_data, NULL, NULL, c);	set_handlers(pe[0], (void (*)(void *))smb_got_text, NULL, NULL, c);	setcstate(c, S_CONN);}int smbc_get_num(unsigned char *text, int *ptr, off_t *res){	off_t num;	int dec, dec_order, unit;	int was_digit;	int i = *ptr;	while (text[i] == ' ' || text[i] == '\t') i++;	was_digit = 0;	num = 0;	while (text[i] >= '0' && text[i] <= '9') {		num = num * 10 + text[i] - '0';		i++;		was_digit = 1;	}	dec = 0; dec_order = 1;	if (text[i] == '.') {		i++;		while (text[i] >= '0' && text[i] <= '9') {			if (dec_order < 1000000) {				dec = dec * 10 + text[i] - '0';				dec_order *= 10;			}			i++;			was_digit = 1;		}	}	if (!was_digit) return -1;	if (upcase(text[i]) == 'B') unit = 1;	else if (upcase(text[i]) == 'K') unit = 1 << 10;	else if (upcase(text[i]) == 'M') unit = 1 << 20;	else if (upcase(text[i]) == 'G') unit = 1 << 30;	else return -1;	i++;	*ptr = i;	*res = num * unit + (double)dec * ((double)unit / (double)dec_order);	return 0;}void smb_read_text(struct connection *c, int sock){	int r;	struct smb_connection_info *si = c->info;	if ((unsigned)sizeof(struct smb_connection_info) + si->ntext + page_size + 2 > MAXINT) overalloc();	si = mem_realloc(si, sizeof(struct smb_connection_info) + si->ntext + page_size + 2);	c->info = si;	r = read(sock, si->text + si->ntext, page_size);	if (r == -1) {		setcstate(c, -errno);

⌨️ 快捷键说明

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