示例#1
0
Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) {
    char** paths = malloc(argc * sizeof(char*));
    int i;
    for (i = 0; i < argc; ++i) {
        paths[i] = Evaluate(state, argv[i]);
        if (paths[i] == NULL) {
            int j;
            for (j = 0; j < i; ++i) {
                free(paths[j]);
            }
            free(paths);
            return NULL;
        }
    }

    bool recursive = (strcmp(name, "delete_recursive") == 0);

    int success = 0;
    for (i = 0; i < argc; ++i) {
        if ((recursive ? dirUnlinkHierarchy(paths[i]) : unlink(paths[i])) == 0)
            ++success;
        free(paths[i]);
    }
    free(paths);

    char buffer[10];
    sprintf(buffer, "%d", success);
    return StringValue(strdup(buffer));
}
示例#2
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);
}
示例#3
0
/* delete <file1> [<fileN> ...]
 * delete_recursive <file-or-dir1> [<file-or-dirN> ...]
 *
 * Like "rm -f", will try to delete every named file/dir, even if
 * earlier ones fail.  Recursive deletes that fail halfway through
 * give up early.
 */
static int
cmd_delete(const char *name, void *cookie, int argc, const char *argv[],
        PermissionRequestList *permissions)
{
    UNUSED(cookie);
    CHECK_WORDS();
    int nerr = 0;
    bool recurse;

    if (argc < 1) {
        LOGE("Command %s requires at least one argument\n", name);
        return 1;
    }

    recurse = (strcmp(name, "delete_recursive") == 0);
    ui_print("Deleting files...\n");
//xxx permissions

    int i;
    for (i = 0; i < argc; i++) {
        const char *root_path = argv[i];
        char pathbuf[PATH_MAX];
        const char *path;

        /* This guarantees that all paths use "SYSTEM:"-style roots;
         * plain paths won't make it through translate_root_path().
         */
        path = translate_root_path(root_path, pathbuf, sizeof(pathbuf));
        if (path != NULL) {
            int ret = ensure_root_path_mounted(root_path);
            if (ret < 0) {
                LOGW("Can't mount volume to delete \"%s\"\n", root_path);
                nerr++;
                continue;
            }
            if (recurse) {
                ret = dirUnlinkHierarchy(path);
            } else {
                ret = unlink(path);
            }
            if (ret != 0 && errno != ENOENT) {
                LOGW("Can't delete %s\n(%s)\n", path, strerror(errno));
                nerr++;
            }
        } else {
            nerr++;
        }
    }
//TODO: add a way to fail if a delete didn't work

    return 0;
}