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

📄 extensions.c

📁 wu-ftpd类unix下的ftp服务器,可用于嵌入式系统
💻 C
📖 第 1 页 / 共 4 页
字号:
		return (0);	    }	    return (1);	}    curptr = (struct dirlist *) malloc(strlen(cwd) + 1 + sizeof(struct dirlist));    if (curptr != NULL) {	curptr->next = head;	head = curptr;	curptr->dircode = dircode;	strcpy(curptr->dirname, cwd);    }    return (0);}/*************************************************************************//* FUNCTION  : show_banner                                               *//* PURPOSE   : Display a banner on the user's terminal before login      *//* ARGUMENTS : reply code to use                                         *//*************************************************************************/void show_banner(int msgcode){    char *crptr, linebuf[1024], outbuf[1024];    struct aclmember *entry = NULL;    FILE *infile;#ifdef VIRTUAL    extern int virtual_mode;    extern int virtual_ftpaccess;    extern char virtual_banner[];    if (virtual_mode && !virtual_ftpaccess) {	infile = fopen(virtual_banner, "r");	if (infile) {	    while (fgets(linebuf, sizeof(linebuf), infile) != NULL) {		if ((crptr = strchr(linebuf, '\n')) != NULL)		    *crptr = '\0';		msg_massage(linebuf, outbuf, sizeof(outbuf));		lreply(msgcode, "%s", outbuf);	    }	    fclose(infile);#ifndef NO_SUCKING_NEWLINES	    lreply(msgcode, "");#endif	}    }    else {#endif	/* banner <path> */	while (getaclentry("banner", &entry)) {	    infile = fopen(ARG0, "r");	    if (infile) {		while (fgets(linebuf, sizeof(linebuf), infile) != NULL) {		    if ((crptr = strchr(linebuf, '\n')) != NULL)			*crptr = '\0';		    msg_massage(linebuf, outbuf, sizeof(outbuf));		    lreply(msgcode, "%s", outbuf);		}		fclose(infile);#ifndef NO_SUCKING_NEWLINES		lreply(msgcode, "");#endif	    }	}#ifdef VIRTUAL    }#endif}/*************************************************************************//* FUNCTION  : show_message                                              *//* PURPOSE   : Display a message on the user's terminal if the current   *//*             conditions are right                                      *//* ARGUMENTS : reply code to use, LOG_IN|CMD                             *//*************************************************************************/void show_message(int msgcode, int mode){    char *crptr, linebuf[1024], outbuf[1024], class[MAXPATHLEN], cwd[MAXPATHLEN];    int show, which;    struct aclmember *entry = NULL;    FILE *infile;    if (mode == C_WD && cwd_beenhere(1) != 0)	return;#ifdef HAVE_GETCWD    (void) getcwd(cwd, MAXPATHLEN - 1);#else    (void) getwd(cwd);#endif    (void) acl_getclass(class);    /* message <path> [<when> [<class>]] */    while (getaclentry("message", &entry)) {	if (!ARG0)	    continue;	show = 0;	if (mode == LOG_IN && (!ARG1 || !strcasecmp(ARG1, "login")))	    if (!ARG2)		show++;	    else {		for (which = 2; (which < MAXARGS) && ARG[which]; which++)		    if (strcasecmp(class, ARG[which]) == 0)			show++;	    }	if (mode == C_WD && ARG1 && !strncasecmp(ARG1, "cwd=", 4) &&	    (!strcmp((ARG1) + 4, cwd) || *(ARG1 + 4) == '*' ||	     !wu_fnmatch((ARG1) + 4, cwd, FNM_PATHNAME)))	    if (!ARG2)		show++;	    else {		for (which = 2; (which < MAXARGS) && ARG[which]; which++)		    if (strcasecmp(class, ARG[which]) == 0)			show++;	    }	if (show && (int) strlen(ARG0) > 0) {	    infile = fopen(ARG0, "r");	    if (infile) {		while (fgets(linebuf, sizeof(linebuf), infile) != NULL) {		    if ((crptr = strchr(linebuf, '\n')) != NULL)			*crptr = '\0';		    msg_massage(linebuf, outbuf, sizeof(outbuf));		    lreply(msgcode, "%s", outbuf);		}		fclose(infile);#ifndef NO_SUCKING_NEWLINES		lreply(msgcode, "");#endif	    }	}    }}/*************************************************************************//* FUNCTION  : show_readme                                               *//* PURPOSE   : Display a message about a README file to the user if the  *//*             current conditions are right                              *//* ARGUMENTS : pointer to ACL buffer, reply code, LOG_IN|C_WD            *//*************************************************************************/void show_readme(int code, int mode){    char **filelist, **sfilelist, class[MAXPATHLEN], cwd[MAXPATHLEN];    int show, which, days;    time_t clock;    struct stat buf;    struct tm *tp;    struct aclmember *entry = NULL;    if (cwd_beenhere(2) != 0)	return;#ifdef HAVE_GETCWD    (void) getcwd(cwd, MAXPATHLEN - 1);#else    (void) getwd(cwd);#endif    (void) acl_getclass(class);    /* readme  <path> {<when>} */    while (getaclentry("readme", &entry)) {	if (!ARG0)	    continue;	show = 0;	if (mode == LOG_IN && (!ARG1 || !strcasecmp(ARG1, "login")))	    if (!ARG2)		show++;	    else {		for (which = 2; (which < MAXARGS) && ARG[which]; which++)		    if (strcasecmp(class, ARG[which]) == 0)			show++;	    }	if (mode == C_WD && ARG1 && !strncasecmp(ARG1, "cwd=", 4)	    && (!strcmp((ARG1) + 4, cwd) || *(ARG1 + 4) == '*' ||		!wu_fnmatch((ARG1) + 4, cwd, FNM_PATHNAME)))	    if (!ARG2)		show++;	    else {		for (which = 2; (which < MAXARGS) && ARG[which]; which++)		    if (strcasecmp(class, ARG[which]) == 0)			show++;	    }	if (show) {	    globerr = NULL;	    filelist = ftpglob(ARG0);	    sfilelist = filelist;	/* save to free later */	    if (!globerr) {		while (filelist && *filelist) {		    errno = 0;		    if (!stat(*filelist, &buf) &&			(buf.st_mode & S_IFMT) == S_IFREG) {			lreply(code, "Please read the file %s", *filelist);			(void) time(&clock);			tp = localtime(&clock);			days = 365 * tp->tm_year + tp->tm_yday;			tp = localtime((time_t *) & buf.st_mtime);			days -= 365 * tp->tm_year + tp->tm_yday;/*   if (days == 0) {   lreply(code, "  it was last modified on %.24s - Today",   ctime((time_t *)&buf.st_mtime));   } else { */			lreply(code,			   "  it was last modified on %.24s - %d day%s ago",			       ctime((time_t *) & buf.st_mtime), days, days == 1 ? "" : "s");/*   } */		    }		    filelist++;		}	    }	    if (sfilelist) {		blkfree(sfilelist);		free((char *) sfilelist);	    }	}    }}/*************************************************************************//* FUNCTION  : deny_badxfertype                                          *//* PURPOSE   : If user is in ASCII transfer mode and tries to retrieve a *//*             binary file, abort transfer and display appropriate error *//* ARGUMENTS : message code to use for denial, path of file to check for *//*             binary contents or NULL to assume binary file             *//*************************************************************************/int deny_badasciixfer(int msgcode, char *filepath){    if (type == TYPE_A && !*filepath) {	reply(msgcode, "This is a BINARY file, using ASCII mode to transfer will corrupt it.");	return (1);    }    /* The hooks are here to prevent transfers of actual binary files, not     * just TAR or COMPRESS mode files... */    return (0);}/*************************************************************************//* FUNCTION  : is_shutdown                                               *//* PURPOSE   :                                                           *//* ARGUMENTS :                                                           *//*************************************************************************/int is_shutdown(int quiet, int new){    static struct tm tmbuf;    static struct stat s_last;    static time_t last = 0, shut, deny, disc;    static int valid;    static char text[2048];    struct stat s_cur;    extern char *autospout, Shutdown[];    FILE *fp;    int deny_off, disc_off;    time_t curtime = time(NULL);    char buf[1024], linebuf[1024];    if (Shutdown[0] == '\0' || stat(Shutdown, &s_cur))	return (0);    if (s_last.st_mtime != s_cur.st_mtime) {	s_last = s_cur;	valid = 0;	fp = fopen(Shutdown, "r");	if (fp == NULL)	    return (0);	fgets(buf, sizeof(buf), fp);	if (sscanf(buf, "%d %d %d %d %d %ld %ld", &tmbuf.tm_year, &tmbuf.tm_mon,	&tmbuf.tm_mday, &tmbuf.tm_hour, &tmbuf.tm_min, &deny, &disc) != 7) {	    (void) fclose(fp);	    return (0);	}	valid = 1;	deny_off = 3600 * (deny / 100) + 60 * (deny % 100);	disc_off = 3600 * (disc / 100) + 60 * (disc % 100);	tmbuf.tm_year -= 1900;	tmbuf.tm_isdst = -1;	shut = mktime(&tmbuf);	strcpy(shuttime, ctime(&shut));	disc = shut - disc_off;	strcpy(disctime, ctime(&disc));	deny = shut - deny_off;	strcpy(denytime, ctime(&deny));	text[0] = '\0';	while (fgets(buf, sizeof(buf), fp) != NULL) {	    msg_massage(buf, linebuf, sizeof(linebuf));	    if ((strlen(text) + strlen(linebuf)) < sizeof(text))		strcat(text, linebuf);	}	(void) fclose(fp);    }    if (!valid)	return (0);    /* if last == 0, then is_shutdown() only called with quiet == 1 so far */    if (last == 0 && !quiet) {	autospout = text;	/* warn them for the first time */	autospout_free = 0;	last = curtime;    }    /* if a new connection and past deny time, tell caller to drop 'em */    if (new && curtime > deny)	return (1);    /* if past disconnect time, tell caller to drop 'em */    if (curtime > disc)	return (1);    /* if less than 60 seconds to disconnection, warn 'em continuously */    if (curtime > (disc - 60) && !quiet) {	autospout = text;	autospout_free = 0;	last = curtime;    }    /* if less than 15 minutes to disconnection, warn 'em every 5 mins */    if (curtime > (disc - 60 * 15)) {	if ((curtime - last) > (60 * 5) && !quiet) {	    autospout = text;	    autospout_free = 0;	    last = curtime;	}    }    /* if less than 24 hours to disconnection, warn 'em every 30 mins */    if (curtime < (disc - 24 * 60 * 60) && !quiet) {	if ((curtime - last) > (60 * 30)) {	    autospout = text;	    autospout_free = 0;	    last = curtime;	}    }    /* if more than 24 hours to disconnection, warn 'em every 60 mins */    if (curtime > (disc - 24 * 60 * 60) && !quiet) {	if ((curtime - last) >= (24 * 60 * 60)) {	    autospout = text;	    autospout_free = 0;	    last = curtime;	}    }    return (0);}void newer(char *date, char *path, int showlots){    extern int ftw(const char *path, int (*fn) (char *, struct stat *, int), int depth);    struct tm tm;    if (sscanf(date, "%04d%02d%02d%02d%02d%02d",	       &tm.tm_year, &tm.tm_mon, &tm.tm_mday,	       &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) {	tm.tm_year -= 1900;	tm.tm_mon--;	tm.tm_isdst = -1;	newer_time = mktime(&tm);	dout = dataconn("file list", (off_t) - 1, "w");	if (dout != NULL) {	    /* As ftw allocates storage it needs a chance to cleanup, setting	     * ftwflag prevents myoob from calling longjmp, incrementing	     * ftwflag instead which causes check_newer to return non-zero	     * which makes ftw return. */	    ftwflag = 1;	    transflag++;	    show_fullinfo = showlots;#if defined(HAVE_FTW)	    ftw(path, check_newer, -1);#else	    treewalk(path, check_newer, -1, NULL);#endif	    /* don't send a reply if myoob has already replied */	    if (ftwflag == 1) {		if (ferror(dout) != 0)		    perror_reply(550, "Data connection");		else		    reply(226, "Transfer complete.");	    }	    (void) fclose(dout);	    data = -1;	    pdata = -1;	    transflag = 0;	    ftwflag = 0;	}    }    else	reply(501, "Bad DATE format");}int type_match(char *typelist){    if (anonymous && strcasestr(typelist, "anonymous"))	return (1);    if (guest && strcasestr(typelist, "guest"))	return (1);    if (!guest && !anonymous && strcasestr(typelist, "real"))	return (1);    if (strncasecmp(typelist, "class=", 6) == 0) {	char class[1024];	(void) acl_getclass(class);	if (strcasecmp(typelist + 6, class) == 0)	    return (1);    }    return (0);}int path_compare(char *p1, char *p2){    if ((strcmp(p1, "*") == 0) || (wu_fnmatch(p1, p2, FNM_PATHNAME) == 0))	/* 0 means they matched */	return (strlen(p1));    else	return (-2);}void expand_id(void){    char class[1024];    struct aclmember *entry = NULL;    (void) acl_getclass(class);    while (getaclentry("upload", &entry)) {	char *q;	int i = 0;	int options = 1;	int classfound = 0;	int classmatched = 0;	while (options	       && (i < MAXARGS)	       && ((q = entry->arg[i]) != (char *) NULL)	       && (q[0] != '\0')) {	    if (strcasecmp(q, "absolute") == 0)		i++;	    else if (strcasecmp(q, "relative") == 0)		i++;	    else if (strncasecmp(q, "class=", 6) == 0) {		i++;		classfound = 1;		if (strcasecmp(q + 6, class) == 0)		    classmatched = 1;	    }	    else if (strcmp(q, "-") == 0) {		i++;		options = 0;	    }	    else		options = 0;	}	if (!classfound || classmatched) {	    char buf[BUFSIZ];	    /*	       *  UID	     */	    if (((i + 3) < MAXARGS)		&& ((q = entry->arg[i + 3]) != (char *) NULL)		&& (q[0] != '\0')		&& (strcmp(q, "*") != 0)) {		if (q[0] == '%')		    sprintf(buf, "%s", q + 1);		else {		    struct passwd *pwent = getpwnam(q);		    if (pwent)			sprintf(buf, "%" PW_UID_FORMAT, pwent->pw_uid);		    else			sprintf(buf, "%d", 0);		}		entry->arg[i + 3] = (char *) malloc(strlen(buf) + 1);		if (entry->arg[i + 3] == NULL) {		    syslog(LOG_ERR, "calloc error in expand_id");		    exit(0);		}		strcpy(entry->arg[i + 3], buf);	    }	    /*	       *  GID	     */	    if (((i + 4) < MAXARGS)		&& ((q = entry->arg[i + 4]) != (char *) NULL)		&& (q[0] != '\0')		&& (strcmp(q, "*") != 0)) {		if (q[0] == '%')		    sprintf(buf, "%s", q + 1);		else {		    struct group *grent = getgrnam(q);		    if (grent)			sprintf(buf, "%" GR_GID_FORMAT, grent->gr_gid);		    else			sprintf(buf, "%d", 0);		    endgrent();		}		entry->arg[i + 4] = (char *) malloc(strlen(buf) + 1);		if (entry->arg[i + 4] == NULL) {		    syslog(LOG_ERR, "calloc error in expand_id");		    exit(0);		}		strcpy(entry->arg[i + 4], buf);	    }	}    }}int fn_check(char *name){    /* check to see if this is a valid file name... path-filter <type>     * <message_file> <allowed_charset> <disallowed> */    struct aclmember *entry = NULL;    int j;    char *path;#if ! defined(HAVE_REGEXEC)    char *sp;#endif#ifdef M_UNIX#ifdef HAVE_REGEX    char *regp;#endif#endif#ifdef HAVE_REGEXEC    regex_t regexbuf;    regmatch_t regmatchbuf;#endif#ifdef LINUX    re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;#endif    while (getaclentry("path-filter", &entry) && ARG0 != NULL) {	if (type_match(ARG0) && ARG1 && ARG2) {	    /*	     * check *only* the basename	     */	    if ((path = strrchr(name, '/')))		++path;	    else		path = name;	    /* is it in the allowed character set? */#if defined(HAVE_REGEXEC)	    if (regcomp(&regexbuf, ARG2, REG_EXTENDED) != 0) {		reply(550, "HAVE_REGEX error");#elif defined(HAVE_REGEX)		if ((sp = regcmp(ARG2, (char *) 0)) == NULL) {		    reply(550, "HAVE_REGEX error");#else	    if ((sp = re_comp(ARG2)) != 0) {		perror_reply(550, sp);#endif		return (0);	    }#if defined(HAVE_REGEXEC)	    if (regexec(&regexbuf, path, 1, &regmatchbuf, 0) != 0) {#elif defined(HAVE_REGEX)#ifdef M_UNIX		regp = regex(sp, path);		free(sp);		if (regp == NULL) {#else		if ((regex(sp, path)) == NULL) {#endif#else	    if ((re_exec(path)) != 1) {#endif		pr_mesg(550, ARG1);		reply(550, "%s: Permission denied on server. (Filename (accept))", name);

⌨️ 快捷键说明

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