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