]> Nishi Git Mirror - libw3.git/commitdiff
ftp works
authornishi <nishi@d27a3e52-49c5-7645-884c-6793ebffc270>
Wed, 14 Feb 2024 01:28:20 +0000 (01:28 +0000)
committernishi <nishi@d27a3e52-49c5-7645-884c-6793ebffc270>
Wed, 14 Feb 2024 01:28:20 +0000 (01:28 +0000)
git-svn-id: file:///raid/svn-main/nishi-libw3/trunk@213 d27a3e52-49c5-7645-884c-6793ebffc270

Example/Makefile
Example/ftp-list/Makefile [new file with mode: 0644]
Example/ftp-list/ftp-list.c [new file with mode: 0644]
Library/Core.c
Library/FTP.c
Library/URL.c
Library/W3FTP.h
Makefile
W3Version.h.p

index b92f3a1ad0f2348955fca23ae2027288bf97e92a..a75b6c564ca7cd6c022b0f4a90fff5b7cc76b1a0 100644 (file)
@@ -10,6 +10,7 @@ examples:
        $(MAKE) -C ./interactive CC=$(CC) SUFFIX=$(SUFFIX)
        $(MAKE) -C ./pop3-list CC=$(CC) SUFFIX=$(SUFFIX)
        $(MAKE) -C ./w3b CC=$(CC) SUFFIX=$(SUFFIX)
+       $(MAKE) -C ./ftp-list CC=$(CC) SUFFIX=$(SUFFIX)
 ifeq ($(TCL),YES)
        $(MAKE) -C ./tclw3 CC=$(CC) TCL_LIBS="$(TCL_LIBS)" TCL_CFLAGS="$(TCL_CFLAGS)" SUFFIX=$(SUFFIX)
 endif
@@ -19,6 +20,7 @@ install:
        $(MAKE) -C ./interactive CC=$(CC) PREFIX=$(PREFIX) SUFFIX=$(SUFFIX) install
        $(MAKE) -C ./pop3-list CC=$(CC) PREFIX=$(PREFIX) SUFFIX=$(SUFFIX) install
        $(MAKE) -C ./w3b CC=$(CC) PREFIX=$(PREFIX) SUFFIX=$(SUFFIX) install
+       $(MAKE) -C ./ftp-list CC=$(CC) PREFIX=$(PREFIX) SUFFIX=$(SUFFIX) install
 ifeq ($(TCL),YES)
        $(MAKE) -C ./tclw3 CC=$(CC) PREFIX=$(PREFIX) SUFFIX=$(SUFFIX) install
 endif
@@ -29,6 +31,7 @@ clean:
        $(MAKE) -C ./interactive SUFFIX=$(SUFFIX) clean
        $(MAKE) -C ./pop3-list SUFFIX=$(SUFFIX) clean
        $(MAKE) -C ./w3b SUFFIX=$(SUFFIX) clean
+       $(MAKE) -C ./ftp-list SUFFIX=$(SUFFIX) clean
 ifeq ($(TCL),YES)
        $(MAKE) -C ./tclw3 CC=$(CC) SUFFIX=$(SUFFIX) clean
 endif
diff --git a/Example/ftp-list/Makefile b/Example/ftp-list/Makefile
new file mode 100644 (file)
index 0000000..0125761
--- /dev/null
@@ -0,0 +1,18 @@
+# $Id$
+.PHONY: clean install
+
+./ftp-list$(SUFFIX): ./ftp-list.o $(RESFILE)
+       $(CC) -g -o $@ -L ../../Library $^ -lw3
+
+./%.o: ./%.c
+       $(CC) -g -c -o $@ -I ../../Library $<
+
+../libw3.res:
+       $(MAKE) -C .. ./libw3.res WINDRES=$(WINDRES)
+
+clean:
+       rm -f ftp-list *.o *.so *.core *~ *.exe *.res
+
+install: ./ftp-list
+       mkdir -p $(PREFIX)/bin
+       cp ./ftp-list $(PREFIX)/bin/w3-ftp-list
diff --git a/Example/ftp-list/ftp-list.c b/Example/ftp-list/ftp-list.c
new file mode 100644 (file)
index 0000000..cf8937f
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Lists the FTP files 
+ */
+
+#include <W3Core.h>
+#include <W3FTP.h>
+
+#include <W3URL.h>
+#include <W3Util.h> /* It has some useful functions, you know */
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void resp_handler(struct W3* w3, int status, char* data){
+       printf("%d\n%s\n", status, data);
+       if(status == 230){
+               W3_Set_Method(w3, "LIST");
+               W3_Set_Path(w3, "/");
+               W3_FTP_Send_Request(w3);
+       }else if(status == 226){
+               W3_FTP_Disconnect(w3);
+       }
+}
+
+void data_handler(struct W3* w3, char* data, size_t size){
+       write(1, data, size);
+}
+
+int main(int argc, char** argv) {
+       if(argc < 2) {
+               fprintf(stderr, "%s: usage: %s url\n", argv[0], argv[0]);
+               return 1;
+       }
+       W3_Library_Init();
+       struct W3URL* w3url = W3_Parse_URL(argv[1]);
+       if(w3url != NULL){
+               bool err = false;
+               if(w3url->username == NULL){
+                       err = true;
+                       fprintf(stderr, "%s: missing username\n", argv[0]);
+               }
+               if(w3url->password == NULL){
+                       err = true;
+                       fprintf(stderr, "%s: missing password\n", argv[0]);
+               }
+               if(err){
+                       W3_Free_URL(w3url);
+                       return 1;
+               }
+               struct W3* w3 = W3_Create("ftp", w3url->host, w3url->port);
+               W3_FTP_Set_Username(w3, w3url->username);
+               W3_FTP_Set_Password(w3, w3url->password);
+               W3_On(w3, "ftpresp", resp_handler);
+               W3_On(w3, "data", data_handler);
+               W3_Send_Request(w3);
+               W3_Free_URL(w3url);
+       }else{
+               return 1;
+       }
+}
index e11e85172e69bac62a39a61a0f0cb2ad4199444d..8f0d6d9693467709511b23dde682e8a517b03f64 100644 (file)
@@ -11,6 +11,7 @@
 #include "W3HTTP.h"
 #include "W3POP3.h"
 #include "W3Nex.h"
+#include "W3FTP.h"
 #ifdef SSL_SUPPORT
 #include "W3Gemini.h"
 #endif
@@ -92,6 +93,7 @@ struct W3* W3_Create(const char* protocol, const char* hostname, int port) {
                } else if(strcmp(protocol, "finger") == 0) {
                } else if(strcmp(protocol, "gopher") == 0) {
                } else if(strcmp(protocol, "pop3") == 0) {
+               } else if(strcmp(protocol, "ftp") == 0) {
                } else {
                        __W3_Debug("Protocol", "Not suppported");
                        W3_Free(w3);
@@ -161,6 +163,8 @@ void W3_Send_Request(struct W3* w3) {
                __W3_Finger_Request(w3);
        } else if(strcmp(w3->protocol, "nex") == 0) {
                __W3_Nex_Request(w3);
+       } else if(strcmp(w3->protocol, "ftp") == 0) {
+               __W3_FTP_Request(w3);
        } else if(strcmp(w3->protocol, "file") == 0) {
                __W3_File_Request(w3);
        }
index a25ed39cd1e9f67ec36e1fdd84aeb977577a0460..4f275dcc653d2f23b7a9e7948c6c4d41fb70d794 100644 (file)
 #include "W3FTP.h"
 
 #include "W3Core.h"
+#include "W3DNS.h"
 #include "W3Util.h"
 
 #include <stdlib.h>
 #include <string.h>
 
+extern int strcasecmp(const char* s1, const char* s2);
+
+void __W3_FTP_Start_Passive(struct W3* w3){
+       __W3_Auto_Write(w3, "PASV\r\n", 6);
+}
+
 void __W3_FTP_Request(struct W3* w3) {
+       if(__W3_Get_Prop(w3, "FTP_USERNAME") == NULL || __W3_Get_Prop(w3, "FTP_PASSWORD") == NULL) {
+               __W3_Debug("LibW3-FTP", "Set the username/password");
+               void* funcptr = __W3_Get_Event(w3, "error");
+               if(funcptr != NULL) {
+                       void (*func)(struct W3*, const char*) = (void (*)(struct W3*, const char*))funcptr;
+                       func(w3, "did-not-auth");
+               }
+               return;
+       }
        __W3_Debug("LibW3-FTP", "Sending the request");
+       int cond = 1;
+       w3->generic = &cond;
+       char* buf = malloc(w3->readsize);
+       bool cont = false;
+       int status = 0;
+       bool gotstatus = false;
+       char* buffer = malloc(1);
+       buffer[0] = 0;
+       char* cbuf = malloc(2);
+       cbuf[1] = 0;
+       int auth = 0;
+       int pasvsock = -1;
+       while(true) {
+               int len = __W3_Auto_Read(w3, buf, w3->readsize);
+               if(len <= 0) break;
+               int i;
+               for(i = 0; i < len; i++){
+                       if((buf[i] == ' ' || buf[i] == '-') && !gotstatus){
+                               cont = buf[i] == '-';
+                               gotstatus = true;
+                       }else if(!gotstatus){
+                               status = status * 10;
+                               status += buf[i] - '0';
+                       }else if(buf[i] != '\r' && buf[i] != '\n'){
+                               cbuf[0] = buf[i];
+                               char* tmp = buffer;
+                               buffer = __W3_Concat(tmp, cbuf);
+                               free(tmp);
+                       }else if(buf[i] == '\n'){
+                               gotstatus = false;
+                               cbuf[0] = '\n';
+                               char* tmp = buffer;
+                               buffer = __W3_Concat(tmp, cbuf);
+                               free(tmp);
+                               if(!cont){
+                                       if(status == 220 && auth == 0){
+                                               __W3_Auto_Write(w3, "USER ", 5);
+                                               __W3_Auto_Write(w3, __W3_Get_Prop(w3, "FTP_USERNAME"), strlen(__W3_Get_Prop(w3, "FTP_USERNAME")));
+                                               __W3_Auto_Write(w3, "\r\n", 2);
+                                               auth = 1;
+                                       }else if(status == 331 && auth == 1){
+                                               __W3_Auto_Write(w3, "PASS ", 5);
+                                               __W3_Auto_Write(w3, __W3_Get_Prop(w3, "FTP_PASSWORD"), strlen(__W3_Get_Prop(w3, "FTP_PASSWORD")));
+                                               __W3_Auto_Write(w3, "\r\n", 2);
+                                               auth = 2;
+                                       }else if(status == 230 && auth == 2){
+                                               auth = 3;       
+                                       }else if(auth < 3){
+                                               __W3_Debug("LibW3-FTP", "Login failed");
+                                               void* funcptr = __W3_Get_Event(w3, "error");
+                                               if(funcptr != NULL) {
+                                                       void (*func)(struct W3*, const char*) = (void (*)(struct W3*, const char*))funcptr;
+                                                       func(w3, "login-fail");
+                                               }
+                                               goto ftp_stop;
+                                       }else if(auth == 3){
+                                               if(status == 227 && (cond & 1)){
+                                                       /* Passive mode */
+                                                       int j;
+                                                       int cnt = 0;
+                                                       bool pasv = false;
+                                                       char* addr = malloc(1);
+                                                       addr[0] = 0;
+                                                       char* numbuf = malloc(1);
+                                                       numbuf[0] = 0;
+                                                       int port = 0;
+                                                       for(j = 0; buffer[j] != 0; j++){
+                                                               if(buffer[j] == '('){
+                                                                       pasv = true;
+                                                               }else if(pasv){
+                                                                       if(buffer[j] == ',' || (pasv && buffer[j] == ')')){
+                                                                               cnt++;
+                                                                               if(cnt < 4){    
+                                                                                       cbuf[0] = '.';
+                                                                                       char* tmp = addr;
+                                                                                       addr = __W3_Concat(tmp, cbuf);
+                                                                                       free(tmp);
+                                                                               }else{
+                                                                                       port = port << 8;
+                                                                                       port |= atoi(numbuf);
+                                                                                       free(numbuf);
+                                                                                       numbuf = malloc(1);
+                                                                                       numbuf[0] = 0;
+                                                                               }
+                                                                               if(buffer[j] == ')') break;
+                                                                       }else{
+                                                                               if(cnt < 4){
+                                                                                       cbuf[0] = buffer[j];
+                                                                                       char* tmp = addr;
+                                                                                       addr = __W3_Concat(tmp, cbuf);
+                                                                                       free(tmp);
+                                                                               }else{
+                                                                                       cbuf[0] = buffer[j];
+                                                                                       char* tmp = numbuf;
+                                                                                       numbuf = __W3_Concat(tmp, cbuf);
+                                                                                       free(tmp);
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                                       free(numbuf);
+                                                       pasvsock = __W3_DNS_Connect(addr, false, port,
+#ifdef SSL_SUPPORT
+                                                               NULL, NULL
+#endif
+                                                       );
+                                                       free(addr);
+                                                       if(strcasecmp(w3->method, "LIST") == 0){
+                                                               __W3_Auto_Write(w3, "LIST ", 5);
+                                                               __W3_Auto_Write(w3, w3->path, strlen(w3->path));
+                                                               __W3_Auto_Write(w3, "\r\n", 2);
+                                                       }
+                                                       char* ftpbuf = malloc(w3->readsize);
+                                                       while(true){
+                                                               int ftplen = recv(pasvsock, ftpbuf, w3->readsize, 0);
+                                                               if(ftplen <= 0) break;
+                                                               void* funcptr = __W3_Get_Event(w3, "data");
+                                                               if(funcptr != NULL) {
+                                                                       void (*func)(struct W3*, char*, size_t) = (void (*)(struct W3*, char*, size_t))funcptr;
+                                                                       func(w3, ftpbuf, ftplen);
+                                                               }
+                                                       }
+                                                       free(ftpbuf);
+                                               }
+                                       }
+                                       void* funcptr = __W3_Get_Event(w3, "ftpresp");
+                                       if(funcptr != NULL) {
+                                               void (*func)(struct W3*, int, char*) = (void (*)(struct W3*, int, char*))funcptr;
+                                               func(w3, status, buffer);
+                                       }
+                                       free(buffer);
+                                       buffer = malloc(1);
+                                       buffer[0] = 0;
+                               }
+                               status = 0;
+                       }
+               }
+       }
+ftp_stop:;
+       free(cbuf);
+       free(buffer);
+       free(buf);
+}
+
+void W3_FTP_Set_Username(struct W3* w3, const char* username) { __W3_Add_Prop(w3, "FTP_USERNAME", username); }
+
+void W3_FTP_Set_Password(struct W3* w3, const char* password) { __W3_Add_Prop(w3, "FTP_PASSWORD", password); }
+
+void W3_FTP_Send_Request(struct W3* w3) {
+       if(strcasecmp(w3->method, "LIST") == 0){
+               __W3_FTP_Start_Passive(w3);
+               *((int*)w3->generic) |= 1;
+       }
 }
+
+void W3_FTP_Disconnect(struct W3* w3) { __W3_Auto_Write(w3, "QUIT\r\n", 6); }
index 2763719a0f2018d7adeac2bf66cd444293ffaf23..26267203f3738e031393b3e89ebffea5b0436ed1 100644 (file)
@@ -126,8 +126,11 @@ struct W3URL* W3_Parse_URL(const char* _url) {
                                        r->port = 79;
                                }else if(strcmp(r->protocol, "nex") == 0) {
                                        r->port = 1900;
+                               }else if(strcmp(r->protocol, "ftp") == 0) {
+                                       r->port = 21;
                                }
 
+
                        }
                        r->host = __W3_Strdup(url + start + (atmark == 0 ? 0 : (atmark - 1)));
                        char* str = malloc(strlen(r->host) + 64);
index 15da012349abacfceb3c3235972abad4df0c5181..a4d92844bd9ef59f448e9a37f7dc191069aa1c25 100644 (file)
@@ -9,6 +9,10 @@ extern "C" {
 #include "W3Core.h"
 
 void __W3_FTP_Request(struct W3* w3);
+void W3_FTP_Set_Username(struct W3* w3, const char* username);
+void W3_FTP_Set_Password(struct W3* w3, const char* password);
+void W3_FTP_Send_Request(struct W3* w3);
+void W3_FTP_Disconnect(struct W3* w3);
 
 #ifdef __cplusplus
 }
index 7234eb3533c6e900e33b549b1d4d226957a8d566..d1c0e5bd599f038e2b2bdf0f3f2044cbf98e4cdf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -146,6 +146,7 @@ ifeq ($(TCL),YES)
        mkdir -p w3-$(VERSION)/Example/tclw3/bin
        mkdir -p w3-$(VERSION)/Example/tclw3/lib
 endif
+       mkdir -p w3-$(VERSION)/Example/ftp-list
        mkdir -p w3-$(VERSION)/Example/pop3-list
        mkdir -p w3-$(VERSION)/Example/interactive
        mkdir -p w3-$(VERSION)/Example/fetch
@@ -157,6 +158,7 @@ ifeq ($(WINDOWS),YES)
        cp ./Example/interactive/interactive.exe w3-$(VERSION)/Example/interactive/
        cp ./Example/pop3-list/pop3-list.exe w3-$(VERSION)/Example/pop3-list/
        cp ./Example/w3b/w3b.exe w3-$(VERSION)/Example/w3b/
+       cp ./Example/ftp-list/ftp-list.exe w3-$(VERSION)/Example/ftp-list/
 ifeq ($(TCL),YES)
        cp ./Example/tclw3/tclw3.exe w3-$(VERSION)/Example/tclw3/bin/
        cp /usr/$(MINGW)/sys-root/mingw/bin/tcl86.dll w3-$(VERSION)/Example/tclw3/bin/
@@ -171,6 +173,7 @@ else
        cp ./Example/interactive/interactive w3-$(VERSION)/Example/interactive/
        cp ./Example/pop3-list/pop3-list w3-$(VERSION)/Example/pop3-list/
        cp ./Example/w3b/w3b w3-$(VERSION)/Example/w3b/
+       cp ./Example/ftp-list/ftp-list w3-$(VERSION)/Example/ftp-list/
 ifeq ($(TCL),YES)
        cp ./Example/tclw3/tclw3 w3-$(VERSION)/Example/tclw3/bin/
 endif
index e740f9f4d826128dc6d44457cae852bf6eca066b..c2b02bc840fa03a2881907c18c71679ac962a743 100644 (file)
@@ -6,7 +6,7 @@
 extern "C" {
 #endif
 
-#define LIBW3_VERSION "2.11" \
+#define LIBW3_VERSION "2.11A" \
 SUFFIX
 
 #ifdef __cplusplus