Ticket #613: mod_dirlist_sorting.patch

File mod_dirlist_sorting.patch, 5.2 kB (added by mcosby, 7 months ago)

patch for client-selectable directory list sorting

  • lighttpd-1.4.18/src/mod_dirlisting.c

    old new  
    2222 * this is a dirlisting for a lighttpd plugin 
    2323 */ 
    2424 
     25// you can't change these values without changing 
     26// the constant strings in http_list_directory_header() 
     27#define SORT_MIN 1 
     28#define SORT_ALPHA 1 
     29#define SORT_MODIFIED 2 
     30#define SORT_SIZE 3 
     31#define SORT_MAX 3 
     32 
     33#define SORT_DIR_MIN 1 
     34#define SORT_DIR_ASC 1 
     35#define SORT_DIR_DESC 2 
     36#define SORT_DIR_MAX 2 
     37 
    2538 
    2639#ifdef HAVE_SYS_SYSLIMITS_H 
    2740#include <sys/syslimits.h> 
     
    384397#define DIRLIST_BLOB_SIZE               16 
    385398 
    386399/* simple combsort algorithm */ 
    387 static void http_dirls_sort(dirls_entry_t **ent, int num) { 
     400static void http_dirls_sort(dirls_entry_t **ent, int num, int type, int dir) { 
    388401        int gap = num; 
    389402        int i, j; 
    390403        int swapped; 
     404        int res; 
    391405        dirls_entry_t *tmp; 
    392406 
    393407        do { 
     
    400414 
    401415                for (i = 0; i < num - gap; i++) { 
    402416                        j = i + gap; 
    403                         if (strcmp(DIRLIST_ENT_NAME(ent[i]), DIRLIST_ENT_NAME(ent[j])) > 0) { 
    404                                 tmp = ent[i]; 
    405                                 ent[i] = ent[j]; 
    406                                 ent[j] = tmp; 
    407                                 swapped = 1; 
     417                        if (type == SORT_ALPHA) { 
     418                                res = strcmp(DIRLIST_ENT_NAME(ent[i]), DIRLIST_ENT_NAME(ent[j])); 
     419                                if ((dir == SORT_DIR_ASC && res > 0) ||  
     420                                        (dir == SORT_DIR_DESC && res < 0)) { 
     421                                        tmp = ent[i]; 
     422                                        ent[i] = ent[j]; 
     423                                        ent[j] = tmp; 
     424                                        swapped = 1; 
     425                                } 
     426                        } else if (type == SORT_MODIFIED) { 
     427                                if ((dir == SORT_DIR_ASC && ent[i]->mtime > ent[j]->mtime) || 
     428                                        (dir == SORT_DIR_DESC && ent[i]->mtime < ent[j]->mtime)) { 
     429                                        tmp = ent[i]; 
     430                                        ent[i] = ent[j]; 
     431                                        ent[j] = tmp; 
     432                                        swapped = 1; 
     433                                } 
     434                        } else if (type == SORT_SIZE) { 
     435                                if ((dir == SORT_DIR_ASC && ent[i]->size > ent[j]->size) || 
     436                                        (dir == SORT_DIR_DESC && ent[i]->size < ent[j]->size)) { 
     437                                        tmp = ent[i]; 
     438                                        ent[i] = ent[j]; 
     439                                        ent[j] = tmp; 
     440                                        swapped = 1; 
     441                                } 
    408442                        } 
    409443                } 
    410444 
     
    451485        return (out + 3 - buf); 
    452486} 
    453487 
    454 static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) { 
     488static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out, int sort, int sort_dir) { 
    455489        UNUSED(srv); 
     490        int sort_dir_rev; 
    456491 
     492        sort_dir_rev = SORT_DIR_ASC; 
     493        if (sort_dir == SORT_DIR_ASC) sort_dir_rev = SORT_DIR_DESC; 
     494         
    457495        BUFFER_APPEND_STRING_CONST(out, 
    458496                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n" 
    459497                "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n" 
     
    532570                "<table summary=\"Directory Listing\" cellpadding=\"0\" cellspacing=\"0\">\n" 
    533571                "<thead>" 
    534572                "<tr>" 
    535                         "<th class=\"n\">Name</th>" 
    536                         "<th class=\"m\">Last Modified</th>" 
    537                         "<th class=\"s\">Size</th>" 
    538                         "<th class=\"t\">Type</th>" 
     573                "<th class=\"n\"><a href=\"?s=1&d=" 
     574        ); 
     575        if (sort == SORT_ALPHA) { 
     576                buffer_append_long(out, sort_dir_rev); 
     577        } else { 
     578                buffer_append_long(out, sort_dir); 
     579        } 
     580        BUFFER_APPEND_STRING_CONST(out, 
     581                "\">Name</th>" 
     582                "<th class=\"m\"><a href=\"?s=2&d=" 
     583        ); 
     584        if (sort == SORT_MODIFIED) { 
     585                buffer_append_long(out, sort_dir_rev); 
     586        } else { 
     587                buffer_append_long(out, SORT_DIR_DESC); 
     588        } 
     589        BUFFER_APPEND_STRING_CONST(out, 
     590                "\">Last Modified</th>" 
     591                "<th class=\"s\"><a href=\"?s=3&d=" 
     592        ); 
     593        if (sort == SORT_SIZE) { 
     594                buffer_append_long(out, sort_dir_rev); 
     595        } else { 
     596                buffer_append_long(out, sort_dir); 
     597        } 
     598        BUFFER_APPEND_STRING_CONST(out, 
     599                "\">Size</th>" 
     600                "<th class=\"t\">Type</th>" 
     601        ); 
     602        BUFFER_APPEND_STRING_CONST(out, 
    539603                "</tr>" 
    540604                "</thead>\n" 
    541605                "<tbody>\n" 
     
    607671        size_t k; 
    608672        const char *content_type; 
    609673        long name_max; 
     674        int sort_dir; 
     675        int sort; 
    610676#ifdef HAVE_XATTR 
    611677        char attrval[128]; 
    612678        int attrlen; 
     
    646712                return -1; 
    647713        } 
    648714 
     715        sort_dir = 0; 
     716        sort = 0; 
     717        if (!buffer_is_empty(con->uri.query)) { 
     718                char *q; 
     719                if ((q = strstr(con->uri.query->ptr, "s="))) { 
     720                        if (*(q+2) != 0) sort = atoi(q+2);  
     721                } 
     722                if ((q = strstr(con->uri.query->ptr, "d="))) { 
     723                        if (*(q+2) != 0) sort_dir = atoi(q+2);  
     724                } 
     725        } 
     726 
     727        if ((sort_dir < SORT_DIR_MIN) || (sort_dir > SORT_DIR_MAX)) { 
     728                sort_dir = SORT_DIR_ASC; 
     729        } 
     730        if ((sort < SORT_MIN) || (sort > SORT_MAX)) { 
     731                sort = SORT_ALPHA; 
     732        } 
     733 
    649734        dirs.ent   = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE); 
    650735        assert(dirs.ent); 
    651736        dirs.size  = DIRLIST_BLOB_SIZE; 
     
    737822        } 
    738823        closedir(dp); 
    739824 
    740         if (dirs.used) http_dirls_sort(dirs.ent, dirs.used); 
     825        if (dirs.used) { 
     826                if (sort != SORT_SIZE) { 
     827                        http_dirls_sort(dirs.ent, dirs.used, sort, sort_dir ); 
     828                } else { 
     829                        http_dirls_sort(dirs.ent, dirs.used, SORT_ALPHA, SORT_DIR_DESC ); 
     830                } 
     831        } 
    741832 
    742         if (files.used) http_dirls_sort(files.ent, files.used); 
     833        if (files.used) http_dirls_sort(files.ent, files.used, sort, sort_dir ); 
    743834 
    744835        out = chunkqueue_get_append_buffer(con->write_queue); 
    745836        BUFFER_COPY_STRING_CONST(out, "<?xml version=\"1.0\" encoding=\""); 
     
    749840                buffer_append_string_buffer(out, p->conf.encoding); 
    750841        } 
    751842        BUFFER_APPEND_STRING_CONST(out, "\"?>\n"); 
    752         http_list_directory_header(srv, con, p, out); 
     843        http_list_directory_header(srv, con, p, out, sort, sort_dir); 
    753844 
    754845        /* directories */ 
    755846        for (i = 0; i < dirs.used; i++) {