file_sync_client.c revision 457d81cec12fce6e38c0dcd94d33d06036c2618a
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/time.h>
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <time.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h>
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <limits.h>
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <zipfile/zipfile.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h"
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h"
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb_client.h"
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "file_sync_service.h"
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic unsigned total_bytes;
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long long start_time;
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long long NOW()
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct timeval tv;
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    gettimeofday(&tv, 0);
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ((long long) tv.tv_usec) +
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        1000000LL * ((long long) tv.tv_sec);
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void BEGIN()
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    total_bytes = 0;
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    start_time = NOW();
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void END()
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long long t = NOW() - start_time;
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(total_bytes == 0) return;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (t == 0)  /* prevent division by 0 :-) */
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t = 1000000;
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"%lld KB/s (%d bytes in %lld.%03llds)\n",
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ((((long long) total_bytes) * 1000000LL) / t) / 1024LL,
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL);
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid sync_quit(int fd)
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_QUIT;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = 0;
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    writex(fd, &msg.req, sizeof(msg.req));
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef void (*sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie);
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sync_ls(int fd, const char *path, sync_ls_cb func, void *cookie)
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[257];
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = strlen(path);
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len > 1024) goto fail;
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_LIST;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, &msg.dent, sizeof(msg.dent))) break;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(msg.dent.id == ID_DONE) return 0;
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(msg.dent.id != ID_DENT) break;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = ltohl(msg.dent.namelen);
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len > 256) break;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, buf, len)) break;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buf[len] = 0;
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        func(ltohl(msg.dent.mode),
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             ltohl(msg.dent.size),
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             ltohl(msg.dent.time),
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             buf, cookie);
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail:
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct syncsendbuf syncsendbuf;
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct syncsendbuf {
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned id;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned size;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char data[SYNC_DATA_MAX];
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic syncsendbuf send_buffer;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sync_readtime(int fd, const char *path, unsigned *timestamp)
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len = strlen(path);
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_STAT;
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.stat, sizeof(msg.stat))) {
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.stat.id != ID_STAT) {
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *timestamp = ltohl(msg.stat.time);
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sync_start_readtime(int fd, const char *path)
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len = strlen(path);
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_STAT;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sync_finish_readtime(int fd, unsigned int *timestamp,
168f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner                                unsigned int *mode, unsigned int *size)
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.stat, sizeof(msg.stat)))
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.stat.id != ID_STAT)
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *timestamp = ltohl(msg.stat.time);
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *mode = ltohl(msg.stat.mode);
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *size = ltohl(msg.stat.size);
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sync_readmode(int fd, const char *path, unsigned *mode)
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len = strlen(path);
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_STAT;
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.stat, sizeof(msg.stat))) {
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.stat.id != ID_STAT) {
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *mode = ltohl(msg.stat.mode);
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int lfd, err = 0;
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    lfd = adb_open(path, O_RDONLY);
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(lfd < 0) {
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno));
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->id = ID_DATA;
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = adb_read(lfd, sbuf->data, SYNC_DATA_MAX);
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(!ret)
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(ret < 0) {
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(errno == EINTR)
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno));
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sbuf->size = htoll(ret);
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(fd, sbuf, sizeof(unsigned) * 2 + ret)){
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            err = -1;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total_bytes += ret;
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(lfd);
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return err;
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf)
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int err = 0;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int total = 0;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->id = ID_DATA;
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (total < size) {
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int count = size - total;
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (count > SYNC_DATA_MAX) {
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            count = SYNC_DATA_MAX;
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy(sbuf->data, &file_buffer[total], count);
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sbuf->size = htoll(count);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(fd, sbuf, sizeof(unsigned) * 2 + count)){
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            err = -1;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total += count;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total_bytes += count;
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return err;
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len, ret;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = readlink(path, sbuf->data, SYNC_DATA_MAX-1);
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len < 0) {
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "error reading link '%s': %s\n", path, strerror(errno));
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->data[len] = '\0';
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->size = htoll(len + 1);
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->id = ID_DATA;
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = writex(fd, sbuf, sizeof(unsigned) * 2 + len + 1);
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ret)
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    total_bytes += len + 1;
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sync_send(int fd, const char *lpath, const char *rpath,
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     unsigned mtime, mode_t mode, int verifyApk)
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len, r;
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncsendbuf *sbuf = &send_buffer;
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* file_buffer = NULL;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int size = 0;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char tmp[64];
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = strlen(rpath);
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len > 1024) goto fail;
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(tmp, sizeof(tmp), ",%d", mode);
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    r = strlen(tmp);
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (verifyApk) {
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int lfd;
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        zipfile_t zip;
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        zipentry_t entry;
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int amt;
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // if we are transferring an APK file, then sanity check to make sure
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // we have a real zip file that contains an AndroidManifest.xml
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // this requires that we read the entire file into memory.
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lfd = adb_open(lpath, O_RDONLY);
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(lfd < 0) {
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        size = adb_lseek(lfd, 0, SEEK_END);
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (size == -1 || -1 == adb_lseek(lfd, 0, SEEK_SET)) {
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "error seeking in file '%s'\n", lpath);
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        file_buffer = (char *)malloc(size);
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (file_buffer == NULL) {
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "could not allocate buffer for '%s'\n",
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    lpath);
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        amt = adb_read(lfd, file_buffer, size);
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (amt != size) {
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "error reading from file: '%s'\n", lpath);
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(file_buffer);
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(lfd);
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        zip = init_zipfile(file_buffer, size);
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (zip == NULL) {
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "file '%s' is not a valid zip file\n",
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    lpath);
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(file_buffer);
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        entry = lookup_zipentry(zip, "AndroidManifest.xml");
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        release_zipfile(zip);
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (entry == NULL) {
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "file '%s' does not contain AndroidManifest.xml\n",
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    lpath);
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(file_buffer);
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_SEND;
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len + r);
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, rpath, len) || writex(fd, tmp, r)) {
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(file_buffer);
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (file_buffer) {
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        write_data_buffer(fd, file_buffer, size, sbuf);
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(file_buffer);
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (S_ISREG(mode))
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        write_data_file(fd, lpath, sbuf);
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else if (S_ISLNK(mode))
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        write_data_link(fd, lpath, sbuf);
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.data.id = ID_DONE;
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.data.size = htoll(mtime);
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.data, sizeof(msg.data)))
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.status, sizeof(msg.status)))
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.status.id != ID_OKAY) {
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(msg.status.id == ID_FAIL) {
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            len = ltohl(msg.status.msglen);
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(len > 256) len = 256;
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(readx(fd, sbuf->data, len)) {
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sbuf->data[len] = 0;
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            strcpy(sbuf->data, "unknown reason");
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"failed to copy '%s' to '%s': %s\n", lpath, rpath, sbuf->data);
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail:
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"protocol failure\n");
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int mkdirs(char *name)
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret;
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *x = name + 1;
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x = adb_dirstart(x);
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(x == 0) return 0;
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *x = 0;
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = adb_mkdir(name, 0775);
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *x = OS_PATH_SEPARATOR;
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if((ret < 0) && (errno != EEXIST)) {
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return ret;
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x++;
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sync_recv(int fd, const char *rpath, const char *lpath)
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len;
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int lfd = -1;
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *buffer = send_buffer.data;
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned id;
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = strlen(rpath);
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len > 1024) return -1;
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_RECV;
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, rpath, len)) {
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.data, sizeof(msg.data))) {
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    id = msg.data.id;
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((id == ID_DATA) || (id == ID_DONE)) {
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_unlink(lpath);
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mkdirs((char *)lpath);
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lfd = adb_creat(lpath, 0644);
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(lfd < 0) {
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto handle_data;
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto remote_error;
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, &msg.data, sizeof(msg.data))) {
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        id = msg.data.id;
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    handle_data:
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = ltohl(msg.data.size);
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(id == ID_DONE) break;
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(id != ID_DATA) goto remote_error;
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len > SYNC_DATA_MAX) {
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"data overrun\n");
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, buffer, len)) {
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(lfd, buffer, len)) {
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot write '%s': %s\n", rpath, strerror(errno));
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total_bytes += len;
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(lfd);
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectremote_error:
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(lfd);
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_unlink(lpath);
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(id == ID_FAIL) {
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = ltohl(msg.data.size);
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len > 256) len = 256;
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, buffer, len)) {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buffer[len] = 0;
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy(buffer, &id, 4);
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buffer[4] = 0;
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//        strcpy(buffer,"unknown reason");
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"failed to copy '%s' to '%s': %s\n", rpath, lpath, buffer);
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* --- */
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void do_sync_ls_cb(unsigned mode, unsigned size, unsigned time,
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                          const char *name, void *cookie)
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("%08x %08x %08x %s\n", mode, size, time, name);
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint do_sync_ls(const char *path)
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd = adb_connect("sync:");
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(sync_ls(fd, path, do_sync_ls_cb, 0)) {
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sync_quit(fd);
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct copyinfo copyinfo;
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct copyinfo
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *next;
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *src;
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *dst;
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int time;
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int mode;
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int size;
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int flag;
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //char data[0];
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcopyinfo *mkcopyinfo(const char *spath, const char *dpath,
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     const char *name, int isdir)
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int slen = strlen(spath);
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dlen = strlen(dpath);
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int nlen = strlen(name);
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ssize = slen + nlen + 2;
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dsize = dlen + nlen + 2;
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci = malloc(sizeof(copyinfo) + ssize + dsize);
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ci == 0) {
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"out of memory\n");
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        abort();
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->next = 0;
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->time = 0;
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->mode = 0;
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->size = 0;
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->flag = 0;
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->src = (const char*)(ci + 1);
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->dst = ci->src + ssize;
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf((char*) ci->src, ssize, isdir ? "%s%s/" : "%s%s", spath, name);
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf((char*) ci->dst, dsize, isdir ? "%s%s/" : "%s%s", dpath, name);
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//    fprintf(stderr,"mkcopyinfo('%s','%s')\n", ci->src, ci->dst);
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ci;
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int local_build_list(copyinfo **filelist,
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            const char *lpath, const char *rpath)
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DIR *d;
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct dirent *de;
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *dirlist = 0;
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci, *next;
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//    fprintf(stderr,"local_build_list('%s','%s')\n", lpath, rpath);
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d = opendir(lpath);
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(d == 0) {
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while((de = readdir(d))) {
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char stat_path[PATH_MAX];
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *name = de->d_name;
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(name[0] == '.') {
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(name[1] == 0) continue;
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if((name[1] == '.') && (name[2] == 0)) continue;
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /*
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * We could use d_type if HAVE_DIRENT_D_TYPE is defined, but reiserfs
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * always returns DT_UNKNOWN, so we just use stat() for all cases.
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path))
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcpy(stat_path, lpath);
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcat(stat_path, de->d_name);
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        stat(stat_path, &st);
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (S_ISDIR(st.st_mode)) {
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ci = mkcopyinfo(lpath, rpath, name, 1);
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ci->next = dirlist;
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dirlist = ci;
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ci = mkcopyinfo(lpath, rpath, name, 0);
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(lstat(ci->src, &st)) {
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                closedir(d);
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "skipping special file '%s'\n", ci->src);
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                free(ci);
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ci->time = st.st_mtime;
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ci->mode = st.st_mode;
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ci->size = st.st_size;
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ci->next = *filelist;
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *filelist = ci;
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    closedir(d);
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(ci = dirlist; ci != 0; ci = next) {
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        next = ci->next;
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        local_build_list(filelist, ci->src, ci->dst);
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ci);
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, int checktimestamps)
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *filelist = 0;
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci, *next;
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int pushed = 0;
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int skipped = 0;
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((lpath[0] == 0) || (rpath[0] == 0)) return -1;
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(lpath[strlen(lpath) - 1] != '/') {
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  tmplen = strlen(lpath)+2;
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(tmp == 0) return -1;
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/",lpath);
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lpath = tmp;
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(rpath[strlen(rpath) - 1] != '/') {
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int tmplen = strlen(rpath)+2;
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(tmp == 0) return -1;
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/",rpath);
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        rpath = tmp;
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(local_build_list(&filelist, lpath, rpath)) {
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(checktimestamps){
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(ci = filelist; ci != 0; ci = ci->next) {
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(sync_start_readtime(fd, ci->dst)) {
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(ci = filelist; ci != 0; ci = ci->next) {
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            unsigned int timestamp, mode, size;
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(sync_finish_readtime(fd, &timestamp, &mode, &size))
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(size == ci->size) {
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* for links, we cannot update the atime/mtime */
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ci->flag = 1;
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(ci = filelist; ci != 0; ci = next) {
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        next = ci->next;
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(ci->flag == 0) {
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"push: %s -> %s\n", ci->src, ci->dst);
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pushed++;
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped++;
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ci);
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"%d file%s pushed. %d file%s skipped.\n",
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pushed, (pushed == 1) ? "" : "s",
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped, (skipped == 1) ? "" : "s");
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint do_sync_push(const char *lpath, const char *rpath, int verifyApk)
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned mode;
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_connect("sync:");
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(stat(lpath, &st)) {
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno));
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sync_quit(fd);
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(S_ISDIR(st.st_mode)) {
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(copy_local_dir_remote(fd, lpath, rpath, 0)) {
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(sync_readmode(fd, rpath, &mode)) {
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if((mode != 0) && S_ISDIR(mode)) {
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* if we're copying a local file to a remote directory,
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ** we *really* want to copy to remotedir + "/" + localfilename
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                */
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const char *name = adb_dirstop(lpath);
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(name == 0) {
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                name = lpath;
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                name++;
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int  tmplen = strlen(name) + strlen(rpath) + 2;
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            char *tmp = malloc(strlen(name) + strlen(rpath) + 2);
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(tmp == 0) return 1;
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            snprintf(tmp, tmplen, "%s/%s", rpath, name);
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            rpath = tmp;
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk)) {
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct {
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo **filelist;
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo **dirlist;
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *rpath;
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *lpath;
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} sync_ls_build_list_cb_args;
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time,
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                      const char *name, void *cookie)
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie;
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci;
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (S_ISDIR(mode)) {
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        copyinfo **dirlist = args->dirlist;
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* Don't try recursing down "." or ".." */
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (name[0] == '.') {
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (name[1] == '\0') return;
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if ((name[1] == '.') && (name[2] == '\0')) return;
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci = mkcopyinfo(args->rpath, args->lpath, name, 1);
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->next = *dirlist;
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *dirlist = ci;
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (S_ISREG(mode) || S_ISLNK(mode)) {
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        copyinfo **filelist = args->filelist;
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci = mkcopyinfo(args->rpath, args->lpath, name, 0);
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->time = time;
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->mode = mode;
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->size = size;
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->next = *filelist;
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *filelist = ci;
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "skipping special file '%s'\n", name);
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remote_build_list(int syncfd, copyinfo **filelist,
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                             const char *rpath, const char *lpath)
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *dirlist = NULL;
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sync_ls_build_list_cb_args args;
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.filelist = filelist;
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.dirlist = &dirlist;
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.rpath = rpath;
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.lpath = lpath;
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Put the files/dirs in rpath on the lists. */
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sync_ls(syncfd, rpath, sync_ls_build_list_cb, (void *)&args)) {
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Recurse into each directory we found. */
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (dirlist != NULL) {
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        copyinfo *next = dirlist->next;
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (remote_build_list(syncfd, filelist, dirlist->src, dirlist->dst)) {
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(dirlist);
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dirlist = next;
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                 int checktimestamps)
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *filelist = 0;
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci, *next;
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int pulled = 0;
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int skipped = 0;
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Make sure that both directory paths end in a slash. */
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (rpath[0] == 0 || lpath[0] == 0) return -1;
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (rpath[strlen(rpath) - 1] != '/') {
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  tmplen = strlen(rpath) + 2;
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (tmp == 0) return -1;
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/", rpath);
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        rpath = tmp;
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (lpath[strlen(lpath) - 1] != '/') {
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  tmplen = strlen(lpath) + 2;
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (tmp == 0) return -1;
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/", lpath);
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lpath = tmp;
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "pull: building file list...\n");
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Recursively build the list of files to copy. */
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (remote_build_list(fd, &filelist, rpath, lpath)) {
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (checktimestamps) {
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (ci = filelist; ci != 0; ci = ci->next) {
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (sync_start_readtime(fd, ci->dst)) {
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (ci = filelist; ci != 0; ci = ci->next) {
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            unsigned int timestamp, mode, size;
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (sync_finish_readtime(fd, &timestamp, &mode, &size))
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
911f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner            if (size == ci->size) {
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* for links, we cannot update the atime/mtime */
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
914f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner                    (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ci->flag = 1;
916f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner            }
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (ci = filelist; ci != 0; ci = next) {
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        next = ci->next;
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ci->flag == 0) {
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (sync_recv(fd, ci->src, ci->dst)) {
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pulled++;
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped++;
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ci);
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "%d file%s pulled. %d file%s skipped.\n",
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pulled, (pulled == 1) ? "" : "s",
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped, (skipped == 1) ? "" : "s");
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint do_sync_pull(const char *rpath, const char *lpath)
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned mode;
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_connect("sync:");
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(sync_readmode(fd, rpath, &mode)) {
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(mode == 0) {
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"remote object '%s' does not exist\n", rpath);
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
962457d81cec12fce6e38c0dcd94d33d06036c2618aMatt Fischer    if(S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) {
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(stat(lpath, &st) == 0) {
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(S_ISDIR(st.st_mode)) {
965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* if we're copying a remote file to a local directory,
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ** we *really* want to copy to localdir + "/" + remotefilename
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    */
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const char *name = adb_dirstop(rpath);
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(name == 0) {
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    name = rpath;
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } else {
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    name++;
973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                int  tmplen = strlen(name) + strlen(lpath) + 2;
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                char *tmp = malloc(tmplen);
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(tmp == 0) return 1;
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                snprintf(tmp, tmplen, "%s/%s", lpath, name);
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                lpath = tmp;
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(sync_recv(fd, rpath, lpath)) {
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(S_ISDIR(mode)) {
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (copy_remote_dir_local(fd, rpath, lpath, 0)) {
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"remote object '%s' not a file or directory\n", rpath);
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint do_sync_sync(const char *lpath, const char *rpath)
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"syncing %s...\n",rpath);
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd = adb_connect("sync:");
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BEGIN();
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(copy_local_dir_remote(fd, lpath, rpath, 1)){
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        END();
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sync_quit(fd);
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1023