• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <limits.h>
23 #include <stdarg.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <ctype.h>
27 #include <assert.h>
28 
29 #include "sysdeps.h"
30 
31 #ifdef HAVE_TERMIO_H
32 #include <termios.h>
33 #endif
34 
35 #define  TRACE_TAG  TRACE_ADB
36 #include "adb.h"
37 #include "adb_client.h"
38 #include "file_sync_service.h"
39 
40 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
41 
42 void get_my_path(char *s, size_t maxLen);
43 int find_sync_dirs(const char *srcarg,
44         char **android_srcdir_out, char **data_srcdir_out);
45 int install_app(transport_type transport, char* serial, int argc, char** argv);
46 int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
47 
48 static const char *gProductOutPath = NULL;
49 
product_file(const char * extra)50 static char *product_file(const char *extra)
51 {
52     int n;
53     char *x;
54 
55     if (gProductOutPath == NULL) {
56         fprintf(stderr, "adb: Product directory not specified; "
57                 "use -p or define ANDROID_PRODUCT_OUT\n");
58         exit(1);
59     }
60 
61     n = strlen(gProductOutPath) + strlen(extra) + 2;
62     x = malloc(n);
63     if (x == 0) {
64         fprintf(stderr, "adb: Out of memory (product_file())\n");
65         exit(1);
66     }
67 
68     snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
69     return x;
70 }
71 
version(FILE * out)72 void version(FILE * out) {
73     fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
74          ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
75 }
76 
help()77 void help()
78 {
79     version(stderr);
80 
81     fprintf(stderr,
82         "\n"
83         " -d                            - directs command to the only connected USB device\n"
84         "                                 returns an error if more than one USB device is present.\n"
85         " -e                            - directs command to the only running emulator.\n"
86         "                                 returns an error if more than one emulator is running.\n"
87         " -s <serial number>            - directs command to the USB device or emulator with\n"
88         "                                 the given serial number. Overrides ANDROID_SERIAL\n"
89         "                                 environment variable.\n"
90         " -p <product name or path>     - simple product name like 'sooner', or\n"
91         "                                 a relative/absolute path to a product\n"
92         "                                 out directory like 'out/target/product/sooner'.\n"
93         "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
94         "                                 environment variable is used, which must\n"
95         "                                 be an absolute path.\n"
96         " devices                       - list all connected devices\n"
97         " connect <host>[:<port>]       - connect to a device via TCP/IP\n"
98         "                                 Port 5555 is used by default if no port number is specified.\n"
99         " disconnect [<host>[:<port>]]  - disconnect from a TCP/IP device.\n"
100         "                                 Port 5555 is used by default if no port number is specified.\n"
101         "                                 Using this command with no additional arguments\n"
102         "                                 will disconnect from all connected TCP/IP devices.\n"
103         "\n"
104         "device commands:\n"
105         "  adb push <local> <remote>    - copy file/dir to device\n"
106         "  adb pull <remote> [<local>]  - copy file/dir from device\n"
107         "  adb sync [ <directory> ]     - copy host->device only if changed\n"
108         "                                 (-l means list but don't copy)\n"
109         "                                 (see 'adb help all')\n"
110         "  adb shell                    - run remote shell interactively\n"
111         "  adb shell <command>          - run remote shell command\n"
112         "  adb emu <command>            - run emulator console command\n"
113         "  adb logcat [ <filter-spec> ] - View device log\n"
114         "  adb forward <local> <remote> - forward socket connections\n"
115         "                                 forward specs are one of: \n"
116         "                                   tcp:<port>\n"
117         "                                   localabstract:<unix domain socket name>\n"
118         "                                   localreserved:<unix domain socket name>\n"
119         "                                   localfilesystem:<unix domain socket name>\n"
120         "                                   dev:<character device name>\n"
121         "                                   jdwp:<process pid> (remote only)\n"
122         "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
123         "  adb install [-l] [-r] [-s] <file> - push this package file to the device and install it\n"
124         "                                 ('-l' means forward-lock the app)\n"
125         "                                 ('-r' means reinstall the app, keeping its data)\n"
126         "                                 ('-s' means install on SD card instead of internal storage)\n"
127         "  adb uninstall [-k] <package> - remove this app package from the device\n"
128         "                                 ('-k' means keep the data and cache directories)\n"
129         "  adb bugreport                - return all information from the device\n"
130         "                                 that should be included in a bug report.\n"
131         "\n"
132         "  adb backup [-f <file>] [-apk|-noapk] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
133         "                               - write an archive of the device's data to <file>.\n"
134         "                                 If no -f option is supplied then the data is written\n"
135         "                                 to \"backup.ab\" in the current directory.\n"
136         "                                 (-apk|-noapk enable/disable backup of the .apks themselves\n"
137         "                                    in the archive; the default is noapk.)\n"
138         "                                 (-shared|-noshared enable/disable backup of the device's\n"
139         "                                    shared storage / SD card contents; the default is noshared.)\n"
140         "                                 (-all means to back up all installed applications)\n"
141         "                                 (-system|-nosystem toggles whether -all automatically includes\n"
142         "                                    system applications; the default is to include system apps)\n"
143         "                                 (<packages...> is the list of applications to be backed up.  If\n"
144         "                                    the -all or -shared flags are passed, then the package\n"
145         "                                    list is optional.  Applications explicitly given on the\n"
146         "                                    command line will be included even if -nosystem would\n"
147         "                                    ordinarily cause them to be omitted.)\n"
148         "\n"
149         "  adb restore <file>           - restore device contents from the <file> backup archive\n"
150         "\n"
151         "  adb help                     - show this help message\n"
152         "  adb version                  - show version num\n"
153         "\n"
154         "scripting:\n"
155         "  adb wait-for-device          - block until device is online\n"
156         "  adb start-server             - ensure that there is a server running\n"
157         "  adb kill-server              - kill the server if it is running\n"
158         "  adb get-state                - prints: offline | bootloader | device\n"
159         "  adb get-serialno             - prints: <serial-number>\n"
160         "  adb status-window            - continuously print device status for a specified device\n"
161         "  adb remount                  - remounts the /system partition on the device read-write\n"
162         "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
163         "  adb reboot-bootloader        - reboots the device into the bootloader\n"
164         "  adb root                     - restarts the adbd daemon with root permissions\n"
165         "  adb usb                      - restarts the adbd daemon listening on USB\n"
166         "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port"
167         "\n"
168         "networking:\n"
169         "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
170         " Note: you should not automatically start a PPP connection.\n"
171         " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
172         " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
173         "\n"
174         "adb sync notes: adb sync [ <directory> ]\n"
175         "  <localdir> can be interpreted in several ways:\n"
176         "\n"
177         "  - If <directory> is not specified, both /system and /data partitions will be updated.\n"
178         "\n"
179         "  - If it is \"system\" or \"data\", only the corresponding partition\n"
180         "    is updated.\n"
181         "\n"
182         "environmental variables:\n"
183         "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
184         "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
185         "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
186         "  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.\n"
187         );
188 }
189 
usage()190 int usage()
191 {
192     help();
193     return 1;
194 }
195 
196 #ifdef HAVE_TERMIO_H
197 static struct termios tio_save;
198 
stdin_raw_init(int fd)199 static void stdin_raw_init(int fd)
200 {
201     struct termios tio;
202 
203     if(tcgetattr(fd, &tio)) return;
204     if(tcgetattr(fd, &tio_save)) return;
205 
206     tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
207 
208         /* no timeout but request at least one character per read */
209     tio.c_cc[VTIME] = 0;
210     tio.c_cc[VMIN] = 1;
211 
212     tcsetattr(fd, TCSANOW, &tio);
213     tcflush(fd, TCIFLUSH);
214 }
215 
stdin_raw_restore(int fd)216 static void stdin_raw_restore(int fd)
217 {
218     tcsetattr(fd, TCSANOW, &tio_save);
219     tcflush(fd, TCIFLUSH);
220 }
221 #endif
222 
read_and_dump(int fd)223 static void read_and_dump(int fd)
224 {
225     char buf[4096];
226     int len;
227 
228     while(fd >= 0) {
229         D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
230         len = adb_read(fd, buf, 4096);
231         D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
232         if(len == 0) {
233             break;
234         }
235 
236         if(len < 0) {
237             if(errno == EINTR) continue;
238             break;
239         }
240         fwrite(buf, 1, len, stdout);
241         fflush(stdout);
242     }
243 }
244 
copy_to_file(int inFd,int outFd)245 static void copy_to_file(int inFd, int outFd) {
246     const size_t BUFSIZE = 32 * 1024;
247     char* buf = (char*) malloc(BUFSIZE);
248     int len;
249     long total = 0;
250 
251     D("copy_to_file(%d -> %d)\n", inFd, outFd);
252     for (;;) {
253         len = adb_read(inFd, buf, BUFSIZE);
254         if (len == 0) {
255             D("copy_to_file() : read 0 bytes; exiting\n");
256             break;
257         }
258         if (len < 0) {
259             if (errno == EINTR) {
260                 D("copy_to_file() : EINTR, retrying\n");
261                 continue;
262             }
263             D("copy_to_file() : error %d\n", errno);
264             break;
265         }
266         adb_write(outFd, buf, len);
267         total += len;
268     }
269     D("copy_to_file() finished after %lu bytes\n", total);
270     free(buf);
271 }
272 
stdin_read_thread(void * x)273 static void *stdin_read_thread(void *x)
274 {
275     int fd, fdi;
276     unsigned char buf[1024];
277     int r, n;
278     int state = 0;
279 
280     int *fds = (int*) x;
281     fd = fds[0];
282     fdi = fds[1];
283     free(fds);
284 
285     for(;;) {
286         /* fdi is really the client's stdin, so use read, not adb_read here */
287         D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
288         r = unix_read(fdi, buf, 1024);
289         D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
290         if(r == 0) break;
291         if(r < 0) {
292             if(errno == EINTR) continue;
293             break;
294         }
295         for(n = 0; n < r; n++){
296             switch(buf[n]) {
297             case '\n':
298                 state = 1;
299                 break;
300             case '\r':
301                 state = 1;
302                 break;
303             case '~':
304                 if(state == 1) state++;
305                 break;
306             case '.':
307                 if(state == 2) {
308                     fprintf(stderr,"\n* disconnect *\n");
309 #ifdef HAVE_TERMIO_H
310                     stdin_raw_restore(fdi);
311 #endif
312                     exit(0);
313                 }
314             default:
315                 state = 0;
316             }
317         }
318         r = adb_write(fd, buf, r);
319         if(r <= 0) {
320             break;
321         }
322     }
323     return 0;
324 }
325 
interactive_shell(void)326 int interactive_shell(void)
327 {
328     adb_thread_t thr;
329     int fdi, fd;
330     int *fds;
331 
332     fd = adb_connect("shell:");
333     if(fd < 0) {
334         fprintf(stderr,"error: %s\n", adb_error());
335         return 1;
336     }
337     fdi = 0; //dup(0);
338 
339     fds = malloc(sizeof(int) * 2);
340     fds[0] = fd;
341     fds[1] = fdi;
342 
343 #ifdef HAVE_TERMIO_H
344     stdin_raw_init(fdi);
345 #endif
346     adb_thread_create(&thr, stdin_read_thread, fds);
347     read_and_dump(fd);
348 #ifdef HAVE_TERMIO_H
349     stdin_raw_restore(fdi);
350 #endif
351     return 0;
352 }
353 
354 
format_host_command(char * buffer,size_t buflen,const char * command,transport_type ttype,const char * serial)355 static void format_host_command(char* buffer, size_t  buflen, const char* command, transport_type ttype, const char* serial)
356 {
357     if (serial) {
358         snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
359     } else {
360         const char* prefix = "host";
361         if (ttype == kTransportUsb)
362             prefix = "host-usb";
363         else if (ttype == kTransportLocal)
364             prefix = "host-local";
365 
366         snprintf(buffer, buflen, "%s:%s", prefix, command);
367     }
368 }
369 
status_window(transport_type ttype,const char * serial)370 static void status_window(transport_type ttype, const char* serial)
371 {
372     char command[4096];
373     char *state = 0;
374     char *laststate = 0;
375 
376         /* silence stderr */
377 #ifdef _WIN32
378     /* XXX: TODO */
379 #else
380     int  fd;
381     fd = unix_open("/dev/null", O_WRONLY);
382     dup2(fd, 2);
383     adb_close(fd);
384 #endif
385 
386     format_host_command(command, sizeof command, "get-state", ttype, serial);
387 
388     for(;;) {
389         adb_sleep_ms(250);
390 
391         if(state) {
392             free(state);
393             state = 0;
394         }
395 
396         state = adb_query(command);
397 
398         if(state) {
399             if(laststate && !strcmp(state,laststate)){
400                 continue;
401             } else {
402                 if(laststate) free(laststate);
403                 laststate = strdup(state);
404             }
405         }
406 
407         printf("%c[2J%c[2H", 27, 27);
408         printf("Android Debug Bridge\n");
409         printf("State: %s\n", state ? state : "offline");
410         fflush(stdout);
411     }
412 }
413 
414 /** duplicate string and quote all \ " ( ) chars + space character. */
415 static char *
dupAndQuote(const char * s)416 dupAndQuote(const char *s)
417 {
418     const char *ts;
419     size_t alloc_len;
420     char *ret;
421     char *dest;
422 
423     ts = s;
424 
425     alloc_len = 0;
426 
427     for( ;*ts != '\0'; ts++) {
428         alloc_len++;
429         if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
430             alloc_len++;
431         }
432     }
433 
434     ret = (char *)malloc(alloc_len + 1);
435 
436     ts = s;
437     dest = ret;
438 
439     for ( ;*ts != '\0'; ts++) {
440         if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
441             *dest++ = '\\';
442         }
443 
444         *dest++ = *ts;
445     }
446 
447     *dest++ = '\0';
448 
449     return ret;
450 }
451 
452 /**
453  * Run ppp in "notty" mode against a resource listed as the first parameter
454  * eg:
455  *
456  * ppp dev:/dev/omap_csmi_tty0 <ppp options>
457  *
458  */
ppp(int argc,char ** argv)459 int ppp(int argc, char **argv)
460 {
461 #ifdef HAVE_WIN32_PROC
462     fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
463     return -1;
464 #else
465     char *adb_service_name;
466     pid_t pid;
467     int fd;
468 
469     if (argc < 2) {
470         fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
471                 argv[0]);
472 
473         return 1;
474     }
475 
476     adb_service_name = argv[1];
477 
478     fd = adb_connect(adb_service_name);
479 
480     if(fd < 0) {
481         fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
482                 adb_service_name, adb_error());
483         return 1;
484     }
485 
486     pid = fork();
487 
488     if (pid < 0) {
489         perror("from fork()");
490         return 1;
491     } else if (pid == 0) {
492         int err;
493         int i;
494         const char **ppp_args;
495 
496         // copy args
497         ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
498         ppp_args[0] = "pppd";
499         for (i = 2 ; i < argc ; i++) {
500             //argv[2] and beyond become ppp_args[1] and beyond
501             ppp_args[i - 1] = argv[i];
502         }
503         ppp_args[i-1] = NULL;
504 
505         // child side
506 
507         dup2(fd, STDIN_FILENO);
508         dup2(fd, STDOUT_FILENO);
509         adb_close(STDERR_FILENO);
510         adb_close(fd);
511 
512         err = execvp("pppd", (char * const *)ppp_args);
513 
514         if (err < 0) {
515             perror("execing pppd");
516         }
517         exit(-1);
518     } else {
519         // parent side
520 
521         adb_close(fd);
522         return 0;
523     }
524 #endif /* !HAVE_WIN32_PROC */
525 }
526 
send_shellcommand(transport_type transport,char * serial,char * buf)527 static int send_shellcommand(transport_type transport, char* serial, char* buf)
528 {
529     int fd, ret;
530 
531     for(;;) {
532         fd = adb_connect(buf);
533         if(fd >= 0)
534             break;
535         fprintf(stderr,"- waiting for device -\n");
536         adb_sleep_ms(1000);
537         do_cmd(transport, serial, "wait-for-device", 0);
538     }
539 
540     read_and_dump(fd);
541     ret = adb_close(fd);
542     if (ret)
543         perror("close");
544 
545     return ret;
546 }
547 
logcat(transport_type transport,char * serial,int argc,char ** argv)548 static int logcat(transport_type transport, char* serial, int argc, char **argv)
549 {
550     char buf[4096];
551 
552     char *log_tags;
553     char *quoted_log_tags;
554 
555     log_tags = getenv("ANDROID_LOG_TAGS");
556     quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
557 
558     snprintf(buf, sizeof(buf),
559         "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
560         quoted_log_tags);
561 
562     free(quoted_log_tags);
563 
564     argc -= 1;
565     argv += 1;
566     while(argc-- > 0) {
567         char *quoted;
568 
569         quoted = dupAndQuote (*argv++);
570 
571         strncat(buf, " ", sizeof(buf)-1);
572         strncat(buf, quoted, sizeof(buf)-1);
573         free(quoted);
574     }
575 
576     send_shellcommand(transport, serial, buf);
577     return 0;
578 }
579 
backup(int argc,char ** argv)580 static int backup(int argc, char** argv) {
581     char buf[4096];
582     const char* filename = "./backup.ab";
583     int fd, outFd;
584     int i, j;
585 
586     /* find, extract, and use any -f argument */
587     for (i = 1; i < argc; i++) {
588         if (!strcmp("-f", argv[i])) {
589             if (i == argc-1) {
590                 fprintf(stderr, "adb: -f passed with no filename\n");
591                 return usage();
592             }
593             filename = argv[i+1];
594             for (j = i+2; j <= argc; ) {
595                 argv[i++] = argv[j++];
596             }
597             argc -= 2;
598             argv[argc] = NULL;
599         }
600     }
601 
602     /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
603     if (argc < 2) return usage();
604 
605     outFd = adb_open_mode(filename, O_WRONLY | O_CREAT | O_TRUNC, 0640);
606     if (outFd < 0) {
607         fprintf(stderr, "adb: unable to open file %s\n", filename);
608         return -1;
609     }
610 
611     snprintf(buf, sizeof(buf), "backup");
612     for (argc--, argv++; argc; argc--, argv++) {
613         strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
614         strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
615     }
616 
617     D("backup. filename=%s buf=%s\n", filename, buf);
618     fd = adb_connect(buf);
619     if (fd < 0) {
620         fprintf(stderr, "adb: unable to connect for backup\n");
621         adb_close(outFd);
622         return -1;
623     }
624 
625     copy_to_file(fd, outFd);
626 
627     adb_close(fd);
628     adb_close(outFd);
629     return 0;
630 }
631 
restore(int argc,char ** argv)632 static int restore(int argc, char** argv) {
633     const char* filename;
634     int fd, tarFd;
635 
636     if (argc != 2) return usage();
637 
638     filename = argv[1];
639     tarFd = adb_open(filename, O_RDONLY);
640     if (tarFd < 0) {
641         fprintf(stderr, "adb: unable to open file %s\n", filename);
642         return -1;
643     }
644 
645     fd = adb_connect("restore:");
646     if (fd < 0) {
647         fprintf(stderr, "adb: unable to connect for backup\n");
648         adb_close(tarFd);
649         return -1;
650     }
651 
652     copy_to_file(tarFd, fd);
653 
654     adb_close(fd);
655     adb_close(tarFd);
656     return 0;
657 }
658 
659 #define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
top_works(const char * top)660 static int top_works(const char *top)
661 {
662     if (top != NULL && adb_is_absolute_host_path(top)) {
663         char path_buf[PATH_MAX];
664         snprintf(path_buf, sizeof(path_buf),
665                 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
666         return access(path_buf, F_OK) == 0;
667     }
668     return 0;
669 }
670 
find_top_from(const char * indir,char path_buf[PATH_MAX])671 static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
672 {
673     strcpy(path_buf, indir);
674     while (1) {
675         if (top_works(path_buf)) {
676             return path_buf;
677         }
678         char *s = adb_dirstop(path_buf);
679         if (s != NULL) {
680             *s = '\0';
681         } else {
682             path_buf[0] = '\0';
683             return NULL;
684         }
685     }
686 }
687 
find_top(char path_buf[PATH_MAX])688 static char *find_top(char path_buf[PATH_MAX])
689 {
690     char *top = getenv("ANDROID_BUILD_TOP");
691     if (top != NULL && top[0] != '\0') {
692         if (!top_works(top)) {
693             fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
694             return NULL;
695         }
696     } else {
697         top = getenv("TOP");
698         if (top != NULL && top[0] != '\0') {
699             if (!top_works(top)) {
700                 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
701                 return NULL;
702             }
703         } else {
704             top = NULL;
705         }
706     }
707 
708     if (top != NULL) {
709         /* The environment pointed to a top directory that works.
710          */
711         strcpy(path_buf, top);
712         return path_buf;
713     }
714 
715     /* The environment didn't help.  Walk up the tree from the CWD
716      * to see if we can find the top.
717      */
718     char dir[PATH_MAX];
719     top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
720     if (top == NULL) {
721         /* If the CWD isn't under a good-looking top, see if the
722          * executable is.
723          */
724         get_my_path(dir, PATH_MAX);
725         top = find_top_from(dir, path_buf);
726     }
727     return top;
728 }
729 
730 /* <hint> may be:
731  * - A simple product name
732  *   e.g., "sooner"
733 TODO: debug?  sooner-debug, sooner:debug?
734  * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
735  *   e.g., "out/target/product/sooner"
736  * - An absolute path to the PRODUCT_OUT dir
737  *   e.g., "/src/device/out/target/product/sooner"
738  *
739  * Given <hint>, try to construct an absolute path to the
740  * ANDROID_PRODUCT_OUT dir.
741  */
find_product_out_path(const char * hint)742 static const char *find_product_out_path(const char *hint)
743 {
744     static char path_buf[PATH_MAX];
745 
746     if (hint == NULL || hint[0] == '\0') {
747         return NULL;
748     }
749 
750     /* If it's already absolute, don't bother doing any work.
751      */
752     if (adb_is_absolute_host_path(hint)) {
753         strcpy(path_buf, hint);
754         return path_buf;
755     }
756 
757     /* If there are any slashes in it, assume it's a relative path;
758      * make it absolute.
759      */
760     if (adb_dirstart(hint) != NULL) {
761         if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
762             fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
763             return NULL;
764         }
765         if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
766             fprintf(stderr, "adb: Couldn't assemble path\n");
767             return NULL;
768         }
769         strcat(path_buf, OS_PATH_SEPARATOR_STR);
770         strcat(path_buf, hint);
771         return path_buf;
772     }
773 
774     /* It's a string without any slashes.  Try to do something with it.
775      *
776      * Try to find the root of the build tree, and build a PRODUCT_OUT
777      * path from there.
778      */
779     char top_buf[PATH_MAX];
780     const char *top = find_top(top_buf);
781     if (top == NULL) {
782         fprintf(stderr, "adb: Couldn't find top of build tree\n");
783         return NULL;
784     }
785 //TODO: if we have a way to indicate debug, look in out/debug/target/...
786     snprintf(path_buf, sizeof(path_buf),
787             "%s" OS_PATH_SEPARATOR_STR
788             "out" OS_PATH_SEPARATOR_STR
789             "target" OS_PATH_SEPARATOR_STR
790             "product" OS_PATH_SEPARATOR_STR
791             "%s", top_buf, hint);
792     if (access(path_buf, F_OK) < 0) {
793         fprintf(stderr, "adb: Couldn't find a product dir "
794                 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
795         return NULL;
796     }
797     return path_buf;
798 }
799 
adb_commandline(int argc,char ** argv)800 int adb_commandline(int argc, char **argv)
801 {
802     char buf[4096];
803     int no_daemon = 0;
804     int is_daemon = 0;
805     int is_server = 0;
806     int persist = 0;
807     int r;
808     int quote;
809     transport_type ttype = kTransportAny;
810     char* serial = NULL;
811     char* server_port_str = NULL;
812 
813         /* If defined, this should be an absolute path to
814          * the directory containing all of the various system images
815          * for a particular product.  If not defined, and the adb
816          * command requires this information, then the user must
817          * specify the path using "-p".
818          */
819     gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
820     if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
821         gProductOutPath = NULL;
822     }
823     // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
824 
825     serial = getenv("ANDROID_SERIAL");
826 
827     /* Validate and assign the server port */
828     server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
829     int server_port = DEFAULT_ADB_PORT;
830     if (server_port_str && strlen(server_port_str) > 0) {
831         server_port = (int) strtol(server_port_str, NULL, 0);
832         if (server_port <= 0) {
833             fprintf(stderr,
834                     "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n",
835                     server_port_str);
836             return usage();
837         }
838     }
839 
840     /* modifiers and flags */
841     while(argc > 0) {
842         if(!strcmp(argv[0],"server")) {
843             is_server = 1;
844         } else if(!strcmp(argv[0],"nodaemon")) {
845             no_daemon = 1;
846         } else if (!strcmp(argv[0], "fork-server")) {
847             /* this is a special flag used only when the ADB client launches the ADB Server */
848             is_daemon = 1;
849         } else if(!strcmp(argv[0],"persist")) {
850             persist = 1;
851         } else if(!strncmp(argv[0], "-p", 2)) {
852             const char *product = NULL;
853             if (argv[0][2] == '\0') {
854                 if (argc < 2) return usage();
855                 product = argv[1];
856                 argc--;
857                 argv++;
858             } else {
859                 product = argv[1] + 2;
860             }
861             gProductOutPath = find_product_out_path(product);
862             if (gProductOutPath == NULL) {
863                 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
864                         product);
865                 return usage();
866             }
867         } else if (argv[0][0]=='-' && argv[0][1]=='s') {
868             if (isdigit(argv[0][2])) {
869                 serial = argv[0] + 2;
870             } else {
871                 if(argc < 2 || argv[0][2] != '\0') return usage();
872                 serial = argv[1];
873                 argc--;
874                 argv++;
875             }
876         } else if (!strcmp(argv[0],"-d")) {
877             ttype = kTransportUsb;
878         } else if (!strcmp(argv[0],"-e")) {
879             ttype = kTransportLocal;
880         } else {
881                 /* out of recognized modifiers and flags */
882             break;
883         }
884         argc--;
885         argv++;
886     }
887 
888     adb_set_transport(ttype, serial);
889     adb_set_tcp_specifics(server_port);
890 
891     if (is_server) {
892         if (no_daemon || is_daemon) {
893             r = adb_main(is_daemon, server_port);
894         } else {
895             r = launch_server(server_port);
896         }
897         if(r) {
898             fprintf(stderr,"* could not start server *\n");
899         }
900         return r;
901     }
902 
903 top:
904     if(argc == 0) {
905         return usage();
906     }
907 
908     /* adb_connect() commands */
909 
910     if(!strcmp(argv[0], "devices")) {
911         char *tmp;
912         snprintf(buf, sizeof buf, "host:%s", argv[0]);
913         tmp = adb_query(buf);
914         if(tmp) {
915             printf("List of devices attached \n");
916             printf("%s\n", tmp);
917             return 0;
918         } else {
919             return 1;
920         }
921     }
922 
923     if(!strcmp(argv[0], "connect")) {
924         char *tmp;
925         if (argc != 2) {
926             fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
927             return 1;
928         }
929         snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
930         tmp = adb_query(buf);
931         if(tmp) {
932             printf("%s\n", tmp);
933             return 0;
934         } else {
935             return 1;
936         }
937     }
938 
939     if(!strcmp(argv[0], "disconnect")) {
940         char *tmp;
941         if (argc > 2) {
942             fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
943             return 1;
944         }
945         if (argc == 2) {
946             snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
947         } else {
948             snprintf(buf, sizeof buf, "host:disconnect:");
949         }
950         tmp = adb_query(buf);
951         if(tmp) {
952             printf("%s\n", tmp);
953             return 0;
954         } else {
955             return 1;
956         }
957     }
958 
959     if (!strcmp(argv[0], "emu")) {
960         return adb_send_emulator_command(argc, argv);
961     }
962 
963     if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
964         int r;
965         int fd;
966 
967         char h = (argv[0][0] == 'h');
968 
969         if (h) {
970             printf("\x1b[41;33m");
971             fflush(stdout);
972         }
973 
974         if(argc < 2) {
975             D("starting interactive shell\n");
976             r = interactive_shell();
977             if (h) {
978                 printf("\x1b[0m");
979                 fflush(stdout);
980             }
981             return r;
982         }
983 
984         snprintf(buf, sizeof buf, "shell:%s", argv[1]);
985         argc -= 2;
986         argv += 2;
987         while(argc-- > 0) {
988             strcat(buf, " ");
989 
990             /* quote empty strings and strings with spaces */
991             quote = (**argv == 0 || strchr(*argv, ' '));
992             if (quote)
993                 strcat(buf, "\"");
994             strcat(buf, *argv++);
995             if (quote)
996                 strcat(buf, "\"");
997         }
998 
999         for(;;) {
1000             D("interactive shell loop. buff=%s\n", buf);
1001             fd = adb_connect(buf);
1002             if(fd >= 0) {
1003                 D("about to read_and_dump(fd=%d)\n", fd);
1004                 read_and_dump(fd);
1005                 D("read_and_dump() done.\n");
1006                 adb_close(fd);
1007                 r = 0;
1008             } else {
1009                 fprintf(stderr,"error: %s\n", adb_error());
1010                 r = -1;
1011             }
1012 
1013             if(persist) {
1014                 fprintf(stderr,"\n- waiting for device -\n");
1015                 adb_sleep_ms(1000);
1016                 do_cmd(ttype, serial, "wait-for-device", 0);
1017             } else {
1018                 if (h) {
1019                     printf("\x1b[0m");
1020                     fflush(stdout);
1021                 }
1022                 D("interactive shell loop. return r=%d\n", r);
1023                 return r;
1024             }
1025         }
1026     }
1027 
1028     if(!strcmp(argv[0], "kill-server")) {
1029         int fd;
1030         fd = _adb_connect("host:kill");
1031         if(fd == -1) {
1032             fprintf(stderr,"* server not running *\n");
1033             return 1;
1034         }
1035         return 0;
1036     }
1037 
1038     if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
1039             || !strcmp(argv[0], "reboot-bootloader")
1040             || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
1041             || !strcmp(argv[0], "root")) {
1042         char command[100];
1043         if (!strcmp(argv[0], "reboot-bootloader"))
1044             snprintf(command, sizeof(command), "reboot:bootloader");
1045         else if (argc > 1)
1046             snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
1047         else
1048             snprintf(command, sizeof(command), "%s:", argv[0]);
1049         int fd = adb_connect(command);
1050         if(fd >= 0) {
1051             read_and_dump(fd);
1052             adb_close(fd);
1053             return 0;
1054         }
1055         fprintf(stderr,"error: %s\n", adb_error());
1056         return 1;
1057     }
1058 
1059     if(!strcmp(argv[0], "bugreport")) {
1060         if (argc != 1) return usage();
1061         do_cmd(ttype, serial, "shell", "bugreport", 0);
1062         return 0;
1063     }
1064 
1065     /* adb_command() wrapper commands */
1066 
1067     if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1068         char* service = argv[0];
1069         if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1070             if (ttype == kTransportUsb) {
1071                 service = "wait-for-usb";
1072             } else if (ttype == kTransportLocal) {
1073                 service = "wait-for-local";
1074             } else {
1075                 service = "wait-for-any";
1076             }
1077         }
1078 
1079         format_host_command(buf, sizeof buf, service, ttype, serial);
1080 
1081         if (adb_command(buf)) {
1082             D("failure: %s *\n",adb_error());
1083             fprintf(stderr,"error: %s\n", adb_error());
1084             return 1;
1085         }
1086 
1087         /* Allow a command to be run after wait-for-device,
1088             * e.g. 'adb wait-for-device shell'.
1089             */
1090         if(argc > 1) {
1091             argc--;
1092             argv++;
1093             goto top;
1094         }
1095         return 0;
1096     }
1097 
1098     if(!strcmp(argv[0], "forward")) {
1099         if(argc != 3) return usage();
1100         if (serial) {
1101             snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial, argv[1], argv[2]);
1102         } else if (ttype == kTransportUsb) {
1103             snprintf(buf, sizeof buf, "host-usb:forward:%s;%s", argv[1], argv[2]);
1104         } else if (ttype == kTransportLocal) {
1105             snprintf(buf, sizeof buf, "host-local:forward:%s;%s", argv[1], argv[2]);
1106         } else {
1107             snprintf(buf, sizeof buf, "host:forward:%s;%s", argv[1], argv[2]);
1108         }
1109         if(adb_command(buf)) {
1110             fprintf(stderr,"error: %s\n", adb_error());
1111             return 1;
1112         }
1113         return 0;
1114     }
1115 
1116     /* do_sync_*() commands */
1117 
1118     if(!strcmp(argv[0], "ls")) {
1119         if(argc != 2) return usage();
1120         return do_sync_ls(argv[1]);
1121     }
1122 
1123     if(!strcmp(argv[0], "push")) {
1124         if(argc != 3) return usage();
1125         return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
1126     }
1127 
1128     if(!strcmp(argv[0], "pull")) {
1129         if (argc == 2) {
1130             return do_sync_pull(argv[1], ".");
1131         } else if (argc == 3) {
1132             return do_sync_pull(argv[1], argv[2]);
1133         } else {
1134             return usage();
1135         }
1136     }
1137 
1138     if(!strcmp(argv[0], "install")) {
1139         if (argc < 2) return usage();
1140         return install_app(ttype, serial, argc, argv);
1141     }
1142 
1143     if(!strcmp(argv[0], "uninstall")) {
1144         if (argc < 2) return usage();
1145         return uninstall_app(ttype, serial, argc, argv);
1146     }
1147 
1148     if(!strcmp(argv[0], "sync")) {
1149         char *srcarg, *android_srcpath, *data_srcpath;
1150         int listonly = 0;
1151 
1152         int ret;
1153         if(argc < 2) {
1154             /* No local path was specified. */
1155             srcarg = NULL;
1156         } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1157             listonly = 1;
1158             if (argc == 3) {
1159                 srcarg = argv[2];
1160             } else {
1161                 srcarg = NULL;
1162             }
1163         } else if(argc == 2) {
1164             /* A local path or "android"/"data" arg was specified. */
1165             srcarg = argv[1];
1166         } else {
1167             return usage();
1168         }
1169         ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1170         if(ret != 0) return usage();
1171 
1172         if(android_srcpath != NULL)
1173             ret = do_sync_sync(android_srcpath, "/system", listonly);
1174         if(ret == 0 && data_srcpath != NULL)
1175             ret = do_sync_sync(data_srcpath, "/data", listonly);
1176 
1177         free(android_srcpath);
1178         free(data_srcpath);
1179         return ret;
1180     }
1181 
1182     /* passthrough commands */
1183 
1184     if(!strcmp(argv[0],"get-state") ||
1185         !strcmp(argv[0],"get-serialno"))
1186     {
1187         char *tmp;
1188 
1189         format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1190         tmp = adb_query(buf);
1191         if(tmp) {
1192             printf("%s\n", tmp);
1193             return 0;
1194         } else {
1195             return 1;
1196         }
1197     }
1198 
1199     /* other commands */
1200 
1201     if(!strcmp(argv[0],"status-window")) {
1202         status_window(ttype, serial);
1203         return 0;
1204     }
1205 
1206     if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1207         return logcat(ttype, serial, argc, argv);
1208     }
1209 
1210     if(!strcmp(argv[0],"ppp")) {
1211         return ppp(argc, argv);
1212     }
1213 
1214     if (!strcmp(argv[0], "start-server")) {
1215         return adb_connect("host:start-server");
1216     }
1217 
1218     if (!strcmp(argv[0], "backup")) {
1219         return backup(argc, argv);
1220     }
1221 
1222     if (!strcmp(argv[0], "restore")) {
1223         return restore(argc, argv);
1224     }
1225 
1226     if (!strcmp(argv[0], "jdwp")) {
1227         int  fd = adb_connect("jdwp");
1228         if (fd >= 0) {
1229             read_and_dump(fd);
1230             adb_close(fd);
1231             return 0;
1232         } else {
1233             fprintf(stderr, "error: %s\n", adb_error());
1234             return -1;
1235         }
1236     }
1237 
1238     /* "adb /?" is a common idiom under Windows */
1239     if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1240         help();
1241         return 0;
1242     }
1243 
1244     if(!strcmp(argv[0], "version")) {
1245         version(stdout);
1246         return 0;
1247     }
1248 
1249     usage();
1250     return 1;
1251 }
1252 
do_cmd(transport_type ttype,char * serial,char * cmd,...)1253 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1254 {
1255     char *argv[16];
1256     int argc;
1257     va_list ap;
1258 
1259     va_start(ap, cmd);
1260     argc = 0;
1261 
1262     if (serial) {
1263         argv[argc++] = "-s";
1264         argv[argc++] = serial;
1265     } else if (ttype == kTransportUsb) {
1266         argv[argc++] = "-d";
1267     } else if (ttype == kTransportLocal) {
1268         argv[argc++] = "-e";
1269     }
1270 
1271     argv[argc++] = cmd;
1272     while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1273     va_end(ap);
1274 
1275 #if 0
1276     int n;
1277     fprintf(stderr,"argc = %d\n",argc);
1278     for(n = 0; n < argc; n++) {
1279         fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1280     }
1281 #endif
1282 
1283     return adb_commandline(argc, argv);
1284 }
1285 
find_sync_dirs(const char * srcarg,char ** android_srcdir_out,char ** data_srcdir_out)1286 int find_sync_dirs(const char *srcarg,
1287         char **android_srcdir_out, char **data_srcdir_out)
1288 {
1289     char *android_srcdir, *data_srcdir;
1290 
1291     if(srcarg == NULL) {
1292         android_srcdir = product_file("system");
1293         data_srcdir = product_file("data");
1294     } else {
1295         /* srcarg may be "data", "system" or NULL.
1296          * if srcarg is NULL, then both data and system are synced
1297          */
1298         if(strcmp(srcarg, "system") == 0) {
1299             android_srcdir = product_file("system");
1300             data_srcdir = NULL;
1301         } else if(strcmp(srcarg, "data") == 0) {
1302             android_srcdir = NULL;
1303             data_srcdir = product_file("data");
1304         } else {
1305             /* It's not "system" or "data".
1306              */
1307             return 1;
1308         }
1309     }
1310 
1311     if(android_srcdir_out != NULL)
1312         *android_srcdir_out = android_srcdir;
1313     else
1314         free(android_srcdir);
1315 
1316     if(data_srcdir_out != NULL)
1317         *data_srcdir_out = data_srcdir;
1318     else
1319         free(data_srcdir);
1320 
1321     return 0;
1322 }
1323 
pm_command(transport_type transport,char * serial,int argc,char ** argv)1324 static int pm_command(transport_type transport, char* serial,
1325                       int argc, char** argv)
1326 {
1327     char buf[4096];
1328 
1329     snprintf(buf, sizeof(buf), "shell:pm");
1330 
1331     while(argc-- > 0) {
1332         char *quoted;
1333 
1334         quoted = dupAndQuote(*argv++);
1335 
1336         strncat(buf, " ", sizeof(buf)-1);
1337         strncat(buf, quoted, sizeof(buf)-1);
1338         free(quoted);
1339     }
1340 
1341     send_shellcommand(transport, serial, buf);
1342     return 0;
1343 }
1344 
uninstall_app(transport_type transport,char * serial,int argc,char ** argv)1345 int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1346 {
1347     /* if the user choose the -k option, we refuse to do it until devices are
1348        out with the option to uninstall the remaining data somehow (adb/ui) */
1349     if (argc == 3 && strcmp(argv[1], "-k") == 0)
1350     {
1351         printf(
1352             "The -k option uninstalls the application while retaining the data/cache.\n"
1353             "At the moment, there is no way to remove the remaining data.\n"
1354             "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1355             "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1356         return -1;
1357     }
1358 
1359     /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1360     return pm_command(transport, serial, argc, argv);
1361 }
1362 
delete_file(transport_type transport,char * serial,char * filename)1363 static int delete_file(transport_type transport, char* serial, char* filename)
1364 {
1365     char buf[4096];
1366     char* quoted;
1367 
1368     snprintf(buf, sizeof(buf), "shell:rm ");
1369     quoted = dupAndQuote(filename);
1370     strncat(buf, quoted, sizeof(buf)-1);
1371     free(quoted);
1372 
1373     send_shellcommand(transport, serial, buf);
1374     return 0;
1375 }
1376 
get_basename(const char * filename)1377 static const char* get_basename(const char* filename)
1378 {
1379     const char* basename = adb_dirstop(filename);
1380     if (basename) {
1381         basename++;
1382         return basename;
1383     } else {
1384         return filename;
1385     }
1386 }
1387 
check_file(const char * filename)1388 static int check_file(const char* filename)
1389 {
1390     struct stat st;
1391 
1392     if (filename == NULL) {
1393         return 0;
1394     }
1395 
1396     if (stat(filename, &st) != 0) {
1397         fprintf(stderr, "can't find '%s' to install\n", filename);
1398         return 1;
1399     }
1400 
1401     if (!S_ISREG(st.st_mode)) {
1402         fprintf(stderr, "can't install '%s' because it's not a file\n", filename);
1403         return 1;
1404     }
1405 
1406     return 0;
1407 }
1408 
install_app(transport_type transport,char * serial,int argc,char ** argv)1409 int install_app(transport_type transport, char* serial, int argc, char** argv)
1410 {
1411     static const char *const DATA_DEST = "/data/local/tmp/%s";
1412     static const char *const SD_DEST = "/sdcard/tmp/%s";
1413     const char* where = DATA_DEST;
1414     char apk_dest[PATH_MAX];
1415     char verification_dest[PATH_MAX];
1416     char* apk_file;
1417     char* verification_file = NULL;
1418     int file_arg = -1;
1419     int err;
1420     int i;
1421 
1422     for (i = 1; i < argc; i++) {
1423         if (*argv[i] != '-') {
1424             file_arg = i;
1425             break;
1426         } else if (!strcmp(argv[i], "-i")) {
1427             // Skip the installer package name.
1428             i++;
1429         } else if (!strcmp(argv[i], "-s")) {
1430             where = SD_DEST;
1431         }
1432     }
1433 
1434     if (file_arg < 0) {
1435         fprintf(stderr, "can't find filename in arguments\n");
1436         return 1;
1437     } else if (file_arg + 2 < argc) {
1438         fprintf(stderr, "too many files specified; only takes APK file and verifier file\n");
1439         return 1;
1440     }
1441 
1442     apk_file = argv[file_arg];
1443 
1444     if (file_arg != argc - 1) {
1445         verification_file = argv[file_arg + 1];
1446     }
1447 
1448     if (check_file(apk_file) || check_file(verification_file)) {
1449         return 1;
1450     }
1451 
1452     snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
1453     if (verification_file != NULL) {
1454         snprintf(verification_dest, sizeof(verification_dest), where, get_basename(verification_file));
1455 
1456         if (!strcmp(apk_dest, verification_dest)) {
1457             fprintf(stderr, "APK and verification file can't have the same name\n");
1458             return 1;
1459         }
1460     }
1461 
1462     err = do_sync_push(apk_file, apk_dest, 1 /* verify APK */);
1463     if (err) {
1464         return err;
1465     } else {
1466         argv[file_arg] = apk_dest; /* destination name, not source location */
1467     }
1468 
1469     if (verification_file != NULL) {
1470         err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */);
1471         if (err) {
1472             goto cleanup_apk;
1473         } else {
1474             argv[file_arg + 1] = verification_dest; /* destination name, not source location */
1475         }
1476     }
1477 
1478     pm_command(transport, serial, argc, argv);
1479 
1480     if (verification_file != NULL) {
1481         delete_file(transport, serial, verification_dest);
1482     }
1483 
1484 cleanup_apk:
1485     delete_file(transport, serial, apk_dest);
1486 
1487     return err;
1488 }
1489