backup_service.c revision 5b811fa5dd00288954f15209a56aea03d5e4a004
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// socketpair but do *not* mark as close_on_exec
26static int backup_socketpair(int sv[2]) {
27    int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
28    if (rc < 0)
29        return -1;
30
31    return 0;
32}
33
34static void* backup_child_waiter(void* pid_cookie) {
35    int status;
36
37    waitpid((pid_t) pid_cookie, &status, 0);
38    D("harvested backup/restore child, status=%d\n", status);
39    return NULL;
40}
41
42/* returns the data socket passing the backup data here for forwarding */
43int backup_service(BackupOperation op, char* args) {
44    pid_t pid;
45    int s[2];
46    char* operation;
47    int socketnum;
48
49    // Command string and choice of stdin/stdout for the pipe depend on our invocation
50    if (op == BACKUP) {
51        operation = "backup";
52        socketnum = STDOUT_FILENO;
53    } else {
54        operation = "restore";
55        socketnum = STDIN_FILENO;
56    }
57
58    D("backup_service(%s, %s)\n", operation, args);
59
60    // set up the pipe from the subprocess to here
61    // parent will read s[0]; child will write s[1]
62    if (backup_socketpair(s)) {
63        D("can't create backup/restore socketpair\n");
64        fprintf(stderr, "unable to create backup/restore socketpair\n");
65        return -1;
66    }
67
68    D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]);
69    close_on_exec(s[0]);    // only the side we hold on to
70
71    // spin off the child process to run the backup command
72    pid = fork();
73    if (pid < 0) {
74        // failure
75        D("can't fork for %s\n", operation);
76        fprintf(stderr, "unable to fork for %s\n", operation);
77        adb_close(s[0]);
78        adb_close(s[1]);
79        return -1;
80    }
81
82    // Great, we're off and running.
83    if (pid == 0) {
84        // child -- actually run the backup here
85        char* p;
86        int argc;
87        char portnum[16];
88        char** bu_args;
89
90        // fixed args:  [0] is 'bu', [1] is the port number, [2] is the 'operation' string
91        argc = 3;
92        for (p = (char*)args; p && *p; ) {
93            argc++;
94            while (*p && *p != ':') p++;
95            if (*p == ':') p++;
96        }
97
98        bu_args = (char**) alloca(argc*sizeof(char*) + 1);
99
100        // run through again to build the argv array
101        argc = 0;
102        bu_args[argc++] = "bu";
103        snprintf(portnum, sizeof(portnum), "%d", s[1]);
104        bu_args[argc++] = portnum;
105        bu_args[argc++] = operation;
106        for (p = (char*)args; p && *p; ) {
107            bu_args[argc++] = p;
108            while (*p && *p != ':') p++;
109            if (*p == ':') {
110                *p = 0;
111                p++;
112            }
113        }
114        bu_args[argc] = NULL;
115
116        // Close the half of the socket that we don't care about, route 'bu's console
117        // to the output socket, and off we go
118        adb_close(s[0]);
119
120        // off we go
121        execvp("/system/bin/bu", (char * const *)bu_args);
122        // oops error - close up shop and go home
123        fprintf(stderr, "Unable to exec 'bu', bailing\n");
124        exit(-1);
125    } else {
126        adb_thread_t t;
127
128        // parent, i.e. adbd -- close the sending half of the socket
129        D("fork() returned pid %d\n", pid);
130        adb_close(s[1]);
131
132        // spin a thread to harvest the child process
133        if (adb_thread_create(&t, backup_child_waiter, (void*)pid)) {
134            adb_close(s[0]);
135            D("Unable to create child harvester\n");
136            return -1;
137        }
138    }
139
140    // we'll be reading from s[0] as the data is sent by the child process
141    return s[0];
142}
143