file_sync_client.c
来自「Android 一些工具」· C语言 代码 · 共 1,023 行 · 第 1/2 页
C
1,023 行
if(id == ID_FAIL) { len = ltohl(msg.data.size); if(len > 256) len = 256; if(readx(fd, buffer, len)) { return -1; } buffer[len] = 0; } else { memcpy(buffer, &id, 4); buffer[4] = 0;// strcpy(buffer,"unknown reason"); } fprintf(stderr,"failed to copy '%s' to '%s': %s\n", rpath, lpath, buffer); return 0;}/* --- */static void do_sync_ls_cb(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie){ printf("%08x %08x %08x %s\n", mode, size, time, name);}int do_sync_ls(const char *path){ int fd = adb_connect("sync:"); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return 1; } if(sync_ls(fd, path, do_sync_ls_cb, 0)) { return 1; } else { sync_quit(fd); return 0; }}typedef struct copyinfo copyinfo;struct copyinfo{ copyinfo *next; const char *src; const char *dst; unsigned int time; unsigned int mode; unsigned int size; int flag; //char data[0];};copyinfo *mkcopyinfo(const char *spath, const char *dpath, const char *name, int isdir){ int slen = strlen(spath); int dlen = strlen(dpath); int nlen = strlen(name); int ssize = slen + nlen + 2; int dsize = dlen + nlen + 2; copyinfo *ci = malloc(sizeof(copyinfo) + ssize + dsize); if(ci == 0) { fprintf(stderr,"out of memory\n"); abort(); } ci->next = 0; ci->time = 0; ci->mode = 0; ci->size = 0; ci->flag = 0; ci->src = (const char*)(ci + 1); ci->dst = ci->src + ssize; snprintf((char*) ci->src, ssize, isdir ? "%s%s/" : "%s%s", spath, name); snprintf((char*) ci->dst, dsize, isdir ? "%s%s/" : "%s%s", dpath, name);// fprintf(stderr,"mkcopyinfo('%s','%s')\n", ci->src, ci->dst); return ci;}static int local_build_list(copyinfo **filelist, const char *lpath, const char *rpath){ DIR *d; struct dirent *de; struct stat st; copyinfo *dirlist = 0; copyinfo *ci, *next;// fprintf(stderr,"local_build_list('%s','%s')\n", lpath, rpath); d = opendir(lpath); if(d == 0) { fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno)); return -1; } while((de = readdir(d))) { char stat_path[PATH_MAX]; char *name = de->d_name; if(name[0] == '.') { if(name[1] == 0) continue; if((name[1] == '.') && (name[2] == 0)) continue; } /* * We could use d_type if HAVE_DIRENT_D_TYPE is defined, but reiserfs * always returns DT_UNKNOWN, so we just use stat() for all cases. */ if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path)) continue; strcpy(stat_path, lpath); strcat(stat_path, de->d_name); stat(stat_path, &st); if (S_ISDIR(st.st_mode)) { ci = mkcopyinfo(lpath, rpath, name, 1); ci->next = dirlist; dirlist = ci; } else { ci = mkcopyinfo(lpath, rpath, name, 0); if(lstat(ci->src, &st)) { closedir(d); fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno)); return -1; } if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { fprintf(stderr, "skipping special file '%s'\n", ci->src); free(ci); } else { ci->time = st.st_mtime; ci->mode = st.st_mode; ci->size = st.st_size; ci->next = *filelist; *filelist = ci; } } } closedir(d); for(ci = dirlist; ci != 0; ci = next) { next = ci->next; local_build_list(filelist, ci->src, ci->dst); free(ci); } return 0;}static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, int checktimestamps){ copyinfo *filelist = 0; copyinfo *ci, *next; int pushed = 0; int skipped = 0; if((lpath[0] == 0) || (rpath[0] == 0)) return -1; if(lpath[strlen(lpath) - 1] != '/') { int tmplen = strlen(lpath)+2; char *tmp = malloc(tmplen); if(tmp == 0) return -1; snprintf(tmp, tmplen, "%s/",lpath); lpath = tmp; } if(rpath[strlen(rpath) - 1] != '/') { int tmplen = strlen(rpath)+2; char *tmp = malloc(tmplen); if(tmp == 0) return -1; snprintf(tmp, tmplen, "%s/",rpath); rpath = tmp; } if(local_build_list(&filelist, lpath, rpath)) { return -1; } if(checktimestamps){ for(ci = filelist; ci != 0; ci = ci->next) { if(sync_start_readtime(fd, ci->dst)) { return 1; } } for(ci = filelist; ci != 0; ci = ci->next) { unsigned int timestamp, mode, size; if(sync_finish_readtime(fd, ×tamp, &mode, &size)) return 1; if(size == ci->size) { /* for links, we cannot update the atime/mtime */ if((S_ISREG(ci->mode & mode) && timestamp == ci->time) || (S_ISLNK(ci->mode & mode) && timestamp >= ci->time)) ci->flag = 1; } } } for(ci = filelist; ci != 0; ci = next) { next = ci->next; if(ci->flag == 0) { fprintf(stderr,"push: %s -> %s\n", ci->src, ci->dst); if(sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){ return 1; } pushed++; } else { skipped++; } free(ci); } fprintf(stderr,"%d file%s pushed. %d file%s skipped.\n", pushed, (pushed == 1) ? "" : "s", skipped, (skipped == 1) ? "" : "s"); return 0;}int do_sync_push(const char *lpath, const char *rpath, int verifyApk){ struct stat st; unsigned mode; int fd; fd = adb_connect("sync:"); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return 1; } if(stat(lpath, &st)) { fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno)); sync_quit(fd); return 1; } if(S_ISDIR(st.st_mode)) { BEGIN(); if(copy_local_dir_remote(fd, lpath, rpath, 0)) { return 1; } else { END(); sync_quit(fd); } } else { if(sync_readmode(fd, rpath, &mode)) { return 1; } if((mode != 0) && S_ISDIR(mode)) { /* if we're copying a local file to a remote directory, ** we *really* want to copy to remotedir + "/" + localfilename */ const char *name = adb_dirstop(lpath); if(name == 0) { name = lpath; } else { name++; } int tmplen = strlen(name) + strlen(rpath) + 2; char *tmp = malloc(strlen(name) + strlen(rpath) + 2); if(tmp == 0) return 1; snprintf(tmp, tmplen, "%s/%s", rpath, name); rpath = tmp; } BEGIN(); if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk)) { return 1; } else { END(); sync_quit(fd); return 0; } } return 0;}typedef struct { copyinfo **filelist; copyinfo **dirlist; const char *rpath; const char *lpath;} sync_ls_build_list_cb_args;voidsync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie){ sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie; copyinfo *ci; if (S_ISDIR(mode)) { copyinfo **dirlist = args->dirlist; /* Don't try recursing down "." or ".." */ if (name[0] == '.') { if (name[1] == '\0') return; if ((name[1] == '.') && (name[2] == '\0')) return; } ci = mkcopyinfo(args->rpath, args->lpath, name, 1); ci->next = *dirlist; *dirlist = ci; } else if (S_ISREG(mode) || S_ISLNK(mode)) { copyinfo **filelist = args->filelist; ci = mkcopyinfo(args->rpath, args->lpath, name, 0); ci->time = time; ci->mode = mode; ci->size = size; ci->next = *filelist; *filelist = ci; } else { fprintf(stderr, "skipping special file '%s'\n", name); }}static int remote_build_list(int syncfd, copyinfo **filelist, const char *rpath, const char *lpath){ copyinfo *dirlist = NULL; sync_ls_build_list_cb_args args; args.filelist = filelist; args.dirlist = &dirlist; args.rpath = rpath; args.lpath = lpath; /* Put the files/dirs in rpath on the lists. */ if (sync_ls(syncfd, rpath, sync_ls_build_list_cb, (void *)&args)) { return 1; } /* Recurse into each directory we found. */ while (dirlist != NULL) { copyinfo *next = dirlist->next; if (remote_build_list(syncfd, filelist, dirlist->src, dirlist->dst)) { return 1; } free(dirlist); dirlist = next; } return 0;}static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath, int checktimestamps){ copyinfo *filelist = 0; copyinfo *ci, *next; int pulled = 0; int skipped = 0; /* Make sure that both directory paths end in a slash. */ if (rpath[0] == 0 || lpath[0] == 0) return -1; if (rpath[strlen(rpath) - 1] != '/') { int tmplen = strlen(rpath) + 2; char *tmp = malloc(tmplen); if (tmp == 0) return -1; snprintf(tmp, tmplen, "%s/", rpath); rpath = tmp; } if (lpath[strlen(lpath) - 1] != '/') { int tmplen = strlen(lpath) + 2; char *tmp = malloc(tmplen); if (tmp == 0) return -1; snprintf(tmp, tmplen, "%s/", lpath); lpath = tmp; } fprintf(stderr, "pull: building file list...\n"); /* Recursively build the list of files to copy. */ if (remote_build_list(fd, &filelist, rpath, lpath)) { return -1; }#if 0 if (checktimestamps) { for (ci = filelist; ci != 0; ci = ci->next) { if (sync_start_readtime(fd, ci->dst)) { return 1; } } for (ci = filelist; ci != 0; ci = ci->next) { unsigned int timestamp, mode, size; if (sync_finish_readtime(fd, ×tamp, &mode, &size)) return 1; if (size == ci->size) { /* for links, we cannot update the atime/mtime */ if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) || (S_ISLNK(ci->mode & mode) && timestamp >= ci->time)) ci->flag = 1; } } }#endif for (ci = filelist; ci != 0; ci = next) { next = ci->next; if (ci->flag == 0) { fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst); if (sync_recv(fd, ci->src, ci->dst)) { return 1; } pulled++; } else { skipped++; } free(ci); } fprintf(stderr, "%d file%s pulled. %d file%s skipped.\n", pulled, (pulled == 1) ? "" : "s", skipped, (skipped == 1) ? "" : "s"); return 0;}int do_sync_pull(const char *rpath, const char *lpath){ unsigned mode; struct stat st; int fd; fd = adb_connect("sync:"); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return 1; } if(sync_readmode(fd, rpath, &mode)) { return 1; } if(mode == 0) { fprintf(stderr,"remote object '%s' does not exist\n", rpath); return 1; } if(S_ISREG(mode) || S_ISCHR(mode) || S_ISBLK(mode)) { if(stat(lpath, &st) == 0) { if(S_ISDIR(st.st_mode)) { /* if we're copying a remote file to a local directory, ** we *really* want to copy to localdir + "/" + remotefilename */ const char *name = adb_dirstop(rpath); if(name == 0) { name = rpath; } else { name++; } int tmplen = strlen(name) + strlen(lpath) + 2; char *tmp = malloc(tmplen); if(tmp == 0) return 1; snprintf(tmp, tmplen, "%s/%s", lpath, name); lpath = tmp; } } BEGIN(); if(sync_recv(fd, rpath, lpath)) { return 1; } else { END(); sync_quit(fd); return 0; } } else if(S_ISDIR(mode)) { BEGIN(); if (copy_remote_dir_local(fd, rpath, lpath, 0)) { return 1; } else { END(); sync_quit(fd); return 0; } } else { fprintf(stderr,"remote object '%s' not a file or directory\n", rpath); return 1; }}int do_sync_sync(const char *lpath, const char *rpath){ fprintf(stderr,"syncing %s...\n",rpath); int fd = adb_connect("sync:"); if(fd < 0) { fprintf(stderr,"error: %s\n", adb_error()); return 1; } BEGIN(); if(copy_local_dir_remote(fd, lpath, rpath, 1)){ return 1; } else { END(); sync_quit(fd); return 0; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?