/*
 * 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <limits.h>

#include "DirUtil.h"

typedef enum { DMISSING, DDIR, DILLEGAL } DirStatus;

static DirStatus
getPathDirStatus(const char *path)
{
    struct stat st;
    int err;

    err = stat(path, &st);
    if (err == 0) {
        /* Something's there; make sure it's a directory.
         */
        if (S_ISDIR(st.st_mode)) {
            return DDIR;
        }
        errno = ENOTDIR;
        return DILLEGAL;
    } else if (errno != ENOENT) {
        /* Something went wrong, or something in the path
         * is bad.  Can't do anything in this situation.
         */
        return DILLEGAL;
    }
    return DMISSING;
}

int
dirCreateHierarchy(const char *path, int mode,
        const struct utimbuf *timestamp, bool stripFileName,
        struct selabel_handle *sehnd)
{
    DirStatus ds;

    /* Check for an empty string before we bother
     * making any syscalls.
     */
    if (path[0] == '\0') {
        errno = ENOENT;
        return -1;
    }

    /* Allocate a path that we can modify; stick a slash on
     * the end to make things easier.
     */
    size_t pathLen = strlen(path);
    char *cpath = (char *)malloc(pathLen + 2);
    if (cpath == NULL) {
        errno = ENOMEM;
        return -1;
    }
    memcpy(cpath, path, pathLen);
    if (stripFileName) {
        /* Strip everything after the last slash.
         */
        char *c = cpath + pathLen - 1;
        while (c != cpath && *c != '/') {
            c--;
        }
        if (c == cpath) {
//xxx test this path
            /* No directory component.  Act like the path was empty.
             */
            errno = ENOENT;
            free(cpath);
            return -1;
        }
        c[1] = '\0';    // Terminate after the slash we found.
    } else {
        /* Make sure that the path ends in a slash.
         */
        cpath[pathLen] = '/';
        cpath[pathLen + 1] = '\0';
    }

    /* See if it already exists.
     */
    ds = getPathDirStatus(cpath);
    if (ds == DDIR) {
        return 0;
    } else if (ds == DILLEGAL) {
        return -1;
    }

    /* Walk up the path from the root and make each level.
     * If a directory already exists, no big deal.
     */
    char *p = cpath;
    while (*p != '\0') {
        /* Skip any slashes, watching out for the end of the string.
         */
        while (*p != '\0' && *p == '/') {
            p++;
        }
        if (*p == '\0') {
            break;
        }

        /* Find the end of the next path component.
         * We know that we'll see a slash before the NUL,
         * because we added it, above.
         */
        while (*p != '/') {
            p++;
        }
        *p = '\0';

        /* Check this part of the path and make a new directory
         * if necessary.
         */
        ds = getPathDirStatus(cpath);
        if (ds == DILLEGAL) {
            /* Could happen if some other process/thread is
             * messing with the filesystem.
             */
            free(cpath);
            return -1;
        } else if (ds == DMISSING) {
            int err;

#ifdef HAVE_SELINUX
            char *secontext = NULL;

            if (sehnd) {
                selabel_lookup(sehnd, &secontext, cpath, mode);
                setfscreatecon(secontext);
            }
#endif

            err = mkdir(cpath, mode);

#ifdef HAVE_SELINUX

            if (secontext) {
                freecon(secontext);
                setfscreatecon(NULL);
            }
#endif

            if (err != 0) {
                free(cpath);
                return -1;
            }
            if (timestamp != NULL && utime(cpath, timestamp)) {
                free(cpath);
                return -1;
            }
        }
        // else, this directory already exists.
        
        /* Repair the path and continue.
         */
        *p = '/';
    }
    free(cpath);

    return 0;
}

int
dirUnlinkHierarchy(const char *path)
{
    struct stat st;
    DIR *dir;
    struct dirent *de;
    int fail = 0;

    /* is it a file or directory? */
    if (lstat(path, &st) < 0) {
        return -1;
    }

    /* a file, so unlink it */
    if (!S_ISDIR(st.st_mode)) {
        return unlink(path);
    }

    /* a directory, so open handle */
    dir = opendir(path);
    if (dir == NULL) {
        return -1;
    }

    /* recurse over components */
    errno = 0;
    while ((de = readdir(dir)) != NULL) {
//TODO: don't blow the stack
        char dn[PATH_MAX];
        if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
            continue;
        }
        snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
        if (dirUnlinkHierarchy(dn) < 0) {
            fail = 1;
            break;
        }
        errno = 0;
    }
    /* in case readdir or unlink_recursive failed */
    if (fail || errno < 0) {
        int save = errno;
        closedir(dir);
        errno = save;
        return -1;
    }

    /* close directory handle */
    if (closedir(dir) < 0) {
        return -1;
    }

    /* delete target directory */
    return rmdir(path);
}

int
dirSetHierarchyPermissions(const char *path,
        int uid, int gid, int dirMode, int fileMode)
{
    struct stat st;
    if (lstat(path, &st)) {
        return -1;
    }

    /* ignore symlinks */
    if (S_ISLNK(st.st_mode)) {
        return 0;
    }

    /* directories and files get different permissions */
    if (chown(path, uid, gid) ||
        chmod(path, S_ISDIR(st.st_mode) ? dirMode : fileMode)) {
        return -1;
    }

    /* recurse over directory components */
    if (S_ISDIR(st.st_mode)) {
        DIR *dir = opendir(path);
        if (dir == NULL) {
            return -1;
        }

        errno = 0;
        const struct dirent *de;
        while (errno == 0 && (de = readdir(dir)) != NULL) {
            if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
                continue;
            }

            char dn[PATH_MAX];
            snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
            if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode)) {
                errno = 0;
            } else if (errno == 0) {
                errno = -1;
            }
        }

        if (errno != 0) {
            int save = errno;
            closedir(dir);
            errno = save;
            return -1;
        }

        if (closedir(dir)) {
            return -1;
        }
    }

    return 0;
}
