19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <errno.h>
1852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <fcntl.h>
1952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <limits.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
2352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <sys/resource.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
26efd13938013099e58f4dcbf818f508c585547817Dan Egnor#include <sys/wait.h>
2752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <unistd.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include <cutils/properties.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#include "private/android_filesystem_config.h"
32f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato
33bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood#define LOG_TAG "dumpstate"
34bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood#include <utils/Log.h>
35bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "dumpstate.h"
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor/* read before root is shed */
3952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic char cmdline_buf[16384] = "(unknown)";
4052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic const char *dump_traces_path = NULL;
4130b9f57c8b2c1e3d0b3d2668ad04980ea0050d04San Mehat
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* dumps the current system state to stdout */
4352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic void dumpstate() {
4452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    time_t now = time(NULL);
4552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
4652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
4752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char network[PROPERTY_VALUE_MAX], date[80];
4852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
4952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.build.display.id", build, "(unknown)");
5052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.build.fingerprint", fingerprint, "(unknown)");
5152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.baseband", radio, "(unknown)");
5252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("ro.bootloader", bootloader, "(unknown)");
5352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("gsm.operator.alpha", network, "(unknown)");
5452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
5552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
5652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
5752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("== dumpstate: %s\n", date);
5852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
5952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
6052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("\n");
6152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Build: %s\n", build);
6252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Bootloader: %s\n", bootloader);
6352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Radio: %s\n", radio);
6452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Network: %s\n", network);
6552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
6652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Kernel: ");
6752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/proc/version");
6852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
6952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("\n");
7052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
7152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("MEMORY INFO", "/proc/meminfo");
7252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
7352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("PROCRANK", 20, "procrank", NULL);
7452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
7552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("VMALLOC INFO", "/proc/vmallocinfo");
7652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("SLAB INFO", "/proc/slabinfo");
7752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("ZONEINFO", "/proc/zoneinfo");
7852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
7952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("SYSTEM LOG", 20, "logcat", "-v", "time", "-d", "*:v", NULL);
8052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
8152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* show the traces we collected in main(), if that was done */
8252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (dump_traces_path != NULL) {
8352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        dump_file("VM TRACES JUST NOW", dump_traces_path);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
8652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* only show ANR traces if they're less than 15 minutes old */
8752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    struct stat st;
8852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char anr_traces_path[PATH_MAX];
8952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
90efd13938013099e58f4dcbf818f508c585547817Dan Egnor    if (!anr_traces_path[0]) {
91efd13938013099e58f4dcbf818f508c585547817Dan Egnor        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
92efd13938013099e58f4dcbf818f508c585547817Dan Egnor    } else if (stat(anr_traces_path, &st)) {
93efd13938013099e58f4dcbf818f508c585547817Dan Egnor        printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
94efd13938013099e58f4dcbf818f508c585547817Dan Egnor    } else {
9552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        dump_file("VM TRACES AT LAST ANR", anr_traces_path);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
9952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "time", "-d", "*:v", NULL);
10052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "time", "-d", "*:v", NULL);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("NETWORK INTERFACES", 10, "netcfg", NULL);
10352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("NETWORK ROUTES", "/proc/net/route");
10484b72ec3b455a016fcb7a7c8d02959fc6b5b88d2Dmitry Shmidt    dump_file("ARP CACHE", "/proc/net/arp");
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#ifdef FWDUMP_bcm4329
10752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("DUMP WIFI FIRMWARE LOG", 60,
108c277f2c43dfae5d28c345663fa7b970dd5bc383eDmitry Shmidt            "su", "root", "dhdutil", "-i", "eth0", "upload", "/data/local/tmp/wlan_crash.dump", NULL);
10952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor#endif
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    print_properties();
11252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
11352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("KERNEL LOG", 20, "dmesg", NULL);
11452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
11552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
11652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
11752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
1189e3f8c631e8406d905e79523ab8853324cc02abcSan Mehat    run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
11954aa577ea28999de2f30bc34daed0cc821934409San Mehat    run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
12054aa577ea28999de2f30bc34daed0cc821934409San Mehat
12152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("PROCESSES", 10, "ps", "-P", NULL);
12252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
12352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("LIBRANK", 10, "librank", NULL);
12452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
12552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER FAILED TRANSACTION LOG", "/proc/binder/failed_transaction_log");
12652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER TRANSACTION LOG", "/proc/binder/transaction_log");
12752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER TRANSACTIONS", "/proc/binder/transactions");
12852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("BINDER STATS", "/proc/binder/stats");
12952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("BINDER PROCESS STATE", 10, "sh", "-c", "cat /proc/binder/proc/*");
13052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
13152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
13252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
13352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
13452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
13552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
13652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("LAST KMSG", "/proc/last_kmsg");
13752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
13852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
13952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
14052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
14157fff78a70c82ca09beb91c4f92d97b6f0b897e4San Mehat    for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
14257fff78a70c82ca09beb91c4f92d97b6f0b897e4San Mehat
143ea11654e684cb91252487f697c72e76da507f7beDan Egnor    printf("------ BACKLIGHTS ------\n");
14452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("LCD brightness=");
14552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
14652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Button brightness=");
14752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
14852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("Keyboard brightness=");
14952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
15052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("ALS mode=");
15152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
15252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("LCD driver registers:\n");
15352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
15452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("\n");
15552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
15652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
15752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("== Android Framework Services\n");
15852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    printf("========================================================\n");
15952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
16052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* the full dumpsys is starting to take a long time, so we need
16152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor       to increase its timeout.  we really need to do the timeouts in
16252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor       dumpsys itself... */
16352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    run_command("DUMPSYS", 60, "dumpsys", NULL);
16452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor}
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnorstatic void usage() {
16752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    fprintf(stderr, "usage: dumpstate [-d] [-o file] [-s] [-z]\n"
16852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -d: append date to filename (requires -o)\n"
16952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -o: write to file (instead of stdout)\n"
17052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -s: write output to control socket (for init)\n"
17152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            "  -z: gzip output (requires -o)\n");
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint main(int argc, char *argv[]) {
17552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int do_add_date = 0;
17652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int do_compress = 0;
17752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char* use_outfile = 0;
17852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int use_socket = 0;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
180bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood    LOGI("begin\n");
181bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* set as high priority, and protect from OOM killer */
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setpriority(PRIO_PROCESS, 0, -20);
18452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
18552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (oom_adj) {
18652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fputs("-17", oom_adj);
18752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(oom_adj);
18852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* very first thing, collect VM traces from Dalvik (needs root) */
19152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dump_traces_path = dump_vm_traces();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    int c;
19452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    while ((c = getopt(argc, argv, "dho:svz")) != -1) {
1958d5337301b87ba84a45327f355aa768c864de021Mike Lockwood        switch (c) {
19652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'd': do_add_date = 1;       break;
19752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'o': use_outfile = optarg;  break;
19852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 's': use_socket = 1;        break;
19952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'v': break;  // compatibility no-op
20052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'z': do_compress = 6;       break;
20152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case '?': printf("\n");
20252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            case 'h':
20352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor                usage();
2048d5337301b87ba84a45327f355aa768c864de021Mike Lockwood                exit(1);
2058d5337301b87ba84a45327f355aa768c864de021Mike Lockwood        }
20652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* open the vibrator before dropping root */
20952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    FILE *vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
21052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
21152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
21252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* read /proc/cmdline before dropping root */
21352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    FILE *cmdline = fopen("/proc/cmdline", "r");
21452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (cmdline != NULL) {
21552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
21652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(cmdline);
21752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* switch to non-root user and group */
22054aa577ea28999de2f30bc34daed0cc821934409San Mehat    gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
221472be48007f8c3a9b462b8c9024cb4a0a0beac04Mike Lockwood    setgroups(sizeof(groups)/sizeof(groups[0]), groups);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setuid(AID_SHELL);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    char path[PATH_MAX], tmp_path[PATH_MAX];
22552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    pid_t gzip_pid = -1;
22652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
22752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (use_socket) {
22852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        redirect_to_socket(stdout, "dumpstate");
22952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    } else if (use_outfile) {
23052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcpy(path, use_outfile, sizeof(path));
23152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        if (do_add_date) {
23252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            char date[80];
23352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            time_t now = time(NULL);
23452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", localtime(&now));
23552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            strlcat(path, date, sizeof(path));
2368d5337301b87ba84a45327f355aa768c864de021Mike Lockwood        }
23752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcat(path, ".txt", sizeof(path));
23852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        if (do_compress) strlcat(path, ".gz", sizeof(path));
23952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcpy(tmp_path, path, sizeof(tmp_path));
24052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        strlcat(tmp_path, ".tmp", sizeof(tmp_path));
24152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        gzip_pid = redirect_to_file(stdout, tmp_path, do_compress);
24252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2438d5337301b87ba84a45327f355aa768c864de021Mike Lockwood
24452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* bzzzzzz */
24552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (vibrator) {
24652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fputs("150", vibrator);
24752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fflush(vibrator);
24852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2498d5337301b87ba84a45327f355aa768c864de021Mike Lockwood
25052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    dumpstate();
25152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor
25252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* bzzz bzzz bzzz */
25352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (vibrator) {
25452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        int i;
25552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        for (i = 0; i < 3; i++) {
25652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            fputs("75\n", vibrator);
25752952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            fflush(vibrator);
25852952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor            usleep((75 + 50) * 1000);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
26052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(vibrator);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26352952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* wait for gzip to finish, otherwise it might get killed when we exit */
26452952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (gzip_pid > 0) {
26552952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fclose(stdout);
26652952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        waitpid(gzip_pid, NULL, 0);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26952952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    /* rename the (now complete) .tmp file to its final location */
27052952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    if (use_outfile && rename(tmp_path, path)) {
27152952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor        fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
27252952b1bcab28f655775efbad8f2e2b41d06a34bDan Egnor    }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
274bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood    LOGI("done\n");
275bb6fa17558ff9212a48bd4be24aef235814b944eMike Lockwood
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
278