Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
10 kB
2
Indexable
Never
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// �w�q�@���ɮ׵��c��
typedef struct {
    char* filename;  // �ɮצW��
    int32_t is_dir;      // �O�_�O�ؿ�
} file_t;

char* file_name(FILE* pFile) {
    int16_t filelen = 0;
    fseek(pFile, 24, SEEK_CUR);
    fread(&filelen, 2, 1, pFile);  // n name
    char* filename = calloc(filelen + 1, sizeof(char));
    fseek(pFile, 16, SEEK_CUR);
    fread(filename, filelen, 1, pFile);  // file name
    filename[filelen] = 0;
    return filename;
}

int32_t compare(char* a, char* b, int32_t option) {
    int32_t n = strlen(a);
    int32_t m = strlen(b);
    int32_t a_is_dir = 0, b_is_dir = 0, diff = 0;
    while (diff < n && diff < m && a[diff] == b[diff]) diff++;
    for (int32_t i = diff; i < n; i++) {
        if (a[i] == '/') a_is_dir = 1;
    }
    for (int32_t i = diff; i < m; i++) {
        if (b[i] == '/') b_is_dir = 1;
    }
    if (a_is_dir && !b_is_dir) {
        return 0;
    }
    if (b_is_dir && !a_is_dir) {
        return 1;
    }
    if (strcmp(a, b) > 0) {
        return 1 ^ option;
    } else {
        return 0 ^ option;
    }
}

void substr(char* dest, const char* src, unsigned int start, unsigned int cnt) {
    strncpy(dest, src + start, cnt);
    dest[cnt] = 0;
}

int32_t main(int32_t argc, char* argv[]) {
    int32_t a = 0, c = 0, d = 0, reverse = 0;
    while ((c = getopt(argc, argv, "ad")) != -1) {
        switch (c) {
            case 'd':
                d = 1;
                break;
            case 'a':
                a = 1;
                break;
            case '?':
                break;
            default:
                printf("option: unknown\n");
                break;
        }
    }
    if (d == 1 && a == 1) {
        printf("Error\n");
        return 0;
    }
    if (d == 1) {
        reverse = 1;
    }
    char input[256] = {0};
    strncpy(input, argv[argc - 1], 256);
    FILE* pFile = NULL;
    if (strstr(input, ".zip") == NULL) {
        printf("This is not an zip file\n");
        return 0;
    }
    if ((pFile = fopen(input, "rb")) == NULL) {
        printf("file coule not be open\n");
        return 0;
    }

    int32_t num = 0;
    char** name = malloc(sizeof(char*));
    if (name == NULL) {
        fprintf(stderr, "Failed to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    int8_t read = 0;
    while (fread(&read, 1, 1, pFile) == 1) {
        if (read == 0x50) {
            if (fread(&read, 1, 1, pFile) != 1 || read != 0x4B) {
                continue;
            }
            if (fread(&read, 1, 1, pFile) != 1 || read != 0x01) {
                continue;
            }
            if (fread(&read, 1, 1, pFile) != 1 || read != 0x02) {
                continue;
            }

            char* filename = file_name(pFile);
            if (filename == NULL) {
                fprintf(stderr, "Failed to read filename.\n");
                exit(EXIT_FAILURE);
            }

            name[num++] = filename;

            char** new_name = realloc(name, (num + 1) * sizeof(char*));
            if (new_name == NULL) {
                fprintf(stderr, "Failed to reallocate memory.\n");
                exit(EXIT_FAILURE);
            }
            name = new_name;
        }
    }
    for (int32_t i = 0; i < num; i++) {
        for (int32_t j = i + 1; j < num; j++) {
            int32_t value = compare(name[i], name[j], reverse);
            if (value == 1) {
                char* tmp = name[i];
                name[i] = name[j];
                name[j] = tmp;
            }
        }
    }
    for(int32_t i=0;i<num;i++){
        if(name[i][strlen(name[i])-1]=='/'){
            if(i && strlen(name[i-1])>strlen(name[i])){
                char* cur = malloc(strlen(name[i]));
                char* oth = malloc(strlen(name[i]));
                substr(cur, name[i], 0, strlen(name[i]));
                substr(oth, name[i-1], 0, strlen(name[i]));
                if(strcmp(cur,oth)==0){
                    for(int32_t j=i;j+1<num;j++){
                        name[j]=name[j+1];
                    }
                    num--;
                    i--;
                }
                free(cur);
                free(oth);
            }
            if(i+1<num && strlen(name[i+1])>strlen(name[i])){
                char* cur = malloc(strlen(name[i]+1));
                char* oth = malloc(strlen(name[i]+1));
                substr(cur, name[i], 0, strlen(name[i]));
                substr(oth, name[i+1], 0, strlen(name[i]));
                if(strcmp(cur,oth)==0){
                    for(int32_t j=i;j+1<num;j++){
                        name[j]=name[j+1];
                    }
                    num--;
                    i--;
                }
                free(cur);
                free(oth);
            }
        }
    }
    for (int32_t i = 0; i < num; i++) {
        int32_t n = strlen(name[i]);
        for (int32_t j = 0; j < n; j++) {
            int32_t pre_same = 0;
            if (i) {
                int32_t cur_right_slash = j;
                int32_t pre_right_slash = j;
                while (name[i-1][pre_right_slash] != '/' && pre_right_slash < strlen(name[i - 1])) {
                    pre_right_slash++;
                }
                while (name[i][cur_right_slash] != '/' && cur_right_slash < strlen(name[i])) {
                    cur_right_slash++;
                }
                char* cur = malloc(pre_right_slash+1);
                char* pre = malloc(cur_right_slash+1);
                substr(cur, name[i - 1], 0, pre_right_slash);
                substr(pre, name[i], 0, cur_right_slash);
                if (strcmp(cur, pre) == 0) {
                    pre_same = 1;
                }
                free(cur);
                free(pre);
            }

            int32_t print_straight_line = 0;
            if (i + 1 < num) {
                int32_t pre_same = 1;
                for (int32_t k = 0; k < j; k++) {
                    if (name[i][k] != name[i + 1][k]) {
                        pre_same = 0;
                    }
                }

                for (int32_t k = i + 1; k < num; k++) {
                    int32_t cur_right_slash = j;
                    int32_t kth_right_slash = j;
                    while (name[i][cur_right_slash] != '/' && cur_right_slash < strlen(name[i])) {
                        cur_right_slash++;
                    }
                    while (name[k][kth_right_slash] != '/' && kth_right_slash < strlen(name[k])) {
                        kth_right_slash++;
                    }
                    char* cur = malloc(cur_right_slash+1);
                    char* suf = malloc(kth_right_slash+1);
                    substr(cur, name[k], 0, cur_right_slash);
                    substr(suf, name[i], 0, kth_right_slash);
                    if (pre_same && strcmp(cur, suf) != 0) {
                        print_straight_line = 1;
                    }
                    free(cur);
                    free(suf);
                }
            }

            if (!j || name[i][j - 1] == '/') {
                if (!pre_same) {
                    printf("+-- ");
                } else if (print_straight_line) {
                    printf("|   ");
                } else {
                    printf("    ");
                }
            }

            if (pre_same) {
                printf(" ");
            } else {
                printf("%c", name[i][j]);
            }

            if (name[i][j] == '/') {
                if (pre_same) {
                    printf("   ");
                } else {
                    printf(" --");
                }
            }
        }
        printf("\n");
        if (i == num - 1) break;
        for (int32_t j = 0; j < n; j++) {
            int32_t print_straight_line = 0;
            for (int32_t k = i + 1; k < num; k++) {
                int32_t cur_right_slash = j;
                int32_t kth_right_slash = j;
                while (name[i][cur_right_slash] != '/' && cur_right_slash < strlen(name[i])) {
                    cur_right_slash++;
                }
                while (name[k][kth_right_slash] != '/' && kth_right_slash < strlen(name[k])) {
                    kth_right_slash++;
                }
                char* cur = malloc(cur_right_slash+1);
                char* kth = malloc(kth_right_slash+1);
                substr(cur, name[i], 0, cur_right_slash);
                substr(kth, name[k], 0, kth_right_slash);
                int32_t pre_same = 1;
                if(strlen(name[k])<j) {
                    pre_same=0;
                }else{
                    for (int32_t l = 0; l < j; l++) {
                        if (name[i][l] != name[k][l]) {
                            pre_same = 0;
                        }
                    }
                }
                if (pre_same && strcmp(cur, kth) != 0) {
                    print_straight_line = 1;
                }
                free(cur);
                free(kth);
            }

            if (!j || name[i][j - 1] == '/') {
                if (print_straight_line) {
                    printf("|   ");
                    int32_t pre_same = 1;
                    for (int32_t k = 0; k < j; k++) {
                        if (name[i][k] != name[i + 1][k]) {
                            pre_same = 0;
                        }
                    }
                    int32_t suf_same = 1;
                    for (int32_t k = j; k < strlen(name[i]) && k < strlen(name[i + 1]) && name[i][k] != '/'; k++) {
                        if (name[i][k] != name[i + 1][k]) {
                            suf_same = 0;
                        }
                    }
                    if (pre_same && !suf_same) {
                        break;
                    }
                } else {
                    printf("    ");
                }
            }

            printf(" ");
            if (name[i][j] == '/') {
                printf("   ");
            }
        }
        printf("\n");
    }

    fclose(pFile);
    for (int32_t i = 0;i < num;i++) {
        free(name[i]);
    }
    free(name);
    return 0;
}