| 821 //printf("service_index\n"); |
821 //printf("service_index\n"); |
| 822 const CxAllocator *a = pool_allocator(sn->pool); |
822 const CxAllocator *a = pool_allocator(sn->pool); |
| 823 |
823 |
| 824 char *path = pblock_findkeyval(pb_key_path, rq->vars); |
824 char *path = pblock_findkeyval(pb_key_path, rq->vars); |
| 825 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); |
825 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); |
| |
826 |
| |
827 // params |
| |
828 char *useemojis = pblock_findval("use-emojis", pb); |
| |
829 char *diricon = pblock_findval("dir-icon", pb); |
| |
830 char *fileicon = pblock_findval("file-icon", pb); |
| |
831 char *hidden = pblock_findval("show-hidden", pb); |
| |
832 |
| |
833 WSBool show_hidden = TRUE; |
| |
834 char *dir_str = "<dir>"; |
| |
835 char *file_str = "<file>"; |
| |
836 |
| |
837 if(hidden) { |
| |
838 show_hidden = util_getboolean(hidden, FALSE); |
| |
839 } |
| |
840 if(useemojis && util_getboolean(useemojis, FALSE)) { |
| |
841 dir_str = "📁"; |
| |
842 file_str = "📄"; |
| |
843 } else { |
| |
844 if(diricon) { |
| |
845 dir_str = cx_asprintf_a(a, "<img src=\"%s\" alt=\"directory\" border=\"0\"/>", diricon).ptr; |
| |
846 } |
| |
847 if(fileicon) { |
| |
848 file_str = cx_asprintf_a(a, "<img src=\"%s\" alt=\"directory\" border=\"0\"/>", fileicon).ptr; |
| |
849 } |
| |
850 } |
| 826 |
851 |
| 827 // open the file |
852 // open the file |
| 828 VFSContext *vfs = vfs_request_context(sn, rq); |
853 VFSContext *vfs = vfs_request_context(sn, rq); |
| 829 VFS_DIR dir = vfs_opendir(vfs, path); |
854 VFS_DIR dir = vfs_opendir(vfs, path); |
| 830 if(!dir) { |
855 if(!dir) { |
| 831 return REQ_ABORTED; |
856 return REQ_ABORTED; |
| 832 } |
857 } |
| |
858 |
| |
859 CxList *files = cxLinkedListCreate(a, (cx_compare_func)cmp_file_type_name, sizeof(IndexEntry)); |
| |
860 if(!files) { |
| |
861 vfs_closedir(dir); |
| |
862 return REQ_ABORTED; |
| |
863 } |
| |
864 |
| 833 |
865 |
| 834 sbuf_t *out = sbuf_new(1024); // output buffer |
866 sbuf_t *out = sbuf_new(1024); // output buffer |
| 835 |
867 |
| 836 // write html header |
868 // write html header |
| 837 sbuf_puts(out, "<!DOCTYPE html>\n<html>\n<head>\n<title>Index of "); |
869 sbuf_puts(out, "<!DOCTYPE html>\n<html>\n<head>\n<title>Index of "); |
| 838 sbuf_puts(out, uri); |
870 sbuf_puts(out, uri); |
| 839 sbuf_puts(out, "</title>\n"); |
871 sbuf_puts(out, "</title>\n"); |
| 840 sbuf_puts(out, "<style>\n"); |
872 sbuf_puts(out, "<style>\n"); |
| 841 sbuf_puts(out, "th { text-align: left; }\n"); |
873 sbuf_puts(out, "th { text-align: left; }\n"); |
| 842 sbuf_puts(out, "td { padding-right: 1em; }\n"); |
874 sbuf_puts(out, "td { padding-right: 2em; }\n"); |
| |
875 sbuf_puts(out, ".type { padding-right: 0em; }\n"); |
| 843 sbuf_puts(out, "</style>\n"); |
876 sbuf_puts(out, "</style>\n"); |
| 844 sbuf_puts(out, "</head><body>\n<h1>Index of "); |
877 sbuf_puts(out, "</head><body>\n<h1>Index of "); |
| 845 sbuf_puts(out, uri); |
878 sbuf_puts(out, uri); |
| 846 sbuf_puts(out, "</h1><hr>\n\n"); |
879 sbuf_puts(out, "</h1><hr>\n\n"); |
| 847 |
|
| 848 CxList *files = cxLinkedListCreate(a, (cx_compare_func)cmp_file_type_name, sizeof(IndexEntry)); |
|
| 849 if(!files) { |
|
| 850 return REQ_ABORTED; |
|
| 851 } |
|
| 852 |
880 |
| 853 // read directory at store entries in the files list |
881 // read directory at store entries in the files list |
| 854 int ret = REQ_PROCEED; |
882 int ret = REQ_PROCEED; |
| 855 VFS_ENTRY f; |
883 VFS_ENTRY f; |
| 856 while(vfs_readdir_stat(dir, &f)) { |
884 while(vfs_readdir_stat(dir, &f)) { |
| |
885 if(!show_hidden && f.name[0] == '.') { |
| |
886 continue; |
| |
887 } |
| |
888 |
| 857 IndexEntry entry; |
889 IndexEntry entry; |
| 858 entry.name = pool_strdup(sn->pool, f.name); |
890 entry.name = pool_strdup(sn->pool, f.name); |
| 859 if(!entry.name) { |
891 if(!entry.name) { |
| 860 ret = REQ_ABORTED; |
892 ret = REQ_ABORTED; |
| 861 break; |
893 break; |
| 877 break; |
909 break; |
| 878 } |
910 } |
| 879 } |
911 } |
| 880 |
912 |
| 881 // generate html output |
913 // generate html output |
| 882 sbuf_puts(out, "<table>\n<tr><th>Type</th><th>Name</th><th>Size</th><th>Last Modified</th></tr>\n"); |
914 sbuf_puts(out, "<table>\n<tr><th colspan=\"2\">Name</th><th>Size</th><th>Last Modified</th></tr>\n"); |
| 883 cxListSort(files); |
915 cxListSort(files); |
| 884 CxIterator i = cxListIterator(files); |
916 CxIterator i = cxListIterator(files); |
| 885 cx_foreach(IndexEntry *, entry, i) { |
917 cx_foreach(IndexEntry *, entry, i) { |
| 886 sbuf_puts(out, "<tr>\n"); |
918 sbuf_puts(out, "<tr>\n"); |
| 887 |
919 |
| 888 sbuf_puts(out, "<td>"); |
920 sbuf_puts(out, "<td class=\"type\">"); |
| 889 sbuf_puts(out, entry->isdir ? "[DIR]" : "[FILE]"); |
921 sbuf_puts(out, entry->isdir ? dir_str : file_str); |
| 890 sbuf_puts(out, "</td>"); |
922 sbuf_puts(out, "</td>"); |
| 891 |
923 |
| 892 sbuf_puts(out, "<td>"); |
924 sbuf_puts(out, "<td>"); |
| 893 sbuf_puts(out, "<a href=\""); |
925 sbuf_puts(out, "<a href=\""); |
| 894 sbuf_puts(out, entry->name); |
926 sbuf_puts(out, entry->name); |