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

📄 ftpd.c

📁 wu-ftpd类unix下的ftp服务器,可用于嵌入式系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    route_vectored = routevector();    conv_init();#ifdef MAIL_ADMIN    incmails = 0;    mailfrom = NULL;#endif /* MAIL_ADMIN */#ifdef VIRTUAL    /*       ** If virtual_mode is set at this point then an alternate ftpaccess       ** is in use.  Otherwise we need to check the Master ftpaccess file       ** to see if the site is only using the "virtual" directives to       ** specify virtual site directives.       **       ** In this manner an admin can put a virtual site in the ftpservers       ** file if they need expanded configuration support or can use the       ** minimal root/banner/logfile if they do not need any more than that.     */    if (virtual_mode) {	/* Get the root of the virtual server directory */	entry = (struct aclmember *) NULL;	if (getaclentry("root", &entry)) {	    if (ARG0)		strcpy(virtual_root, ARG0);	}	/* Get the logfile to use */	entry = (struct aclmember *) NULL;	if (getaclentry("logfile", &entry)) {	    if (ARG0)		strcpy(logfile, ARG0);	}    }    else {	virtual_hostname[0] = '\0';	virtual_address[0] = '\0';	virtual_len = sizeof(virtual_addr);	if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) {	    virtual_ptr = (struct sockaddr_in *) &virtual_addr;	    strcpy(virtual_address, inet_ntoa(virtual_ptr->sin_addr));	    shp = gethostbyaddr((char *) &virtual_ptr->sin_addr, sizeof(struct in_addr), AF_INET);	    if (shp != NULL) {		(void) strncpy(virtual_hostname, shp->h_name, sizeof(virtual_hostname));		virtual_hostname[sizeof(virtual_hostname) - 1] = '\0';	    }	    entry = (struct aclmember *) NULL;	    while (getaclentry("virtual", &entry)) {		if (!ARG0 || !ARG1 || !ARG2)		    continue;		if (hostmatch(ARG0, virtual_address, virtual_hostname)) {		    if (!strcasecmp(ARG1, "root")) {			syslog(LOG_NOTICE, "VirtualFTP Connect to: %s [%s]",			       virtual_hostname, virtual_address);			virtual_mode = 1;			strncpy(virtual_root, ARG2, sizeof(virtual_root));			virtual_root[sizeof(virtual_root) - 1] = '\0';			/* reset hostname to this virtual name */			(void) strcpy(hostname, virtual_hostname);			virtual_email[0] = '\0';		    }		    if (!strcasecmp(ARG1, "banner")) {			strncpy(virtual_banner, ARG2, sizeof(virtual_banner));			virtual_banner[sizeof(virtual_banner) - 1] = '\0';		    }		    if (!strcasecmp(ARG1, "logfile")) {			strncpy(logfile, ARG2, sizeof(logfile));			logfile[sizeof(logfile) - 1] = '\0';		    }		    if (!strcasecmp(ARG1, "hostname")) {			strncpy(hostname, ARG2, sizeof(hostname));			hostname[sizeof(hostname) - 1] = '\0';		    }		    if (!strcasecmp(ARG1, "email")) {			strncpy(virtual_email, ARG2, sizeof(virtual_email));			virtual_email[sizeof(virtual_email) - 1] = '\0';		    }#ifdef OTHER_PASSWD		    if (!strcasecmp(ARG1, "passwd")) {			strncpy(_path_passwd, ARG2, sizeof(_path_passwd));			_path_passwd[sizeof(_path_passwd) - 1] = '\0';#ifdef USE_PAM			use_pam = 0;#endif		    }#ifdef SHADOW_PASSWORD		    if (!strcasecmp(ARG1, "shadow")) {			strncpy(_path_shadow, ARG2, sizeof(_path_shadow));			_path_shadow[sizeof(_path_shadow) - 1] = '\0';#ifdef USE_PAM			use_pam = 0;#endif		    }#endif#endif#ifdef MAIL_ADMIN		    if (mailfrom == NULL)			if (!strcasecmp(ARG1, "mailfrom")) {			    mailfrom = strdup(ARG2);			}		    if (!strcasecmp(ARG1, "incmail")) {			if (incmails < INCMAILS)			    incmail[incmails++] = strdup(ARG2);		    }#endif		}	    }	    if (!virtual_mode) {		entry = (struct aclmember *) NULL;		while (getaclentry("defaultserver", &entry)) {		    if (!ARG0 || !ARG1)			continue;#ifdef MAIL_ADMIN		    if (mailfrom == NULL)			if (!strcasecmp(ARG0, "mailfrom")) {			    mailfrom = strdup(ARG1);			}		    if (!strcasecmp(ARG0, "incmail")) {			if (incmails < INCMAILS)			    incmail[incmails++] = strdup(ARG1);		    }#endif		}	    }	}    }#ifdef VIRTUAL_DEBUG    lreply(220, "_path_ftpaccess == %s", _path_ftpaccess);    lreply(220, "_path_ftpusers == %s", _path_ftpusers);    lreply(220, "_path_ftphosts == %s", _path_ftphosts);    lreply(220, "_path_private == %s", _path_private);    lreply(220, "_path_cvt == %s", _path_cvt);    if (virtual_mode) {	if (virtual_ftpaccess)	    lreply(220, "VIRTUAL Mode: Using %s specific %s access file",		   hostname, _path_ftpaccess);	else	    lreply(220, "VIRTUAL Mode: Using Master access file %s",		   _path_ftpaccess);	lreply(220, "virtual_root == %s", virtual_root);	if (!virtual_ftpaccess)	    lreply(220, "virtual_banner == %s", virtual_banner);    }    lreply(220, "logfile == %s", logfile);#endif#endif    if (is_shutdown(1, 1) != 0) {	syslog(LOG_INFO, "connection refused (server shut down) from %s",	       remoteident);	reply(500, "%s FTP server shut down -- please try again later.",	      hostname);	exit(0);    }#ifdef OPIE    af_pwok = opieaccessfile(remotehost);#endif#ifdef HAVE_LIBRESOLV    /* check permitted access based on remote host DNS information */    if (!check_reverse_dns()) {	exit(0);    }    if (!check_matching_dns()) {	exit(0);    }#endif /* HAVE_LIBRESOLV */    show_banner(220);#ifndef INTERNAL_LS    entry = (struct aclmember *) NULL;    if (getaclentry("lslong", &entry) && ARG0 && (int) strlen(ARG0) > 0) {	strcpy(ls_long, ARG0);	for (which = 1; (which < MAXARGS) && ARG[which]; which++) {	    strcat(ls_long, " ");	    strcat(ls_long, ARG[which]);	}    }    else {#if defined(SVR4) || defined(ISC)#if defined(AIX) || defined(SOLARIS2)	strcpy(ls_long, "/bin/ls -lA");#else	strcpy(ls_long, "/bin/ls -la");#endif#else	strcpy(ls_long, "/bin/ls -lgA");#endif    }    strcat(ls_long, " %s");    entry = (struct aclmember *) NULL;    if (getaclentry("lsshort", &entry) && ARG0 && (int) strlen(ARG0) > 0) {	strcpy(ls_short, ARG0);	for (which = 1; (which < MAXARGS) && ARG[which]; which++) {	    strcat(ls_short, " ");	    strcat(ls_short, ARG[which]);	}    }    else {#if defined(SVR4) || defined(ISC)#if defined(AIX) || defined(SOLARIS2)	strcpy(ls_short, "/bin/ls -lA");#else	strcpy(ls_short, "/bin/ls -la");#endif#else	strcpy(ls_short, "/bin/ls -lgA");#endif    }    strcat(ls_short, " %s");    entry = (struct aclmember *) NULL;    if (getaclentry("lsplain", &entry) && ARG0 && (int) strlen(ARG0) > 0) {	strcpy(ls_plain, ARG0);	for (which = 1; (which < MAXARGS) && ARG[which]; which++) {	    strcat(ls_plain, " ");	    strcat(ls_plain, ARG[which]);	}    }    else	strcpy(ls_plain, "/bin/ls");    strcat(ls_plain, " %s");#endif /* ! INTERNAL_LS */#ifdef MAIL_ADMIN    mailservers = 0;    entry = (struct aclmember *) NULL;    while (getaclentry("mailserver", &entry) && ARG0 && mailservers < MAILSERVERS)	mailserver[mailservers++] = strdup(ARG0);    if (mailservers == 0)	mailserver[mailservers++] = strdup("localhost");    if (incmails == 0) {	entry = (struct aclmember *) NULL;	while (getaclentry("incmail", &entry) && ARG0 && incmails < INCMAILS)	    incmail[incmails++] = strdup(ARG0);    }    if (mailfrom == NULL) {	entry = (struct aclmember *) NULL;	if (getaclentry("mailfrom", &entry) && ARG0)	    mailfrom = strdup(ARG0);	else	    mailfrom = strdup("wu-ftpd");    }#endif /* MAIL_ADMIN */    {#define OUTPUT_LEN 1024	int version_option = 0;	char output_text[OUTPUT_LEN + 1];	int arg_count, output_len;	entry = NULL;	if (getaclentry("greeting", &entry) && ARG0) {	    if (!strcasecmp(ARG0, "full"))		version_option = 0;	    else if (!strcasecmp(ARG0, "text") && ARG1)		version_option = 3;	    else if (!strcasecmp(ARG0, "terse"))		version_option = 2;	    else if (!strcasecmp(ARG0, "brief"))		version_option = 1;	}	switch (version_option) {	default:	    reply(220, "%s FTP server (%s) ready.", hostname, version);	    break;	case 1:	    reply(220, "%s FTP server ready.", hostname);	    break;	case 2:	    reply(220, "FTP server ready.");	    break;	case 3:	    output_text[0] = '\0';	    output_len = 0;	    for (arg_count = 1; ARG[arg_count] != NULL; arg_count++) {		int arg_len;		arg_len = strlen(ARG[arg_count]);		if ((output_len + arg_len) > OUTPUT_LEN) {		    /* avoid possible buffer overflow */		    break;		}		/* append the text to the greeting */		strcat(output_text, ARG[arg_count]);		output_len += arg_len;		if (ARG[arg_count + 1] != NULL) {		    if ((output_len + 2) > OUTPUT_LEN) {			/* avoid possible buffer overflow and adding a trailing space */			break;		    }		    /* if the next entry exists, add a white space */		    strcat(output_text, " ");		    output_len += 1;		}	    }	    reply(220, "%s", output_text);	    break;	}    }    (void) setjmp(errcatch);    for (;;)	(void) yyparse();    /* NOTREACHED */}SIGNAL_TYPE randomsig(int sig){#ifdef HAVE_SIGLIST    syslog(LOG_ERR, "exiting on signal %d: %s", sig, sys_siglist[sig]);#else    syslog(LOG_ERR, "exiting on signal %d", sig);#endif    chdir("/");    signal(SIGIOT, SIG_DFL);    signal(SIGILL, SIG_DFL);    exit(1);    /* dologout(-1); *//* NOTREACHED */}SIGNAL_TYPE lostconn(int sig){#ifdef VERBOSE_ERROR_LOGING    syslog(LOG_INFO, "lost connection to %s", remoteident);#else    if (debug)	syslog(LOG_DEBUG, "lost connection to %s", remoteident);#endif    dologout(-1);}static char ttyline[20];#ifdef MAPPING_CHDIR/* Keep track of the path the user has chdir'd into and respond with * that to pwd commands.  This is to avoid having the absolue disk * path returned, which I want to avoid. */char mapped_path[MAXPATHLEN] = "/";char *mapping_getwd(char *path){    strcpy(path, mapped_path);    return path;}char *mapping_getcwd(char *path, size_t size){    strncpy(path, mapped_path, size);    path[size - 1] = '\0';    return path;}/* Make these globals rather than local to mapping_chdir to avoid stack overflow */char pathspace[MAXPATHLEN];char old_mapped_path[MAXPATHLEN];void do_elem(char *dir){    /* . */    if (dir[0] == '.' && dir[1] == '\0') {	/* ignore it */	return;    }    /* .. */    if (dir[0] == '.' && dir[1] == '.' && dir[2] == '\0') {	char *last;	/* lop the last directory off the path */	if ((last = strrchr(mapped_path, '/'))) {	    /* If start of pathname leave the / */	    if (last == mapped_path)		last++;	    *last = '\0';	}	return;    }    /* append the dir part with a leading / unless at root */    if (!(mapped_path[0] == '/' && mapped_path[1] == '\0'))	if (strlen(mapped_path) < sizeof(mapped_path) - 1)	    strcat(mapped_path, "/");    if (sizeof(mapped_path) - strlen(mapped_path) > 1)	strncat(mapped_path, dir, sizeof(mapped_path) - strlen(mapped_path) - 1);}int mapping_chdir(char *orig_path){    int ret;    char *sl, *path;    strcpy(old_mapped_path, mapped_path);    path = &pathspace[0];    strcpy(path, orig_path);    /* / at start of path, set the start of the mapped_path to / */    if (path[0] == '/') {	mapped_path[0] = '/';	mapped_path[1] = '\0';	path++;    }    while ((sl = strchr(path, '/'))) {	char *dir;	dir = path;	*sl = '\0';	path = sl + 1;	if (*dir)	    do_elem(dir);	if (*path == '\0')	    break;    }    if (*path)	do_elem(path);    if ((ret = chdir(mapped_path)) < 0) {	strcpy(mapped_path, old_mapped_path);    }    return ret;}/* From now on use the mapping version */#define chdir(d) mapping_chdir(d)#define getwd(d) mapping_getwd(d)#define getcwd(d,u) mapping_getcwd((d),(u))#endif /* MAPPING_CHDIR *//* Helper function for sgetpwnam(). */char *sgetsave(char *s){    char *new;    new = (char *) malloc(strlen(s) + 1);    if (new == NULL) {	perror_reply(421, "Local resource failure: malloc");	dologout(1);	/* NOTREACHED */    }    (void) strcpy(new, s);    return (new);}/* Save the result of a getpwnam.  Used for USER command, since the data * returned must not be clobbered by any other command (e.g., globbing). */struct passwd *sgetpwnam(char *name){    static struct passwd save;    register struct passwd *p;#ifdef M_UNIX    struct passwd *ret = (struct passwd *) NULL;#endif    char *sgetsave(char *s);#ifdef KERBEROS    register struct authorization *q;#endif /* KERBEROS */#if defined(SecureWare) || defined(HPUX_10_TRUSTED)    struct pr_passwd *pr;#endif#ifdef KERBEROS    init_krb();    q = getauthuid(p->pw_uid);    end_krb();#endif /* KERBEROS */#ifdef M_UNIX#if defined(SecureWare) || defined(HPUX_10_TRUSTED)    if ((pr = getprpwnam(name)) == NULL)	goto DONE;#endif /* SecureWare || HPUX_10_TRUSTED */#ifdef OTHER_PASSWD    if ((p = bero_getpwnam(name, _path_passwd)) == NULL)#else    if ((p = getpwnam(name)) == NULL)#endif	goto DONE;#else /* M_UNIX */#if defined(SecureWare) || defined(HPUX_10_TRUSTED)    if ((pr = getprpwnam(name)) == NULL)	return ((struct passwd *) pr);#endif /* SecureWare || HPUX_10_TRUSTED */#ifdef OTHER_PASSWD    if ((p = bero_getpwnam(name, _path_passwd)) == NULL)#else    if ((p = getpwnam(name)) == NULL)#endif	return (p);#endif /* M_UNIX */    if (save.pw_name)	free(save.pw_name);    if (save.pw_gecos)	free(save.pw_gecos);    if (save.pw_dir)	free(save.pw_dir);    if (save.pw_shell)	free(save.pw_shell);    if (save.pw_passwd)	free(save.pw_passwd);    save = *p;    save.pw_name = sgetsave(p->pw_name);#ifdef KERBEROS    save.pw_passwd = sgetsave(q->a_password);#elif defined(SecureWare) || defined(HPUX_10_TRUSTED)    if (pr->uflg.fg_encrypt && pr->ufld.fd_encrypt && *pr->ufld.fd_encrypt)	save.pw_passwd = sgetsave(pr->ufld.fd_encrypt);    else	save.pw_passwd = sgetsave("");#else    save.pw_passwd = sgetsave(p->pw_passwd);#endif#ifdef SHADOW_PASSWORD    if (p && (p->pw_passwd==NULL || strlen(p->pw_passwd)<8)) {	struct spwd *spw;#ifdef OTHER_PASSWD	if ((spw = bero_getspnam(p->pw_name, _path_shadow)) != NULL) {

⌨️ 快捷键说明

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