/*
 * Copyright (C) 2012 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.
 */

#define LOG_TAG "cutils"

/* These defines are only needed because prebuilt headers are out of date */
#define __USE_XOPEN2K8 1
#define _ATFILE_SOURCE 1
#define _GNU_SOURCE 1

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cutils/fs.h>
#include <log/log.h>

#define ALL_PERMS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
#define BUF_SIZE 64

static int fs_prepare_path_impl(const char* path, mode_t mode, uid_t uid, gid_t gid,
        int allow_fixup, int prepare_as_dir) {
    // Check if path needs to be created
    struct stat sb;
    int create_result = -1;
    if (TEMP_FAILURE_RETRY(lstat(path, &sb)) == -1) {
        if (errno == ENOENT) {
            goto create;
        } else {
            ALOGE("Failed to lstat(%s): %s", path, strerror(errno));
            return -1;
        }
    }

    // Exists, verify status
    int type_ok = prepare_as_dir ? S_ISDIR(sb.st_mode) : S_ISREG(sb.st_mode);
    if (!type_ok) {
        ALOGE("Not a %s: %s", (prepare_as_dir ? "directory" : "regular file"), path);
        return -1;
    }

    int owner_match = ((sb.st_uid == uid) && (sb.st_gid == gid));
    int mode_match = ((sb.st_mode & ALL_PERMS) == mode);
    if (owner_match && mode_match) {
        return 0;
    } else if (allow_fixup) {
        goto fixup;
    } else {
        if (!owner_match) {
            ALOGE("Expected path %s with owner %d:%d but found %d:%d",
                    path, uid, gid, sb.st_uid, sb.st_gid);
            return -1;
        } else {
            ALOGW("Expected path %s with mode %o but found %o",
                    path, mode, (sb.st_mode & ALL_PERMS));
            return 0;
        }
    }

create:
    create_result = prepare_as_dir
        ? TEMP_FAILURE_RETRY(mkdir(path, mode))
        : TEMP_FAILURE_RETRY(open(path, O_CREAT | O_CLOEXEC | O_NOFOLLOW | O_RDONLY, 0644));
    if (create_result == -1) {
        if (errno != EEXIST) {
            ALOGE("Failed to %s(%s): %s",
                    (prepare_as_dir ? "mkdir" : "open"), path, strerror(errno));
            return -1;
        }
    } else if (!prepare_as_dir) {
        // For regular files we need to make sure we close the descriptor
        if (close(create_result) == -1) {
            ALOGW("Failed to close file after create %s: %s", path, strerror(errno));
        }
    }
fixup:
    if (TEMP_FAILURE_RETRY(chmod(path, mode)) == -1) {
        ALOGE("Failed to chmod(%s, %d): %s", path, mode, strerror(errno));
        return -1;
    }
    if (TEMP_FAILURE_RETRY(chown(path, uid, gid)) == -1) {
        ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno));
        return -1;
    }

    return 0;
}

int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) {
    return fs_prepare_path_impl(path, mode, uid, gid, /*allow_fixup*/ 1, /*prepare_as_dir*/ 1);
}

int fs_prepare_dir_strict(const char* path, mode_t mode, uid_t uid, gid_t gid) {
    return fs_prepare_path_impl(path, mode, uid, gid, /*allow_fixup*/ 0, /*prepare_as_dir*/ 1);
}

int fs_prepare_file_strict(const char* path, mode_t mode, uid_t uid, gid_t gid) {
    return fs_prepare_path_impl(path, mode, uid, gid, /*allow_fixup*/ 0, /*prepare_as_dir*/ 0);
}

int fs_read_atomic_int(const char* path, int* out_value) {
    int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY));
    if (fd == -1) {
        ALOGE("Failed to read %s: %s", path, strerror(errno));
        return -1;
    }

    char buf[BUF_SIZE];
    if (TEMP_FAILURE_RETRY(read(fd, buf, BUF_SIZE)) == -1) {
        ALOGE("Failed to read %s: %s", path, strerror(errno));
        goto fail;
    }
    if (sscanf(buf, "%d", out_value) != 1) {
        ALOGE("Failed to parse %s: %s", path, strerror(errno));
        goto fail;
    }
    close(fd);
    return 0;

fail:
    close(fd);
    *out_value = -1;
    return -1;
}

int fs_write_atomic_int(const char* path, int value) {
    char temp[PATH_MAX];
    if (snprintf(temp, PATH_MAX, "%s.XXXXXX", path) >= PATH_MAX) {
        ALOGE("Path too long");
        return -1;
    }

    int fd = TEMP_FAILURE_RETRY(mkstemp(temp));
    if (fd == -1) {
        ALOGE("Failed to open %s: %s", temp, strerror(errno));
        return -1;
    }

    char buf[BUF_SIZE];
    int len = snprintf(buf, BUF_SIZE, "%d", value) + 1;
    if (len > BUF_SIZE) {
        ALOGE("Value %d too large: %s", value, strerror(errno));
        goto fail;
    }
    if (TEMP_FAILURE_RETRY(write(fd, buf, len)) < len) {
        ALOGE("Failed to write %s: %s", temp, strerror(errno));
        goto fail;
    }
    if (close(fd) == -1) {
        ALOGE("Failed to close %s: %s", temp, strerror(errno));
        goto fail_closed;
    }

    if (rename(temp, path) == -1) {
        ALOGE("Failed to rename %s to %s: %s", temp, path, strerror(errno));
        goto fail_closed;
    }

    return 0;

fail:
    close(fd);
fail_closed:
    unlink(temp);
    return -1;
}

#ifndef __APPLE__

int fs_mkdirs(const char* path, mode_t mode) {
    int res = 0;
    int fd = 0;
    struct stat sb;
    char* buf = strdup(path);

    if (*buf != '/') {
        ALOGE("Relative paths are not allowed: %s", buf);
        res = -EINVAL;
        goto done;
    }

    if ((fd = open("/", 0)) == -1) {
        ALOGE("Failed to open(/): %s", strerror(errno));
        res = -errno;
        goto done;
    }

    char* segment = buf + 1;
    char* p = segment;
    while (*p != '\0') {
        if (*p == '/') {
            *p = '\0';

            if (!strcmp(segment, "..") || !strcmp(segment, ".") || !strcmp(segment, "")) {
                ALOGE("Invalid path: %s", buf);
                res = -EINVAL;
                goto done_close;
            }

            if (fstatat(fd, segment, &sb, AT_SYMLINK_NOFOLLOW) != 0) {
                if (errno == ENOENT) {
                    /* Nothing there yet; let's create it! */
                    if (mkdirat(fd, segment, mode) != 0) {
                        if (errno == EEXIST) {
                            /* We raced with someone; ignore */
                        } else {
                            ALOGE("Failed to mkdirat(%s): %s", buf, strerror(errno));
                            res = -errno;
                            goto done_close;
                        }
                    }
                } else {
                    ALOGE("Failed to fstatat(%s): %s", buf, strerror(errno));
                    res = -errno;
                    goto done_close;
                }
            } else {
                if (S_ISLNK(sb.st_mode)) {
                    ALOGE("Symbolic links are not allowed: %s", buf);
                    res = -ELOOP;
                    goto done_close;
                }
                if (!S_ISDIR(sb.st_mode)) {
                    ALOGE("Existing segment not a directory: %s", buf);
                    res = -ENOTDIR;
                    goto done_close;
                }
            }

            /* Yay, segment is ready for us to step into */
            int next_fd;
            if ((next_fd = openat(fd, segment, O_NOFOLLOW | O_CLOEXEC)) == -1) {
                ALOGE("Failed to openat(%s): %s", buf, strerror(errno));
                res = -errno;
                goto done_close;
            }

            close(fd);
            fd = next_fd;

            *p = '/';
            segment = p + 1;
        }
        p++;
    }

done_close:
    close(fd);
done:
    free(buf);
    return res;
}

#endif
