+int login_attempts; /* number of failed login attempts */
+int askpasswd; /* had user command, ask for passwd */
+
+/*
+ * USER command.
+ * Sets global passwd pointer pw if named account exists
+ * and is acceptable; sets askpasswd if a PASS command is
+ * expected. If logged in previously, need to reset state.
+ * If name is "ftp" or "anonymous" and ftp account exists,
+ * set guest and pw, then just return.
+ * If account doesn't exist, ask for passwd anyway.
+ * Otherwise, check user requesting login privileges.
+ * Disallow anyone who does not have a standard
+ * shell returned by getusershell() (/etc/shells).
+ * Disallow anyone mentioned in the file FTPUSERS
+ * to allow people such as root and uucp to be avoided.
+ */
+user(name)
+ char *name;
+{
+ register char *cp;
+ FILE *fd;
+ char *shell;
+ char line[BUFSIZ], *index(), *getusershell();
+
+ if (logged_in) {
+ if (guest) {
+ reply(530, "Can't change user from guest login.");
+ return;
+ }
+ end_login();
+ }
+
+ guest = 0;
+ if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
+ if ((pw = sgetpwnam("ftp")) != NULL) {
+ guest = 1;
+ askpasswd = 1;
+ reply(331, "Guest login ok, send ident as password.");
+ } else
+ reply(530, "User %s unknown.", name);
+ return;
+ }
+ if (pw = sgetpwnam(name)) {
+ if ((shell = pw->pw_shell) == NULL || *shell == 0)
+ shell = "/bin/sh";
+ while ((cp = getusershell()) != NULL)
+ if (strcmp(cp, shell) == 0)
+ break;
+ endusershell();
+ if (cp == NULL) {
+ reply(530, "User %s access denied.", name);
+ pw = (struct passwd *) NULL;
+ return;
+ }
+ if ((fd = fopen(FTPUSERS, "r")) != NULL) {
+ while (fgets(line, sizeof (line), fd) != NULL) {
+ if ((cp = index(line, '\n')) != NULL)
+ *cp = '\0';
+ if (strcmp(line, name) == 0) {
+ reply(530, "User %s access denied.", name);
+ pw = (struct passwd *) NULL;
+ return;
+ }
+ }
+ }
+ (void) fclose(fd);
+ }
+ reply(331, "Password required for %s.", name);
+ askpasswd = 1;
+ /*
+ * Delay before reading passwd after first failed
+ * attempt to slow down passwd-guessing programs.
+ */
+ if (login_attempts)
+ sleep((unsigned) login_attempts);
+}
+
+/*
+ * Terminate login as previous user, if any, resetting state;
+ * used when USER command is given or login fails.
+ */
+end_login()
+{
+
+ (void) seteuid((uid_t)0);
+ if (logged_in)
+ logwtmp(ttyline, "", "");
+ pw = NULL;
+ logged_in = 0;
+ guest = 0;
+}
+