]> Git repositories of Nishi - tewi.git/commitdiff
icon works
authorNishi <nishi@nishi.boats>
Sat, 14 Sep 2024 13:25:38 +0000 (13:25 +0000)
committerNishi <nishi@nishi.boats>
Sat, 14 Sep 2024 13:25:38 +0000 (13:25 +0000)
git-svn-id: file:///raid/svn-personal/tewi/trunk@22 8739d7e6-ffea-ec47-b151-bdff447c6205

Common/dir.c
Server/config.c
Server/http.c
Server/server.c
Server/tw_config.h
example.conf

index eca0e6526616e422ef5b3fe30db500be97387b6c..f830d9bdc26bc14f2caa2b914a2801566f5c0407 100644 (file)
@@ -9,20 +9,20 @@
 #include <stdlib.h>
 #include <string.h>
 
-int cm_sort(const void* _a, const void* _b){
+int cm_sort(const void* _a, const void* _b) {
        char* a = *(char**)_a;
        char* b = *(char**)_b;
        return strcmp(a, b);
 }
 
-char** cm_scandir(const char* path){
+char** cm_scandir(const char* path) {
        DIR* dir = opendir(path);
-       if(dir != NULL){
+       if(dir != NULL) {
                char** r = malloc(sizeof(*r));
                r[0] = NULL;
                struct dirent* d;
-               while((d = readdir(dir)) != NULL){
-                       if(strcmp(d->d_name, ".") != 0){
+               while((d = readdir(dir)) != NULL) {
+                       if(strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
                                struct stat s;
                                char* p = cm_strcat3(path, "/", d->d_name);
                                stat(p, &s);
@@ -30,7 +30,8 @@ char** cm_scandir(const char* path){
 
                                char** old = r;
                                int i;
-                               for(i = 0; old[i] != NULL; i++);
+                               for(i = 0; old[i] != NULL; i++)
+                                       ;
                                r = malloc(sizeof(*r) * (i + 2));
                                for(i = 0; old[i] != NULL; i++) r[i] = old[i];
                                r[i] = cm_strcat(d->d_name, S_ISDIR(s.st_mode) ? "/" : "");
@@ -39,10 +40,22 @@ char** cm_scandir(const char* path){
                        }
                }
                int len;
-               for(len = 0; r[len] != NULL; len++);
+               for(len = 0; r[len] != NULL; len++)
+                       ;
                qsort(r, len, sizeof(char*), cm_sort);
+
+               char** old = r;
+               int i;
+               for(i = 0; old[i] != NULL; i++)
+                       ;
+               r = malloc(sizeof(*r) * (i + 2));
+               for(i = 0; old[i] != NULL; i++) r[i + 1] = old[i];
+               r[0] = cm_strdup("../");
+               r[i + 1] = NULL;
+               free(old);
+
                return r;
-       }else{
+       } else {
                return NULL;
        }
 }
index 26e577fd9c09ec204cd72ba318ed877a2917434c..15bcee7b50ccbf7a367c20f80a2878a317484205 100644 (file)
@@ -30,20 +30,20 @@ struct tw_config_entry* tw_vhost_match(const char* name, int port) {
        return &config.root;
 }
 
-bool tw_permission_allowed(const char* path, SOCKADDR addr, struct tw_http_request req, struct tw_config_entry* vhost){
+bool tw_permission_allowed(const char* path, SOCKADDR addr, struct tw_http_request req, struct tw_config_entry* vhost) {
        int i;
        bool found = false;
        bool pathstart = false;
        bool perm = false;
 again:
-       for(i = 0; i < vhost->dir_count; i++){
+       for(i = 0; i < vhost->dir_count; i++) {
                struct tw_dir_entry* e = &vhost->dirs[i];
                pathstart = false;
-               if(strlen(path) >= strlen(e->dir)){
+               if(strlen(path) >= strlen(e->dir)) {
                        pathstart = true;
                        int j;
-                       for(j = 0; path[j] != 0 && e->dir[j] != 0; j++){
-                               if(path[j] != e->dir[j]){
+                       for(j = 0; path[j] != 0 && e->dir[j] != 0; j++) {
+                               if(path[j] != e->dir[j]) {
                                        pathstart = false;
                                        break;
                                }
@@ -51,15 +51,15 @@ again:
                }
                char* noslash = cm_strdup(e->dir);
                noslash[strlen(noslash) - 1] = 0;
-               if(strcmp(e->dir, path) == 0 || strcmp(noslash, path) == 0 || pathstart){
+               if(strcmp(e->dir, path) == 0 || strcmp(noslash, path) == 0 || pathstart) {
                        found = true;
-                       if(strcmp(e->name, "all") == 0){
+                       if(strcmp(e->name, "all") == 0) {
                                perm = e->type == TW_DIR_ALLOW;
                        }
                }
                free(noslash);
        }
-       if(!found && vhost != &config.root){
+       if(!found && vhost != &config.root) {
                vhost = &config.root;
                goto again;
        }
@@ -81,6 +81,7 @@ void tw_config_init(void) {
        config.root.root = NULL;
        config.root.mime_count = 0;
        config.root.dir_count = 0;
+       config.root.icon_count = 0;
        config.vhost_count = 0;
        config.module_count = 0;
        config.extension = NULL;
@@ -179,6 +180,7 @@ int tw_config_read(const char* path) {
                                                                current = &config.vhosts[config.vhost_count++];
                                                                current->dir_count = 0;
                                                                current->mime_count = 0;
+                                                               current->icon_count = 0;
                                                                int i;
                                                                current->name = cm_strdup(vhost);
                                                                current->port = -1;
@@ -246,7 +248,7 @@ int tw_config_read(const char* path) {
                                                if(r[1] == NULL) {
                                                        cm_log("Config", "Missing extension at line %d", ln);
                                                        stop = 1;
-                                               }else if(r[2] == NULL) {
+                                               } else if(r[2] == NULL) {
                                                        cm_log("Config", "Missing MIME at line %d", ln);
                                                        stop = 1;
                                                } else {
@@ -254,6 +256,18 @@ int tw_config_read(const char* path) {
                                                        e->ext = cm_strdup(r[1]);
                                                        e->mime = cm_strdup(r[2]);
                                                }
+                                       } else if(cm_strcaseequ(r[0], "Icon")) {
+                                               if(r[1] == NULL) {
+                                                       cm_log("Config", "Missing MIME at line %d", ln);
+                                                       stop = 1;
+                                               } else if(r[2] == NULL) {
+                                                       cm_log("Config", "Missing path at line %d", ln);
+                                                       stop = 1;
+                                               } else {
+                                                       struct tw_icon_entry* e = &current->icons[current->icon_count++];
+                                                       e->mime = cm_strdup(r[1]);
+                                                       e->icon = cm_strdup(r[2]);
+                                               }
                                        } else if(cm_strcaseequ(r[0], "LoadModule")) {
                                                for(i = 1; r[i] != NULL; i++) {
                                                        void* mod = tw_module_load(r[i]);
index 5c6b5f9fa8ea9ef1b1e3211361c03cbd18f3a5f5..6528d79841e0736f2cc565c8240a2d332419c4b2 100644 (file)
@@ -59,8 +59,14 @@ int tw_http_parse(SSL* ssl, int sock, struct tw_http_request* req) {
                struct timeval tv;
                tv.tv_sec = 5;
                tv.tv_usec = 0;
-               int n = select(FD_SETSIZE, &fds, NULL, NULL, &tv);
-               if(n == 0) break;
+               if(!SSL_has_pending(ssl)) {
+                       int n = select(FD_SETSIZE, &fds, NULL, NULL, &tv);
+                       if(n <= 0) {
+                               free(header);
+                               tw_free_request(req);
+                               return -1;
+                       }
+               }
                int len = tw_read(ssl, sock, buffer, 512);
                if(len <= 0) break;
                int i;
index 322e015424a56dadecf862d714c1ba855928d46b..7d3755c019646325a10accdbf8c2d4af3dfca1a3 100644 (file)
@@ -165,11 +165,11 @@ void tw_process_page(SSL* ssl, int sock, const char* status, const char* type, F
        tw_write(ssl, sock, "\r\n", 2);
        size_t incr = 0;
        while(1) {
-               if(f != NULL){
+               if(f != NULL) {
                        char buffer[128];
                        fread(buffer, size < 128 ? size : 128, 1, f);
                        tw_write(ssl, sock, buffer, size < 128 ? size : 128);
-               }else{
+               } else {
                        tw_write(ssl, sock, (unsigned char*)doc + incr, size < 128 ? size : 128);
                }
                incr += 128;
@@ -268,6 +268,48 @@ void addstring(char** str, const char* add, ...) {
        }
 }
 
+char* tw_get_mime(const char* ext, struct tw_config_entry* vhost_entry) {
+       char* mime = "application/octet-stream";
+       if(ext == NULL) return mime;
+       bool set = false;
+       int i;
+       for(i = 0; i < vhost_entry->mime_count; i++) {
+               if(strcmp(vhost_entry->mimes[i].ext, "all") == 0 || (ext != NULL && strcmp(vhost_entry->mimes[i].ext, ext) == 0)) {
+                       mime = vhost_entry->mimes[i].mime;
+                       set = true;
+               }
+       }
+       if(!set) {
+               for(i = 0; i < config.root.mime_count; i++) {
+                       if(strcmp(config.root.mimes[i].ext, "all") == 0 || (ext != NULL && strcmp(config.root.mimes[i].ext, ext) == 0)) {
+                               mime = config.root.mimes[i].mime;
+                       }
+               }
+       }
+       return mime;
+}
+
+char* tw_get_icon(const char* mime, struct tw_config_entry* vhost_entry) {
+       char* icon = "";
+       if(mime == NULL) return "";
+       bool set = false;
+       int i;
+       for(i = 0; i < vhost_entry->icon_count; i++) {
+               if(strcmp(vhost_entry->icons[i].mime, "all") == 0 || (mime != NULL && strcmp(vhost_entry->icons[i].mime, mime) == 0)) {
+                       icon = vhost_entry->icons[i].icon;
+                       set = true;
+               }
+       }
+       if(!set) {
+               for(i = 0; i < config.root.icon_count; i++) {
+                       if(strcmp(config.root.icons[i].mime, "all") == 0 || (mime != NULL && strcmp(config.root.icons[i].mime, mime) == 0)) {
+                               icon = config.root.icons[i].icon;
+                       }
+               }
+       }
+       return icon;
+}
+
 #ifdef __MINGW32__
 struct pass_entry {
        int sock;
@@ -306,8 +348,8 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
        if(ret == 0) {
                char* vhost = cm_strdup(config.hostname);
                int i;
-               for(i = 0; req.headers[i] != NULL; i += 2){
-                       if(cm_strcaseequ(req.headers[i], "Host")){
+               for(i = 0; req.headers[i] != NULL; i += 2) {
+                       if(cm_strcaseequ(req.headers[i], "Host")) {
                                free(vhost);
                                vhost = req.headers[i + 1];
                                break;
@@ -316,8 +358,8 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
                cm_log("Server", "Host is %s", vhost);
                int port = s == NULL ? 80 : 443;
                char* host = cm_strdup(vhost);
-               for(i = 0; vhost[i] != 0; i++){
-                       if(vhost[i] == ':'){
+               for(i = 0; vhost[i] != 0; i++) {
+                       if(vhost[i] == ':') {
                                host[i] = 0;
                                port = atoi(host + i + 1);
                                break;
@@ -346,10 +388,10 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
                        char* path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);
                        cm_log("Server", "Filesystem path is %s", path);
                        struct stat st;
-                       if(stat(path, &st) == 0){
-                               if(!tw_permission_allowed(path, addr, req, vhost_entry)){
+                       if(stat(path, &st) == 0) {
+                               if(!tw_permission_allowed(path, addr, req, vhost_entry)) {
                                        tw_http_error(s, sock, 403, name, port);
-                               }else if(S_ISDIR(st.st_mode)){
+                               } else if(S_ISDIR(st.st_mode)) {
                                        char* str = malloc(1);
                                        str[0] = 0;
                                        char** items = cm_scandir(path);
@@ -367,12 +409,44 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
                                        addstring(&str, "                               <th></th>\n");
                                        addstring(&str, "                               <th>Filename</th>\n");
                                        addstring(&str, "                       </tr>\n");
-                                       if(items != NULL){
-                                               for(i = 0; items[i] != NULL; i++){
+                                       if(items != NULL) {
+                                               for(i = 0; items[i] != NULL; i++) {
+                                                       char* ext = NULL;
+                                                       int j;
+                                                       for(j = strlen(items[i]) - 1; j >= 0; j--) {
+                                                               if(items[i][j] == '.') {
+                                                                       ext = cm_strdup(items[i] + j);
+                                                                       break;
+                                                               }
+                                                       }
+                                                       char* mime = tw_get_mime(ext, vhost_entry);
+                                                       if(strcmp(items[i], "../") == 0) {
+                                                               mime = "misc/parent";
+                                                       } else if(items[i][strlen(items[i]) - 1] == '/') {
+                                                               mime = "misc/dir";
+                                                       }
+                                                       char* icon = tw_get_icon(mime, vhost_entry);
+                                                       if(ext != NULL) free(ext);
+                                                       char* itm = cm_strdup(items[i]);
+                                                       if(strlen(itm) >= 32) {
+                                                               if(itm[strlen(itm) - 1] == '/') {
+                                                                       itm[31] = 0;
+                                                                       itm[30] = '/';
+                                                                       itm[29] = '.';
+                                                                       itm[28] = '.';
+                                                                       itm[27] = '.';
+                                                               } else {
+                                                                       itm[31] = 0;
+                                                                       itm[30] = '.';
+                                                                       itm[29] = '.';
+                                                                       itm[28] = '.';
+                                                               }
+                                                       }
                                                        addstring(&str, "<tr>\n");
-                                                       addstring(&str, "       <td></td>\n");
-                                                       addstring(&str, "       <td><a href=\"%l\">%h</a></td>\n", items[i], items[i]);
+                                                       addstring(&str, "       <td><img src=\"%s\" alt=\"icon\"></td>\n", icon);
+                                                       addstring(&str, "       <td><a href=\"%l\"><code>%h</code></a></td>\n", items[i], itm);
                                                        addstring(&str, "</tr>\n");
+                                                       free(itm);
                                                }
                                        }
                                        addstring(&str, "               </table>\n");
@@ -382,42 +456,28 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
                                        addstring(&str, "</html>\n");
                                        tw_process_page(s, sock, tw_http_status(200), "text/html", NULL, str, strlen(str));
                                        free(str);
-                               }else{
-                                       char* mime = "application/octet-stream";
-                                       bool set = false;
+                               } else {
                                        char* ext = NULL;
-                                       for(i = strlen(req.path) - 1; i >= 0; i--){
-                                               if(req.path[i] == '.'){
+                                       for(i = strlen(req.path) - 1; i >= 0; i--) {
+                                               if(req.path[i] == '.') {
                                                        ext = cm_strdup(req.path + i);
                                                        break;
                                                }
                                        }
-                                       for(i = 0; i < vhost_entry->mime_count; i++){
-                                               if(strcmp(vhost_entry->mimes[i].ext, "all") == 0 || (ext != NULL && strcmp(vhost_entry->mimes[i].ext, ext) == 0)){
-                                                       mime = vhost_entry->mimes[i].mime;
-                                                       set = true;
-                                               }
-                                       }
-                                       if(!set){
-                                               for(i = 0; i < config.root.mime_count; i++){
-                                                       if(strcmp(config.root.mimes[i].ext, "all") == 0 || (ext != NULL && strcmp(config.root.mimes[i].ext, ext) == 0)){
-                                                               mime = config.root.mimes[i].mime;
-                                                               set = true;
-                                                       }
-                                               }
-                                       }
+                                       char* mime = tw_get_mime(ext, vhost_entry);
                                        if(ext != NULL) free(ext);
                                        FILE* f = fopen(path, "rb");
                                        tw_process_page(s, sock, tw_http_status(200), mime, f, NULL, st.st_size);
                                        fclose(f);
                                }
-                       }else{
+                       } else {
                                tw_http_error(s, sock, 404, name, port);
                        }
                        free(path);
                }
                free(vhost);
                free(host);
+       } else if(ret == -1) {
        } else {
                tw_http_error(s, sock, 400, name, port);
        }
index 1ec6e4eb613ac4aed0478f9c7ab76fd92f23a842..7f63ddaabc943868c70d753db976ce930e7abef3 100644 (file)
 #define SOCKADDR struct sockaddr_in6
 #endif
 
-#define MAX_PORTS      1024
-#define MAX_VHOSTS     1024
-#define MAX_MODULES    1024
-#define MAX_DIRS       1024
-#define MAX_MIME       1024
+#define MAX_PORTS 1024
+#define MAX_VHOSTS 1024
+#define MAX_MODULES 1024
+#define MAX_DIRS 1024
+#define MAX_MIME 1024
+#define MAX_ICON 1024
 
 enum TW_DIR_TYPE {
        TW_DIR_ALLOW = 0,
@@ -43,6 +44,11 @@ struct tw_mime_entry {
        char* mime;
 };
 
+struct tw_icon_entry {
+       char* mime;
+       char* icon;
+};
+
 struct tw_config_entry {
        char* name;
        int port;
@@ -53,6 +59,8 @@ struct tw_config_entry {
        int dir_count;
        struct tw_mime_entry mimes[MAX_DIRS];
        int mime_count;
+       struct tw_icon_entry icons[MAX_DIRS];
+       int icon_count;
 };
 
 struct tw_config {
index 163bae7e4df33364800af38f733c43198ad92859..0d11fd1a24f8b033cd838b42d56166eda9f8651a 100644 (file)
@@ -11,16 +11,19 @@ SSLCertificate cert.pem
 
 MIMEType all application/octet-stream
 MIMEType .html text/html
+MIMEType .txt text/plain
+MIMEType .png image/png
 
-DocumentRoot /
+Icon all /icons/unknown.png
+Icon text/plain /icons/text.png
+Icon misc/dir /icons/folder.png
+Icon misc/parent /icons/parent.png
+
+DocumentRoot /var/www
 
 BeginDirectory /
        Allow all
 EndDirectory
 
-BeginDirectory /var/www
-       Deny all
-EndDirectory
-
 BeginVirtualHost nishinbsd-ssd
 EndVirtualHost