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

📄 ftpcmd.y

📁 wu-ftpd类unix下的ftp服务器,可用于嵌入式系统
💻 Y
📖 第 1 页 / 共 3 页
字号:
		if (strncasecmp(passtxt, s, 5) == 0)		    syslog(LOG_DEBUG, "command: %s", passtxt);		else		    syslog(LOG_DEBUG, "command: %s", s);	    }	    tmpline[0] = '\0';	    return (s);	}	if (c == 0)	    tmpline[0] = '\0';    }  retry:    while ((c = getc(iop)) != EOF) {#ifdef TRANSFER_COUNT	byte_count_total++;	byte_count_in++;#endif	c &= 0377;	if (c == IAC) {	    if ((c = getc(iop)) != EOF) {#ifdef TRANSFER_COUNT		byte_count_total++;		byte_count_in++;#endif		c &= 0377;		switch (c) {		case WILL:		case WONT:		    c = getc(iop);#ifdef TRANSFER_COUNT		    byte_count_total++;		    byte_count_in++;#endif		    printf("%c%c%c", IAC, DONT, 0377 & c);		    (void) fflush(stdout);		    continue;		case DO:		case DONT:		    c = getc(iop);#ifdef TRANSFER_COUNT		    byte_count_total++;		    byte_count_in++;#endif		    printf("%c%c%c", IAC, WONT, 0377 & c);		    (void) fflush(stdout);		    continue;		case IAC:		    break;		default:		    continue;	/* ignore command */		}	    }	}	*cs++ = c;	if (--n <= 0 || c == '\n')	    break;    }    if (c == EOF && cs == s) {	if (ferror(iop) && (errno == EINTR))	    goto retry;	return (NULL);    }    *cs++ = '\0';    if (debug) {	if (strncasecmp(passtxt, s, 5) == 0)	    syslog(LOG_DEBUG, "command: %s", passtxt);	else	    syslog(LOG_DEBUG, "command: %s", s);    }    return (s);}static void toolong(int a) /* signal that caused this function to be called */{    time_t now;    reply(421,	  "Timeout (%d seconds): closing control connection.", timeout_idle);    (void) time(&now);    if (logging) {	syslog(LOG_INFO,	       "User %s timed out after %d seconds at %.24s",	       (pw ? pw->pw_name : "unknown"), timeout_idle, ctime(&now));    }    dologout(1);}int yylex(void){    static int cpos, state;    register char *cp, *cp2;    register struct tab *p;    int n;    time_t now;    char c = '\0';    extern time_t limit_time;    extern time_t login_time;    for (;;) {	switch (state) {	case CMD:	    yyerrorcalled = 0;	    setproctitle("%s: IDLE", proctitle);	    if (is_shutdown(!logged_in, 0) != 0) {		reply(221, "Server shutting down.  Goodbye.");		dologout(0);	    }	    time(&now);	    if ((limit_time > 0) && (((now - login_time) / 60) > limit_time)) {		reply(221, "Time limit reached.  Goodbye.");		dologout(0);	    }#ifdef IGNORE_NOOP	    if (!alarm_running) {		(void) signal(SIGALRM, toolong);		(void) alarm((unsigned) timeout_idle);		alarm_running = 1;	    }#else	    (void) signal(SIGALRM, toolong);	    (void) alarm((unsigned) timeout_idle);#endif	    if (wu_getline(cbuf, sizeof(cbuf) - 1, stdin) == NULL) {		(void) alarm(0);		reply(221, "You could at least say goodbye.");		dologout(0);	    }#ifndef IGNORE_NOOP	    (void) alarm(0);#endif	    if ((cp = strchr(cbuf, '\r'))) {		*cp++ = '\n';		*cp = '\0';	    }	    if ((cp = strpbrk(cbuf, " \n")))		cpos = cp - cbuf;	    if (cpos == 0)		cpos = 4;	    c = cbuf[cpos];	    cbuf[cpos] = '\0';	    upper(cbuf);#ifdef IGNORE_NOOP	    if (strncasecmp(cbuf, "NOOP", 4) != 0) {		(void) alarm(0);		alarm_running = 0;	    }#endif	    p = lookup(cmdtab, cbuf);	    cbuf[cpos] = c;	    if (strncasecmp(cbuf, "PASS", 4) != 0 &&		strncasecmp(cbuf, "SITE GPASS", 10) != 0) {		if ((cp = strchr(cbuf, '\n')))		    *cp = '\0';		setproctitle("%s: %s", proctitle, cbuf);		if (cp)		    *cp = '\n';	    }	    if (p != 0) {		if (p->implemented == 0) {		    nack(p->name);		    longjmp(errcatch, 0);		    /* NOTREACHED */		}		state = p->state;		yylval.String = p->name;		return (p->token);	    }	    break;	case SITECMD:	    if (cbuf[cpos] == ' ') {		cpos++;		return (SP);	    }	    cp = &cbuf[cpos];	    if ((cp2 = strpbrk(cp, " \n")))		cpos = cp2 - cbuf;	    c = cbuf[cpos];	    cbuf[cpos] = '\0';	    upper(cp);	    p = lookup(sitetab, cp);	    cbuf[cpos] = c;	    if (p != 0) {#ifndef PARANOID		/* what GOOD is SITE *, anyways?!  _H */		if (p->implemented == 0) {#else		if (1) {		    syslog(LOG_WARNING, "refused SITE %s %s from %s of %s",			   p->name, &cbuf[cpos],			   anonymous ? guestpw : authuser, remoteident);#endif /* PARANOID */		    state = CMD;		    nack(p->name);		    longjmp(errcatch, 0);		    /* NOTREACHED */		}		state = p->state;		yylval.String = p->name;		return (p->token);	    }	    state = CMD;	    break;	case OSTR:	    if (cbuf[cpos] == '\n') {		state = CMD;		return (CRLF);	    }	    /* FALLTHROUGH */	case STR1:	case ZSTR1:	  dostr1:	    if (cbuf[cpos] == ' ') {		cpos++;		if (state == OSTR)		    state = STR2;		else		    ++state;		return (SP);	    }	    break;	case ZSTR2:	    if (cbuf[cpos] == '\n') {		state = CMD;		return (CRLF);	    }	    /* FALLTHROUGH */	case STR2:	    cp = &cbuf[cpos];	    n = strlen(cp);	    cpos += n - 1;	    /*	     * Make sure the string is nonempty and \n terminated.	     */	    if (n > 1 && cbuf[cpos] == '\n') {		cbuf[cpos] = '\0';		yylval.String = copy(cp);		cbuf[cpos] = '\n';		state = ARGS;		return (STRING);	    }	    break;	case NSTR:	    if (cbuf[cpos] == ' ') {		cpos++;		return (SP);	    }	    if (isdigit(cbuf[cpos])) {		cp = &cbuf[cpos];		while (isdigit(cbuf[++cpos]));		c = cbuf[cpos];		cbuf[cpos] = '\0';		yylval.Number = atoi(cp);		cbuf[cpos] = c;		state = STR1;		return (NUMBER);	    }	    state = STR1;	    goto dostr1;	case STR3:	    if (cbuf[cpos] == ' ') {		cpos++;		return (SP);	    }	    cp = &cbuf[cpos];	    cp2 = strpbrk(cp, " \n");	    if (cp2 != NULL) {		c = *cp2;		*cp2 = '\0';	    }	    n = strlen(cp);	    cpos += n;	    /*	     * Make sure the string is nonempty and SP terminated.	     */	    if ((cp2 - cp) > 1) {		yylval.String = copy(cp);		cbuf[cpos] = c;		state = OSTR;		return (STRING);	    }	    break;	case ARGS:	    if (isdigit(cbuf[cpos])) {		cp = &cbuf[cpos];		while (isdigit(cbuf[++cpos]));		c = cbuf[cpos];		cbuf[cpos] = '\0';		yylval.Number = atoi(cp);		cbuf[cpos] = c;		return (NUMBER);	    }	    switch (cbuf[cpos++]) {	    case '\n':		state = CMD;		return (CRLF);	    case ' ':		return (SP);	    case ',':		return (COMMA);	    case 'A':	    case 'a':		return (A);	    case 'B':	    case 'b':		return (B);	    case 'C':	    case 'c':		return (C);	    case 'E':	    case 'e':		return (E);	    case 'F':	    case 'f':		return (F);	    case 'I':	    case 'i':		return (I);	    case 'L':	    case 'l':		return (L);	    case 'N':	    case 'n':		return (N);	    case 'P':	    case 'p':		return (P);	    case 'R':	    case 'r':		return (R);	    case 'S':	    case 's':		return (S);	    case 'T':	    case 't':		return (T);	    }	    break;	default:	    fatal("Unknown state in scanner.");	}	if (yyerrorcalled == 0) {	    if ((cp = strchr(cbuf, '\n')) != NULL)		*cp = '\0';	    if (logged_in)		reply(500, "'%s': command not understood.", cbuf);	    else		reply(530, "Please login with USER and PASS.");	}	state = CMD;	longjmp(errcatch, 0);    }}void upper(char *s){    while (*s != '\0') {	if (islower(*s))	    *s = toupper(*s);	s++;    }}char *copy(char *s){    char *p;    p = (char *) malloc((unsigned) strlen(s) + 1);    if (p == NULL)	fatal("Ran out of memory.");    (void) strcpy(p, s);    return (p);}void help(struct tab *ctab, char *s){    struct aclmember *entry = NULL;    struct tab *c;    size_t width, NCMDS;    char *type;    if (ctab == sitetab)	type = "SITE ";    else	type = "";    width = 0, NCMDS = 0;    for (c = ctab; c->name != NULL; c++) {	size_t len = strlen(c->name);	if (len > width)	    width = len;	NCMDS++;    }    width = (width + 8) & ~7;    if (s == 0) {	register size_t i, j, w;	size_t columns, lines;	lreply(214, "The following %scommands are recognized %s.",	       type, "(* =>'s unimplemented)");	columns = 76 / width;	if (columns == 0)	    columns = 1;	lines = (NCMDS + columns - 1) / columns;	for (i = 0; i < lines; i++) {	    char line[BUFSIZ], *ptr = line;	    strcpy(ptr, "   ");	    ptr += 3;	    for (j = 0; j < columns; j++) {		c = ctab + j * lines + i;		(void) sprintf(ptr, "%s%c", c->name,			       c->implemented ? ' ' : '*');		w = strlen(c->name) + 1;		ptr += w;		if (c + lines >= &ctab[NCMDS])		    break;		while (w < width) {		    *(ptr++) = ' ';		    w++;		}	    }	    *ptr = '\0';	    lreply(0, "%s", line);	}	(void) fflush(stdout);#ifdef VIRTUAL	if (virtual_mode && !virtual_ftpaccess && virtual_email[0] != '\0')	    reply(214, "Direct comments to %s.", virtual_email);	else#endif	if ((getaclentry("email", &entry)) && ARG0)	    reply(214, "Direct comments to %s.", ARG0);	else	    reply(214, "Direct comments to ftp-bugs@%s.", hostname);	return;    }    upper(s);    c = lookup(ctab, s);    if (c == (struct tab *) NULL) {	reply(502, "Unknown command %s.", s);	return;    }    if (c->implemented)	reply(214, "Syntax: %s%s %s", type, c->name, c->help);    else	reply(214, "%s%-*s\t%s; unimplemented.", type, width,	      c->name, c->help);}void sizecmd(char *filename){    switch (type) {    case TYPE_L:    case TYPE_I:{	    struct stat stbuf;	    if (stat(filename, &stbuf) < 0 ||		(stbuf.st_mode & S_IFMT) != S_IFREG)		reply(550, "%s: not a plain file.", filename);	    else#if OFFSET_SIZE == 8		reply(213, "%qu", stbuf.st_size);#else#ifdef _AIX42		reply(213, "%llu", stbuf.st_size);#else		reply(213, "%lu", stbuf.st_size);#endif#endif	    break;	}    case TYPE_A:{	    FILE *fin;	    register int c;	    register long count;	    struct stat stbuf;	    fin = fopen(filename, "r");	    if (fin == NULL) {		perror_reply(550, filename);		return;	    }	    if (fstat(fileno(fin), &stbuf) < 0 ||		(stbuf.st_mode & S_IFMT) != S_IFREG) {		reply(550, "%s: not a plain file.", filename);		(void) fclose(fin);		return;	    }	    count = 0;	    while ((c = getc(fin)) != EOF) {		if (c == '\n')	/* will get expanded to \r\n */		    count++;		count++;	    }	    (void) fclose(fin);	    reply(213, "%ld", count);	    break;	}    default:	reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);    }}void site_exec(char *cmd){#ifdef PARANOID    syslog(LOG_CRIT, "REFUSED SITE_EXEC (slipped through!!): %s", cmd);#else    char buf[MAXPATHLEN];    char *sp = (char *) strchr(cmd, ' '), *slash, *t;    FILE *cmdf;    /* sanitize the command-string */    if (sp == 0) {	while ((slash = strchr(cmd, '/')) != 0)	    cmd = slash + 1;    }    else {	while (sp && (slash = (char *) strchr(cmd, '/'))	       && (slash < sp))	    cmd = slash + 1;    }    for (t = cmd; *t && !isspace(*t); t++) {	if (isupper(*t)) {	    *t = tolower(*t);	}    }    /* build the command */    if (strlen(_PATH_EXECPATH) + strlen(cmd) + 2 > sizeof(buf))	return;    sprintf(buf, "%s/%s", _PATH_EXECPATH, cmd);    cmdf = ftpd_popen(buf, "r", 0);    if (!cmdf) {	perror_reply(550, cmd);	if (log_commands)	    syslog(LOG_INFO, "SITE EXEC (FAIL: %m): %s", cmd);    }    else {	int lines = 0;	int maxlines = 0;	struct aclmember *entry = NULL;	char class[1024];	int maxfound = 0;	int defmaxlines = 20;	int which;	(void) acl_getclass(class);	while ((getaclentry("site-exec-max-lines", &entry)) && ARG0) {	    if (ARG1)		for (which = 1; (which < MAXARGS) && ARG[which]; which++) {		    if (!strcasecmp(ARG[which], class)) {			maxlines = atoi(ARG0);			maxfound = 1;		    }		    if (!strcmp(ARG[which], "*"))			defmaxlines = atoi(ARG0);		}	    else		defmaxlines = atoi(ARG0);	}	if (!maxfound)	    maxlines = defmaxlines;	lreply(200, "%s", cmd);	while (fgets(buf, sizeof buf, cmdf)) {	    size_t len = strlen(buf);	    if (len > 0 && buf[len - 1] == '\n')		buf[--len] = '\0';	    lreply(200, "%s", buf);	    if (maxlines <= 0)		++lines;	    else if (++lines >= maxlines) {		lreply(200, "*** Truncated ***");		break;	    }	}	reply(200, " (end of '%s')", cmd);	if (log_commands)	    syslog(LOG_INFO, "SITE EXEC (lines: %d): %s", lines, cmd);	ftpd_pclose(cmdf);    }#endif /* PARANOID */}void alias(char *s){    struct aclmember *entry = NULL;    if (s != (char *) NULL) {	while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL)	    if (!strcmp(ARG0, s)) {		reply(214, "%s is an alias for %s.", ARG0, ARG1);		return;	    }	reply(502, "Unknown alias %s.", s);	return;    }    lreply(214, "The following aliases are available.");    while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL)	lreply(0, "   %-8s %s", ARG0, ARG1);    (void) fflush(stdout);    reply(214, "");}void cdpath(void){    struct aclmember *entry = NULL;    lreply(214, "The cdpath is:");    while (getaclentry("cdpath", &entry) && ARG0 != NULL)	lreply(0, "  %s", ARG0);    (void) fflush(stdout);    reply(214, "");}void print_groups(void){    gid_t groups[NGROUPS_MAX];    int ngroups = 0;    if ((ngroups = getgroups(NGROUPS_MAX, groups)) < 0) {	return;    }    lreply(214, "Group membership is:");    ngroups--;    for (; ngroups >= 0; ngroups--)	lreply(214, "  %d", groups[ngroups]);    (void) fflush(stdout);    reply(214, "");}

⌨️ 快捷键说明

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