Exemple #1
0
int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) {
    int fd;
    const char *args[11];
    int rc;
    int status;

    if (wipe) {
        Fat::wipe(fsPath, numSectors);
    }

    args[0] = MKDOSFS_PATH;
    args[1] = "-F";
    args[2] = "32";
    args[3] = "-O";
    args[4] = "android";
    args[5] = "-c";
    args[6] = "64";
    args[7] = "-A";

    if (numSectors) {
        char tmp[32];
        snprintf(tmp, sizeof(tmp), "%u", numSectors);
        const char *size = tmp;
        args[8] = "-s";
        args[9] = size;
        args[10] = fsPath;
        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
                false, true);
    } else {
        args[8] = fsPath;
        rc = android_fork_execvp(9, (char **)args, &status, false,
                true);
    }

    if (rc != 0) {
        SLOGE("Filesystem format failed due to logwrap error");
        errno = EIO;
        return -1;
    }

    if (!WIFEXITED(status)) {
        SLOGE("Filesystem format did not exit properly");
        errno = EIO;
        return -1;
    }

    status = WEXITSTATUS(status);

    if (status == 0) {
        SLOGI("Filesystem formatted OK");
        return 0;
    } else {
        SLOGE("Format failed (unknown exit code %d)", status);
        errno = EIO;
        return -1;
    }
    return 0;
}
Exemple #2
0
int Exfat::format(const char *fsPath) {

    int fd;
    const char *args[3];
    int rc = -1;
    int status;

    if (access(EXFAT_MKFS, X_OK)) {
        SLOGE("Unable to format, mkexfatfs not found.");
        return -1;
    }

    args[0] = EXFAT_MKFS;
    args[1] = fsPath;
    args[2] = NULL;

    rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
            true);

    if (rc == 0) {
        SLOGI("Filesystem (exFAT) formatted OK");
        return 0;
    } else {
        SLOGE("Format (exFAT) failed (unknown exit code %d)", rc);
        errno = EIO;
        return -1;
    }
    return 0;
}
bool handle_command_flash_boot_partition(Socket *client, const char *file, const char *devname) {
    const char *mountpoint = "/data/misc/fastbootd/mnt";

    send_reply(client, "INFO", "format boot partition ...");
    {
        const char *argv[] = {
            "/system/bin/newfs_msdos",
            "-F", "32",
            "-L", "boot",
            "-b", "512",
            "-A", devname,
        };
        int status;

        android_fork_execvp(sizeof(argv) / sizeof(argv[0]), (char **)argv, &status, true, true);
    }

    send_reply(client, "INFO", "mount boot partition ...");
    {
        int rc = mount(devname, mountpoint, "vfat", MS_NODEV | MS_NOSUID | MS_DIRSYNC,
                "utf8,uid=0,gid=0,shortname=mixed");
        if (rc != 0) {
            send_reply(client, "FAIL", "failed to mount boot partition");
            return false;
        }
    }

    send_reply(client, "INFO", "extract files to boot partition ...");
    {
        const char *argv[] = {
            "/system/bin/tar",
            "-C", mountpoint,
            "-xvf", file,
        };
        int status;

        android_fork_execvp(sizeof(argv) / sizeof(argv[0]), (char **)argv, &status, true, true);
    }

    send_reply(client, "INFO", "umount boot partition ...");
    umount(mountpoint);

    sync();

    return send_reply(client, "OKAY", "");
}
int BandwidthController::runIptablesCmd(const char *cmd, IptJumpOp jumpHandling,
                                        IptIpVer iptVer, IptFailureLog failureHandling) {
    char buffer[MAX_CMD_LEN];
    const char *argv[MAX_CMD_ARGS];
    int argc = 0;
    char *next = buffer;
    char *tmp;
    int res;
    int status = 0;

    std::string fullCmd = cmd;

    switch (jumpHandling) {
    case IptJumpReject:
        /*
         * Must be carefull what one rejects with, as uper layer protocols will just
         * keep on hammering the device until the number of retries are done.
         * For port-unreachable (default), TCP should consider as an abort (RFC1122).
         */
        fullCmd += " --jump REJECT";
        break;
    case IptJumpReturn:
        fullCmd += " --jump RETURN";
        break;
    case IptJumpNoAdd:
        break;
    }

    fullCmd.insert(0, " -w ");
    fullCmd.insert(0, iptVer == IptIpV4 ? IPTABLES_PATH : IP6TABLES_PATH);

    if (StrncpyAndCheck(buffer, fullCmd.c_str(), sizeof(buffer))) {
        ALOGE("iptables command too long");
        return -1;
    }

    argc = 0;
    while ((tmp = strsep(&next, " "))) {
        argv[argc++] = tmp;
        if (argc >= MAX_CMD_ARGS) {
            ALOGE("iptables argument overflow");
            return -1;
        }
    }

    argv[argc] = NULL;
    res = android_fork_execvp(argc, (char **)argv, &status, false,
            failureHandling == IptFailShow);
    res = res || !WIFEXITED(status) || WEXITSTATUS(status);
    if (res && failureHandling == IptFailShow) {
      ALOGE("runIptablesCmd(): res=%d status=%d failed %s", res, status,
            fullCmd.c_str());
    }
    return res;
}
Exemple #5
0
int Exfat::doMount(const char *fsPath, const char *mountPoint,
                 bool ro, bool remount, bool executable,
                 int ownerUid, int ownerGid, int permMask) {

    int rc = -1;
    char mountData[255];
    const char *args[6];
    int status;

    if (access(EXFAT_MOUNT, X_OK)) {
        SLOGE("Unable to mount, exFAT FUSE helper not found!");
        return rc;
    }

    sprintf(mountData,
            "noatime,nodev,nosuid,dirsync,uid=%d,gid=%d,fmask=%o,dmask=%o,%s,%s",
            ownerUid, ownerGid, permMask, permMask,
            (executable ? "exec" : "noexec"),
            (ro ? "ro" : "rw"));

    args[0] = EXFAT_MOUNT;
    args[1] = "-o";
    args[2] = mountData;
    args[3] = fsPath;
    args[4] = mountPoint;
    args[5] = NULL;

    SLOGW("Executing exFAT mount (%s) -> (%s)", fsPath, mountPoint);

    rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
            true);

    if (rc && errno == EROFS) {
        SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath);
        strcat(mountData, ",ro");
        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
            true);
    }

    return rc;
}
Exemple #6
0
void start_modem(){
    int fd;
    const char *args[3];
    int rc;
    int status;
    SLOGD("Just use muxreport to start modem\n");

    args[0] = "/system/bin/muxreport";
    args[1] = "4";
    rc = android_fork_execvp(2, (char **)args, &status, false,
            true);
    if (rc != 0) {
        SLOGE("start md1 failed due to logwrap error");     
    }

    args[1] = "8";
    rc = android_fork_execvp(2, (char **)args, &status, false,
            true);
    if (rc != 0) {
        SLOGE("start md2 failed due to logwrap error");     
    }
}
static int execIptablesCommand(int argc, const char *argv[], bool silent) {
    int res;
    int status;

    res = android_fork_execvp(argc, (char **)argv, &status, false,
        !silent);
    if (res || !WIFEXITED(status) || WEXITSTATUS(status)) {
        if (!silent) {
            logExecError(argv, res, status);
        }
        if (res)
            return res;
        if (!WIFEXITED(status))
            return ECHILD;
    }
    return WEXITSTATUS(status);
}
Exemple #8
0
int Exfat::check(const char *fsPath) {

    int rc = -1;
    int status;

    if (access(EXFAT_FSCK, X_OK)) {
        SLOGW("Skipping fs checks, exfatfsck not found.\n");
        return 0;
    }

    do {
        const char *args[3];
        args[0] = EXFAT_FSCK;
        args[1] = fsPath;
        args[2] = NULL;

        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
            true);

        switch(rc) {
        case 0:
            SLOGI("exFAT filesystem check completed OK.\n");
            return 0;
        case 1:
            SLOGI("exFAT filesystem check completed, errors corrected OK.\n");
            return 0;
        case 2:
            SLOGE("exFAT filesystem check completed, errors corrected, need reboot.\n");
            return 0;
        case 4:
            SLOGE("exFAT filesystem errors left uncorrected.\n");
            return 0;
        case 8:
            SLOGE("exfatfsck operational error.\n");
            errno = EIO;
            return -1;
        default:
            SLOGE("exFAT filesystem check failed (unknown exit code %d).\n", rc);
            errno = EIO;
            return -1;
        }
    } while (0);

    return 0;
}
int NatController::runCmd(int argc, const char **argv) {
    int res;

    res = android_fork_execvp(argc, (char **)argv, NULL, false, false);

#if !LOG_NDEBUG
    std::string full_cmd = argv[0];
    argc--; argv++;
    /*
     * HACK: Sometimes runCmd() is called with a ridcously large value (32)
     * and it works because the argv[] contains a NULL after the last
     * true argv. So here we use the NULL argv[] to terminate when the argc
     * is horribly wrong, and argc for the normal cases.
     */
    for (; argc && argv[0]; argc--, argv++) {
        full_cmd += " ";
        full_cmd += argv[0];
    }
    ALOGV("runCmd(%s) res=%d", full_cmd.c_str(), res);
#endif
    return res;
}
Exemple #10
0
int Fat::check(const char *fsPath) {
    bool rw = true;
    if (access(FSCK_MSDOS_PATH, X_OK)) {
        SLOGW("Skipping fs checks\n");
        return 0;
    }

    int pass = 1;
    int rc = 0;
    do {
        const char *args[4];
        int status;
        args[0] = FSCK_MSDOS_PATH;
        args[1] = "-p";
        args[2] = "-f";
        args[3] = fsPath;

        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
                false, true);
        if (rc != 0) {
            SLOGE("Filesystem check failed due to logwrap error");
            errno = EIO;
            return -1;
        }

        if (!WIFEXITED(status)) {
            SLOGE("Filesystem check did not exit properly");
            errno = EIO;
            return -1;
        }

        status = WEXITSTATUS(status);

        switch(status) {
        case 0:
            SLOGI("Filesystem check completed OK");
            return 0;

        case 2:
            SLOGE("Filesystem check failed (not a FAT filesystem)");
            errno = ENODATA;
            return -1;

        case 4:
            if (pass++ <= 3) {
                SLOGW("Filesystem modified - rechecking (pass %d)",
                        pass);
                continue;
            }
            SLOGE("Failing check after too many rechecks");
            errno = EIO;
            return -1;

        default:
            SLOGE("Filesystem check failed (unknown exit code %d)", status);
            errno = EIO;
            return -1;
        }
    } while (0);

    return 0;
}
int SecondaryTableController::runCmd(int argc, const char **argv) {
    int ret = 0;

    ret = android_fork_execvp(argc, (char **)argv, NULL, false, false);
    return ret;
}
Exemple #12
0
int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe, bool forceFat32) {
    int fd;
    const char *args[11];
    int rc;
    int status;
    int curArg = 0;

#ifndef MTK_FORMAT_NOT_PARAM
    unsigned int bps;
    unsigned int bsize;
#endif

    if (wipe) {
        Fat::wipe(fsPath, numSectors);
    }

    if (forceFat32){
        SLOGI("%s: force to fat32! \n", __FUNCTION__);
    }

  
    args[curArg++] = MKDOSFS_PATH;

    if (forceFat32){
       args[curArg++] = "-F";
       args[curArg++] = "32";
    }
    else {
        #ifndef MTK_FORMAT_NOT_PARAM
            args[curArg++] = "-F";
            if (-1 == (fd = open(fsPath, O_RDONLY, 0644)) )
            {
                  SLOGE("failed to open %s\n", fsPath);
                  errno = EIO;
                  return -1;
            }

            if (ioctl(fd, BLKSSZGET, &bps))
            {
                bps = 0;
                SLOGE("failed to get %s bytes/sector\n", fsPath);
            }
            if (ioctl(fd, BLKGETSIZE, &bsize))
            {
                bsize = 0;
                SLOGE("failed to get %s device size\n", fsPath);
            }

            close(fd);
            SLOGD("total cluster is %llu", ( (unsigned long long)bsize * 512) / (bps * 8));

            if (!numSectors && bps && bsize)
            {
                if ( (((unsigned long long)bsize * 512) / (bps * 8)) > 65536 )
                    args[curArg++] = "32";
                else
                    args[curArg++] = "16";
            }
            else {
                args[curArg++] = "32";
            }
        #endif
    }

    args[curArg++] = "-O";
    args[curArg++] = "android";

#ifndef MTK_FORMAT_NOT_PARAM
    args[curArg++] = "-c";
    args[curArg++] = "64";
    args[curArg++] = "-A";
#endif    

    if (numSectors) {
        char tmp[32];
        snprintf(tmp, sizeof(tmp), "%u", numSectors);
        const char *size = tmp;
        args[curArg++] = "-s";
        args[curArg++] = size;
        args[curArg++] = fsPath;
    } else {
        args[curArg++] = fsPath;
    }

    SLOGD("Arg num=%d", curArg);
    for(int i = 0; i<curArg; i++) {
        SLOGD("%s", args[i]);
    }

    rc = android_fork_execvp(curArg, (char **)args, &status, false,
                   true);

    if (rc != 0) {
        SLOGE("Filesystem format failed due to logwrap error");
        errno = EIO;
        return -1;
    }

    if (!WIFEXITED(status)) {
        SLOGE("Filesystem format did not exit properly");
        errno = EIO;
        return -1;
    }

    status = WEXITSTATUS(status);

    if (status == 0) {
        sync();
        SLOGI("Filesystem formatted OK");
        return 0;
    } else {
        SLOGE("Format failed (unknown exit code %d)", status);
        errno = EIO;
        return -1;
    }
    return 0;
}
Exemple #13
0
int Fat::check(const char *fsPath) {
    bool rw = true;
    if (access(FSCK_MSDOS_PATH, X_OK)) {
        SLOGW("Skipping fs checks\n");
        return 0;
    }

#ifdef FSCK_MSDOS_MTK
	SLOGI("-- MTK_FSCK_MSDOS_MTK enabled--");

	int fsck_enhanced = 0 ; // 0 : original ver(fsck_msdos), 1 : enhanced ver(fsck_msdos_mtk)
	if (access(FSCK_MSDOS_MTK_PATH, X_OK)) {
        SLOGW("Because %s does not exist, we just use fsck_msdos (original ver.)", FSCK_MSDOS_MTK_PATH) ;
        fsck_enhanced = 0 ;
    }
	else {
		SLOGI("vold:fat:check fs = %s\n", fsPath) ;
		int fd = open(fsPath, O_RDONLY);
		if(fd < 0) {
			SLOGW("Because cannot read dev, we just use fsck_msdos (original ver.)") ;
			fsck_enhanced = 0 ;
		}
		else {
			struct bootblock boot ;
			if(readboot(fd, &boot) == 0) {
				if(boot.ClustMask == 0xfff) {
					SLOGW("Because fsck_msdos_mtk only supports FAT32, but this is FAT12!") ;
					SLOGW("We still use fsck_msdos for FAT12!") ;
					fsck_enhanced = 0 ;
				}
				else if(boot.ClustMask == 0xffff) {
					SLOGW("Because fsck_msdos_mtk only supports FAT32, but this is FAT16!") ;
					SLOGW("We still use fsck_msdos for FAT16!") ;
					fsck_enhanced = 0 ;
				}
				else {
					SLOGW("We always use fsck_msdos_mtk for FAT32 now!") ;
					fsck_enhanced = 1 ;
				}

				/*if(boot.NumClusters * 16 > 8*1024*1024) {
					SLOGI("It may need %d bytes ! It is too much ! Try enhanced fsck -- fsck_msdos_mtk !", boot.NumClusters * 16) ;
					fsck_enhanced = 1 ;
				}
				else
					SLOGW("Use fsck_msdos (original ver.)") ;
				*/
			}
			close(fd) ;
		}
	}
#endif

    int pass = 1;
    int rc = 0;
    do {
        const char *args[4];
        int status;
#ifdef FSCK_MSDOS_MTK
		if(fsck_enhanced)
			args[0] = FSCK_MSDOS_MTK_PATH;
		else
#endif
        args[0] = FSCK_MSDOS_PATH;
        args[1] = "-p";
        args[2] = "-f";
        args[3] = fsPath;

        rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
                false, true);
        if (rc != 0) {
            SLOGE("Filesystem check failed due to logwrap error");
            errno = EIO;
            return -1;
        }

        if (!WIFEXITED(status)) {
            SLOGE("Filesystem check did not exit properly");
            errno = EIO;
            return -1;
        }

        status = WEXITSTATUS(status);

        switch(status) {
        case 0:
            SLOGI("Filesystem check completed OK");
            return 0;

        case 2:
            SLOGE("Filesystem check failed (not a FAT filesystem)");
            errno = ENODATA;
            return -1;

        case 4:
            if (pass++ <= 3) {
                SLOGW("Filesystem modified - rechecking (pass %d)",
                        pass);
                continue;
            }
            SLOGE("Failing check after too many rechecks");
            errno = EIO;
            return -1;

        case 16:
            SLOGE("Filesystem check failed (not support file system, %d)", status);
            errno = ENODATA;
            return -1;

        default:
            SLOGE("Filesystem check failed (unknown exit code %d)", status);
            errno = EIO;
            return -1;
        }
    } while (1);

    return 0;
}
bool handle_command(Socket *client, std::string cmd, std::vector<std::string> args) {
    const char *trampfile = "/data/misc/fastbootd/mid.bin";

    if (cmd == "getvar") {
        if (args[0] == "max-download-size") {
            return send_reply(client, "OKAY", "%d", kMaxDownloadSize);
        } else if (args[0] == "partition-type") {
            for (size_t i = 0; i < sizeof(part_info) / sizeof(part_info[0]); i++) {
                if (args[1] == part_info[i].name) {
                    return send_reply(client, "OKAY", part_info[i].type);
                }
            }
        } else if (args[0] == "product") {
            char property[PROPERTY_VALUE_MAX];
            property_get("ro.product.board", property, "");
            return send_reply(client, "OKAY", property);
        } else if (args[0] == "serialno") {
            char property[PROPERTY_VALUE_MAX];
            property_get("ro.serialno", property, "");
            return send_reply(client, "OKAY", property);
        } else if (args[0] == "version-bootloader") {
            return send_reply(client, "OKAY", "0.1");
        }
        return send_reply(client, "OKAY", "");
    } else if (cmd == "download") {
        uint32_t size = strtol(args[0].c_str(), 0, 16);
        send_reply(client, "DATA", "%08x", size);

        int fd = open(trampfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
        if (fd < 0) {
            send_reply(client, "FAIL", "fail to create trampoline file to store data!");
            return false;
        }

        while (size > 0) {
            char buffer[4096];
            ssize_t read = client->Receive(buffer, 8, 0);
            if (read != 8) {
                send_reply(client, "FAIL", "fail to receive data!");
                close(fd);
                return false;
            }
            size_t length = ExtractMessageLength(buffer);
            do {
                read = client->Receive(buffer, std::min(length, sizeof(buffer)), 0);
                if (read < 0) {
                    close(fd);
                    return false;
                }

                write(fd, buffer, read);

                length -= read;
                size -= read;
            } while (length > 0);
        }

        close(fd);

        return send_reply(client, "OKAY", "");
    } else if (cmd == "flash") {
        std::unique_ptr<char, int (*)(const char *)> tmpfile((char *)trampfile, unlink);
        int fd = open(tmpfile.get(), O_RDONLY);
        if (fd < 0) {
            send_reply(client, "FAIL", "please run download command first!");
            return false;
        }

        const char *devname = NULL;
        const char *partname = NULL;
        for (size_t i = 0; i < sizeof(part_info) / sizeof(part_info[0]); i++) {
            if (args[0] == part_info[i].name) {
                devname = part_info[i].device;
                partname = part_info[i].name;
                break;
            }
        }

        if (devname == NULL) {
            close(fd);
            send_reply(client, "FAIL", "partition: %s does not exist!", args[0].c_str());
            return false;
        }

        if (!strcmp("boot", partname)) {
            close(fd);
            return handle_command_flash_boot_partition(client, tmpfile.get(), devname);
        }

        int fddev = open(devname, O_WRONLY | O_CREAT, 0600);
        if (fddev < 0) {
            close(fd);
            send_reply(client, "FAIL", "failed to open partition: %s", args[0].c_str());
            return false;
        }

        struct sparse_file *s = sparse_file_import(fd, true, false);
        if (!s) {
            close(fd);
            close(fddev);

            send_reply(client, "FAIL", "failed to read sparse file!");
            return false;
        }

        sparse_file_write(s, fddev, false, false, false);
        sparse_file_destroy(s);

        close(fd);
        close(fddev);

        sync();

        return send_reply(client, "OKAY", "");
    } else if (cmd == "erase") {
        const char *devname = NULL;
        for (size_t i = 0; i < sizeof(part_info) / sizeof(part_info[0]); i++) {
            if (args[0] == part_info[i].name) {
                devname = part_info[i].device;
                break;
            }
        }

        if (devname == NULL) {
            send_reply(client, "FAIL", "partition: %s does not exist!", args[0].c_str());
            return false;
        }

        uint64_t devsize = 0;
        int fd = open(devname, O_RDONLY);
        ioctl(fd, BLKGETSIZE64, &devsize);

        const uint64_t blksize = 64 * 1024;
        const uint64_t numblk = (devsize + blksize - 1) / blksize;
        const uint64_t updsize = (numblk / 10) * blksize;
        for (uint64_t offset = 0; offset < devsize; offset += updsize) {
            uint64_t realsize = std::min(updsize, devsize - offset);
            const char *argv[] = {
                "/system/bin/dd",
                "if=/dev/zero",
                android::base::StringPrintf("of=%s", devname).c_str(),
                android::base::StringPrintf("seek=%lld", offset).c_str(),
                android::base::StringPrintf("bs=%lld", realsize).c_str(),
                "count=1",
            };
            int status;

            android_fork_execvp(sizeof(argv) / sizeof(argv[0]), (char **)argv, &status, true, true);
            send_reply(client, "INFO", android::base::StringPrintf("erase %s: %3lld/100",
                    devname, (offset + realsize) * 100 / devsize).c_str());
        }

        return send_reply(client, "OKAY", "");
    } else if (cmd == "continue") {
        android::base::WriteStringToFile("5", "/sys/module/bcm2709/parameters/reboot_part");
        android_reboot(ANDROID_RB_RESTART, 0, NULL);
//        while (true) { pause(); }
        return send_reply(client, "OKAY", "");
    } else if (cmd == "reboot" || cmd == "reboot-bootloader") {
        android::base::WriteStringToFile("0", "/sys/module/bcm2709/parameters/reboot_part");
        android_reboot(ANDROID_RB_RESTART, 0, NULL);
//        while (true) { pause(); }
        return send_reply(client, "OKAY", "");
    }

    return send_reply(client, "FAIL", "unknown command: %s", cmd.c_str());
}