Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
7.8 kB
6
Indexable
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// �w�q�@���ɮ׵��c��
typedef struct {
    char* filename;  // �ɮצW��
    int 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;
}

int compare(char* a, char* b, int32_t option) {
    int n = strlen(a);
    int m = strlen(b);
    int a_is_dir = 0, b_is_dir = 0, diff = 0;
    while (diff < n && diff < m && a[diff] == b[diff]) diff++;
    for (int i = diff; i < n; i++)
        if (a[i] == '/') a_is_dir = 1;
    for (int 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;
}

int main(int argc, char* argv[]) {
    int32_t a = 0, c = 0, d = 0, reverse = 0;
    // int8_t 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;
    }

    int 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);
            }

            if (filename[strlen(filename) - 1] == '/') continue;

            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++) {
            int value = compare(name[i], name[j], reverse);
            if (value == 1) {
                char* tmp = name[i];
                name[i] = name[j];
                name[j] = tmp;
            }
        }
    }
    for (int i = 0; i < num; i++) printf("%s\n", name[i]);
    // return 0;
    for (int32_t i = 0; i < num; i++) {
        int n = strlen(name[i]);
        for (int j = 0; j < n; j++) {
            int pre_same = 0;
            if (i) {
                int cur_right_slash = j;
                int pre_right_slash = j;
                while (name[i][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);
                char* pre = malloc(cur_right_slash);
                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;
            }

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

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

            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 (int j = 0; j < n; j++) {
            int print_straight_line = 0;
            for (int k = i + 1; k < num; k++) {
                int cur_right_slash = j;
                int suf_right_slash = j;
                while (name[i][cur_right_slash] != '/' && cur_right_slash < strlen(name[k])) cur_right_slash++;
                while (name[i][suf_right_slash] != '/' && suf_right_slash < strlen(name[i])) suf_right_slash++;
                char* cur = malloc(cur_right_slash);
                char* suf = malloc(suf_right_slash);
                substr(cur, name[k], 0, cur_right_slash);
                substr(suf, name[i], 0, suf_right_slash);
                int pre_same = 1;
                for (int l = 0; l < j && l < strlen(name[k]); l++)
                    if (name[i][l] != name[k][l]) pre_same = 0;

                if (pre_same && strcmp(cur, suf) != 0) print_straight_line = 1;
            }

            if (!j || name[i][j - 1] == '/') {
                if (print_straight_line) {
                    printf("|   ");
                    int pre_same = 1;
                    for (int k = 0; k < j; k++)
                        if (name[i][k] != name[i + 1][k]) pre_same = 0;
                    int suf_same = 1;
                    for (int 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);
    return 0;
}