#include #include #include #include #include #include #include #include #include "cJSON/cJSON.h" #define bool unsigned char #define DEBUG 3 #if defined(DEBUG) && DEBUG > 1 #define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \ __FILE__, __LINE__, __func__, ##args) #elif DEBUG == 1 #define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %d:%s(): " fmt, \ __LINE__, __func__, ##args) #else #define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */ #endif struct tred_pizdec{ char* name; long int* size; }; struct dir_list_struct{ struct metadata* top; struct metadata* file; struct dir_list_struct* next; }; typedef struct metadata { char* name; bool tipe_dir; long int size; struct dir_list_struct* dir_list; struct metadata* top; struct dir_list_struct* jamp; } stack_element; // Функция для получения размера файла long get_file_size(char* size) { struct stat st; DEBUG_PRINT("get_file_size START!\n"); DEBUG_PRINT("name: %s!\n", size); if (stat(size, &st) == 0) { return st.st_size; } return 0; } void* get_file_size_multi_tred(void *arg) { struct tred_pizdec* mata = (struct tred_pizdec*) arg; struct stat st; DEBUG_PRINT("get_file_size START!\n"); DEBUG_PRINT("mata->name: %s!\n", mata->name); if (stat(mata->name, &st) == 0) { //return st.st_size; *mata->size = st.st_size; } //DEBUG_PRINT("mata->size: %li!\n", *mata->size); free(mata); DEBUG_PRINT("СВОБОДА!!!\n"); return NULL; } void format_size(unsigned long long bytes, char *output, size_t output_size) { const double KB = 1024.0; const double MB = 1024.0 * KB; const double GB = 1024.0 * MB; const double TB = 1024.0 * GB; if (bytes >= TB) { snprintf(output, output_size, "%.2f TiB", bytes / TB); } else if (bytes >= GB) { snprintf(output, output_size, "%.2f GiB", bytes / GB); } else if (bytes >= MB) { snprintf(output, output_size, "%.2f MiB", bytes / MB); } else if (bytes >= KB) { snprintf(output, output_size, "%.2f KiB", bytes / KB); } else { snprintf(output, output_size, "%llu B", bytes); } } struct metadata* metadata_create(bool tipe_dir,char* path, struct metadata* top){ DEBUG_PRINT("Пред mata malloc\n"); struct metadata* mata = malloc(sizeof(struct metadata)); DEBUG_PRINT("После mata malloc\n"); mata->name = path; mata->tipe_dir = tipe_dir; mata->top = top; if (tipe_dir){ mata->size = 0; } else{ mata->name = path; mata->size = mata->size; //struct metadata* mata_2 = mata; struct tred_pizdec* mata_2 = malloc(sizeof(struct tred_pizdec)); mata_2->name = path; mata_2->size = &mata->size; pthread_t thread; pthread_create(&thread, NULL, get_file_size_multi_tred, (void*)mata_2); //pthread_join(thread, NULL); //mata->size = get_file_size(path); DEBUG_PRINT("Объём:%li - %s\n", mata->size, mata->name); } return mata; } void scanning(struct metadata *mata){ struct dirent *entry = NULL; DIR *dp; bool AAA = 1; dp = opendir(mata->name); //printf("TEST: %s\n", mata->name); DEBUG_PRINT("TEST: %s\n", mata->name); struct dir_list_struct* put_2; DEBUG_PRINT("XXXXXXXXXXXXX_1!\n"); DEBUG_PRINT("One\n"); DEBUG_PRINT("%i\n", errno); if (errno == 2){ printf("Нет такого файла или каталога!\n"); //printf("%s\n", strerror(errno)); } if (errno == 22){ printf("Недопустимый аргумент!\n"); //printf("%s\n", strerror(errno)); } if (errno == 13){ printf("Отказ в доступе!\n"); //printf("%s\n", strerror(errno)); } else{ entry = readdir(dp); } DEBUG_PRINT("Two\n"); while(entry != NULL){ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0){ entry = readdir(dp); continue; } DEBUG_PRINT("mata->name: %s\n", mata->name); DEBUG_PRINT("entry->d_name: %s\n", entry->d_name); DEBUG_PRINT("Сум обём: %li\n", (strlen(mata->name) * sizeof(char) + strlen(entry->d_name) * sizeof(char) + sizeof(char))); DEBUG_PRINT("mata->name обём: %li\n",(strlen(mata->name) * sizeof(char))); DEBUG_PRINT("entry->d_name обём: %li\n",(strlen(entry->d_name) * sizeof(char))); char* putaa = malloc((strlen(mata->name) + 1) * sizeof(char) + (strlen(entry->d_name) + 1) * sizeof(char) + sizeof(char) *2); //char* putaa = malloc(sizeof(mata->name) + sizeof(entry->d_name) + sizeof(char)); DEBUG_PRINT("putaa готов! \n"); sprintf(putaa, "%s%s%s",mata->name,"/",entry->d_name); DEBUG_PRINT("putaa обединён! \n"); struct metadata* SAS; if (entry->d_type == DT_DIR){ SAS = metadata_create(1, putaa, mata); } else{ SAS = metadata_create(0, putaa, mata); } DEBUG_PRINT("SAS готов! \n"); if (AAA){ put_2 = malloc(sizeof(struct dir_list_struct)); DEBUG_PRINT("put_2 1 готов! \n"); mata->dir_list = put_2; AAA = 0; } else{ put_2->next = malloc(sizeof(struct dir_list_struct)); DEBUG_PRINT("put_2 2 готов! \n"); put_2 = put_2->next; } put_2->top = mata; put_2->file = SAS; entry = readdir(dp); } closedir(dp); DEBUG_PRINT("XXXXXXXXXXXXXs_3!\n"); } void sum_dir(struct metadata* meta_data){ DEBUG_PRINT("Пред вычисляю объём!\n"); meta_data->size = 0; if (meta_data->dir_list == NULL) return; DEBUG_PRINT("Вычисляю объём!\n"); struct dir_list_struct* list = meta_data->dir_list; while (list != NULL){ meta_data->size += list->file->size; list = list->next; } DEBUG_PRINT("Объём готов!\n"); } // Функция для сохранения кеша на диск void save_cache(struct metadata** cache, int cache_size) { FILE* file = fopen("cache.dat", "wb"); if (file != NULL) { for (int i = 0; i < cache_size; i++) { fwrite(cache[i], sizeof(struct metadata), 1, file); } fclose(file); } } // Функция для загрузки кеша с диска void load_cache(struct metadata** cache, int* cache_size) { FILE* file = fopen("cache.dat", "rb"); if (file != NULL) { struct metadata info; while (fread(&info, sizeof(struct metadata), 1, file) == 1) { (*cache_size)++; cache[*cache_size] = malloc(sizeof(struct metadata)); memcpy(cache[*cache_size], &info, sizeof(struct metadata)); } fclose(file); } } void json_create(){ char* name = "TEST"; int volume = 200; /* cJSON *device = cJSON_CreateObject(); cJSON* devices = cJSON_CreateArray(); cJSON *type = cJSON_CreateString(name); cJSON_AddItemToObject(devices, "name", type); cJSON_AddItemToObject(device, "list", devices); cJSON* id = cJSON_CreateObject(); cJSON_AddItemToArray(devices, id); cJSON *value = cJSON_CreateNumber(volume); //cJSON_AddItemToObject(devices, "volume", value); char *string = cJSON_Print(device); */ //printf("AA: %s\n", string); } int main(int argc, char *argv[]){ // /home/romenskiy2012/ char *path; setlocale(LC_ALL, ""); //printf("Your locale is: %s\n", setlocale(LC_CTYPE, NULL)); if (argc == 2){ path = argv[1]; //printf("ZZZZ %s\n", path); } else{ if (!strcmp (setlocale(LC_CTYPE, NULL), "ru_RU.UTF-8")){ printf("Путь не указан!\n"); } else printf("The path is not specified!\n"); return 0; } //char *path = malloc(sizeof(char)* (argc+1)); //path = argv; //char path[] = "/home/romenskiy2012/projects/WebDisk/SAS/"; // /home/romenskiy2012/projects/WebDisk/SAS/ //char name[] = "SAS"; struct metadata *mata, *meta_data, *meta_data_tmp; mata = malloc(sizeof(stack_element)); mata->name = path; mata->tipe_dir = 1; scanning(mata); meta_data = mata; if (meta_data->dir_list == NULL) meta_data->jamp = meta_data->dir_list; struct dir_list_struct* global_dir_list = meta_data->dir_list; while(1){ //printf("%s%s",global_dir_list->file->name ,"\n"); DEBUG_PRINT("Цикол!\n"); //else if (meta_data->jamp->next != NULL) // global_dir_list = meta_data->jamp->next; while(global_dir_list != NULL){ DEBUG_PRINT("%s" ,"while global_dir_list\n"); if (global_dir_list->file->tipe_dir){ DEBUG_PRINT("Выполняю прыжок вниз!\n"); scanning(global_dir_list->file); DEBUG_PRINT("%s%s",global_dir_list->file->name ," AAA \n"); meta_data_tmp = global_dir_list->file; DEBUG_PRINT("%s --- dd\n", global_dir_list->file->name); meta_data_tmp->jamp = global_dir_list; meta_data = meta_data_tmp; global_dir_list = meta_data->dir_list; break; } else{ DEBUG_PRINT("Нaйден файл: %s\n",global_dir_list->file->name); global_dir_list = global_dir_list->next; DEBUG_PRINT("Прыгаю вперёд!\n"); } //if (){} } if (global_dir_list == NULL){ DEBUG_PRINT("Глобальный список закончен, прыгаю верх за контрольную точку!\n"); //if (meta_data->jamp->next == NULL) printf("XXXXXXXX!\n"); if (meta_data->jamp != NULL && meta_data->jamp->next != NULL ){ if(meta_data->tipe_dir) sum_dir(meta_data); global_dir_list = meta_data->jamp->next; meta_data = meta_data->jamp->next->file; } else{ DEBUG_PRINT("Контлоьные точки закончелись, поднимаюсь!\n"); if(meta_data->tipe_dir)sum_dir(meta_data); if (meta_data->top == NULL){ DEBUG_PRINT("Подём отменён!\n"); break; } DEBUG_PRINT("Подём!\n"); meta_data = meta_data->top; } } //if (mata == meta_data){ // break; //} } DEBUG_PRINT("Готово!\n"); struct dir_list_struct* list = mata->dir_list; DEBUG_PRINT("list получен!\n"); char output[64]; do{ format_size(list->file->size, output, sizeof(output)); printf("%s\t%li\t%s\n", output, list->file->size, list->file->name); DEBUG_PRINT("прыгаем_1!\n"); list = list->next; DEBUG_PRINT("прыгаем_2!\n"); }while(list != NULL); //while(list->next != NULL); //save_cache(mata, int cache_size) printf("%s","bye.\n"); json_create(); return 0; }