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