#include #include #include #include #include #include #include "defines.h" extern time_t seed; int skip_hidden_files(const struct dirent *entry){ if (entry->d_name[0] == '.') { return 0; } return 1; } int skip_dot(const struct dirent *entry){ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { return 0; } return 1; } int sort_natural(const void *file0, const void *file1){ if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) { return -1; } if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) { return 1; } const unsigned char *a = (unsigned char*)((file*)file0)->file_name; const unsigned char *b = (unsigned char*)((file*)file1)->file_name; long parsed_number0 = 0; long parsed_number1 = 0; char is_num = 0; char result = 0; do { if ((*a <= '9') && (*a >= '0')) { parsed_number0 = 0; do { parsed_number0 = (parsed_number0 * 10) + (*a - '0'); a++; } while((*a <= '9') && (*a >= '0')); is_num |= 1; } if ((*b <= '9') && (*b >= '0')) { parsed_number1 = 0; do { parsed_number1 = (parsed_number1 * 10) + (*b - '0'); b++; } while((*b <= '9') && (*b >= '0')); is_num |= 2; } if (is_num) { if (is_num == 1) { if (*b > '9') { result = -1; } else { result = 1; } break; } else if (is_num == 2) { if (*a > '9') { result = 1; } else { result = -1; } break; } else { if (parsed_number0 > parsed_number1) { result = 1; break; } else if (parsed_number0 < parsed_number1) { result = -1; break; } } /* those breaks are not set here, due to the possibillity that both numbers are equal * in which case the comparison should continue */ is_num = 0; } unsigned char aa = ((*a >= 'A') && (*a <= 'Z')) ? (*a | ' ') : *a; unsigned char bb = ((*b >= 'A') && (*b <= 'Z')) ? (*b | ' ') : *b; /*using a simple aa - bb would occasionaly cause underflows with wide chars*/ result = ((aa == bb) ? 0 : ((aa > bb) ? 1 : -1 )); a++; b++; } while (result == 0); return result; } int sort_alpha(const void *file0, const void *file1){ if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) { return -1; } if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) { return 1; } return strcmp(((file*)file0)->file_name, ((file*)file1)->file_name); } int sort_random(const void *file0, const void *file1){ if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) { return -1; } if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) { return 1; } /* seed is the only value that actually changes whenever this funcion is called. * seed only updates when the order_by binding is executed. * this means that the random output only changes on the command of the user, and not SETTINGS_RELOAD_DIR_DELTA, this is intentional. * well the other stuff like file sizes and file count in a dir may also change, but this needs user intervention too. * that is unless the user decides to sort random in /var/log or something, which begs the question: why would you do that? */ time_t num = (((time_t)&sort_random) + (time_t)seed) ^ (((file*)file0)->file_size + ((file*)file1)->file_size); int i; for (i = 1; i < (((time_t)&getpid)%3); i++) { num ^= num << ((((time_t)&file0)%27)+i); num ^= num >> ((((time_t)&file1)%18)+i); num ^= ((time_t)&getpid) ^ (((time_t)&getpid) >> ((time_t)getpid())%10); } return (((num & (3 << seed%16)) >> seed%16) - 1); /*return ((num%3) - 1);*/ } int sort_type(const void *file0, const void *file1){ if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) { return -1; } if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) { return 1; } if (((file*)file0)->file_type > ((file*)file1)->file_type) { return -1; } else if (((file*)file0)->file_type < ((file*)file1)->file_type) { return 1; } else { return sort_natural(file0, file1); } } int sort_size(const void *file0, const void *file1){ if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) { return -1; } if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) { return 1; } if (((file*)file0)->file_size > ((file*)file1)->file_size) { return -1; } else if (((file*)file0)->file_size < ((file*)file1)->file_size) { return 1; } else { return sort_natural(file0, file1); } } int sort_extension(const void *file0, const void *file1){ if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) { return -1; } if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) { return 1; } char *extension0 = strrchr(((file*)file0)->file_name, '.'); char *extension1 = strrchr(((file*)file1)->file_name, '.'); if (extension0 && extension1) { if ((strcmp(extension0, extension1)) == 0) { return sort_natural(file0, file1); } else { file f0; file f1; memcpy(&f0, file0, sizeof(file)); memcpy(&f1, file1, sizeof(file)); f0.file_name = extension0; f1.file_name = extension1; return sort_natural(&f0, &f1); } } else if (extension0 != NULL && extension1 == NULL) { return 1; } else if (extension0 == NULL && extension1 != NULL) { return -1; } else { return sort_natural(file0, file1); } }