1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <unistd.h> 18 #include <stdio.h> 19 20 #include "sysdeps.h" 21 22 #define TRACE_TAG TRACE_ADB 23 #include "adb.h" 24 25 typedef struct { 26 pid_t pid; 27 int fd; 28 } backup_harvest_params; 29 30 // socketpair but do *not* mark as close_on_exec 31 static int backup_socketpair(int sv[2]) { 32 int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); 33 if (rc < 0) 34 return -1; 35 36 return 0; 37 } 38 39 // harvest the child process then close the read end of the socketpair 40 static void* backup_child_waiter(void* args) { 41 int status; 42 backup_harvest_params* params = (backup_harvest_params*) args; 43 44 waitpid(params->pid, &status, 0); 45 adb_close(params->fd); 46 free(params); 47 return NULL; 48 } 49 50 /* returns the data socket passing the backup data here for forwarding */ 51 int backup_service(BackupOperation op, char* args) { 52 pid_t pid; 53 int s[2]; 54 char* operation; 55 int socketnum; 56 57 // Command string and choice of stdin/stdout for the pipe depend on our invocation 58 if (op == BACKUP) { 59 operation = "backup"; 60 socketnum = STDOUT_FILENO; 61 } else { 62 operation = "restore"; 63 socketnum = STDIN_FILENO; 64 } 65 66 D("backup_service(%s, %s)\n", operation, args); 67 68 // set up the pipe from the subprocess to here 69 // parent will read s[0]; child will write s[1] 70 if (backup_socketpair(s)) { 71 D("can't create backup/restore socketpair\n"); 72 fprintf(stderr, "unable to create backup/restore socketpair\n"); 73 return -1; 74 } 75 76 D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]); 77 close_on_exec(s[0]); // only the side we hold on to 78 79 // spin off the child process to run the backup command 80 pid = fork(); 81 if (pid < 0) { 82 // failure 83 D("can't fork for %s\n", operation); 84 fprintf(stderr, "unable to fork for %s\n", operation); 85 adb_close(s[0]); 86 adb_close(s[1]); 87 return -1; 88 } 89 90 // Great, we're off and running. 91 if (pid == 0) { 92 // child -- actually run the backup here 93 char* p; 94 int argc; 95 char portnum[16]; 96 char** bu_args; 97 98 // fixed args: [0] is 'bu', [1] is the port number, [2] is the 'operation' string 99 argc = 3; 100 for (p = (char*)args; p && *p; ) { 101 argc++; 102 while (*p && *p != ':') p++; 103 if (*p == ':') p++; 104 } 105 106 bu_args = (char**) alloca(argc*sizeof(char*) + 1); 107 108 // run through again to build the argv array 109 argc = 0; 110 bu_args[argc++] = "bu"; 111 snprintf(portnum, sizeof(portnum), "%d", s[1]); 112 bu_args[argc++] = portnum; 113 bu_args[argc++] = operation; 114 for (p = (char*)args; p && *p; ) { 115 bu_args[argc++] = p; 116 while (*p && *p != ':') p++; 117 if (*p == ':') { 118 *p = 0; 119 p++; 120 } 121 } 122 bu_args[argc] = NULL; 123 124 // Close the half of the socket that we don't care about, route 'bu's console 125 // to the output socket, and off we go 126 adb_close(s[0]); 127 128 // off we go 129 execvp("/system/bin/bu", (char * const *)bu_args); 130 // oops error - close up shop and go home 131 fprintf(stderr, "Unable to exec 'bu', bailing\n"); 132 exit(-1); 133 } else { 134 adb_thread_t t; 135 backup_harvest_params* params; 136 137 // parent, i.e. adbd -- close the sending half of the socket 138 D("fork() returned pid %d\n", pid); 139 adb_close(s[1]); 140 141 // spin a thread to harvest the child process 142 params = (backup_harvest_params*) malloc(sizeof(backup_harvest_params)); 143 params->pid = pid; 144 params->fd = s[0]; 145 if (adb_thread_create(&t, backup_child_waiter, params)) { 146 adb_close(s[0]); 147 free(params); 148 D("Unable to create child harvester\n"); 149 return -1; 150 } 151 } 152 153 // we'll be reading from s[0] as the data is sent by the child process 154 return s[0]; 155 } 156