1b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include "fs.h"
2b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include "files.h"
3b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <unistd.h>
40b3ec5d32f15bdea67d15af95cf68e455867c668Raphael#include <stdlib.h>
5b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <sys/types.h>
60b3ec5d32f15bdea67d15af95cf68e455867c668Raphael#include <sys/wait.h>
7b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <dirent.h>
8b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <string>
9b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <vector>
10b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <stdio.h>
114f85cc54b3347e00e32a07cae4fd5473987b71afThe Android Open Source Project#include <string.h>
12b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <errno.h>
13b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <sys/stat.h>
14b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <unistd.h>
158ae3ad5802c7fe78d6b353b0d9090276a4f6a210Alexey Zaytsev#include <string.h>
16b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <host/CopyFile.h>
17b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
18b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectusing namespace std;
19b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
20b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic bool
21b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectis_dir(const string& path)
22b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
23b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
24b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct stat st;
25b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = stat(path.c_str(), &st);
26b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return err != 0 || S_ISDIR(st.st_mode);
27b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
28b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
29b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic int
30b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectremove_file(const string& path)
31b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
32b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err = unlink(path.c_str());
33b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err != 0) {
34b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "error deleting file %s (%s)\n", path.c_str(),
35b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                strerror(errno));
36b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return errno;
37b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
38b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return 0;
39b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
40b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
41b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
42b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectremove_recursively(const string& path)
43b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
44b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
45b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
46b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (is_dir(path)) {
47b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        DIR *d = opendir(path.c_str());
48b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (d == NULL) {
49b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            fprintf(stderr, "error getting directory contents %s (%s)\n",
50b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    path.c_str(), strerror(errno));
51b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return errno;
52b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
53b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
54b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        vector<string> files;
55b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        vector<string> dirs;
56b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
57b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        struct dirent *ent;
58b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        while (NULL != (ent = readdir(d))) {
59b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (0 == strcmp(".", ent->d_name)
60b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    || 0 == strcmp("..", ent->d_name)) {
61b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                continue;
62b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
63b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            string full = path;
64b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            full += '/';
65b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            full += ent->d_name;
66b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            bool is_directory = (ent->d_type == DT_DIR);
67b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (is_directory) {
68b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                dirs.push_back(full);
69b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            } else {
70b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                files.push_back(full);
71b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
72b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
73b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        closedir(d);
74b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
75b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        for (vector<string>::iterator it=files.begin(); it!=files.end(); it++) {
76b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            err = remove_file(*it);
77b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (err != 0) {
78b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                return err;
79b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
80b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
81b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
82b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) {
83b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            err = remove_recursively(*it);
84b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (err != 0) {
85b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                return err;
86b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
87b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
88b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
89b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = rmdir(path.c_str());
90b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (err != 0) {
91b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            fprintf(stderr, "error deleting directory %s (%s)\n", path.c_str(),
92b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    strerror(errno));
93b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return errno;
94b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
95b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return 0;
96b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    } else {
97b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return remove_file(path);
98b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
99b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
100b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
101b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
102b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectmkdir_recursively(const string& path)
103b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
104b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
105b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    size_t pos = 0;
1069af5fc4e447863f0961bc60c1cf252c88f1088c2Jey    // For absolute pathnames, that starts with leading '/'
1079af5fc4e447863f0961bc60c1cf252c88f1088c2Jey    // use appropriate initial value.
1089af5fc4e447863f0961bc60c1cf252c88f1088c2Jey    if (path.length() != 0 and path[0] == '/') pos++;
1099af5fc4e447863f0961bc60c1cf252c88f1088c2Jey
110b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (true) {
111b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        pos = path.find('/', pos);
112b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        string p = path.substr(0, pos);
113b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        struct stat st;
114b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = stat(p.c_str(), &st);
115b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (err != 0) {
116b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            err = mkdir(p.c_str(), 0770);
117b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (err != 0) {
118b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                fprintf(stderr, "can't create directory %s (%s)\n",
119b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                        path.c_str(), strerror(errno));
120b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                return errno;
121b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
122b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
123b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else if (!S_ISDIR(st.st_mode)) {
124b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            fprintf(stderr, "can't create directory %s because %s is a file.\n",
125b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                        path.c_str(), p.c_str());
126b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return 1;
127b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
128b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        pos++;
129b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (p == path) {
130b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return 0;
131b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
132b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
133b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
134b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
135b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
136b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectcopy_file(const string& src, const string& dst)
137b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
138b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
139b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
140b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = copyFile(src.c_str(), dst.c_str(),
141b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    COPY_NO_DEREFERENCE | COPY_FORCE | COPY_PERMISSIONS);
142b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return err;
143b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
1440b3ec5d32f15bdea67d15af95cf68e455867c668Raphael
1450b3ec5d32f15bdea67d15af95cf68e455867c668Raphaelint
1460b3ec5d32f15bdea67d15af95cf68e455867c668Raphaelstrip_file(const string& path)
1470b3ec5d32f15bdea67d15af95cf68e455867c668Raphael{
148ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll    // Default strip command to run is "strip" unless overridden by the ATREE_STRIP env var.
149ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll    const char* strip_cmd = getenv("ATREE_STRIP");
1500b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    if (!strip_cmd || !strip_cmd[0]) {
1510b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        strip_cmd = "strip";
1520b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    }
1530b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    pid_t pid = fork();
1540b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    if (pid == -1) {
1550b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        // Fork failed. errno should be set.
1560b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        return -1;
1570b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    } else if (pid == 0) {
1580b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        // Exec in the child. Only returns if execve failed.
159ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
160ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        int num_args = 0;
161ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        const char *s = strip_cmd;
162ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        while (*s) {
163ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            while (*s == ' ') ++s;
164ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            if (*s && *s != ' ') {
165ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                ++num_args;
166ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                while (*s && *s != ' ') ++s;
167ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            }
168ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        }
169ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
170ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        if (num_args <= 0) {
171ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            fprintf(stderr, "Invalid ATREE_STRIP command '%s'\n", strip_cmd);
172ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            return 1;
173ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
174ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        } else if (num_args == 1) {
175ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            return execlp(strip_cmd, strip_cmd, path.c_str(), (char *)NULL);
176ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
177ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        } else {
178ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            // Split the arguments if more than 1
179ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            char* cmd = strdup(strip_cmd);
180ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            const char** args = (const char**) malloc(sizeof(const char*) * (num_args + 2));
181ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
182ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            const char** curr = args;
183ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            char* s = cmd;
184ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            while (*s) {
185ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                while (*s == ' ') ++s;
186ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                if (*s && *s != ' ') {
187ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                    *curr = s;
188ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                    ++curr;
189ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                    while (*s && *s != ' ') ++s;
190ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                    if (*s) {
191ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                        *s = '\0';
192ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                        ++s;
193ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                    }
194ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll                }
195ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            }
196ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
197ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            args[num_args] = path.c_str();
198ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            args[num_args + 1] = NULL;
199ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll
200ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            int ret = execvp(args[0], (char* const*)args);
201ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            free(args);
202ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            free(cmd);
203ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll            return ret;
204ec5fe91ead27bf4bfb4e728222ac6d475f04a18bRaphael Moll        }
2050b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    } else {
2060b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        // Wait for child pid and return its exit code.
2070b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        int status;
2080b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        waitpid(pid, &status, 0);
2090b3ec5d32f15bdea67d15af95cf68e455867c668Raphael        return status;
2100b3ec5d32f15bdea67d15af95cf68e455867c668Raphael    }
2110b3ec5d32f15bdea67d15af95cf68e455867c668Raphael}
2120b3ec5d32f15bdea67d15af95cf68e455867c668Raphael
213