/*
 * Copyright (C) 2008 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 <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/klog.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "private/android_filesystem_config.h"

// Sentinel file used to track whether we've forced a reboot
static const char *kMarkerFile = "/data/misc/check-lost+found-rebooted-2";

// Output file in tombstones directory (first 8K will be uploaded)
static const char *kOutputDir = "/data/tombstones";
static const char *kOutputFile = "/data/tombstones/check-lost+found-log";

// Partitions to check
static const char *kPartitions[] = { "/system", "/data", "/cache", NULL };

/*
 * 1. If /data/misc/forced-reboot is missing, touch it & force "unclean" boot.
 * 2. Write a log entry with the number of files in lost+found directories.
 */

int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) {
    mkdir(kOutputDir, 0755);
    chown(kOutputDir, AID_SYSTEM, AID_SYSTEM);
    FILE *out = fopen(kOutputFile, "a");
    if (out == NULL) {
        fprintf(stderr, "Can't write %s: %s\n", kOutputFile, strerror(errno));
        return 1;
    }

    // Note: only the first 8K of log will be uploaded, so be terse.
    time_t start = time(NULL);
    fprintf(out, "*** check-lost+found ***\nStarted: %s", ctime(&start));

    struct stat st;
    if (stat(kMarkerFile, &st)) {
        // No reboot marker -- need to force an unclean reboot.
        // But first, try to create the marker file.  If that fails,
        // skip the reboot, so we don't get caught in an infinite loop.

        int fd = open(kMarkerFile, O_WRONLY|O_CREAT, 0444);
        if (fd >= 0 && close(fd) == 0) {
            fprintf(out, "Wrote %s, rebooting\n", kMarkerFile);
            fflush(out);
            sync();  // Make sure the marker file is committed to disk

            // If possible, dirty each of these partitions before rebooting,
            // to make sure the filesystem has to do a scan on mount.
            int i;
            for (i = 0; kPartitions[i] != NULL; ++i) {
                char fn[PATH_MAX];
                snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "dirty");
                fd = open(fn, O_WRONLY|O_CREAT, 0444);
                if (fd >= 0) {  // Don't sweat it if we can't write the file.
                    TEMP_FAILURE_RETRY(write(fd, fn, sizeof(fn)));  // write, you know, some data
                    close(fd);
                    unlink(fn);
                }
            }

            reboot(RB_AUTOBOOT);  // reboot immediately, with dirty filesystems
            fprintf(out, "Reboot failed?!\n");
            exit(1);
        } else {
            fprintf(out, "Can't write %s: %s\n", kMarkerFile, strerror(errno));
        }
    } else {
        fprintf(out, "Found %s\n", kMarkerFile);
    }

    int i;
    for (i = 0; kPartitions[i] != NULL; ++i) {
        char fn[PATH_MAX];
        snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "lost+found");
        DIR *dir = opendir(fn);
        if (dir == NULL) {
            fprintf(out, "Can't open %s: %s\n", fn, strerror(errno));
        } else {
            int count = 0;
            struct dirent *ent;
            while ((ent = readdir(dir))) {
                if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
                    ++count;
            }
            closedir(dir);
            if (count > 0) {
                fprintf(out, "OMGZ FOUND %d FILES IN %s\n", count, fn);
            } else {
                fprintf(out, "%s is clean\n", fn);
            }
        }
    }

    char dmesg[131073];
    int len = klogctl(KLOG_READ_ALL, dmesg, sizeof(dmesg) - 1);
    if (len < 0) {
        fprintf(out, "Can't read kernel log: %s\n", strerror(errno));
    } else {  // To conserve space, only write lines with certain keywords
        fprintf(out, "--- Kernel log ---\n");
        dmesg[len] = '\0';
        char *saveptr, *line;
        int in_yaffs = 0;
        for (line = strtok_r(dmesg, "\n", &saveptr); line != NULL;
             line = strtok_r(NULL, "\n", &saveptr)) {
            if (strstr(line, "yaffs: dev is")) in_yaffs = 1;

            if (in_yaffs ||
                    strstr(line, "yaffs") ||
                    strstr(line, "mtd") ||
                    strstr(line, "msm_nand")) {
                fprintf(out, "%s\n", line);
            }

            if (strstr(line, "yaffs_read_super: isCheckpointed")) in_yaffs = 0;
        }
    }

    return 0;
}
