📄 htftp.c
字号:
control->socket = -1; return HT_INTERRUPTED; } if (ich == EOF) { CTRACE((tfp, "Error on rx: closing socket %d\n", control->socket)); strcpy(response_text, "000 *** TCP read error on response\n"); close_connection(control); return -1; /* End of file on response */ } } /* Loop over characters */ } while (continuation_response != -1); if (result == 421) { CTRACE((tfp, "HTFTP: They close so we close socket %d\n", control->socket)); close_connection(control); return -1; } if ((result == 255 && server_type == CMS_SERVER) && (0 == strncasecomp(cmd, "CWD", 3) || 0 == strcasecomp(cmd, "CDUP"))) { /* ** Alas, CMS returns 255 on failure to CWD to parent of root. - PG */ result = 555; } return result/100;}PRIVATE int send_cmd_1 ARGS1(char *, verb){ char command[80]; sprintf(command, "%.*s%c%c", (int) sizeof(command)-4, verb, CR, LF); return response (command);}PRIVATE int send_cmd_2 ARGS2(char *, verb, char *, param){ char *command = 0; int status; HTSprintf0(&command, "%s %s%c%c", verb, param, CR, LF); status = response (command); FREE(command); return status;}#define send_cwd(path) send_cmd_2("CWD", path)/* * This function should try to set the macintosh server into binary mode. * Some servers need an additional letter after the MACB command. */PRIVATE int set_mac_binary ARGS1( eServerType, ServerType){ /* try to set mac binary mode */ if (ServerType == APPLESHARE_SERVER || ServerType == NETPRESENZ_SERVER) { /* * Presumably E means "Enable". - KW */ return(2 == response("MACB E\r\n")); } else { return(2 == response("MACB\r\n")); }}/* This function gets the current working directory to help * determine what kind of host it is */PRIVATE void get_ftp_pwd ARGS2( eServerType *, ServerType, BOOLEAN *, UseList){ char *cp; /* get the working directory (to see what it looks like) */ int status = response("PWD\r\n"); if (status < 0) { return; } else { cp = strchr(response_text+5,'"'); if (cp) *cp = '\0'; if (*ServerType == TCPC_SERVER) { *ServerType = ((response_text[5] == '/') ? NCSA_SERVER : TCPC_SERVER); CTRACE((tfp, "HTFTP: Treating as %s server.\n", ((*ServerType == NCSA_SERVER) ? "NCSA" : "TCPC"))); } else if (response_text[5] == '/') { /* path names beginning with / imply Unix, * right? */ if (set_mac_binary(*ServerType)) { *ServerType = NCSA_SERVER; CTRACE((tfp, "HTFTP: Treating as NCSA server.\n")); } else { *ServerType = UNIX_SERVER; *UseList = TRUE; CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); } return; } else if (response_text[strlen(response_text)-1] == ']') { /* path names ending with ] imply VMS, right? */ *ServerType = VMS_SERVER; *UseList = TRUE; CTRACE((tfp, "HTFTP: Treating as VMS server.\n")); } else { *ServerType = GENERIC_SERVER; CTRACE((tfp, "HTFTP: Treating as Generic server.\n")); } if ((*ServerType == NCSA_SERVER) || (*ServerType == TCPC_SERVER) || (*ServerType == PETER_LEWIS_SERVER) || (*ServerType == NETPRESENZ_SERVER)) set_mac_binary(*ServerType); }}/* This function turns MSDOS-like directory output off for * Windows NT servers. */PRIVATE void set_unix_dirstyle ARGS2( eServerType *, ServerType, BOOLEAN *, UseList){ char *cp; /* This is a toggle. It seems we have to toggle in order to see * the current state (after toggling), so we may end up toggling * twice. - kw */ int status = response("SITE DIRSTYLE\r\n"); if (status != 2) { *ServerType = GENERIC_SERVER; CTRACE((tfp, "HTFTP: DIRSTYLE failed, treating as Generic server.\n")); return; } else { *UseList = TRUE; /* Expecting one of: * 200 MSDOS-like directory output is off * 200 MSDOS-like directory output is on * The following code doesn't look for the full exact string - * who knows how the wording may change in some future version. * If the first response isn't recognized, we toggle again * anyway, under the assumption that it's more likely that * the MSDOS setting was "off" originally. - kw */ cp = strstr(response_text+4, "MSDOS"); if (cp && strstr(cp, " off")) { return; /* already off now. */ } else { response("SITE DIRSTYLE\r\n"); } }}/* Get a valid connection to the host** ----------------------------------**** On entry,** arg points to the name of the host in a hypertext address** On exit,** returns <0 if error** socket number if success**** This routine takes care of managing timed-out connections, and** limiting the number of connections in use at any one time.**** It ensures that all connections are logged in if they exist.** It ensures they have the port number transferred.*/PRIVATE int get_connection ARGS2( CONST char *, arg, HTParentAnchor *, anchor){ int status; char * command = 0; connection * con; char * username = NULL; char * password = NULL; static BOOLEAN firstuse = TRUE; if (firstuse) { /* ** Set up freeing at exit. - FM */#ifdef LY_FIND_LEAKS atexit(free_FTPGlobals);#endif firstuse = FALSE; } if (control) { /* ** Reuse this object - KW, DW & FM */ if (control->socket != -1) { NETCLOSE(control->socket); } con = control; con->addr = 0; con->binary = FALSE; } else { /* ** Allocate and init control struct. */ con = typecalloc(connection); if (con == NULL) outofmem(__FILE__, "get_connection"); } con->socket = -1; if (!arg) return -1; /* Bad if no name specified */ if (!*arg) return -1; /* Bad if name had zero length *//* Get node name:*/ CTRACE((tfp, "get_connection(%s)\n", arg)); { char *p1 = HTParse(arg, "", PARSE_HOST); char *p2 = strrchr(p1, '@'); /* user? */ char * pw = NULL; if (p2 != NULL) { username = p1; *p2 = '\0'; /* terminate */ p1 = p2+1; /* point to host */ pw = strchr(username, ':'); if (pw != NULL) { *pw++ = '\0'; password = HTUnEscape(pw); } if (*username) HTUnEscape(username); /* * If the password doesn't exist then we are going to have * to ask the user for it. The only problem is that we * don't want to ask for it every time, so we will store * away in a primitive fashion. */ if (!password) { char *tmp = NULL; HTSprintf0(&tmp, "%s@%s", username, p1); /* * If the user@host is not equal to the last time through * or user_entered_password has no data then we need * to ask the user for the password. */ if (!last_username_and_host || strcmp(tmp, last_username_and_host) || !user_entered_password) { StrAllocCopy(last_username_and_host, tmp); HTSprintf0(&tmp, gettext("Enter password for user %s@%s:"), username, p1); FREE(user_entered_password); user_entered_password = HTPromptPassword(tmp); } /* else we already know the password */ password = user_entered_password; FREE(tmp); } } if (!username) FREE(p1); } /* scope of p1 */ status = HTDoConnect (arg, "FTP", IPPORT_FTP, (int *)&con->socket); if (status < 0) { if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted on connect\n")); } else { CTRACE((tfp, "HTFTP: Unable to connect to remote host for `%s'.\n", arg)); } if (status == HT_INTERRUPTED) { _HTProgress (CONNECTION_INTERRUPTED); status = HT_NOT_LOADED; } else { HTAlert(gettext("Unable to connect to FTP host.")); } if (con->socket != -1) { NETCLOSE(con->socket); } FREE(username); if (control == con) control = NULL; FREE(con); return status; /* Bad return */ } CTRACE((tfp, "FTP connected, socket %d control %p\n", con->socket, con)); control = con; /* Current control connection */ /* Initialise buffering for control connection */ HTInitInput(control->socket); init_help_message_cache(); /* Clear the login message buffer. *//* Now we log in Look up username, prompt for pw.*/ status = response((char *)0); /* Get greeting */ if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted at beginning of login.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; } server_type = GENERIC_SERVER; /* reset */ if (status == 2) { /* Send username */ char *cp; /* look at greeting text */ /* don't gettext() this -- incoming text: */ if (strlen(response_text) > 4) { if ((cp = strstr(response_text, " awaits your command")) || (cp = strstr(response_text, " ready."))) { *cp = '\0'; } cp = response_text + 4; if (!strncasecomp(cp, "NetPresenz", 10)) server_type = NETPRESENZ_SERVER; } else { cp = response_text; } StrAllocCopy(anchor->server, cp); status = send_cmd_2("USER", (username && *username) ? username : "anonymous"); if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted while sending username.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; } } if (status == 3) { /* Send password */ if (password) { /* * We have non-zero length password, so send it. - FM */ HTSprintf0(&command, "PASS %s%c%c", password, CR, LF); } else { /* * Create and send a mail address as the password. - FM */ char *user = NULL; CONST char *host = NULL; char * cp; if (personal_mail_address && *personal_mail_address) { /* * We have a non-zero length personal * mail address, so use that. - FM */ StrAllocCopy(user, personal_mail_address); if ((cp=strchr(user, '@')) != NULL) { *cp++ = '\0'; host = cp; } else { host = HTHostName(); } } else { /* * Use an environment variable and the host global. - FM */ if ((cp=LYGetEnv("USER")) != NULL) StrAllocCopy(user, cp); else StrAllocCopy(user, "WWWuser"); host = HTHostName(); } /* * If host is not fully qualified, suppress it * as ftp.uu.net prefers a blank to a bad name */ if (!(host) || strchr(host, '.') == NULL) host = ""; HTSprintf0(&command, "PASS %s@%s%c%c", user, host, CR, LF); FREE(user); } status = response(command); FREE(command); if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted while sending password.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; } } FREE(username); if (status == 3) { status = send_cmd_1("ACCT noaccount"); if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted while sending password.\n")); _HTProgress (CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; } } if (status != 2) { CTRACE((tfp, "HTFTP: Login fail: %s", response_text)); /* if (control->socket > 0) close_connection(control->socket); */ return -1; /* Bad return */ } CTRACE((tfp, "HTFTP: Logged in.\n")); /** Check for host type **/ if (server_type != NETPRESENZ_SERVER) server_type = GENERIC_SERVER; /* reset */ use_list = FALSE; /* reset */ if ((status=response("SYST\r\n")) == 2) { /* we got a line -- what kind of server are we talking to? */ if (strncmp(response_text+4, "UNIX Type: L8 MAC-OS MachTen", 28) == 0) { server_type = MACHTEN_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as MachTen server.\n")); } else if (strstr(response_text+4, "UNIX") != NULL || strstr(response_text+4, "Unix") != NULL) { server_type = UNIX_SERVER; unsure_type = FALSE; /* to the best of out knowledge... */ use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); } else if (strstr(response_text+4, "MSDOS") != NULL) { server_type = MSDOS_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as MSDOS (Unix emulation) server.\n")); } else if (strncmp(response_text+4, "VMS", 3) == 0) { char *tilde = strstr(arg, "/~"); use_list = TRUE; if (tilde != 0 && tilde[2] != 0 && strstr(response_text+4, "MadGoat") != 0) { server_type = UNIX_SERVER; CTRACE((tfp, "HTFTP: Treating VMS as UNIX server.\n")); } else { server_type = VMS_SERVER; CTRACE((tfp, "HTFTP: Treating as VMS server.\n")); } } else if ((strncmp(response_text+4, "VM/CMS", 6) == 0) || (strncmp(response_text+4, "VM ", 3) == 0)) { server_type = CMS_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as CMS server.\n")); } else if (strncmp(response_text+4, "DCTS", 4) == 0) { server_type = DCTS_SERVER; CTRACE((tfp, "HTFTP: Treating as DCTS server.\n")); } else if (strstr(response_text+4, "MAC-OS TCP/Connect II") != NULL) { server_type = TCPC_SERVER; CTRACE((tfp, "HTFTP: Looks like a TCPC server.\n")); get_ftp_pwd(&server_type, &use_list); unsure_type = TRUE; } else if (server_type == NETPRESENZ_SERVER) { /* already set above */ use_list = TRUE; set_mac_binary(server_type); CTRACE((tfp, "HTFTP: Treating as NetPresenz (MACOS) server.\n")); } else if (strncmp(response_text+4, "MACOS Peter's Server", 20) == 0) { server_type = PETER_LEWIS_SERVER; use_list = TRUE; set_mac_binary(server_type); CTRACE((tfp, "HTFTP: Treating as Peter Lewis (MACOS) server.\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -