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

📄 extensions.c

📁 wu-ftpd类unix下的ftp服务器,可用于嵌入式系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************     Copyright (c) 1999,2000 WU-FTPD Development Group.    All rights reserved.    Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994    The Regents of the University of California.  Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.  Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.  Portions Copyright (c) 1989 Massachusetts Institute of Technology.  Portions Copyright (c) 1998 Sendmail, Inc.  Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P.  Allman.  Portions Copyright (c) 1997 by Stan Barber.  Portions Copyright (c) 1997 by Kent Landfield.  Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997    Free Software Foundation, Inc.     Use and distribution of this software and its source code are governed   by the terms and conditions of the WU-FTPD Software License ("LICENSE").   If you did not receive a copy of the license, it may be obtained online  at http://www.wu-ftpd.org/license.html.   $Id: extensions.c,v 1.48 2000/07/01 18:17:38 wuftpd Exp $ ****************************************************************************/#include "config.h"#include <stdio.h>#include <errno.h>#include <string.h>#ifdef HAVE_SYS_SYSLOG_H#include <sys/syslog.h>#elif defined(HAVE_SYSLOG_H) || !defined(AUTOCONF)#include <syslog.h>#endif#ifdef TIME_WITH_SYS_TIME#include <time.h>#include <sys/time.h>#else#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#else#include <time.h>#endif#endif#include <pwd.h>#include <setjmp.h>#include <grp.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/param.h>#ifdef HAVE_SYS_FS_UFS_QUOTA_H#include <sys/fs/ufs_quota.h>#elif defined(HAVE_UFS_UFS_QUOTA_H)#include <ufs/ufs/quota.h>#elif defined(HAVE_UFS_QUOTA_H)#include <ufs/quota.h>#elif defined(HAVE_SYS_MNTENT_H)#include <sys/mntent.h>#elif defined(HAVE_SYS_MNTTAB_H)#include <sys/mnttab.h>#endif#if defined(HAVE_STATVFS)#include <sys/statvfs.h>#elif defined(HAVE_SYS_VFS)#include <sys/vfs.h>#elif defined(HAVE_SYS_MOUNT)#include <sys/mount.h>#endif#include "../support/ftp.h"#ifdef HAVE_PATHS_H#include <paths.h>#endif#include "pathnames.h"#include "extensions.h"#include "wu_fnmatch.h"#include "proto.h"#if defined(HAVE_FTW)#include <ftw.h>#else#include "support/ftw.h"#endif#ifdef QUOTAstruct dqblk quota;char *time_quota(long curstate, long softlimit, long timelimit, char *timeleft);#endif#ifdef HAVE_REGEX_H#include <regex.h>#endif#if defined(HAVE_REGEX) && defined(SVR4) && ! (defined(NO_LIBGEN))#include <libgen.h>#endifextern int type, transflag, ftwflag, authenticated, autospout_free, data,    pdata, anonymous, guest;#ifdef TRANSFER_COUNTextern int data_count_total;	/* total number of data bytes */extern int data_count_in;extern int data_count_out;extern int byte_count_total;	/* total number of general traffic */extern int byte_count_in;extern int byte_count_out;extern int file_count_total;	/* total number of data files */extern int file_count_in;extern int file_count_out;extern int xfer_count_total;	/* total number of transfers */extern int xfer_count_in;extern int xfer_count_out;#ifdef TRANSFER_LIMIT  extern int file_limit_raw_in;extern int file_limit_raw_out;extern int file_limit_raw_total;extern int file_limit_data_in;  extern int file_limit_data_out; extern int file_limit_data_total;extern int data_limit_raw_in;extern int data_limit_raw_out;extern int data_limit_raw_total;extern int data_limit_data_in;  extern int data_limit_data_out; extern int data_limit_data_total;#ifdef RATIO /* 1998/08/06 K.Wakui */#define TRUNC_KB(n)   ((n)/1024+(((n)%1024)?1:0))extern time_t	login_time;extern time_t	limit_time;extern off_t    total_free_dl;extern int      upload_download_rate;#endif /* RATIO */#endif#endif#ifdef OTHER_PASSWD#include "getpwnam.h"extern char _path_passwd[];#endif#ifdef LOG_FAILEDextern char the_user[];#endifextern char *globerr, remotehost[];#ifdef THROUGHPUTextern char remoteaddr[];#endif#ifndef HAVE_REGEXchar *re_comp(const char *regex);int re_exec(const char *p1);#endifchar shuttime[30], denytime[30], disctime[30];FILE *dout;time_t newer_time;int show_fullinfo;/* This always was a bug, because neither st_size nor time_t were required to   be compatible with int, but needs fixing properly for C9X. *//* Some systems use one format, some another.  This takes care of the garbage *//* Do the system specific stuff only if we aren't autoconfed */#if !defined(L_FORMAT)#if (defined(BSD) && (BSD >= 199103)) && !defined(LONGOFF_T)#define L_FORMAT "qd"#else#define L_FORMAT "d"#endif#endif#if !defined(T_FORMAT)#define T_FORMAT "d"#endif#if !defined(PW_UID_FORMAT)#define PW_UID_FORMAT "d"#endif#if !defined(GR_GID_FORMAT)#define GR_GID_FORMAT "d"#endifint snprintf(char *str, size_t count, const char *fmt,...);int check_newer(char *path, struct stat *st, int flag){    if (st->st_mtime > newer_time) {	if (show_fullinfo != 0) {	    if (flag == FTW_F || flag == FTW_D) {		fprintf(dout, "%s %" L_FORMAT " %" T_FORMAT " %s\n",			flag == FTW_F ? "F" : "D",			st->st_size, st->st_mtime, path);	    }	}	else if (flag == FTW_F)	    fprintf(dout, "%s\n", path);    }    /* When an ABOR has been received (which sets ftwflag > 1) return a     * non-zero value which causes ftw to stop tree traversal and return.      */    return (ftwflag > 1 ? 1 : 0);}#if defined(HAVE_STATVFS)long getSize(char *s){    int c;    struct statvfs buf;    if ((c = statvfs(s, &buf)) != 0)	return (0);    return (buf.f_bavail * buf.f_frsize / 1024);}#elif defined(HAVE_SYS_VFS) || defined (HAVE_SYS_MOUNT)long getSize(char *s){    int c;    struct statfs buf;    if ((c = statfs(s, &buf)) != 0)	return (0);    return (buf.f_bavail * buf.f_bsize / 1024);}#endif/*************************************************************************//* FUNCTION  : msg_massage                                               *//* PURPOSE   : Scan a message line for magic cookies, replacing them as  *//*             needed.                                                   *//* ARGUMENTS : pointer input and output buffers                          *//*************************************************************************/void msg_massage(const char *inbuf, char *outbuf, size_t outlen){    const char *inptr = inbuf;    char *outptr = outbuf;#ifdef QUOTA    char timeleft[80];#endif    char buffer[MAXPATHLEN];    time_t curtime;    int limit;#ifndef LOG_FAILED    extern struct passwd *pw;#endif    struct aclmember *entry;#ifdef VIRTUAL    extern int virtual_mode;    extern int virtual_ftpaccess;    extern char virtual_email[];#endif    extern char hostname[];    extern char authuser[];    (void) acl_getclass(buffer);    limit = acl_getlimit(buffer, NULL);    while ((outlen > 1) && (*inptr != '\0')) {	if (*inptr != '%') {	    *outptr++ = *inptr;	    outlen -= 1;	}	else {	    entry = NULL;	    switch (*++inptr) {	    case 'E':#ifdef VIRTUAL		if (virtual_mode && !virtual_ftpaccess && virtual_email[0] != '\0')		    snprintf(outptr, outlen, "%s", virtual_email);		else#endif		if ((getaclentry("email", &entry)) && ARG0)		    snprintf(outptr, outlen, "%s", ARG0);		else		    *outptr = '\0';		break;	    case 'N':		snprintf(outptr, outlen, "%d", acl_countusers(buffer));		break;	    case 'M':		if (limit == -1)		    strncpy(outptr, "unlimited", outlen);		else		    snprintf(outptr, outlen, "%d", limit);		break;	    case 'T':		(void) time(&curtime);		strncpy(outptr, ctime(&curtime), outlen);		if (outlen > 24)		    *(outptr + 24) = '\0';		break;	    case 'F':#if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined(HAVE_SYS_MOUNT)		snprintf(outptr, outlen, "%lu", (long) getSize("."));#else		*outptr = '\0';#endif		break;	    case 'C':#ifdef HAVE_GETCWD		(void) getcwd(outptr, outlen);#else#error	wu-ftpd on this platform has security deficiencies!!!		(void) getwd(outptr);#endif		break;	    case 'R':		strncpy(outptr, remotehost, outlen);		break;	    case 'L':		strncpy(outptr, hostname, outlen);		break;	    case 'U':#ifdef LOG_FAILED		strncpy(outptr, the_user, outlen);#else /* LOG_FAILED */		strncpy(outptr,			(pw == NULL) ? "[unknown]" : pw->pw_name, outlen);#endif /* LOG_FAILED */		break;	    case 's':		strncpy(outptr, shuttime, outlen);		if (outlen > 24)		    *(outptr + 24) = '\0';		break;	    case 'd':		strncpy(outptr, disctime, outlen);		if (outlen > 24)		    *(outptr + 24) = '\0';		break;	    case 'r':		strncpy(outptr, denytime, outlen);		if (outlen > 24)		    *(outptr + 24) = '\0';		break;/* KH : cookie %u for RFC931 name */	    case 'u':		if (authenticated)		    strncpy(outptr, authuser, outlen);		else		    strncpy(outptr, "[unknown]", outlen);		break;#ifdef QUOTA	    case 'B':#ifdef QUOTA_BLOCKS		/* 1024-blocks instead of 512-blocks */		snprintf(outptr, outlen, "%ld", quota.dqb_bhardlimit % 2 ?			 (long) (quota.dqb_bhardlimit / 2 + 1) : (long) (quota.dqb_bhardlimit / 2));#else		snprintf(outptr, outlen, "%ld", (long) quota.dqb_bhardlimit);#endif		break;	    case 'b':#ifdef QUOTA_BLOCKS		/* 1024-blocks instead of 512-blocks */		snprintf(outptr, outlen, "%ld", quota.dqb_bsoftlimit % 2 ?			 (long) (quota.dqb_bsoftlimit / 2 + 1) : (long) (quota.dqb_bsoftlimit / 2));#else		snprintf(outptr, outlen, "%ld", (long) quota.dqb_bsoftlimit);#endif		break;	    case 'Q':#ifdef QUOTA_BLOCKS		/* 1024-blocks instead of 512-blocks */		snprintf(outptr, outlen, "%ld", quota.dqb_curblocks % 2 ?			 (long) (quota.dqb_curblocks / 2 + 1) : (long) (quota.dqb_curblocks / 2));#else		snprintf(outptr, outlen, "%ld", quota.dqb_curblocks);#endif		break;	    case 'I':#if defined(QUOTA_INODE)		snprintf(outptr, outlen, "%d", quota.dqb_ihardlimit);#else		snprintf(outptr, outlen, "%ld", (long) quota.dqb_fhardlimit);#endif		break;	    case 'i':#if defined(QUOTA_INODE)		snprintf(outptr, outlen, "%d", quota.dqb_isoftlimit);#else		snprintf(outptr, outlen, "%ld", (long) quota.dqb_fsoftlimit);#endif		break;	    case 'q':#if defined(QUOTA_INODE)		snprintf(outptr, outlen, "%d", quota.dqb_curinodes);#else		snprintf(outptr, outlen, "%ld", (long) quota.dqb_curfiles);#endif		break;	    case 'H':		time_quota(quota.dqb_curblocks, quota.dqb_bsoftlimit,#if defined(QUOTA_INODE)			   quota.dqb_btime, timeleft);#else			   quota.dqb_btimelimit, timeleft);#endif		strncpy(outptr, timeleft, outlen);		break;	    case 'h':#if defined(QUOTA_INODE)		time_quota(quota.dqb_curinodes, quota.dqb_isoftlimit,			   quota.dqb_itime, timeleft);#else		time_quota(quota.dqb_curfiles, quota.dqb_fsoftlimit,			   quota.dqb_ftimelimit, timeleft);#endif		strncpy(outptr, timeleft, outlen);		break;#endif /* QUOTA */	    case '%':		*outptr++ = '%';		outlen -= 1;		*outptr = '\0';		break;#ifdef TRANSFER_COUNT#ifdef TRANSFER_LIMIT#ifdef RATIO            case 'x':                switch (*++inptr) {                case 'u':       /* upload bytes */                    sprintf(outptr,"%d", TRUNC_KB(data_count_in) );                    break;                case 'd':       /* download bytes */                    sprintf(outptr,"%d", TRUNC_KB(data_count_out) );                    break;                case 'R':       /* rate 1:n */                    if( upload_download_rate > 0 ) {                        sprintf(outptr,"%d", upload_download_rate );                    }                    else {                        strcpy(outptr,"free");                    }                    break;                case 'c':       /* credit bytes */                    if( upload_download_rate > 0 ) {                        off_t credit=( data_count_in * upload_download_rate) - (data_count_out - total_free_dl);                        sprintf(outptr,"%d", TRUNC_KB(credit) );                    }                    else {                        strcpy(outptr,"unlimited");                    }                    break;                case 'T':       /* time limit (minutes) */                    if( limit_time > 0 ) {                        sprintf(outptr,"%d", limit_time );                    }                    else {                        strcpy(outptr,"unlimited");                    }                    break;                case 'E':       /* elapsed time from loggedin (minutes) */                    sprintf(outptr,"%d", (time(NULL)-login_time)/60 );                    break;                case 'L':       /* times left until force logout (minutes) */                    if( limit_time > 0 ) {                        sprintf(outptr,"%d", limit_time-(time(NULL)-login_time)/60 );                    }                    else {                        strcpy(outptr,"unlimited");                    }                    break;                case 'U':       /* upload limit */		    if( data_limit_raw_in > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_raw_in));		    }		    else if( data_limit_data_in > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_data_in));		    }		    else if( data_limit_raw_total > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_raw_total));		    }		    else if( data_limit_data_total > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_data_total));		    }		    else {			strcpy(outptr, "unlimited");		    }                    break;                case 'D':       /* download limit */		    if( data_limit_raw_out > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_raw_out));		    }		    else if( data_limit_data_out > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_data_out));		    }		    else if( data_limit_raw_total > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_raw_total));		    }		    else if( data_limit_data_total > 0 ) {			sprintf(outptr,"%d", TRUNC_KB(data_limit_data_total));		    }		    else {			strcpy(outptr, "unlimited");		    }                    break;                default:                    strcpy(outptr,"%??");                    break;                }                break;#endif /* RATIO */#endif#endif	    default:		*outptr++ = '%';		outlen -= 1;		if (outlen > 1) {		    *outptr++ = *inptr;		    outlen -= 1;		}		*outptr = '\0';		break;	    }	    outptr[outlen - 1] = '\0';	    while (*outptr) {		outptr++;		outlen -= 1;	    }	}	inptr++;    }    if (outlen > 0)	*outptr = '\0';}/*************************************************************************//* FUNCTION  : cwd_beenhere                                              *//* PURPOSE   : Return 1 if the user has already visited this directory   *//*             via C_WD.                                                 *//* ARGUMENTS : a power-of-two directory function code (README, MESSAGE)  *//*************************************************************************/int cwd_beenhere(int dircode){    struct dirlist {	struct dirlist *next;	int dircode;	char dirname[1];    };    static struct dirlist *head = NULL;    struct dirlist *curptr;    char cwd[MAXPATHLEN];    (void) fb_realpath(".", cwd);    for (curptr = head; curptr != NULL; curptr = curptr->next)	if (strcmp(curptr->dirname, cwd) == 0) {	    if (!(curptr->dircode & dircode)) {		curptr->dircode |= dircode;

⌨️ 快捷键说明

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