/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sha1.h>
#include <unistd.h>
#include <limits.h>

#include <sys/stat.h>

#include <netinet/in.h>
#include <resolv.h>

#include <cutils/dir_hash.h>

/**
 * Copies, if it fits within max_output_string bytes, into output_string
 * a hash of the contents, size, permissions, uid, and gid of the file
 * specified by path, using the specified algorithm.  Returns the length
 * of the output string, or a negative number if the buffer is too short.
 */
int get_file_hash(HashAlgorithm algorithm, const char *path,
                  char *output_string, size_t max_output_string) {
    SHA1_CTX context;
    struct stat sb;
    unsigned char md[SHA1_DIGEST_LENGTH];
    int used;
    size_t n;

    if (algorithm != SHA_1) {
        errno = EINVAL;
        return -1;
    }

    if (stat(path, &sb) != 0) {
        return -1;
    }

    if (S_ISLNK(sb.st_mode)) {
        char buf[PATH_MAX];
        int len;

        len = readlink(path, buf, sizeof(buf));
        if (len < 0) {
            return -1;
        }

        SHA1Init(&context);
        SHA1Update(&context, (unsigned char *) buf, len);
        SHA1Final(md, &context);
    } else if (S_ISREG(sb.st_mode)) {
        char buf[10000];
        FILE *f = fopen(path, "rb");
        int len;

        if (f == NULL) {
            return -1;
        }

        SHA1Init(&context);

        while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
            SHA1Update(&context, (unsigned char *) buf, len);
        }

        if (ferror(f)) {
            fclose(f);
            return -1;
        }

        fclose(f);
        SHA1Final(md, &context);
    }

    if (S_ISLNK(sb.st_mode) || S_ISREG(sb.st_mode)) {
        used = b64_ntop(md, SHA1_DIGEST_LENGTH,
                        output_string, max_output_string);
        if (used < 0) {
            errno = ENOSPC;
            return -1;
        }

        n = snprintf(output_string + used, max_output_string - used,
                     " %d 0%o %d %d", (int) sb.st_size, sb.st_mode,
                     (int) sb.st_uid, (int) sb.st_gid);
    } else {
        n = snprintf(output_string, max_output_string,
                     "- - 0%o %d %d", sb.st_mode,
                     (int) sb.st_uid, (int) sb.st_gid);
    }

    if (n >= max_output_string - used) {
        errno = ENOSPC;
        return -(used + n);
    }

    return used + n;
}

struct list {
    char *name;
    struct list *next;
};

static int cmp(const void *a, const void *b) {
    struct list *const *ra = a;
    struct list *const *rb = b;

    return strcmp((*ra)->name, (*rb)->name);
}

static int recurse(HashAlgorithm algorithm, const char *directory_path,
                    struct list **out) {
    struct list *list = NULL;
    struct list *f;

    struct dirent *de;
    DIR *d = opendir(directory_path);

    if (d == NULL) {
        return -1;
    }

    while ((de = readdir(d)) != NULL) {
        if (strcmp(de->d_name, ".") == 0) {
            continue;
        }
        if (strcmp(de->d_name, "..") == 0) {
            continue;
        }

        char *name = malloc(strlen(de->d_name) + 1);
        struct list *node = malloc(sizeof(struct list));

        if (name == NULL || node == NULL) {
            struct list *next;
            for (f = list; f != NULL; f = next) {
                next = f->next;
                free(f->name);
                free(f);
            }

            free(name);
            free(node);
            closedir(d);
            return -1;
        }

        strcpy(name, de->d_name);

        node->name = name;
        node->next = list;
        list = node;
    }

    closedir(d);

    for (f = list; f != NULL; f = f->next) {
        struct stat sb;
        char *name;
        char outstr[NAME_MAX + 100];
        char *keep;
        struct list *res;

        name = malloc(strlen(f->name) + strlen(directory_path) + 2);
        if (name == NULL) {
            struct list *next;
            for (f = list; f != NULL; f = f->next) {
                next = f->next;
                free(f->name);
                free(f);
            }
            for (f = *out; f != NULL; f = f->next) {
                next = f->next;
                free(f->name);
                free(f);
            }
            *out = NULL;
            return -1;
        }

        sprintf(name, "%s/%s", directory_path, f->name);

        int len = get_file_hash(algorithm, name,
                                outstr, sizeof(outstr));
        if (len < 0) {
            // should not happen
            return -1;
        }

        keep = malloc(len + strlen(name) + 3);
        res = malloc(sizeof(struct list));

        if (keep == NULL || res == NULL) {
            struct list *next;
            for (f = list; f != NULL; f = f->next) {
                next = f->next;
                free(f->name);
                free(f);
            }
            for (f = *out; f != NULL; f = f->next) {
                next = f->next;
                free(f->name);
                free(f);
            }
            *out = NULL;

            free(keep);
            free(res);
            return -1;
        }

        sprintf(keep, "%s %s\n", name, outstr);

        res->name = keep;
        res->next = *out;
        *out = res;

        if ((stat(name, &sb) == 0) && S_ISDIR(sb.st_mode)) {
            if (recurse(algorithm, name, out) < 0) {
                struct list *next;
                for (f = list; f != NULL; f = next) {
                    next = f->next;
                    free(f->name);
                    free(f);
                }

                return -1;
            }
        }
    }

    struct list *next;
    for (f = list; f != NULL; f = next) {
        next = f->next;

        free(f->name);
        free(f);
    }
}

/**
 * Allocates a string containing the names and hashes of all files recursively
 * reached under the specified directory_path, using the specified algorithm.
 * The string is returned as *output_string; the return value is the length
 * of the string, or a negative number if there was a failure.
 */
int get_recursive_hash_manifest(HashAlgorithm algorithm,
                                const char *directory_path,
                                char **output_string) {
    struct list *out = NULL;
    struct list *r;
    struct list **list;
    int count = 0;
    int len = 0;
    int retlen = 0;
    int i;
    char *buf;
    
    if (recurse(algorithm, directory_path, &out) < 0) {
        return -1;
    }

    for (r = out; r != NULL; r = r->next) {
        count++;
        len += strlen(r->name);
    }

    list = malloc(count * sizeof(struct list *));
    if (list == NULL) {
        struct list *next;
        for (r = out; r != NULL; r = next) {
            next = r->next;
            free(r->name);
            free(r);
        }
        return -1;
    }

    count = 0;
    for (r = out; r != NULL; r = r->next) {
        list[count++] = r;
    }

    qsort(list, count, sizeof(struct list *), cmp);

    buf = malloc(len + 1);
    if (buf == NULL) {
        struct list *next;
        for (r = out; r != NULL; r = next) {
            next = r->next;
            free(r->name);
            free(r);
        }
        free(list);
        return -1;
    }

    for (i = 0; i < count; i++) {
        int n = strlen(list[i]->name);

        strcpy(buf + retlen, list[i]->name);
        retlen += n;
    }

    free(list);

    struct list *next;
    for (r = out; r != NULL; r = next) {
        next = r->next;

        free(r->name);
        free(r);
    }

    *output_string = buf;
    return retlen;
}
