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

📄 ftp.c

📁 proxy源代码,linux下的ftp 代理的源代码,大家多多支持啊
💻 C
📖 第 1 页 / 共 4 页
字号:
int run_ctp(ftp_t *x){	int	rc, pid, pfd[2];	char	line[300];	FILE	*fp;		if (*x->config->ctp == 0)		return (0);	rc = 0;	if (pipe(pfd) != 0) {		syslog(LOG_NOTICE, "-ERR: can't pipe: %s", strerror(errno));		exit (1);		}	else if ((pid = fork()) < 0) {		syslog(LOG_NOTICE, "-ERR: can't fork trp: %s", strerror(errno));		exit (1);		}	else if (pid == 0) {		int	argc;		char	*argv[32];		close(0);		/* Das trp kann nicht vom client lesen. */		dup2(pfd[1], 1);	/* stdout wird vom parent gelesen. */		close(pfd[0]);		set_variables(x);					copy_string(line, x->config->ctp, sizeof(line));		argc = split(line, argv, ' ', 30);		argv[argc] = NULL;		execvp(argv[0], argv);		syslog(LOG_NOTICE, "-ERR: can't exec trp %s: %s",			argv[0], strerror(errno));		exit (1);		}	else {		char	*p, var[80], line[300];		close(pfd[1]);		fp = fdopen(pfd[0], "r");		while (fgets(line, sizeof(line), fp)) {			p = skip_ws(noctrl(line));			getvarname(&p, var, sizeof(var));			if (strcmp(var, "SERVERNAME") == 0  ||  strcmp(var, "SERVER") == 0)				copy_string(x->server.name, p, sizeof(x->server.name));			else if (strcmp(var, "SERVERLOGIN") == 0  ||  strcmp(var, "LOGIN") == 0)				copy_string(x->username, p, sizeof(x->username));			else if (strcmp(var, "SERVERPASSWD") == 0  ||  strcmp(var, "PASSWD") == 0)				copy_string(x->password, p, sizeof(x->password));			else if (strcmp(var, "SERVERPORT") == 0  ||  strcmp(var, "PORT") == 0)				x->server.port = atoi(p);			/*			 * Enable the trp to send error messages.			 */			else if (strcmp(var, "-ERR") == 0  ||  strcmp(var, "-ERR:") == 0) {				syslog(LOG_NOTICE, "-ERR: %s", skip_ws(p));				exit (1);				}			}		fclose(fp);		/*		 * In standalone mode we do not receive the SIGCHLD because		 * we set it to SIG_IGN -- 030406asg		 */		if (x->config->standalone == 0  &&  waitpid(pid, &rc, 0) < 0) {			syslog(LOG_NOTICE, "-ERR: error while waiting for trp: %s", strerror(errno));			exit (1);			}		rc = WIFEXITED(rc) != 0? WEXITSTATUS(rc): 1;		if (rc != 0) {			syslog(LOG_NOTICE, "-ERR: trp signals error condition, rc= %d", rc);			exit (1);			}		}	return (rc);}int get_ftpdir(ftp_t *x){	int	rc, len;	char	*p, *start, line[300];	static char *quotes = "'\"'`";	sfputs(x, "%s", "PWD");	if (sfgets(x, line, sizeof(line)) == NULL) {		syslog(LOG_NOTICE, "monitor: server not responding");		exit (1);		}	rc = strtol(line, &p, 10);	if (rc != 257) {		syslog(LOG_NOTICE, "monitor: PWD status: %d", rc);		exit (1);		}	p = skip_ws(p);	if (*p == 0) {		syslog(LOG_NOTICE, "monitor: directory unset");		exit (1);		}	if ((start = strchr(p, '/')) == NULL) {		syslog(LOG_NOTICE, "monitor: can't find directory in string: %s", p);		exit (1);		}	get_word(&start, x->cwd, sizeof(x->cwd));	if ((len = strlen(x->cwd)) > 0  &&  strchr(quotes, x->cwd[len-1]) != NULL)		x->cwd[len - 1] = 0;	if (*x->cwd != '/') {		syslog(LOG_NOTICE, "monitor: invalid path: %s", x->cwd);		exit (1);		}			syslog(LOG_NOTICE, "cwd: %s", x->cwd);	return (0);}int get_ftppath(ftp_t *x, char *path){	int	i, k, n, m;	char	cwp[200], ftpdir[200], pbuf[200];	char	*part[DIR_MAXDEPTH+5], *dir[DIR_MAXDEPTH+5];	/*	 * Zuerst wird das aktuelle Verzeichnis (der ftppath) in seine	 * Einzelteile zerlegt ...	 */	if (*path == '/') {		/*		 * ... Ausnahme: die path-Angabe ist absolut ...		 */		dir[0] = "";		n = 1;		}	else {		copy_string(ftpdir, x->cwd, sizeof(ftpdir));		if (*ftpdir != 0  &&  strcmp(ftpdir, "/") != 0)			n = split(ftpdir, part, '/', DIR_MAXDEPTH);		else {			dir[0] = "";			n = 1;			}		}	/*	 * ... danach der path.  Die path Teile werden unter Beachtung	 * der ueblichen Regeln an die Teile des aktuellen Verzeichnisses	 * angehangen ...	 */	copy_string(pbuf, path, sizeof(pbuf));	m = split(pbuf, dir, '/', 15);	for (i=0; i<m; i++) {		if (*dir[i] == 0)			/* zwei aufeinander folgende `/' */ ;		else if (strcmp(dir[i], ".") == 0)			/* nichts */ ;		else if (strcmp(dir[i], "..") == 0) {			if (n > 1)				n = n - 1;			}		else			part[n++] = dir[i];		if (n < 1  ||  n >= DIR_MAXDEPTH)			return (1);		/* ungueltiges Verzeichnis */		}	/*	 * ... und das Ergebnis wieder zusammengesetzt.	 */	if (n <= 1) {		strcpy(cwp, "/");		}	else {		k = 0;		for (i=1; i<n; i++) {			if ((k + strlen(part[i]) + 1 + 2) >= sizeof(dir))				return (1);		/* Name zu lang */							cwp[k++] = '/';			strcpy(&cwp[k], part[i]);			k += strlen(&cwp[k]);			}		cwp[k] = 0;		}	/*	 * Der normalisierte path auf das Objekt (Datei oder Verzeichnis,	 * ist hier egal) ist fertig.	 */	copy_string(x->filepath, cwp, sizeof(x->filepath));	return (0);}int run_ccp(ftp_t *x, char *cmd, char *par){	int	rc, pid, pfd[2], lfd[2];	char	message[300], line[300];	/*	 * Wenn kein ccp angegeben ist ist alles erlaubt.	 */	if (*x->config->ccp == 0)		return (CCP_OK);	/*	 * Der Vorgang fuer ccp's ist fast gleich mit dem fuer acp's.	 */	rc = 0;	if (pipe(pfd) != 0  ||  pipe(lfd)) {		syslog(LOG_NOTICE, "-ERR: can't pipe: %s", strerror(errno));		exit (1);		}	else if ((pid = fork()) < 0) {		syslog(LOG_NOTICE, "-ERR: can't fork ccp: %s", strerror(errno));		exit (1);		}	else if (pid == 0) {		int	argc;		char	*argv[32];		dup2(pfd[1], 2);	/* stderr nach FTP Client */		close(pfd[0]);		dup2(lfd[1], 1);	/* stdout nach syslog */		close(lfd[0]);		close(0);		set_variables(x);		setvar(x, "COMMAND", cmd);		setvar(x, "PARAMETER", par);		setvar(x, "SESSION", x->session);		snprintf (line, sizeof(line) - 2, "%d", x->ccpcoll);		setvar(x, "CCPCOLL", line);		setvar(x, "FTPHOME", x->home);		setvar(x, "FTPPATH", x->filepath);		copy_string(line, x->config->ccp, sizeof(line));		argc = split(line, argv, ' ', 30);		argv[argc] = NULL;		execvp(argv[0], argv);		syslog(LOG_NOTICE, "-ERR: can't exec ccp %s: %s", argv[0], strerror(errno));		exit (1);		}	else {		int	len;		/*		 * Nicht gebrauchte fd's schliessen.		 */		close(pfd[1]);		close(lfd[1]);		/*		 * syslog Meldung lesen und entsprechende pipe schliessen.		 */		*message = 0;		if ((len = read(lfd[0], message, sizeof(message) - 2)) < 0)			len = 0;		message[len] = 0;		noctrl(message);		close(lfd[0]);		if (*message != 0)			syslog(LOG_NOTICE, "%s", message);		/*		 * Fehlermeldung lesen, pipe schliessen.		 */		*message = 0;		if ((len = read(pfd[0], message, sizeof(message) - 2)) < 0)			len = 0;		message[len] = 0;		noctrl(message);		close(pfd[0]);		/*		 * return code holen.		 */		if (waitpid(pid, &rc, 0) < 0) {			syslog(LOG_NOTICE, "-ERR: error while waiting for ccp: %s", strerror(errno));			exit (1);			}		rc = WIFEXITED(rc) != 0? WEXITSTATUS(rc): 1;		if (rc == 0)			return (CCP_OK);		if (*message == 0)			copy_string(message, "permission denied", sizeof(message));/* *		snprintf (command, sizeof(command) - 2, "%s%s%s", cmd, (par != 0? " ": ""), par); *		syslog(LOG_NOTICE, "ccp: -ERR: %s@%s: %s: %s: rc= %d", *				x->username, x->server.name, *				command, message, rc); */		}	x->ccpcoll++;	if (isdigit(*message))		cfputs(x, message);	else {		snprintf (line, sizeof(line) - 2, "553 %s", message);		cfputs(x, line);		}/*	cfputs(x, "553 permission denied."); */	return (CCP_ERROR);}	/*	 * dologin() accepts now blanks with in and at the end of	 * passwords - 22JAN02asg	 */int dologin(ftp_t *x){	int	c, i, rc;	char	*p, word[80], line[300];	struct hostent *hostp;	struct sockaddr_in saddr;				while (1) {		if (readline_fd(x, 0, line, sizeof(line)) == NULL)			return (1);		if (x->config->allow_passwdblanks == 0)			p = noctrl(line);		else {			p = line;			for (i=strlen(line)-1; i>=0; i--) {				if ((c = line[i]) != '\n'  &&  c != '\r') {					line[i+1] = 0;					break;					}				}			}		get_word(&p, word, sizeof(word));		strupr(word);		if (strcmp(word, "USER") == 0) {			get_word(&p, x->username, sizeof(x->username));			cfputs(x, "331 password required");			}		else if (strcmp(word, "PASS") == 0) {			if (*x->username == 0) {				cfputs(x, "503 give USER first");				continue;				}			if (x->config->allow_passwdblanks == 0)				get_word(&p, x->password, sizeof(x->password)); 			else				copy_string(x->password, p, sizeof(x->password));			break;			}		else if (strcmp(word, "QUIT") == 0) {			cfputs(x, "221 goodbye");			return (2);			}		else {			cfputs(x, "530 login first");			}		}	if (*x->config->ctp != 0) {		/*		 * We are extremly liberate here with server selection		 * if we have a dynamic control program, we accept		 * anything here -- 030404asg		 */		if ((p = strchr(x->username, '@')) == NULL  &&  (p = strchr(x->username, '%')) == NULL)			*x->server.name = 0;		else if (x->config->use_last_at == 0) {			*p++ = 0;			copy_string(x->server.name, p, sizeof(x->server.name));			}		else {			if ((p = strrchr(x->username, '@')) == NULL)				p = strrchr(x->username, '%');			*p++ = 0;			copy_string(x->server.name, p, sizeof(x->server.name));			}		}	else if (x->config->selectserver == 0) {		if ((p = strchr(x->username, '@')) != NULL  &&  (p = strchr(x->username, '%')) != NULL) {			cfputs(x, "500 service unavailable");			syslog(LOG_NOTICE, "-ERR: hostname supplied: %s", p);			exit (1);			}		copy_string(x->server.name, x->config->server, sizeof(x->server.name));		}	else {		/*		 * Normally we search for the first '@' so that the client can 		 * not use "proxy hopping". The option "-u" can override		 * this behaviour.		 */		if (x->config->use_last_at == 0) {			if ((p = strchr(x->username, '@')) == NULL  &&  (p = strchr(x->username, '%')) == NULL) {				cfputs(x, "500 service unavailable");				syslog(LOG_NOTICE, "-ERR: missing hostname");				exit (1);				}			}		else {			if ((p = strrchr(x->username, '@')) == NULL  &&  (p = strrchr(x->username, '%')) == NULL) {				cfputs(x, "500 service unavailable");				syslog(LOG_NOTICE, "-ERR: missing hostname");				exit (1);				}			}		*p++ = 0;		copy_string(x->server.name, p, sizeof(x->server.name));		/*		 * Den Server auf der Serverliste suchen, wenn eine Liste		 * vorhanden ist.		 *//* * Checking the server against the given list is done later now, * see below.  Code quoted -- 030404asg * *		if ((p = x->config->serverlist) != NULL  &&  *p != 0) { *			int	permitted; *			char	pattern[80]; * *			permitted = 0; *			while ((p = skip_ws(p)), *get_quoted(&p, ',', pattern, sizeof(pattern)) != 0) { *				noctrl(pattern); *				if (strpcmp(x->server.name, pattern) == 0) { *					permitted = 1; *					break; *					} *				} * *			if (permitted == 0) { *				cfputs(x, "500 service unavailable"); *				syslog(LOG_NOTICE, "-ERR: hostname not permitted: %s", x->server.name); *				exit (1); *				} *			} */		}		/*	 * Wenn vorhanden Proxy Login und Passwort auslesen.	 */	if ((p = strchr(x->username, ':')) != NULL) {		*p++ = 0;		copy_string(x->local.username, x->username, sizeof(x->local.username));

⌨️ 快捷键说明

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