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

📄 smbget.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   smbget: a wget-like utility with support for recursive downloading and    	smb:// urls   Copyright (C) 2003-2004 Jelmer Vernooij <jelmer@samba.org>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "includes.h"#include "libsmbclient.h"#if _FILE_OFFSET_BITS==64#define OFF_T_FORMAT "%lld"#define OFF_T_FORMAT_CAST long long#else#define OFF_T_FORMAT "%ld"#define OFF_T_FORMAT_CAST long#endifint columns = 0;static int _resume, _recursive, debuglevel;static char *outputfile;time_t total_start_time = 0;off_t total_bytes = 0;#define SMB_MAXPATHLEN MAXPATHLEN/* Number of bytes to read when checking whether local and remote file are really the same file */#define RESUME_CHECK_SIZE 				512#define RESUME_DOWNLOAD_OFFSET			1024#define RESUME_CHECK_OFFSET				RESUME_DOWNLOAD_OFFSET+RESUME_CHECK_SIZE/* Number of bytes to read at once */#define SMB_DEFAULT_BLOCKSIZE 					64000const char *username = NULL, *password = NULL, *workgroup = NULL;int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0, send_stdout = 0;int blocksize = SMB_DEFAULT_BLOCKSIZE;int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile);int get_num_cols(void){#ifdef TIOCGWINSZ	struct winsize ws;	if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {		return 0;	}	return ws.ws_col;#else#warning No support for TIOCGWINSZ	char *cols = getenv("COLUMNS");	if(!cols) return 0;	return atoi(cols);#endif}void change_columns(int sig){	columns = get_num_cols();}void human_readable(off_t s, char *buffer, int l){	if(s > 1024 * 1024 * 1024) snprintf(buffer, l, "%.2fGb", 1.0 * s / (1024 * 1024 * 1024));	else if(s > 1024 * 1024) snprintf(buffer, l, "%.2fMb", 1.0 * s / (1024 * 1024));	else if(s > 1024) snprintf(buffer, l, "%.2fkb", 1.0 * s / 1024);	else snprintf(buffer, l, OFF_T_FORMAT"b", (OFF_T_FORMAT_CAST)s);}void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen){	static char hasasked = 0;	char *wgtmp, *usertmp;	char tmp[128];	if(hasasked) return;	hasasked = 1;	if(!nonprompt && !username) {		printf("Username for %s at %s [guest] ", shr, srv);		fgets(tmp, sizeof(tmp), stdin);		if(tmp[strlen(tmp)-1] == '\n')tmp[strlen(tmp)-1] = '\0';		strncpy(un, tmp, unlen-1);	} else if(username) strncpy(un, username, unlen-1);	if(!nonprompt && !password) {		char *prompt, *pass;		asprintf(&prompt, "Password for %s at %s: ", shr, srv);		pass = getpass(prompt);		free(prompt);		strncpy(pw, pass, pwlen-1);	} else if(password) strncpy(pw, password, pwlen-1);	if(workgroup)strncpy(wg, workgroup, wglen-1);	wgtmp = SMB_STRNDUP(wg, wglen); 	usertmp = SMB_STRNDUP(un, unlen);	if(!quiet)printf("Using workgroup %s, %s%s\n", wgtmp, *usertmp?"user ":"guest user", usertmp);	free(wgtmp); free(usertmp);}int smb_download_dir(const char *base, const char *name, int resume){	char path[SMB_MAXPATHLEN];	int dirhandle;	struct smbc_dirent *dirent;	const char *relname = name;	char *tmpname;	struct stat remotestat;	snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (base[0] && name[0] && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name);	/* List files in directory and call smb_download_file on them */	dirhandle = smbc_opendir(path);	if(dirhandle < 1) {		if(errno == ENOTDIR) return smb_download_file(base, name, 1, resume, NULL);		fprintf(stderr, "Can't open directory %s: %s\n", path, strerror(errno));		return 0;	}	while(*relname == '/')relname++;	mkdir(relname, 0755);		tmpname = SMB_STRDUP(name);	while((dirent = smbc_readdir(dirhandle))) {		char *newname;		if(!strcmp(dirent->name, ".") || !strcmp(dirent->name, ".."))continue;		asprintf(&newname, "%s/%s", tmpname, dirent->name);		switch(dirent->smbc_type) {		case SMBC_DIR:			smb_download_dir(base, newname, resume);			break;		case SMBC_WORKGROUP:			smb_download_dir("smb://", dirent->name, resume);			break;		case SMBC_SERVER:			smb_download_dir("smb://", dirent->name, resume);			break;		case SMBC_FILE:			smb_download_file(base, newname, 1, resume, NULL);			break;		case SMBC_FILE_SHARE:			smb_download_dir(base, newname, resume);			break;		case SMBC_PRINTER_SHARE:			if(!quiet)printf("Ignoring printer share %s\n", dirent->name);			break;		case SMBC_COMMS_SHARE:			if(!quiet)printf("Ignoring comms share %s\n", dirent->name);			break;					case SMBC_IPC_SHARE:			if(!quiet)printf("Ignoring ipc$ share %s\n", dirent->name);			break;		default:			fprintf(stderr, "Ignoring file '%s' of type '%d'\n", newname, dirent->smbc_type);			break;		}		free(newname);	}	free(tmpname);	if(keep_permissions) {		if(smbc_fstat(dirhandle, &remotestat) < 0) {			fprintf(stderr, "Unable to get stats on %s on remote server\n", path);			smbc_closedir(dirhandle);			return 0;		}				if(chmod(relname, remotestat.st_mode) < 0) {			fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, remotestat.st_mode);			smbc_closedir(dirhandle);			return 0;		}	}	smbc_closedir(dirhandle);	return 1;}char *print_time(long t){	static char buffer[100];	int secs, mins, hours;	if(t < -1) {		strncpy(buffer, "Unknown", sizeof(buffer));		return buffer;	}	secs = (int)t % 60;	mins = (int)t / 60 % 60;	hours = (int)t / (60 * 60);	snprintf(buffer, sizeof(buffer)-1, "%02d:%02d:%02d", hours, mins, secs);	return buffer;}void print_progress(const char *name, time_t start, time_t now, off_t start_pos, off_t pos, off_t total){	double avg = 0.0;	long  eta = -1; 	double prcnt = 0.0;	char hpos[20], htotal[20], havg[20];	char *status, *filename;	int len;	if(now - start)avg = 1.0 * (pos - start_pos) / (now - start);	eta = (total - pos) / avg;	if(total)prcnt = 100.0 * pos / total;	human_readable(pos, hpos, sizeof(hpos));	human_readable(total, htotal, sizeof(htotal));	human_readable(avg, havg, sizeof(havg));	len = asprintf(&status, "%s of %s (%.2f%%) at %s/s ETA: %s", hpos, htotal, prcnt, havg, print_time(eta));		if(columns) {		int required = strlen(name), available = columns - len - strlen("[] ");		if(required > available) asprintf(&filename, "...%s", name + required - available + 3);		else filename = SMB_STRNDUP(name, available);	} else filename = SMB_STRDUP(name);	fprintf(stderr, "\r[%s] %s", filename, status);	free(filename); free(status);}int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile) {	int remotehandle, localhandle;	time_t start_time = time(NULL);	const char *newpath;	char path[SMB_MAXPATHLEN];	char checkbuf[2][RESUME_CHECK_SIZE];	char *readbuf = NULL;	off_t offset_download = 0, offset_check = 0, curpos = 0, start_offset = 0;	struct stat localstat, remotestat;	snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (*base && *name && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name);		remotehandle = smbc_open(path, O_RDONLY, 0755);	if(remotehandle < 0) {		switch(errno) {		case EISDIR: 			if(!recursive) {				fprintf(stderr, "%s is a directory. Specify -R to download recursively\n", path);				return 0;			}			smb_download_dir(base, name, resume);			return 0;		case ENOENT:			fprintf(stderr, "%s can't be found on the remote server\n", path);			return 0;		case ENOMEM:			fprintf(stderr, "Not enough memory\n");			exit(1);			return 0;		case ENODEV:			fprintf(stderr, "The share name used in %s does not exist\n", path);			return 0;		case EACCES:			fprintf(stderr, "You don't have enough permissions to access %s\n", path);			return 0;		default:			perror("smbc_open");			return 0;		}	} 	if(smbc_fstat(remotehandle, &remotestat) < 0) {		fprintf(stderr, "Can't stat %s: %s\n", path, strerror(errno));		return 0;	}	if(outfile) newpath = outfile;	else if(!name[0]) {		newpath = strrchr(base, '/');		if(newpath)newpath++; else newpath = base;

⌨️ 快捷键说明

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