Project

General

Profile

Feature #613 » dirlisting-1.4.26.patch

mcosby, 2010-04-05 06:59

View differences:

lighttpd-1.4.26/src/mod_dirlisting.c 2010-04-03 09:31:33.000000000 -0400
22 22
 * this is a dirlisting for a lighttpd plugin
23 23
 */
24 24

  
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
25 37

  
26 38
#ifdef HAVE_SYS_SYSLIMITS_H
27 39
#include <sys/syslimits.h>
......
411 423
#define DIRLIST_BLOB_SIZE		16
412 424

  
413 425
/* simple combsort algorithm */
414
static void http_dirls_sort(dirls_entry_t **ent, int num) {
426
static void http_dirls_sort(dirls_entry_t **ent, int num, int type, int dir ) {
415 427
	int gap = num;
416 428
	int i, j;
417 429
	int swapped;
430
	int res;
418 431
	dirls_entry_t *tmp;
419 432

  
420 433
	do {
......
427 440

  
428 441
		for (i = 0; i < num - gap; i++) {
429 442
			j = i + gap;
430
			if (strcmp(DIRLIST_ENT_NAME(ent[i]), DIRLIST_ENT_NAME(ent[j])) > 0) {
431
				tmp = ent[i];
432
				ent[i] = ent[j];
433
				ent[j] = tmp;
434
				swapped = 1;
443
			if (type == SORT_ALPHA) {
444
				res = strcmp(DIRLIST_ENT_NAME(ent[i]), DIRLIST_ENT_NAME(ent[j]));
445
				if ((dir == SORT_DIR_ASC && res > 0) || 
446
					(dir == SORT_DIR_DESC && res < 0)) {
447
					tmp = ent[i];
448
					ent[i] = ent[j];
449
					ent[j] = tmp;
450
					swapped = 1;
451
				}
452
			} else if (type == SORT_MODIFIED) {
453
				if ((dir == SORT_DIR_ASC && ent[i]->mtime > ent[j]->mtime) ||
454
					(dir == SORT_DIR_DESC && ent[i]->mtime < ent[j]->mtime)) {
455
					tmp = ent[i];
456
					ent[i] = ent[j];
457
					ent[j] = tmp;
458
					swapped = 1;
459
				}
460
			} else if (type == SORT_SIZE) {
461
				if ((dir == SORT_DIR_ASC && ent[i]->size > ent[j]->size) ||
462
					(dir == SORT_DIR_DESC && ent[i]->size < ent[j]->size)) {
463
					tmp = ent[i];
464
					ent[i] = ent[j];
465
					ent[j] = tmp;
466
					swapped = 1;
467
				}
435 468
			}
436 469
		}
437 470

  
......
478 511
	return (out + 3 - buf);
479 512
}
480 513

  
481
static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
514
static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out, int sort, int sort_dir) {
482 515
	UNUSED(srv);
516
	int sort_dir_rev;
517

  
518
	sort_dir_rev = SORT_DIR_ASC;
519
	if (sort_dir == SORT_DIR_ASC) sort_dir_rev = SORT_DIR_DESC;
520

  
483 521

  
484 522
	if (p->conf.auto_layout) {
485 523
		buffer_append_string_len(out, CONST_STR_LEN(
......
563 601
		"<table summary=\"Directory Listing\" cellpadding=\"0\" cellspacing=\"0\">\n"
564 602
		"<thead>"
565 603
		"<tr>"
566
			"<th class=\"n\">Name</th>"
567
			"<th class=\"m\">Last Modified</th>"
568
			"<th class=\"s\">Size</th>"
569
			"<th class=\"t\">Type</th>"
604
		"<th class=\"n\"><a href=\"?s=1&d="
605
	));
606
	if (sort == SORT_ALPHA) {
607
		buffer_append_long(out, sort_dir_rev);
608
	} else {
609
		buffer_append_long(out, sort_dir);
610
	}
611
	buffer_append_string_len( out, CONST_STR_LEN(
612
		"\">Name</th>"
613
		"<th class=\"m\"><a href=\"?s=2&d="
614
	));
615
	if (sort == SORT_MODIFIED) {
616
		buffer_append_long(out, sort_dir_rev);
617
	} else {
618
		buffer_append_long(out, SORT_DIR_DESC);
619
	}
620
	buffer_append_string_len( out, CONST_STR_LEN(
621
		"\">Last Modified</th>"
622
		"<th class=\"s\"><a href=\"?s=3&d="
623
	));
624
	if (sort == SORT_SIZE) {
625
		buffer_append_long(out, sort_dir_rev);
626
	} else {
627
		buffer_append_long(out, sort_dir);
628
	}
629
	buffer_append_string_len( out, CONST_STR_LEN(
630
		"\">Size</th>"
631
		"<th class=\"t\">Type</th>"
570 632
		"</tr>"
571 633
		"</thead>\n"
572 634
		"<tbody>\n"
......
644 706
	size_t k;
645 707
	const char *content_type;
646 708
	long name_max;
709
	int sort_dir;
710
	int sort;
647 711
#ifdef HAVE_XATTR
648 712
	char attrval[128];
649 713
	int attrlen;
......
683 747
		return -1;
684 748
	}
685 749

  
750
	sort_dir = 0;
751
	sort = 0;
752
	if (!buffer_is_empty(con->uri.query)) {
753
		char *q;
754
		if ((q = strstr(con->uri.query->ptr, "s="))) {
755
			if (*(q+2) != 0) sort = atoi(q+2); 
756
		}
757
		if ((q = strstr(con->uri.query->ptr, "d="))) {
758
			if (*(q+2) != 0) sort_dir = atoi(q+2); 
759
		}
760
	}
761

  
762
	if ((sort_dir < SORT_DIR_MIN) || (sort_dir > SORT_DIR_MAX)) {
763
		sort_dir = SORT_DIR_ASC;
764
	}
765
	if ((sort < SORT_MIN) || (sort > SORT_MAX)) {
766
		sort = SORT_ALPHA;
767
	}
768

  
686 769
	dirs.ent   = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
687 770
	assert(dirs.ent);
688 771
	dirs.size  = DIRLIST_BLOB_SIZE;
......
774 857
	}
775 858
	closedir(dp);
776 859

  
777
	if (dirs.used) http_dirls_sort(dirs.ent, dirs.used);
860
	if (dirs.used) {
861
		if (sort != SORT_SIZE) {
862
			http_dirls_sort(dirs.ent, dirs.used, sort, sort_dir );
863
		} else {
864
			http_dirls_sort(dirs.ent, dirs.used, SORT_ALPHA, SORT_DIR_DESC );
865
		}
866
	}
778 867

  
779
	if (files.used) http_dirls_sort(files.ent, files.used);
868
	if (files.used) http_dirls_sort(files.ent, files.used, sort, sort_dir);
780 869

  
781 870
	out = chunkqueue_get_append_buffer(con->write_queue);
782 871
	buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
......
786 875
		buffer_append_string_buffer(out, p->conf.encoding);
787 876
	}
788 877
	buffer_append_string_len(out, CONST_STR_LEN("\"?>\n"));
789
	http_list_directory_header(srv, con, p, out);
878
	http_list_directory_header(srv, con, p, out, sort, sort_dir);
790 879

  
791 880
	/* directories */
792 881
	for (i = 0; i < dirs.used; i++) {
(2-2/2)