📄 ftpd.c
字号:
int fclose(FILE *);#endifstatic SIGNAL_TYPE alarm_signal(int sig){}static FILE *draconian_FILE = NULL;static SIGNAL_TYPE draconian_alarm_signal(int sig){ if (draconian_FILE != NULL) { fclose(draconian_FILE); draconian_FILE = NULL; }}static void socket_flush_wait(FILE *file){#ifndef SUPPORT_BROKEN_CLIENTS char c; int fd = fileno(file); if (draconian_FILE != NULL) shutdown(fd, 1); if (draconian_FILE != NULL) read(fd, &c, 1);/* * GAL - the read() here should be checked to ensure it returned 0 (indicating * EOF) or -1 (an error occurred). Anything else (real data) is a protocol * error. */#endif}int main(int argc, char **argv, char **envp){#if defined(UNIXWARE) || defined(AIX) size_t addrlen;#else int addrlen;#endif int on = 1;#ifdef IPTOS_LOWDELAY int tos;#endif int c;#ifndef INTERNAL_LS int which;#endif extern int optopt; extern char *optarg; struct hostent *shp; struct aclmember *entry;#ifdef VIRTUAL#if defined(UNIXWARE) || defined(AIX) size_t virtual_len;#else int virtual_len;#endif struct sockaddr_in *virtual_ptr; struct sockaddr_in virtual_addr;#endif#ifndef DAEMON struct servent *serv;#endif#ifdef AUX setcompat(COMPAT_POSIX | COMPAT_BSDSETUGID);#endif closelog();#ifdef FACILITY openlog("ftpd", LOG_PID | LOG_NDELAY, FACILITY);#else openlog("ftpd", LOG_PID);#endif#ifdef SecureWare setluid(1); /* make sure there is a valid luid */ set_auth_parameters(argc, argv); setreuid(0, 0);#endif#if defined(M_UNIX) && !defined(_M_UNIX) res_init(); /* bug in old (1.1.1) resolver */ _res.retrans = 20; /* because of fake syslog in 3.2.2 */ setlogmask(LOG_UPTO(LOG_INFO));#endif#ifndef DAEMON addrlen = sizeof(his_addr); if (getpeername(0, (struct sockaddr *) &his_addr, &addrlen) < 0) { syslog(LOG_ERR, "getpeername (%s): %m", argv[0]);#ifndef DEBUG exit(1);#endif } addrlen = sizeof(ctrl_addr); if (getsockname(0, (struct sockaddr *) &ctrl_addr, &addrlen) < 0) { syslog(LOG_ERR, "getsockname (%s): %m", argv[0]);#ifndef DEBUG exit(1);#endif }#ifdef IPTOS_LOWDELAY tos = IPTOS_LOWDELAY; if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(int)) < 0) syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");#endif serv = getservbyname("ftp-data", "tcp"); if (serv != NULL) data_source.sin_port = serv->s_port; else data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);#endif /* DAEMON */#ifndef DAEMON while ((c = getopt(argc, argv, ":aAvdlLiIoP:qQr:t:T:u:wVWX")) != -1) {#else /* DAEMON */ while ((c = getopt(argc, argv, ":aAvdlLiIop:P:qQr:sSt:T:u:VwWX")) != -1) {#endif /* DAEMON */ switch (c) { case 'a': use_accessfile = 1; break; case 'A': use_accessfile = 0; break; case 'v': debug = 1; break; case 'd': debug = 1; break; case 'l': logging = 1; break; case 'L': log_commands = 1; break; case 'i': log_incoming_xfers = 1; break; case 'I': disable_rfc931 = 1; break; case 'o': log_outbound_xfers = 1; break; case 'q': Bypass_PID_Files = 0; break; case 'Q': Bypass_PID_Files = 1; break; case 'r': if ((optarg != NULL) && (optarg[0] != '\0')) { RootDirectory = malloc(strlen(optarg) + 1); if (RootDirectory != NULL) strcpy(RootDirectory, optarg); } break; case 'P': data_source.sin_port = htons(atoi(optarg)); break;#ifdef DAEMON case 'p': daemon_port = atoi(optarg); break; case 's': be_daemon = 1; break; case 'S': be_daemon = 2; break;#endif /* DAEMON */ case 't': timeout_idle = atoi(optarg); if (timeout_maxidle < timeout_idle) timeout_maxidle = timeout_idle; break; case 'T': timeout_maxidle = atoi(optarg); if (timeout_idle > timeout_maxidle) timeout_idle = timeout_maxidle; break; case 'u': { unsigned int val = 0; while (*optarg && *optarg >= '0' && *optarg <= '9') val = val * 8 + *optarg++ - '0'; if (*optarg || val > 0777) syslog(LOG_ERR, "bad value for -u"); else defumask = val; break; } case 'V': print_copyright(); exit(0); /* NOTREACHED */ case 'w': wtmp_logging = 1; break; case 'W': wtmp_logging = 0; break; case 'x': syslogmsg = 2; break; case 'X': syslogmsg = 1; break; case ':': syslog(LOG_ERR, "option -%c requires an argument", optopt); break; default: syslog(LOG_ERR, "unknown option -%c ignored", optopt); break; } } initsetproctitle(argc, argv, envp); (void) freopen(_PATH_DEVNULL, "w", stderr); /* Checking for random signals ... */#ifdef NEED_SIGFIX sigemptyset(&block_sigmask);#endif#ifndef SIG_DEBUG#ifdef SIGHUP (void) signal(SIGHUP, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGHUP);#endif#endif#ifdef SIGINT (void) signal(SIGINT, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGINT);#endif#endif#ifdef SIGQUIT (void) signal(SIGQUIT, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGQUIT);#endif#endif#ifdef SIGILL (void) signal(SIGILL, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGILL);#endif#endif#ifdef SIGTRAP (void) signal(SIGTRAP, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGTRAP);#endif#endif#ifdef SIGIOT (void) signal(SIGIOT, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGIOT);#endif#endif#ifdef SIGEMT (void) signal(SIGEMT, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGEMT);#endif#endif#ifdef SIGFPE (void) signal(SIGFPE, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGFPE);#endif#endif#ifdef SIGKILL (void) signal(SIGKILL, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGKILL);#endif#endif#ifdef SIGBUS (void) signal(SIGBUS, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGBUS);#endif#endif#ifdef SIGSEGV (void) signal(SIGSEGV, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGSEGV);#endif#endif#ifdef SIGSYS (void) signal(SIGSYS, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGSYS);#endif#endif#ifdef SIGALRM (void) signal(SIGALRM, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGALRM);#endif#endif#ifdef SIGSTOP (void) signal(SIGSTOP, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGSTOP);#endif#endif#ifdef SIGTSTP (void) signal(SIGTSTP, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGTSTP);#endif#endif#ifdef SIGTTIN (void) signal(SIGTTIN, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGTTIN);#endif#endif#ifdef SIGTTOU (void) signal(SIGTTOU, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGTTOU);#endif#endif#ifdef SIGIO (void) signal(SIGIO, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGIO);#endif#endif#ifdef SIGXCPU (void) signal(SIGXCPU, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGXCPU);#endif#endif#ifdef SIGXFSZ (void) signal(SIGXFSZ, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGXFSZ);#endif#endif#ifdef SIGWINCH (void) signal(SIGWINCH, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGWINCH);#endif#endif#ifdef SIGVTALRM (void) signal(SIGVTALRM, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGVTALRM);#endif#endif#ifdef SIGPROF (void) signal(SIGPROF, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGPROF);#endif#endif#ifdef SIGUSR1 (void) signal(SIGUSR1, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGUSR1);#endif#endif#ifdef SIGUSR2 (void) signal(SIGUSR2, randomsig);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGUSR2);#endif#endif#ifdef SIGPIPE (void) signal(SIGPIPE, lostconn);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGPIPE);#endif#endif#ifdef SIGCHLD (void) signal(SIGCHLD, SIG_IGN);#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGCHLD);#endif#endif#ifdef SIGURG if (signal(SIGURG, myoob) == SIG_ERR) syslog(LOG_ERR, "signal: %m");#ifdef NEED_SIGFIX sigaddset(&block_sigmask, SIGURG);#endif#endif#endif /* SIG_DEBUG */#ifdef VIRTUAL virtual_root[0] = '\0'; virtual_banner[0] = '\0';#endif setup_paths();#ifdef OTHER_PASSWD strcpy(_path_passwd, "/etc/passwd");#ifdef SHADOW_PASSWORD strcpy(_path_shadow, "/etc/shadow");#endif#endif access_init();#ifdef DAEMON if (be_daemon != 0) do_daemon(argc, argv, envp); addrlen = sizeof(his_addr); if (getpeername(0, (struct sockaddr *) &his_addr, &addrlen) < 0) { syslog(LOG_ERR, "getpeername (%s): %m", argv[0]);#ifndef DEBUG exit(1);#endif } addrlen = sizeof(ctrl_addr); if (getsockname(0, (struct sockaddr *) &ctrl_addr, &addrlen) < 0) { syslog(LOG_ERR, "getsockname (%s): %m", argv[0]);#ifndef DEBUG exit(1);#endif }#ifdef IPTOS_LOWDELAY tos = IPTOS_LOWDELAY; if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(int)) < 0) syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");#endif if (keepalive) if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) syslog(LOG_ERR, "setsockopt SO_KEEPALIVE %m"); data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);#endif /* DAEMON */ /* Try to handle urgent data inline */#ifdef SO_OOBINLINE if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof(int)) < 0) syslog(LOG_ERR, "setsockopt (SO_OOBINLINE): %m");#endif#ifdef F_SETOWN if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) syslog(LOG_ERR, "fcntl F_SETOWN: %m");#elif defined(SIOCSPGRP) { int pid; pid = getpid(); if (ioctl(fileno(stdin), SIOCSPGRP, &pid) == -1) syslog(LOG_ERR, "ioctl SIOCSPGRP: %m"); }#endif if (RootDirectory != NULL) { if ((chroot(RootDirectory) < 0) || (chdir("/") < 0)) { syslog(LOG_ERR, "Cannot chroot to initial directory, aborting."); exit(1); } }#ifdef HAVE_LIBRESOLV /* initialize the resolver, and set global DNS variables */ initialize_dns(&his_addr);#endif dolog(&his_addr); /* Set up default state */ data = -1; type = TYPE_A; form = FORM_N; stru = STRU_F; mode = MODE_S; tmpline[0] = '\0'; yyerrorcalled = 0; entry = (struct aclmember *) NULL; if ((getaclentry("hostname", &entry)) && ARG0) { (void) strncpy(hostname, ARG0, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; } else {#ifdef HAVE_SYSINFO sysinfo(SI_HOSTNAME, hostname, sizeof(hostname));#else (void) gethostname(hostname, sizeof(hostname));#endif/* set the FQDN here */ shp = gethostbyname(hostname); if (shp != NULL) { (void) strncpy(hostname, shp->h_name, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -