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

📄 extensions.c

📁 wu-ftpd类unix下的ftp服务器,可用于嵌入式系统
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (strcasecmp(q + 6, class) == 0)		    classmatched = 1;	    }	    else if (strcmp(q, "-") == 0) {		i++;		options = 0;	    }	    else		options = 0;	}	if (!classfound || classmatched) {	    for (; (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0'); i++) {		len = strlen(q);		p = (q[0] == '/') ? whichname : lbasename(whichname);		if (!wu_fnmatch(q, p, FNM_PATHNAME | FNM_LEADING_DIR)) {		    if (!allow_retrieve(name)) {#ifdef VERBOSE_ERROR_LOGING			syslog(LOG_NOTICE, "%s of %s tried to download %s", pw->pw_name, remoteident, realname);#endif			reply(550, "%s is marked unretrievable", localname);			return 1;		    }		}	    }	}    }    return 0;}#ifdef QUOTA#ifndef MNTMAXSTR#define MNTMAXSTR 2048		/* And hope it's enough */#endif#ifdef QUOTA_DEVICEint path_to_device(char *pathname, char *result){    FILE *fp;#ifdef HAS_OLDSTYLE_GETMNTENT    struct mnttab static_mp;    struct mnttab *mp = &static_mp;#else    struct mntent *mp;#endif    struct mount_ent {	char mnt_fsname[MNTMAXSTR], mnt_dir[MNTMAXSTR];	struct mount_ent *next;    } mountent;    struct mount_ent *current, *start, *new;    char path[1024], mnt_dir[1024], *pos;    int flag = 1;    extern char chroot_path[];    start = current = NULL;#ifdef HAS_OLDSTYLE_GETMNTENT    fp = fopen(MNTTAB, "r");#else    fp = setmntent(MNTTAB, "r");#endif    if (fp == NULL)	return 0;#ifdef HAS_OLDSTYLE_GETMNTENT    while (getmntent(fp, &static_mp) == 0)#else    while (mp = getmntent(fp))#endif    {	if (!(new = (struct mount_ent *) malloc(sizeof(mountent)))) {	    perror("malloc");	    flag = 0;	    break;	}	if (!start)	    start = current = new;	else	    current = current->next = new;#ifdef HAS_OLDSTYLE_GETMNTENT	strncpy(current->mnt_fsname, mp->mnt_special, strlen(mp->mnt_special) + 1);	strncpy(current->mnt_dir, mp->mnt_mountp, strlen(mp->mnt_mountp) + 1);#else	strncpy(current->mnt_fsname, mp->mnt_fsname, strlen(mp->mnt_fsname) + 1);	strncpy(current->mnt_dir, mp->mnt_dir, strlen(mp->mnt_dir) + 1);#endif    }#ifdef HAS_OLDSTYLE_GETMNTENT    fclose(fp);#else    endmntent(fp);#endif    current->next = NULL;    wu_realpath(pathname, path, chroot_path);    while (*path && flag) {	current = start;	while (current && flag) {	    if (strcmp(current->mnt_dir, "swap")) {		wu_realpath(current->mnt_dir, mnt_dir, chroot_path);		if (!strcmp(mnt_dir, path)) {		    flag = 0;		    /* no support for remote quota yet */		    if (!strchr(current->mnt_fsname, ':'))			strcpy(result, current->mnt_fsname);		}	    }	    current = current->next;	}	if (!((pos = strrchr(path, '/')) - path) && strlen(path) > 1)	    strcpy(path, "/");	else	    path[pos - path] = '\0';    }    while (current) {	new = current->next;	free(current);	current = new;    }    return 1;}#endifvoid get_quota(char *fs, int uid){    char mnt_fsname[MNTMAXSTR];#ifdef HAS_NO_QUOTACTL    int dirfd;    struct quotctl qp;    if (path_to_device(fs, mnt_fsname)) {	dirfd = open(fs, O_RDONLY);	qp.op = Q_GETQUOTA;	qp.uid = uid;	qp.addr = (char *) &quota;	ioctl(dirfd, Q_QUOTACTL, &qp);	close(dirfd);    }#else#ifdef QUOTA_DEVICE    if (path_to_device(fs, mnt_fsname))#ifdef QCMD	quotactl(QCMD(Q_GETQUOTA, USRQUOTA), mnt_fsname, uid, (char *) &quota);#else	quotactl(Q_GETQUOTA, mnt_fsname, uid, (char *) &quota);#endif#else    quotactl(fs, QCMD(Q_GETQUOTA, USRQUOTA), uid, (char *) &quota);#endif#endif /* HAS_NO_QUOTACTL */}char *time_quota(long curstate, long softlimit, long timelimit, char *timeleft){    struct timeval tv;    gettimeofday(&tv, NULL);    if (softlimit && curstate >= softlimit) {	if (timelimit == 0) {	    strcpy(timeleft, "NOT STARTED");	}	else if (timelimit > tv.tv_sec) {	    fmttime(timeleft, timelimit - tv.tv_sec);	}	else {	    strcpy(timeleft, "EXPIRED");	}    }    else {	timeleft[0] = '\0';    }    return (timeleft);}void fmttime(char *buf, register long time){    int i;    static struct {	int c_secs;		/* conversion units in secs */	char *c_str;		/* unit string */    } cunits[] = {	{	    60 *60 * 24 * 28, "months"	} ,	{	    60 *60 * 24 * 7, "weeks"	} ,	{	    60 *60 * 24, "days"	} ,	{	    60 *60, "hours"	} ,	{	    60, "mins"	} ,	{	    1, "secs"	}    };    if (time <= 0) {	strcpy(buf, "EXPIRED");	return;    }    for (i = 0; i < sizeof(cunits) / sizeof(cunits[0]); i++) {	if (time >= cunits[i].c_secs)	    break;    }    sprintf(buf, "%.1f %s", (double) time / cunits[i].c_secs, cunits[i].c_str);}#endif#ifdef QUOTA#if (defined(LINUX) && !defined(AUTOCONF)) || (defined(AUTOCONF) && !defined(HAVE_QUOTACTL) && defined(__linux__))/* I have no idea why I can't find 'quotactl()' in my libs, here's the source - GAL *//* This was a bug in truly ancient libc's (prior to 5.3.something). It isn't   needed on any modern version of Linux. *//* * QUOTA    An implementation of the diskquota system for the LINUX *          operating system. QUOTA is implemented using the BSD systemcall *          interface as the means of communication with the user level. *          Should work for all filesystems because of integration into the *          VFS layer of the operating system. *          This is based on the Melbourne quota system wich uses both user and *          group quota files. * *          System call interface. * * Version: $Id: extensions.c,v 1.48 2000/07/01 18:17:38 wuftpd Exp $ * * Author:  Marco van Wieringen <mvw@planets.ow.nl> <mvw@tnix.net> * *          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. */#if defined(__alpha__)#include <errno.h>#include <sys/types.h>#include <syscall.h>#include <asm/unistd.h>int quotactl(int cmd, const char *special, int id, caddr_t addr){    return syscall(__NR_quotactl, cmd, special, id, addr);}#else /* __alpha__ */#include <sys/types.h>#define __LIBRARY__#include <linux/unistd.h>_syscall4(int, quotactl, int, cmd, const char *, special, int, id, caddr_t, addr);#endif /* __alpha__ */#elif !defined(HAVE_QUOTACTL)	/* LINUX */#ifdef QUOTA_DEVICE/* I have no idea why I can't find 'quotactl()' in my libs, here's the source - keller */int quotactl(int cmd, const char *special, int id, caddr_t addr){    struct quotctl {	int op;	uid_t uid;	caddr_t addr;    } qp;    /*     * open up the quota file in the root directory to get the file descriptor.     * if no quota file exists, quotas are not enabled.     */    FILE *qf;    char mnt_pnt[1024];    mnt_pnt[0] = '\0';    strncpy(mnt_pnt, special, strlen(mnt_pnt));    strncat(mnt_pnt, "/quota", strlen(mnt_pnt));    qf = fopen(mnt_pnt, "r");    if (qf == NULL)	return(-1);    qp.op = Q_GETQUOTA;    qp.uid = id;    qp.addr = addr;    return ioctl((int) qf, (int) Q_QUOTACTL, qp);}#endif /* QUOTA_DEVICE */#endif /* LINUX */#endif /* QUOTA */#ifdef THROUGHPUTint file_compare(char *patterns, char *file){    char buf[MAXPATHLEN];    char *cp;    char *cp2;    int i;    int matches = 0;    strncpy(buf, patterns, sizeof(buf));    buf[sizeof(buf) - 1] = '\0';    i = strlen(buf);    buf[i++] = ',';    buf[i++] = '\0';    cp = buf;    while ((cp2 = strchr(cp, ',')) != NULL) {	*cp2++ = '\0';	if (wu_fnmatch(cp, file, FNM_PATHNAME) == 0) {	    matches = 1;	    break;	}    }    return matches;}int remote_compare(char *patterns){    char buf[MAXPATHLEN];    char *cp;    char *cp2;    int i;    int matches = 0;    strncpy(buf, patterns, sizeof(buf));    buf[sizeof(buf) - 1] = '\0';    i = strlen(buf);    buf[i++] = ',';    buf[i++] = '\0';    cp = buf;    while ((cp2 = strchr(cp, ',')) != NULL) {	*cp2++ = '\0';	if (hostmatch(cp, remoteaddr, remotehost)) {	    matches = 1;	    break;	}    }    return matches;}void throughput_calc(char *name, int *bps, double *bpsmult){    int match_value = -1;    char cwdir[MAXPATHLEN];    char pwdir[MAXPATHLEN];    char path[MAXPATHLEN];    char file[MAXPATHLEN];    char *ap3 = NULL, *ap4 = NULL;    struct aclmember *entry = NULL;    extern char *home;    extern char chroot_path[];    char *sp;    int i;    /* default is maximum throughput */    *bps = -1;    *bpsmult = 1.0;    /* XXX We could use dynamic RAM to store this path, but I'd rather just bail       out with an error. The rest of wu is so crufy that a long path might       just blow up later */    if ((strlen(name) + 1) > sizeof(path)) {	return;    }    /* what's our current directory? */    strcpy(path, name);    if ((sp = strrchr(path, '/')))	*sp = '\0';    else	strcpy(path, ".");    if ((sp = strrchr(name, '/')))	strcpy(file, sp + 1);    else	strcpy(file, name);    if ((fb_realpath(path, cwdir)) == NULL) {	return;    }    wu_realpath(home, pwdir, chroot_path);    /* find best matching entry */    while (getaclentry("throughput", &entry) && ARG0 && ARG1 && ARG2 && ARG3 && ARG4 && ARG5 != NULL) {	if ((0 < path_compare(ARG0, pwdir))	    && ((i = path_compare(ARG1, cwdir)) >= match_value)	    ) {	    if (file_compare(ARG2, file)) {		if (remote_compare(ARG5)) {		    match_value = i;		    ap3 = ARG3;		    ap4 = ARG4;		}	    }	}    }    /* if we did get matches */    if (match_value >= 0) {	if (strcasecmp(ap3, "oo") == 0)	    *bps = -1;	else	    *bps = atoi(ap3);	if (strcmp(ap4, "-") == 0)	    *bpsmult = 1.0;	else	    *bpsmult = atof(ap4);    }    return;}void throughput_adjust(char *name){    int match_value = -1;    char pwdir[MAXPATHLEN];    char cwdir[MAXPATHLEN];    char path[MAXPATHLEN];    char file[MAXPATHLEN];    char buf[MAXPATHLEN];    char *ap3 = NULL, *ap4 = NULL;    char **pap3;    struct aclmember *entry = NULL;    extern char *home;    extern char chroot_path[];    char *sp;    int i;    /* XXX We could use dynamic RAM to store this path, but I'd rather just bail       out with an error. The rest of wu is so crufy that a long path might       just blow up later */    if ((strlen(name) + 1) > sizeof(path)) {	return;    }    /* what's our current directory? */    strcpy(path, name);    if ((sp = strrchr(path, '/')))	*sp = '\0';    else	strcpy(path, ".");    if ((sp = strrchr(name, '/')))	strcpy(file, sp + 1);    else	strcpy(file, name);    if ((fb_realpath(path, cwdir)) == NULL) {	return;    }    wu_realpath(home, pwdir, chroot_path);    /* find best matching entry */    while (getaclentry("throughput", &entry) && ARG0 && ARG1 && ARG2 && ARG3 && ARG4 && ARG5 != NULL) {	if ((0 < path_compare(ARG0, pwdir))	    && ((i = path_compare(ARG1, cwdir)) >= match_value)	    ) {	    if (file_compare(ARG2, file)) {		if (remote_compare(ARG5)) {		    match_value = i;		    ap3 = ARG3;		    pap3 = &ARG3;		    ap4 = ARG4;		}	    }	}    }    /* if we did get matches */    if (match_value >= 0) {	if (strcasecmp(ap3, "oo") != 0) {	    if (strcmp(ap4, "-") != 0) {		sprintf(buf, "%.0f", atoi(ap3) * atof(ap4));		*pap3 = (char *) malloc(strlen(buf) + 1);		if (*pap3 == NULL) {		    syslog(LOG_ERR, "malloc error in throughput_adjust");		    exit(0);		}		strcpy(*pap3, buf);	    }	}    }    return;}#endifstatic int CheckMethod = 0;void SetCheckMethod(const char *method){    if ((strcasecmp(method, "md5") == 0)	|| (strcasecmp(method, "rfc1321") == 0))	CheckMethod = 0;    else if ((strcasecmp(method, "crc") == 0)	     || (strcasecmp(method, "posix") == 0))	CheckMethod = 1;    else {	reply(500, "Unrecognized checksum method");	return;    }    switch (CheckMethod) {    default:	reply(200, "Checksum method is now: MD5 (RFC1321)");	break;    case 1:	reply(200, "Checksum method is now: CRC (POSIX)");	break;    }}void ShowCheckMethod(void){    switch (CheckMethod) {    default:	reply(200, "Current checksum method: MD5 (RFC1321)");	break;    case 1:	reply(200, "Current checksum method: CRC (POSIX)");	break;    }}void CheckSum(char *pathname){    char *cmd;    char buf[MAXPATHLEN];    FILE *cmdf;    struct stat st;    if (stat(pathname, &st) == 0) {	if ((st.st_mode & S_IFMT) != S_IFREG) {	    reply(500, "%s: not a plain file.", pathname);	    return;	}    }    else {	perror_reply(550, pathname);	return;    }    switch (CheckMethod) {    default:	cmd = "/bin/md5sum";	break;    case 1:	cmd = "/bin/cksum";	break;    }    if (strlen(cmd) + 1 + strlen(pathname) + 1 > sizeof(buf)) {	reply(500, "Pathname too long");	return;    }    sprintf(buf, "%s %s", cmd, pathname);    cmdf = ftpd_popen(buf, "r", 0);    if (!cmdf) {	perror_reply(550, cmd);    }    else {	if (fgets(buf, sizeof buf, cmdf)) {	    char *crptr = strchr(buf, '\n');	    if (crptr != NULL)		*crptr = '\0';	    reply(200, "%s", buf);	}	ftpd_pclose(cmdf);    }}void CheckSumLastFile(void){    extern char LastFileTransferred[];    if (LastFileTransferred[0] == '\0')	reply(500, "Nothing transferred yet");    else	CheckSum(LastFileTransferred);}

⌨️ 快捷键说明

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