(* @ /// *)
(* @ /// procedure t_http.DoBasicAuthorization (const username, password: string); *) procedure t_http.DoBasicAuthorization (const username, password: string); var h: TMemoryStream; encoded: TStringlist; begin f_author: = username ': ' password; h: = nil; Encode: = nil; try h: = tmemorystream.create; stream_write_s (h, f_author); Encoded: = Encode_base64 (h); if encoded.count> 0 THEN F_AUTHOR: =' Basic ' encoded.strings [0]; finally h.free; encoded.free; end; end; (* @ @ @ @ @ @ @ @ @ @ @ @ /// class t_ftp (t_tcpip) *) (* @ /// constructor t_ftp.create (aowner: tComponent); *) Constructor t_ftp.create (Aowner: tComponent); begin inherited create (aowner); f_port: = 21; f_user: = 'ftp'; f_password : = 'nobody @ nowhere'; (* only to make it running without setting user / password *) f_passive: = true; f_mode: = tftp_download; f_cur_dir: = TStringlist.Create; f_comm_socket: = INVALID_SOCKET; f_busy: = false; f_dir_stream : = TmemoryStream.create; End; (* @ /// *) (* @ /// destructor t_ftp.destroy; *) DE Structor t_ftp.destroy; begin f_cur_dir.free; f_dir_stream.free; inherited destroy; end; (* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0000000301 *)
(* @ /// procedure t_ftp.action; *) procedure t_ftp.action; begin login; TMemorystream (f_stream) .clear; case f_mode of tftp_download: download; tftp_upload: upload; tftp_getdir: getdir; end; ( '.') Logout; end; (* @ @ @ /// procedure t_ftp.response; *) procedure t_ftp.response; var s: string; begin s: = self.read_line_comm; if assigned (f_trica) THEN F_Tracer (S, TT_PROTO_GET); try f_status_nr: = start (S, 1, 3)); Except f_status_nr: = 999; End; f_status_txt: = Copy (s, 5, length (s)); if f_status_nr> = 400 TEN RAISE EPROTOCOLERROR.CREATE ('FTP', F_STATUS_TXT, F_STATUS_NR); (* if The answer consists of several line read and discard all the following *) While (POS ('-', s) = 4) or (POS '', s) = 1) Do Begin S: = SELF.READ_LINE_COMM; if Assigned (f_tracer) THEN F_Tracer (s, tt_proto_get); end; end; (* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 00 00 00 00 00 00*
(* @ /// procedure t_ftp.login; // USER and PASS commands *) procedure t_ftp.login; begin f_socket_number: = f_port; inherited login; f_comm_socket: = f_socket; self.response; (* Read the welcome message *) Self.sendCommand ('user' f_use; {self.sendcommand ('pass' f_password);} Write_s (f_comm_socket, 'pass' f_password # 13 # 10); if Assigned (f_tracer) THEN F_Tracer ('Pass ******', tt_proto_sent); self.response; self.sendcommand ('type I'); (* always use binary *) self.response; end; (* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 000000030301 *) (* @ /// procedure t_ftp.logout; // QUIT command *) procedure t_ftp.logout; begin if f_busy then self.abort; if f_logged_in then begin if f_comm_socket <> INVALID_SOCKET then begin self.SendCommand ( 'QUIT'); Self.response; end; if f_socket <> invalid_socket; f_socket: = f_comm_socket; f_comm_socket: = invalid_socket; end; inherited logout; end; 000406 *)
(* @ /// procedure t_ftp.getdir (const dirname: string); // LIST command *) procedure t_ftp.getdir (const dirname: string); begin if f_busy then raise (EProtocolBusy.create); if not f_logged_in then login ; If (dirname = ') THEN EXIT; GET_DATASOCKET; Self.sendCommand (' Type A '); Self.Response; Self.sendCommand (' List ' DirName); Self.Response; f_mode_intern: = tftp_getdir; f_busy: = true; TMemorystream (f_dir_stream) .clear; if not f_async_data then begin while do_read do; f_eof: = false; self.response; finish_getdir; end else begin winsock.WSAAsyncSelect (f_comm_socket, f_handle, uwm_socketevent, fd_read); f_eof: = false; f_async: = true; self.response; f_async: = false; winsock.WSAAsyncSelect (f_comm_socket, f_handle, uwm_socketevent, 0); finish_getdir; end; end; (* @ /// 0000000501 *) (* @ /// procedure t_ftp .download; // Retr command *) Procedure t_ftp.download; begin if f_busy kiln c i c ketocolbusy.create; if not f_logged_in the n login; if f_url <> '' Then Begin Self.sendCommand ('size' f_url); (* can I use the path here? *) Try self.response; f_size: = start (f_status_txt); Except f_size: = 0; end; get_datasocket; self.SendCommand ( 'RETR' f_url); (* can I use the path here *?) self.response; f_mode_intern: = tftp_download; f_busy: = true; TMemorystream (f_stream) .clear; if NOT f_async_data dam, while do_read do; f_eof: = false; self.response; finish_download; end else begin winsock.wsaasyncselect (f_comm_socket, f_handle, uwm_socketevent, fd_read);
f_eof: = false; f_async: = true; self.response; f_async: = false; winsock.WSAAsyncSelect (f_comm_socket, f_handle, uwm_socketevent, 0); finish_download; end; end; end; (* @ /// 0000000907 *) ( * @ /// procedure t_ftp.upload; // STOR command *) procedure t_ftp.upload; begin if f_busy then raise (EProtocolBusy.create); if not f_logged_in then login; if f_url <> '' then begin get_datasocket; self. SendCommand ( 'STOR' f_url); (? * can I use the path here *) self.response; f_mode_intern: = tftp_upload; f_busy: = true; f_size: = TMemorystream (f_stream) .size; TMemorystream (f_stream) .seek (0,0); if not f_async_data then begin while do_write do; finish_upload; end else begin winsock.WSAAsyncSelect (f_comm_socket, f_handle, uwm_socketevent, fd_read); finish_upload; winsock.WSAAsyncSelect (f_comm_socket, f_handle, uwm_socketevent, 0); end; End; end; (* @ @ @ 聽 000000B0B *)
(* @ /// procedure t_ftp.abort; // ABOR command *) procedure t_ftp.abort; begin if f_busy then begin self.SendCommand ( 'ABOR'); try self.response; except on EProtocolError do begin if f_status_nr <> 426 THEN RAISE EPROTOCOLERROR.CREATE ('f_status_nr) else becom self.response; f_busy: = false; end; end; end; end; end; (* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ // / procedure t_ftp.noop; // NOOP command *) procedure t_ftp.noop; begin if f_busy then raise (EProtocolBusy.create); if not f_logged_in then login; self.SendCommand ( 'NOOP'); self.response; end; ( * @ /// 0000000501 *) (* @ /// procedure t_ftp.changedir (const f_dir: string); // CWD command *) procedure t_ftp.changedir (const f_dir: string); begin if f_busy then raise (EProtocolBusy. Create); if not f_logged_in dam; self.sendcommand ('cwd' f_dir); self.response; end; (* @ /// *) (* @ /// procedure t_ ftp.removefile (const filename: string); // DELE command *) procedure t_ftp.removefile (const filename: string); begin if f_busy then raise (EProtocolBusy.create); if not f_logged_in then login; self.SendCommand ( 'DELE ' filename); self.response; end; (* @ ////) (* @ /// procedure t_ftp.removedir (const Dirname: string); // rmd command *) Procedure T_ftp.removedir (const Dirname: String); begin if f_busy. c r; if not f_logged_in life; self.sendcommand ('RMD' DIRNAME); Self.Response; End; (* @ /// *) (* @ // / procedure t_ftp.makedir (const Dirname: string);
// MKD command *) procedure t_ftp.makedir (const dirname: string); begin if f_busy then raise (EProtocolBusy.create); if not f_logged_in then login; self.SendCommand ( 'MKD' dirname); self.response; end ; (* @ /// *) (* @ /// procedure t_ftp.renamefile (const prior, after: string); // rnfr and rnto commands *) procedure t_ftp.renamefile (const prior, after: string); begin If F_BUSY THEN RAISE (EPROTOCOLBUSY.CREATE); if not f_logged_in life; self.sendcommand ('RNFR' prior); self.response; self.sendcommand ('RNTO' AFTER); Self.Response; End; (* @ /// *) (* @ /// Function T_ftp.do_write: boolean; *) function t_ftp.do_write: boolean; var ok: integer; begin result: = false; if f_socket = invalid_socket dam
OK: = f_stream.read (f_buffer ^, buf_size); if ok> 0 Then Write_buf (f_socket, f_buffer ^, ok); Result: = OK> 0; End; (* @ @ @ @ @ / // function t_ftp.do_read: boolean; *) function t_ftp.do_read: boolean; var ok, ok2: integer; h: integer; p: pointer; begin result: = false; if f_socket = invalid_socket then EXIT; read_var (f_socket, F_buffer ^, buf_size, ok; p: = f_buffer; h: = ok; while ok> 0 do begin (* Just to Be Sure Everything Goes Into The Stream *) OK2: = 0; (* Delphi 2 Shut up! * Case f_mode_intern of tftp_download: ok2: = f_stream.write (p ^, ok); tftp_getdir: ok2: = f_dir_stream.write (p ^, ok); end; dec (OK, OK2); P: = Pointer (Longint p) OK2); end; result: = h> 0; if assigned (f_ondata_got) THEN F_ONDATA_GOT (Self, f_mode_intern, h); end; (* @ @ @ @ @ @ @ @ 0000000901 *)
(* @ /// procedure t_ftp.finish_upload; *) procedure t_ftp.finish_upload; begin while do_write do; f_eof: = false; shutdown (f_socket, 1); closesocket (f_socket); f_async: = true; self.response; f_async : = false; if assigned (f_onaction) then f_onaction (self, f_mode_intern); f_busy: = false; end; (* @ /// 0000000901 *) (* @ /// procedure t_ftp.finish_download; *) procedure t_ftp.finish_download Begin while do_read do; f_eof: = false; shutdown (f_socket, 1); CloseSocket (f_socket); f_stream.seek (0); (* set the stream back to start *) if assigned (f_onaction) THEN F_ONAACTION self, f_mode_intern); f_busy: = false; end; (* @ /// 0000000701 *) (* @ /// procedure t_ftp.finish_getdir; *) procedure t_ftp.finish_getdir; begin f_eof: = false; while do_read do; f_eof : = false; shutdown (f_socket, 1); CloseSocket; Self.sendcommand ('Type I'); (* always use binary *) self.response; f_dir_stream.seek (0, 0); (* set the Stream back to start *) f_cur_dir.clear; f_cur_dir.loadfromstream (f_dir_stream); f _dir_stream.clear; f_cur_dir_index: = 0; if assigned (f_onaction) Then f_onaction (self, f_mode_intern); f_busy: = false; end; (* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 0000000000901 *)
(* @ /// procedure t_ftp.get_datasocket; *) procedure t_ftp.get_datasocket; var po: integer; ip: longint; s, t: string; temp_socket: TSocket; SockInfo: TSockAddr; f_data_socket_number: smallint; begin f_socket: = INVALID_SOCKET ; (* @ /// if self.passive dam for the port and open the socket active *) if self.passive dam Self.sendcommand ('PASV'); Self.Response; if f_status_nr <> 227 Then Raise EPROTOCOLERROR .Create ('f_status_status_txt, f_status_nr) else begin s: = copy (f_status_txt, POS (' (', f_status_txt) 1, Length (f_status_txt)); s: = Copy (S, 1, POS (') ', s) -1); PO: = POSN (', ', s, 4); T: = COPY (S, 1, PO-1); While Pos (', ', t) <> 0 DO T [POS (',', t)]: = '.';
(* @ /// ip_address: = Winsock.inet_addr (PCHAR (T)); {Try a xxx.xx.xxx.xx} *) (* $ IFDEF VER80 *) T: = T # 0; IP_Address: = Winsock .Inet_addr (Pchar (@T [1])); (* try a xxx.xx.xxx.xx first *) (* $ e e *) (* $ ifopt h- *) T: = T # 0; ip_address: = Winsock.inet_addr (Pchar (@T [1])); (* try a xxx.xx.xxx.xx first *) (* $ else *) ip_address: = Winsock.inet_addr (PCHAR (T)); (* Try a xxx.xxx.xxx.xx first *) (* $ ENDIF *) (* @ @ @ @ @ @ @ @ @ @ @ p p p (S, PO 1, Length (s)); Try f_data_socket_number: = start (COPY (S, 1, POS (',', S) -1)) * 256 STRTOINT (COPY (S, POS (',', s) 1, Length (s)))) ; f_socket: = self.create_socket; if f_async_data then winsock.WSAAsyncSelect (f_socket, f_handle, uwm_socketevent 1, fd_connect or fd_read or fd_write or fd_accept); self.connect_socket (f_socket, f_data_socket_number, ip_address); except f_socket: = INVALID_SOCKET; end ; End; End (* @ @ @) (* @ /// else send the port and open the sock Et Passive *) Else Begin IP: = my_ip_address; Self.sendCommand ('Port' INTSTR (IP and $ 000000FF) ',' INTOSTR (IP and $ 0000FF00 SHR 8) ',' INTOSTR (ip and $ 00 FF0000 SHR 16) ',' INTOSTR (IP and $ FF000000 SHR 24) ',' INTOSTR (F_Port and $ FF00 SHR 8) ',' INTOSTR (f_port and $ 00ff); self.response; Open_socket_in (f_socket, f_port, ip);