• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
backup_socketpair(int sv[2])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
backup_child_waiter(void * args)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 */
backup_service(BackupOperation op,char * args)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