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>
287a5e2bd0621ee0b1c66d8f4c21497ffb62feff42Greg Hackmann#include <utime.h>
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h"
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h"
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb_client.h"
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "file_sync_service.h"
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
36d9a1430ff2b2d2a52b586dfba1db5ac0128dd85bJeff Smithstatic unsigned long long total_bytes;
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long long start_time;
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long long NOW()
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct timeval tv;
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    gettimeofday(&tv, 0);
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ((long long) tv.tv_usec) +
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        1000000LL * ((long long) tv.tv_sec);
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void BEGIN()
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    total_bytes = 0;
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    start_time = NOW();
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void END()
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long long t = NOW() - start_time;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(total_bytes == 0) return;
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (t == 0)  /* prevent division by 0 :-) */
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t = 1000000;
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61ee878753f915a0176ea411b71bdffde064e24ae0Mike Lockwood    fprintf(stderr,"%lld KB/s (%lld bytes in %lld.%03llds)\n",
62d9a1430ff2b2d2a52b586dfba1db5ac0128dd85bJeff Smith            ((total_bytes * 1000000LL) / t) / 1024LL,
63d9a1430ff2b2d2a52b586dfba1db5ac0128dd85bJeff Smith            total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL);
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindnerstatic const char* transfer_progress_format = "\rTransferring: %llu/%llu (%d%%)";
6776f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
6876f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindnerstatic void print_transfer_progress(unsigned long long bytes_current,
6976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner                                    unsigned long long bytes_total) {
7076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    if (bytes_total == 0) return;
7176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
7276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    fprintf(stderr, transfer_progress_format, bytes_current, bytes_total,
7376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            (int) (bytes_current * 100 / bytes_total));
7476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
7576f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    if (bytes_current == bytes_total) {
7676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        fputc('\n', stderr);
7776f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    }
7876f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
7976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    fflush(stderr);
8076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner}
8176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid sync_quit(int fd)
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_QUIT;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = 0;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    writex(fd, &msg.req, sizeof(msg.req));
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef void (*sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie);
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sync_ls(int fd, const char *path, sync_ls_cb func, void *cookie)
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[257];
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len;
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = strlen(path);
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len > 1024) goto fail;
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_LIST;
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, &msg.dent, sizeof(msg.dent))) break;
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(msg.dent.id == ID_DONE) return 0;
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(msg.dent.id != ID_DENT) break;
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = ltohl(msg.dent.namelen);
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len > 256) break;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, buf, len)) break;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buf[len] = 0;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        func(ltohl(msg.dent.mode),
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             ltohl(msg.dent.size),
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             ltohl(msg.dent.time),
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             buf, cookie);
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail:
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct syncsendbuf syncsendbuf;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct syncsendbuf {
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned id;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned size;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char data[SYNC_DATA_MAX];
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic syncsendbuf send_buffer;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnarint sync_readtime(int fd, const char *path, unsigned int *timestamp,
144de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar                  unsigned int *mode)
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len = strlen(path);
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_STAT;
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.stat, sizeof(msg.stat))) {
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.stat.id != ID_STAT) {
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *timestamp = ltohl(msg.stat.time);
166de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    *mode = ltohl(msg.stat.mode);
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sync_start_readtime(int fd, const char *path)
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len = strlen(path);
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_STAT;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sync_finish_readtime(int fd, unsigned int *timestamp,
187f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner                                unsigned int *mode, unsigned int *size)
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.stat, sizeof(msg.stat)))
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.stat.id != ID_STAT)
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *timestamp = ltohl(msg.stat.time);
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *mode = ltohl(msg.stat.mode);
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *size = ltohl(msg.stat.size);
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint sync_readmode(int fd, const char *path, unsigned *mode)
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len = strlen(path);
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_STAT;
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, path, len)) {
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.stat, sizeof(msg.stat))) {
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.stat.id != ID_STAT) {
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *mode = ltohl(msg.stat.mode);
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
22976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindnerstatic int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show_progress)
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int lfd, err = 0;
23276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    unsigned long long size = 0;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    lfd = adb_open(path, O_RDONLY);
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(lfd < 0) {
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno));
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
24076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    if (show_progress) {
24176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        // Determine local file size.
24276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        struct stat st;
243de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar        if (fstat(lfd, &st)) {
24476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
24576f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            return -1;
24676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        }
24776f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
24876f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        size = st.st_size;
24976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    }
25076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->id = ID_DATA;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = adb_read(lfd, sbuf->data, SYNC_DATA_MAX);
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(!ret)
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(ret < 0) {
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(errno == EINTR)
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno));
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sbuf->size = htoll(ret);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(fd, sbuf, sizeof(unsigned) * 2 + ret)){
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            err = -1;
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total_bytes += ret;
27276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
27376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (show_progress) {
27476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            print_transfer_progress(total_bytes, size);
27576f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        }
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(lfd);
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return err;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
28276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindnerstatic int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf,
28376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner                             int show_progress)
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int err = 0;
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int total = 0;
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->id = ID_DATA;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (total < size) {
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int count = size - total;
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (count > SYNC_DATA_MAX) {
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            count = SYNC_DATA_MAX;
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy(sbuf->data, &file_buffer[total], count);
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sbuf->size = htoll(count);
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(fd, sbuf, sizeof(unsigned) * 2 + count)){
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            err = -1;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total += count;
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total_bytes += count;
30376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
30476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (show_progress) {
30576f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            print_transfer_progress(total, size);
30676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        }
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return err;
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len, ret;
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = readlink(path, sbuf->data, SYNC_DATA_MAX-1);
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len < 0) {
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "error reading link '%s': %s\n", path, strerror(errno));
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->data[len] = '\0';
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->size = htoll(len + 1);
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sbuf->id = ID_DATA;
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = writex(fd, sbuf, sizeof(unsigned) * 2 + len + 1);
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ret)
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    total_bytes += len + 1;
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int sync_send(int fd, const char *lpath, const char *rpath,
338960df97c2356f5a804d3ef87fe49f788d7ecdfafJeff Sharkey                     unsigned mtime, mode_t mode, int show_progress)
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len, r;
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncsendbuf *sbuf = &send_buffer;
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* file_buffer = NULL;
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int size = 0;
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char tmp[64];
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = strlen(rpath);
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len > 1024) goto fail;
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(tmp, sizeof(tmp), ",%d", mode);
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    r = strlen(tmp);
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_SEND;
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len + r);
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, rpath, len) || writex(fd, tmp, r)) {
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(file_buffer);
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (file_buffer) {
36376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        write_data_buffer(fd, file_buffer, size, sbuf, show_progress);
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(file_buffer);
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (S_ISREG(mode))
36676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        write_data_file(fd, lpath, sbuf, show_progress);
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else if (S_ISLNK(mode))
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        write_data_link(fd, lpath, sbuf);
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.data.id = ID_DONE;
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.data.size = htoll(mtime);
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.data, sizeof(msg.data)))
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto fail;
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.status, sizeof(msg.status)))
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(msg.status.id != ID_OKAY) {
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(msg.status.id == ID_FAIL) {
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            len = ltohl(msg.status.msglen);
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(len > 256) len = 256;
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(readx(fd, sbuf->data, len)) {
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sbuf->data[len] = 0;
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            strcpy(sbuf->data, "unknown reason");
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"failed to copy '%s' to '%s': %s\n", lpath, rpath, sbuf->data);
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail:
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"protocol failure\n");
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
40560299dfd6a5dca059a079bc8e11d45a1fecf02d0Mark Salyzynstatic int mkdirs(const char *name)
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret;
40860299dfd6a5dca059a079bc8e11d45a1fecf02d0Mark Salyzyn    char *x = (char *)name + 1;
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x = adb_dirstart(x);
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(x == 0) return 0;
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *x = 0;
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = adb_mkdir(name, 0775);
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *x = OS_PATH_SEPARATOR;
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if((ret < 0) && (errno != EEXIST)) {
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return ret;
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x++;
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
42476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindnerint sync_recv(int fd, const char *rpath, const char *lpath, int show_progress)
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    syncmsg msg;
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len;
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int lfd = -1;
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *buffer = send_buffer.data;
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned id;
43176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    unsigned long long size = 0;
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = strlen(rpath);
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(len > 1024) return -1;
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    if (show_progress) {
43776f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        // Determine remote file size.
43876f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        syncmsg stat_msg;
43976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        stat_msg.req.id = ID_STAT;
44076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        stat_msg.req.namelen = htoll(len);
44176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
44276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (writex(fd, &stat_msg.req, sizeof(stat_msg.req)) ||
44376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            writex(fd, rpath, len)) {
44476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            return -1;
44576f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        }
44676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
44776f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (readx(fd, &stat_msg.stat, sizeof(stat_msg.stat))) {
44876f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            return -1;
44976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        }
45076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
45176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (stat_msg.stat.id != ID_STAT) return -1;
45276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
45376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        size = ltohl(stat_msg.stat.size);
45476f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner    }
45576f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.id = ID_RECV;
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    msg.req.namelen = htoll(len);
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(writex(fd, &msg.req, sizeof(msg.req)) ||
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       writex(fd, rpath, len)) {
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(readx(fd, &msg.data, sizeof(msg.data))) {
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    id = msg.data.id;
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((id == ID_DATA) || (id == ID_DONE)) {
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_unlink(lpath);
47060299dfd6a5dca059a079bc8e11d45a1fecf02d0Mark Salyzyn        mkdirs(lpath);
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lfd = adb_creat(lpath, 0644);
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(lfd < 0) {
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto handle_data;
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto remote_error;
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, &msg.data, sizeof(msg.data))) {
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        id = msg.data.id;
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    handle_data:
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = ltohl(msg.data.size);
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(id == ID_DONE) break;
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(id != ID_DATA) goto remote_error;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len > SYNC_DATA_MAX) {
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"data overrun\n");
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, buffer, len)) {
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(writex(lfd, buffer, len)) {
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"cannot write '%s': %s\n", rpath, strerror(errno));
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(lfd);
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        total_bytes += len;
50976f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner
51076f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (show_progress) {
51176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            print_transfer_progress(total_bytes, size);
51276f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        }
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(lfd);
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectremote_error:
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(lfd);
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_unlink(lpath);
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(id == ID_FAIL) {
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = ltohl(msg.data.size);
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len > 256) len = 256;
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(readx(fd, buffer, len)) {
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buffer[len] = 0;
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy(buffer, &id, 4);
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buffer[4] = 0;
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//        strcpy(buffer,"unknown reason");
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"failed to copy '%s' to '%s': %s\n", rpath, lpath, buffer);
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* --- */
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void do_sync_ls_cb(unsigned mode, unsigned size, unsigned time,
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                          const char *name, void *cookie)
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("%08x %08x %08x %s\n", mode, size, time, name);
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint do_sync_ls(const char *path)
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd = adb_connect("sync:");
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(sync_ls(fd, path, do_sync_ls_cb, 0)) {
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sync_quit(fd);
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct copyinfo copyinfo;
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct copyinfo
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *next;
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *src;
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *dst;
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int time;
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int mode;
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned int size;
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int flag;
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    //char data[0];
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcopyinfo *mkcopyinfo(const char *spath, const char *dpath,
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     const char *name, int isdir)
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int slen = strlen(spath);
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dlen = strlen(dpath);
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int nlen = strlen(name);
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ssize = slen + nlen + 2;
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dsize = dlen + nlen + 2;
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci = malloc(sizeof(copyinfo) + ssize + dsize);
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(ci == 0) {
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"out of memory\n");
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        abort();
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->next = 0;
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->time = 0;
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->mode = 0;
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->size = 0;
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->flag = 0;
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->src = (const char*)(ci + 1);
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ci->dst = ci->src + ssize;
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf((char*) ci->src, ssize, isdir ? "%s%s/" : "%s%s", spath, name);
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf((char*) ci->dst, dsize, isdir ? "%s%s/" : "%s%s", dpath, name);
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//    fprintf(stderr,"mkcopyinfo('%s','%s')\n", ci->src, ci->dst);
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ci;
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int local_build_list(copyinfo **filelist,
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            const char *lpath, const char *rpath)
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DIR *d;
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct dirent *de;
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *dirlist = 0;
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci, *next;
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//    fprintf(stderr,"local_build_list('%s','%s')\n", lpath, rpath);
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d = opendir(lpath);
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(d == 0) {
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while((de = readdir(d))) {
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char stat_path[PATH_MAX];
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *name = de->d_name;
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(name[0] == '.') {
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(name[1] == 0) continue;
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if((name[1] == '.') && (name[2] == 0)) continue;
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /*
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * We could use d_type if HAVE_DIRENT_D_TYPE is defined, but reiserfs
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * always returns DT_UNKNOWN, so we just use stat() for all cases.
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path))
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcpy(stat_path, lpath);
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcat(stat_path, de->d_name);
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
644686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg        if(!lstat(stat_path, &st)) {
645686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg            if (S_ISDIR(st.st_mode)) {
646686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                ci = mkcopyinfo(lpath, rpath, name, 1);
647686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                ci->next = dirlist;
648686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                dirlist = ci;
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
650686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                ci = mkcopyinfo(lpath, rpath, name, 0);
651686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                if(lstat(ci->src, &st)) {
652686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));
653686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    free(ci);
654686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    closedir(d);
655686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    return -1;
656686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                }
657686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
658686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    fprintf(stderr, "skipping special file '%s'\n", ci->src);
659686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    free(ci);
660686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                } else {
661686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    ci->time = st.st_mtime;
662686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    ci->mode = st.st_mode;
663686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    ci->size = st.st_size;
664686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    ci->next = *filelist;
665686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                    *filelist = ci;
666686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg                }
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
668686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg        } else {
669686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg            fprintf(stderr, "cannot lstat '%s': %s\n",stat_path , strerror(errno));
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    closedir(d);
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(ci = dirlist; ci != 0; ci = next) {
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        next = ci->next;
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        local_build_list(filelist, ci->src, ci->dst);
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ci);
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
685705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnamstatic int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, int checktimestamps, int listonly)
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *filelist = 0;
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci, *next;
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int pushed = 0;
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int skipped = 0;
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((lpath[0] == 0) || (rpath[0] == 0)) return -1;
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(lpath[strlen(lpath) - 1] != '/') {
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  tmplen = strlen(lpath)+2;
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(tmp == 0) return -1;
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/",lpath);
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lpath = tmp;
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(rpath[strlen(rpath) - 1] != '/') {
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int tmplen = strlen(rpath)+2;
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(tmp == 0) return -1;
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/",rpath);
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        rpath = tmp;
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(local_build_list(&filelist, lpath, rpath)) {
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(checktimestamps){
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(ci = filelist; ci != 0; ci = ci->next) {
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(sync_start_readtime(fd, ci->dst)) {
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(ci = filelist; ci != 0; ci = ci->next) {
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            unsigned int timestamp, mode, size;
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(sync_finish_readtime(fd, &timestamp, &mode, &size))
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(size == ci->size) {
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* for links, we cannot update the atime/mtime */
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ci->flag = 1;
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(ci = filelist; ci != 0; ci = next) {
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        next = ci->next;
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(ci->flag == 0) {
733705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            fprintf(stderr,"%spush: %s -> %s\n", listonly ? "would " : "", ci->src, ci->dst);
734705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            if(!listonly &&
735960df97c2356f5a804d3ef87fe49f788d7ecdfafJeff Sharkey               sync_send(fd, ci->src, ci->dst, ci->time, ci->mode,
73676f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner                         0 /* no show progress */)) {
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pushed++;
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped++;
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ci);
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"%d file%s pushed. %d file%s skipped.\n",
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pushed, (pushed == 1) ? "" : "s",
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped, (skipped == 1) ? "" : "s");
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
754960df97c2356f5a804d3ef87fe49f788d7ecdfafJeff Sharkeyint do_sync_push(const char *lpath, const char *rpath, int show_progress)
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned mode;
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_connect("sync:");
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(stat(lpath, &st)) {
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno));
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sync_quit(fd);
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(S_ISDIR(st.st_mode)) {
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
774705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam        if(copy_local_dir_remote(fd, lpath, rpath, 0, 0)) {
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(sync_readmode(fd, rpath, &mode)) {
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if((mode != 0) && S_ISDIR(mode)) {
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* if we're copying a local file to a remote directory,
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ** we *really* want to copy to remotedir + "/" + localfilename
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                */
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const char *name = adb_dirstop(lpath);
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(name == 0) {
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                name = lpath;
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                name++;
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int  tmplen = strlen(name) + strlen(rpath) + 2;
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            char *tmp = malloc(strlen(name) + strlen(rpath) + 2);
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(tmp == 0) return 1;
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            snprintf(tmp, tmplen, "%s/%s", rpath, name);
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            rpath = tmp;
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
801960df97c2356f5a804d3ef87fe49f788d7ecdfafJeff Sharkey        if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, show_progress)) {
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct {
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo **filelist;
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo **dirlist;
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *rpath;
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *lpath;
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} sync_ls_build_list_cb_args;
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time,
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                      const char *name, void *cookie)
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie;
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci;
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (S_ISDIR(mode)) {
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        copyinfo **dirlist = args->dirlist;
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* Don't try recursing down "." or ".." */
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (name[0] == '.') {
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (name[1] == '\0') return;
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if ((name[1] == '.') && (name[2] == '\0')) return;
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci = mkcopyinfo(args->rpath, args->lpath, name, 1);
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->next = *dirlist;
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *dirlist = ci;
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (S_ISREG(mode) || S_ISLNK(mode)) {
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        copyinfo **filelist = args->filelist;
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci = mkcopyinfo(args->rpath, args->lpath, name, 0);
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->time = time;
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->mode = mode;
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->size = size;
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ci->next = *filelist;
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *filelist = ci;
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "skipping special file '%s'\n", name);
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remote_build_list(int syncfd, copyinfo **filelist,
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                             const char *rpath, const char *lpath)
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *dirlist = NULL;
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sync_ls_build_list_cb_args args;
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.filelist = filelist;
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.dirlist = &dirlist;
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.rpath = rpath;
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    args.lpath = lpath;
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Put the files/dirs in rpath on the lists. */
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sync_ls(syncfd, rpath, sync_ls_build_list_cb, (void *)&args)) {
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Recurse into each directory we found. */
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (dirlist != NULL) {
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        copyinfo *next = dirlist->next;
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (remote_build_list(syncfd, filelist, dirlist->src, dirlist->dst)) {
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(dirlist);
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dirlist = next;
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
883de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnarstatic int set_time_and_mode(const char *lpath, unsigned int time, unsigned int mode)
884de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar{
8857a5e2bd0621ee0b1c66d8f4c21497ffb62feff42Greg Hackmann    struct utimbuf times = { time, time };
8867a5e2bd0621ee0b1c66d8f4c21497ffb62feff42Greg Hackmann    int r1 = utime(lpath, &times);
887de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar
888de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    /* use umask for permissions */
889de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    mode_t mask=umask(0000);
890de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    umask(mask);
891de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    int r2 = chmod(lpath, mode & ~mask);
892de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar
893de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    return r1 ? : r2;
894de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar}
895de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
897de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar                                 int copy_attrs)
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *filelist = 0;
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    copyinfo *ci, *next;
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int pulled = 0;
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int skipped = 0;
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Make sure that both directory paths end in a slash. */
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (rpath[0] == 0 || lpath[0] == 0) return -1;
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (rpath[strlen(rpath) - 1] != '/') {
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  tmplen = strlen(rpath) + 2;
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (tmp == 0) return -1;
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/", rpath);
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        rpath = tmp;
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (lpath[strlen(lpath) - 1] != '/') {
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  tmplen = strlen(lpath) + 2;
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp = malloc(tmplen);
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (tmp == 0) return -1;
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(tmp, tmplen, "%s/", lpath);
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        lpath = tmp;
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "pull: building file list...\n");
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Recursively build the list of files to copy. */
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (remote_build_list(fd, &filelist, rpath, lpath)) {
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (ci = filelist; ci != 0; ci = next) {
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        next = ci->next;
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ci->flag == 0) {
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
93176f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner            if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 1;
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
934de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar
935de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar            if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
936de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar               return 1;
937de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar            }
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pulled++;
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped++;
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ci);
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "%d file%s pulled. %d file%s skipped.\n",
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pulled, (pulled == 1) ? "" : "s",
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            skipped, (skipped == 1) ? "" : "s");
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
952de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnarint do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
954de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    unsigned mode, time;
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_connect("sync:");
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
965de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar    if(sync_readtime(fd, rpath, &time, &mode)) {
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(mode == 0) {
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"remote object '%s' does not exist\n", rpath);
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
973457d81cec12fce6e38c0dcd94d33d06036c2618aMatt Fischer    if(S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) {
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(stat(lpath, &st) == 0) {
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(S_ISDIR(st.st_mode)) {
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* if we're copying a remote file to a local directory,
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ** we *really* want to copy to localdir + "/" + remotefilename
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    */
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const char *name = adb_dirstop(rpath);
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(name == 0) {
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    name = rpath;
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } else {
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    name++;
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                int  tmplen = strlen(name) + strlen(lpath) + 2;
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                char *tmp = malloc(tmplen);
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(tmp == 0) return 1;
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                snprintf(tmp, tmplen, "%s/%s", lpath, name);
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                lpath = tmp;
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
99376f2a93b18e0d321d527cb64c2b2c4281e1cf70fMark Lindner        if (sync_recv(fd, rpath, lpath, show_progress)) {
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
996de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar            if (copy_attrs && set_time_and_mode(lpath, time, mode))
997de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar                return 1;
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if(S_ISDIR(mode)) {
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        BEGIN();
1004de8ff4adcaa487259f9ddcd0eab4d1117d1cca71Lajos Molnar        if (copy_remote_dir_local(fd, rpath, lpath, copy_attrs)) {
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            END();
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            sync_quit(fd);
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"remote object '%s' not a file or directory\n", rpath);
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1017705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnamint do_sync_sync(const char *lpath, const char *rpath, int listonly)
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"syncing %s...\n",rpath);
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd = adb_connect("sync:");
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BEGIN();
1028705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam    if(copy_local_dir_remote(fd, lpath, rpath, 1, listonly)){
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        END();
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sync_quit(fd);
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1036