}
char src_full_path[PATH_MAX];
- append_file(src_full_path, src_dir, file_name);
+ append_file(src_full_path, src_dir, file_name, PATH_MAX);
char* src_ptr = src_full_path;
if(pwd_flag) {
}
char src_full_path[PATH_MAX];
- append_file(src_full_path, src_dir, file_name);
+ append_file(src_full_path, src_dir, file_name, PATH_MAX);
if(COMPLETE_FLAG) {
fprintf(AC_STDOUT, "%s%c", src_full_path, IFS);
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
#include <limits.h>
#include <stdio.h>
+#include "sdb_constants.h"
#include "file_sync_client.h"
#include "file_sync_functions.h"
#include "utils.h"
byte_flag[1] = 'B';
}
- src_fd = srcF->readopen(src_fd, srcp, src_stat);
- if(src_fd < 0) {
- return -1;
+ /**
+ * local should be opend first
+ * because if remote opens successfully, and fail to open local,
+ * remote channel is created and protocol confliction is made
+ * it is ok to other pull or push process if remote connection is not made
+ */
+ if(srcF->local) {
+ src_fd = srcF->readopen(src_fd, srcp, src_stat);
+ if(src_fd < 0) {
+ return -1;
+ }
+ dst_fd = dstF->writeopen(dst_fd, dstp, src_stat);
+ if(dst_fd < 0) {
+ srcF->readclose(src_fd);
+ return -1;
+ }
}
-
- dst_fd = dstF->writeopen(dst_fd, dstp, src_stat);
- if(dst_fd < 0) {
- return -1;
+ else {
+ dst_fd = dstF->writeopen(dst_fd, dstp, src_stat);
+ if(dst_fd < 0) {
+ return -1;
+ }
+ src_fd = srcF->readopen(src_fd, srcp, src_stat);
+ if(src_fd < 0) {
+ dstF->writeclose(dst_fd, dstp, src_stat);
+ return -1;
+ }
}
FILE_BUFFER srcbuf;
break;
}
else if(ret == 1) {
- ret = dstF->writefile(dst_fd, dstp, &srcbuf, &written_byte);
- if(ret < 0) {
- srcF->readclose(src_fd);
- dstF->writeclose(dst_fd, dstp, src_stat);
- return -1;
+ if(dstF->writefile(dst_fd, dstp, &srcbuf, &written_byte)) {
+ goto error;
}
}
else if(ret == 2) {
continue;
}
else if(ret == 3) {
- ret = dstF->writefile(dst_fd, dstp, &srcbuf, &written_byte);
- if(ret < 0) {
- srcF->readclose(src_fd);
- dstF->writeclose(dst_fd, dstp, src_stat);
- return -1;
+ if(dstF->writefile(dst_fd, dstp, &srcbuf, &written_byte)) {
+ goto error;
}
break;
}
else {
- srcF->readclose(src_fd);
- dstF->writeclose(dst_fd, dstp, src_stat);
- if(ret == 4) {
- return 0;
- }
- return -1;
+ goto error;
}
//TODO pull / push progress bar
int percent = 0;
fprintf(stderr,"%s %30s\t100%%\t%7d%s\n", copy_flag, file_name, file_byte / flag_size, byte_flag);
*total_bytes = *total_bytes + written_byte;
- return 1;
+ return 0;
+
+error:
+ srcF->readclose(src_fd);
+ dstF->writeclose(dst_fd, dstp, src_stat);
+ return -1;
}
static void free_copyinfo(void* data) {
struct stat src_stat;
struct stat dst_stat;
- if(srcF->_stat(src_fd, srcp, &src_stat, 1) < 0) {
- finalize(src_fd, dst_fd, srcF, dstF);
- return 1;
+ if(srcF->_stat(src_fd, srcp, &src_stat, 1)) {
+ goto error;
}
- int src_dir = srcF->is_dir(srcp, &src_stat, 1);
+
+ int src_dir = srcF->is_dir(srcp, &src_stat);
+
+ if(src_dir == -1) {
+ fprintf(stderr, ERR_REASON_SYNC_NOT_FILE, srcp);
+ goto error;
+ }
+
int dst_dir = 0;
- if(dstF->_stat(dst_fd, dstp, &dst_stat, 0) >= 0) {
- dst_dir = dstF->is_dir(dstp, &dst_stat, 0);
+ if(!dstF->_stat(dst_fd, dstp, &dst_stat, 0)) {
+ dst_dir = dstF->is_dir(dstp, &dst_stat);
}
- else {
+ else{
int dst_len = strlen(dstp);
if( dstp[dst_len - 1] == '/' || dstp[dst_len - 1] == '\\') {
dst_dir = 1;
}
}
- if(src_dir == -1) {
- fprintf(stderr, "source '%s' is not a file or directory\n", srcp);
- finalize(src_fd, dst_fd, srcF, dstF);
- return 1;
- }
-
if(dst_dir == -1) {
- fprintf(stderr, "destination '%s' is not a file or directory\n", dstp);
- finalize(src_fd, dst_fd, srcF, dstF);
- return 1;
+ fprintf(stderr, ERR_REASON_SYNC_NOT_FILE, dstp);
+ goto error;
}
+
if(src_dir == 0) {
/* if we're copying a local file to a remote directory,
** we *really* want to copy to remotedir + "/" + localfilename
char full_dstpath[PATH_MAX];
if(dst_dir == 1) {
char* src_filename = get_filename(srcp);
- append_file(full_dstpath, dstp, src_filename);
+ append_file(full_dstpath, dstp, src_filename, PATH_MAX);
if(is_utf8 != 0) {
dstp = ansi_to_utf8(full_dstpath);
dstp = full_dstpath;
}
}
- int result = file_copy(src_fd, dst_fd, srcp, dstp, srcF, dstF, &total_bytes, &src_stat, copy_flag);
-
- if(result == 1) {
+ if(!file_copy(src_fd, dst_fd, srcp, dstp, srcF, dstF, &total_bytes, &src_stat, copy_flag)) {
pushed++;
}
else {
- fprintf(stderr,"skipped: %s -> %s\n", srcp, dstp);
- skiped++;
+ goto error;
}
}
- else if(src_dir == 2) {
- skiped++;
- }
//copy directory
else {
LIST_NODE* dir_list = NULL;
while(dir_list != NULL) {
LIST_NODE* entry_list = NULL;
COPY_INFO* _info = (COPY_INFO*)dir_list->data;
- if(srcF->get_dirlist(src_fd, _info->src, _info->dst, &entry_list) < 0) {
- finalize(src_fd, dst_fd, srcF, dstF);
- return 1;
+ if(srcF->get_dirlist(src_fd, _info->src, _info->dst, &entry_list)) {
+ fprintf(stderr,"skipped: %s -> %s\n", _info->src, _info->dst);
+ skiped++;
+ free_list(entry_list, NULL);
+ remove_first(&dir_list, free_copyinfo);
+ continue;
}
+ remove_first(&dir_list, free_copyinfo);
LIST_NODE* curptr = entry_list;
while(curptr != NULL) {
COPY_INFO* info = (COPY_INFO*)curptr->data;
+ curptr = curptr->next_ptr;
char* src_p = (char*)info->src;
char* dst_p = (char*)info->dst;
- if(srcF->_stat(src_fd, src_p, &src_stat, 1) < 0) {
- finalize(src_fd, dst_fd, srcF, dstF);
- return 1;
+ if(srcF->_stat(src_fd, src_p, &src_stat, 1)) {
+ goto skip_in;
}
- src_dir = srcF->is_dir(src_p, &src_stat, 1);
+ src_dir = srcF->is_dir(src_p, &src_stat);
if(src_dir < 0) {
- finalize(src_fd, dst_fd, srcF, dstF);
- return 1;
+ fprintf(stderr,ERR_REASON_SYNC_NOT_FILE, src_p);
+ goto skip_in;
}
if(src_dir == 1) {
append(&dir_list, info);
+ continue;
}
else {
- if(src_dir == 0) {
- int result = file_copy(src_fd, dst_fd, src_p, dst_p, srcF, dstF, &total_bytes, &src_stat, copy_flag);
-
- if(result == 1) {
- pushed++;
- }
- else {
- fprintf(stderr,"skipped: %s -> %s\n", src_p, dst_p);
- skiped++;
- }
- }
- else if(src_dir == 2) {
- skiped++;
+ if(!file_copy(src_fd, dst_fd, src_p, dst_p, srcF, dstF, &total_bytes, &src_stat, copy_flag)) {
+ pushed++;
+ free(info);
+ free(src_p);
+ free(dst_p);
+ continue;
}
- free(src_p);
- free(dst_p);
- free(info);
}
- curptr = curptr->next_ptr;
+skip_in:
+ fprintf(stderr,"skipped: %s -> %s\n", src_p, dst_p);
+ skiped++;
+ free(info);
+ free(src_p);
+ free(dst_p);
}
free_list(entry_list, no_free);
- remove_first(&dir_list, free_copyinfo);
}
}
finalize(src_fd, dst_fd, srcF, dstF);
return 0;
+
+error:
+ finalize(src_fd, dst_fd, srcF, dstF);
+ return 1;
}
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
.get_dirlist=getdirlist_remote,
};
-static int sync_readstat(int fd, const char *path, struct stat* st);
-
//return > 0 fd, = 0 success, < 0 fail.
int initialize_local(char* path) {
D("initialize local file '%s'\n", path);
int fd = sdb_connect("sync:");
if(fd < 0) {
- return -1;
+ print_error(1, ERR_SITU_SYNC_OPEN_CHANNEL, ERR_REASON_GENERAL_CONNECTION_FAIL, strerror(errno));
}
return fd;
}
}
-int _stat_local(int fd, char* path, struct stat* st, int show_error) {
+int _stat_local(int fd, char* path, struct stat* st, int print_err) {
D("stat local file 'fd:%d' '%s'\n", fd, path);
if(stat(path, st)) {
- if(show_error) {
- fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
+ if(print_err) {
+ print_error(0, ERR_SITU_SYNC_STAT_FILE, strerror(errno), path);
}
st->st_mode = 0;
return -1;
}
- return 1;
+ return 0;
}
-int _stat_remote(int fd, char* path, struct stat* st, int show_error) {
+int _stat_remote(int fd, char* path, struct stat* st, int print_err) {
- D("stat remote file 'fd:%d' '%s'\n", fd, path);
- if(sync_readstat(fd, path, st)) {
- if(show_error) {
- fprintf(stderr,"cannot read mode '%s': %s\n", path, strerror(errno));
- }
- st->st_mode = 0;
- return -1;
+ SYNC_MSG msg;
+ int len = strlen(path);
+ msg.req.id = sync_stat;
+ msg.req.namelen = htoll(len);
+
+ if(writex(fd, &msg.req, sizeof(msg.req)) ||
+ writex(fd, path, len)) {
+ print_error(1, ERR_SITU_SYNC_STAT_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, path, strerror(errno));
}
- return 1;
-}
+ if(readx(fd, &msg.stat, sizeof(msg.stat))) {
+ print_error(1, ERR_SITU_SYNC_STAT_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, path, strerror(errno));
+ }
+
+ if(msg.stat.id != sync_stat) {
+ char expected[5];
+ char result[5];
+ MKCHAR(expected, sync_stat);
+ MKCHAR(result, msg.stat.id);
+
+ print_error(1, ERR_SITU_SYNC_STAT_FILE, ERR_REASON_GENERAL_PROTOCOL_WRONG_ID, path, expected, result);
+ }
+ st->st_mode = ltohl(msg.stat.mode);
-int is_directory_common(char* path, struct stat* st, int show_error) {
- if(st->st_mode == 0) {
- if(show_error) {
- fprintf(stderr,"'%s': No such file or directory\n", path);
+ /**
+ * FIXME
+ * SDBD does not send error reason if remote stat fails.
+ * We cannot know the reason before we change sync protocol.
+ */
+ if(!st->st_mode) {
+ if(print_err) {
+ print_error(0, ERR_SITU_SYNC_STAT_FILE, ERR_REASON_GENERAL_UNKNOWN, path);
}
return -1;
}
+ st->st_size = ltohl(msg.stat.size);
+ D("remote stat: mode %u, size %u\n", st->st_mode, st->st_size);
+ return 0;
+}
+
+int is_directory_common(char* path, struct stat* st) {
if(S_ISDIR(st->st_mode)) {
return 1;
}
return 0;
}
- return 2;
+ return -1;
}
//return fd.
int readopen_local(int fd, char* srcp, struct stat* st) {
D("read open local file 'fd:%d' '%s'\n", fd, srcp);
- if(S_ISREG(st->st_mode)) {
- fd = sdb_open(srcp, O_RDONLY);
-
- if(fd < 0) {
- fprintf(stderr,"cannot open local file '%s': %s\n", srcp, strerror(errno));
- return -1;
- }
+ fd = sdb_open(srcp, O_RDONLY);
- return fd;
+ if(fd < 0) {
+ print_error(0, ERR_SITU_SYNC_OPEN_FILE, strerror(errno), srcp);
+ return -1;
}
return fd;
len = strlen(srcp);
if(len > SYNC_CHAR_MAX) {
- fprintf(stderr,"protocol failure while opening remote file '%s' for reading. request should not exceeds %d\n", srcp, SYNC_CHAR_MAX);
+ print_error(0, ERR_SITU_SYNC_OPEN_FILE, ERR_REASON_GENERAL_PROTOCOL_DATA_OVERRUN, srcp, len, SYNC_CHAR_MAX);
return -1;
}
msg.req.namelen = htoll(len);
if(writex(fd, &msg.req, sizeof(msg.req)) || writex(fd, srcp, len)) {
- fprintf(stderr,"exception occurred while sending read request to remote file'%s': %s\n", srcp, strerror(errno));
- return -1;
+ print_error(1, ERR_SITU_SYNC_OPEN_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, srcp, strerror(errno));
}
return fd;
}
fd = sdb_creat(dstp, 0644);
if(fd < 0) {
- fprintf(stderr,"cannot create '%s': %s\n", dstp, strerror(errno));
+ print_error(0, ERR_SITU_SYNC_CREATE_FILE, strerror(errno), dstp);
return -1;
}
snprintf(tmp, sizeof(tmp), ",%d", st->st_mode);
len = strlen(dstp);
- r = strlen(tmp);
- total_len = len + r;
- if(total_len > PATH_MAX) {
- fprintf(stderr,"protocol failure. buffer [%s%s] exceeds limits: %d\n", dstp, tmp, PATH_MAX);
+ if(len > SYNC_CHAR_MAX) {
+ print_error(0, ERR_SITU_SYNC_CREATE_FILE, ERR_REASON_GENERAL_PROTOCOL_DATA_OVERRUN, dstp, len, SYNC_CHAR_MAX);
return -1;
}
+ r = strlen(tmp);
+ total_len = len + r;
+
msg.req.id = sync_send;
msg.req.namelen = htoll(total_len);
if(writex(fd, &msg.req, sizeof(msg.req)) ||
writex(fd, dstp, len) ||
writex(fd, tmp, r)) {
- fprintf(stderr,"exception occurred while sending read msg: %s\n", dstp);
- return -1;
+ print_error(1, ERR_SITU_SYNC_OPEN_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, dstp, strerror(errno));
}
return fd;
msg.data.size = htoll(st->st_mtime);
if(writex(fd, &msg.data, sizeof(msg.data))) {
- fprintf(stderr,"exception occurred while sending close msg: %s\n", dstp);
- return -1;
+ print_error(1, ERR_SITU_SYNC_CLOSE_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, dstp, strerror(errno));
}
if(readx(fd, &msg.status, sizeof(msg.status))) {
- fprintf(stderr,"exception occurred while receiving close msg: %s\n", dstp);
- return -1;
+ print_error(1, ERR_SITU_SYNC_CLOSE_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, dstp, strerror(errno));
}
if(msg.status.id != sync_okay) {
if(len > 255) {
len = 255;
}
- if(readx(fd, buf, len)) {
- fprintf(stderr, "cannot close remote file '%s' and its failed msg.\n", dstp);
+ if(!readx(fd, buf, len)) {
+ print_error(0, ERR_SITU_SYNC_CLOSE_FILE, buf, dstp);
return -1;
}
- buf[len] = 0;
- } else {
- strcpy(buf, "unknown reason");
+ print_error(1, ERR_SITU_SYNC_CLOSE_FILE, ERR_REASON_GENERAL_UNKNOWN, dstp);
}
+ char expected[5];
+ char result[5];
+ MKCHAR(expected, sync_fail);
+ MKCHAR(result, msg.status.id);
- fprintf(stderr,"cannot close remote file '%s' with failed msg '%s'.\n", dstp, buf);
- return -1;
+ print_error(1, ERR_SITU_SYNC_CLOSE_FILE, ERR_REASON_GENERAL_PROTOCOL_WRONG_ID, dstp, expected, result);
}
return fd;
}
-//4: finish skipped
-//0: finish normally.
-//2: continue load but don't write.
-//-1:fail
-//1: write and continue load
-//3: write and stop
+// 0: finish normally.
+// 2: continue load but don't write.
+//-1: fail
+// 1: write and continue load
+// 3: write and stop
int readfile_local(int lfd, char* srcpath, struct stat* st, FILE_BUFFER* sbuf) {
D("read local file 'fd:%d' '%s'\n", lfd, srcpath);
return 2;
}
//fail.
- fprintf(stderr, "cannot read local file '%s': %s\n", srcpath, strerror(errno));
+ print_error(0, ERR_SITU_SYNC_READ_FILE, strerror(errno), srcpath);
return -1;
}
len = readlink(srcpath, sbuf->data, SYNC_DATA_MAX-1);
//fail
if(len < 0) {
- fprintf(stderr, "cannot read local link '%s': %s\n", srcpath, strerror(errno));
+ print_error(0, ERR_SITU_SYNC_READ_FILE, strerror(errno), srcpath);
return -1;
}
sbuf->data[len] = '\0';
}
#endif
- fprintf(stderr,"protocol failure\n");
//fail
+ print_error(0, ERR_SITU_SYNC_READ_FILE, ERR_REASON_SYNC_NOT_FILE, srcpath, srcpath);
return -1;
}
unsigned id;
if(readx(fd, &(msg.data), sizeof(msg.data))) {
- fprintf(stderr, "cannot read remote file status '%s': %s\n", srcpath, strerror(errno));
- return -1;
+ print_error(1, ERR_SITU_SYNC_READ_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, srcpath, strerror(errno));
}
id = msg.data.id;
buffer->size = ltohl(msg.data.size);
if(id != sync_data) {
int len = 0;
if(id == sync_fail) {
- int len = buffer->size;
+ len = buffer->size;
if(len > 256) {
len = 255;
}
- if(readx(fd, buffer->data, len)) {
- fprintf(stderr, "cannot read remote file '%s' and its failed msg. %s\n", srcpath, strerror(errno));
+ if(!readx(fd, buffer->data, len)) {
+ buffer->data[len] = 0;
+ print_error(0, ERR_SITU_SYNC_READ_FILE, buffer->data, srcpath);
return -1;
}
+ print_error(1, ERR_SITU_SYNC_READ_FILE, ERR_REASON_GENERAL_UNKNOWN, srcpath);
}
- else {
- len = 4;
- memcpy(buffer->data, &id, len);
- }
- buffer->data[len] = 0;
+ char expected[5];
+ char result[5];
+ MKCHAR(expected, sync_fail);
+ MKCHAR(result, id);
- fprintf(stderr, "cannot read remote file '%s' with its failed msg '%s'. %s\n", srcpath, buffer->data, strerror(errno));
- return 4;
+ print_error(1, ERR_SITU_SYNC_READ_FILE, ERR_REASON_GENERAL_PROTOCOL_WRONG_ID, srcpath, expected, result);
}
//fail
if(buffer->size > SYNC_DATA_MAX) {
- fprintf(stderr,"data overrun\n");
- return -1;
+ print_error(1, ERR_SITU_SYNC_READ_FILE, ERR_REASON_GENERAL_PROTOCOL_DATA_OVERRUN, srcpath, buffer->size, SYNC_DATA_MAX);
}
//fail
if(readx(fd, buffer->data, buffer->size)) {
- fprintf(stderr, "cannot read remote file '%s': %s\n", srcpath, strerror(errno));
- return -1;
+ print_error(1, ERR_SITU_SYNC_READ_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, srcpath, strerror(errno));
}
//write and continue load
unsigned len = sbuf->size;
if(writex(fd, data, len)) {
- fprintf(stderr,"cannot write '%s': %s\n", dstp, strerror(errno));
- return -1;
+ /**
+ * remote channel is already opend
+ * if local write fails, protocol conflict happens unless we receive sync_done from remote
+ */
+ print_error(1, ERR_SITU_SYNC_WRITE_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, dstp, strerror(errno));
}
*total_bytes += len;
int size = ltohl(sbuf->size);
if(writex(fd, sbuf, sizeof(unsigned)*2 + size)) {
- fprintf(stderr, "cannot write remote file '%s': %s\n", dstp, strerror(errno));
- return -1;
+ print_error(1, ERR_SITU_SYNC_WRITE_FILE, ERR_REASON_GENERAL_CONNECTION_FAIL, dstp, strerror(errno));
}
*total_bytes += size;
d = opendir(src_dir);
if(d == 0) {
- fprintf(stderr,"cannot open '%s': %s\n", src_dir, strerror(errno));
+ print_error(0, ERR_SITU_SYNC_GET_DIRLIST, strerror(errno), src_dir);
readclose_local(fd);
return -1;
}
}
}
- char* src_full_path = (char*)malloc(sizeof(char)*PATH_MAX);
- append_file(src_full_path, src_dir, file_name);
+ int len = strlen(src_dir) + strlen(file_name) + 2;
+ char* src_full_path = (char*)malloc(sizeof(char)*len);
+ append_file(src_full_path, src_dir, file_name, len);
- char* dst_full_path = (char*)malloc(sizeof(char)*PATH_MAX);
- append_file(dst_full_path, dst_dir, file_name);
+ len = strlen(dst_dir) + strlen(file_name) + 2;
+ char* dst_full_path = (char*)malloc(sizeof(char)*len);
+ append_file(dst_full_path, dst_dir, file_name, len);
COPY_INFO* info;
create_copy_info(&info, src_full_path, dst_full_path);
}
closedir(d);
- return fd;
+ return 0;
}
int getdirlist_remote(int fd, char* src_dir, char* dst_dir, LIST_NODE** dirlist) {
len = strlen(src_dir);
if(len > SYNC_CHAR_MAX) {
- fprintf(stderr,"protocol failure while getting dirlist of remote file '%s'. request should not exceeds %d\n", src_dir, SYNC_CHAR_MAX);
+ print_error(0, ERR_SITU_SYNC_GET_DIRLIST, ERR_REASON_GENERAL_PROTOCOL_DATA_OVERRUN, src_dir, len, SYNC_CHAR_MAX);
return -1;
}
if(writex(fd, &msg.req, sizeof(msg.req)) ||
writex(fd, src_dir, len)) {
- fprintf(stderr,"cannot request directory entry: '%s'\n", src_dir);
- return -1;
+ print_error(1, ERR_SITU_SYNC_GET_DIRLIST, ERR_REASON_GENERAL_CONNECTION_FAIL, src_dir, strerror(errno));
}
while(1) {
if(readx(fd, &msg.dent, sizeof(msg.dent))) {
- fprintf(stderr,"cannot read dirlist: '%s'\n", src_dir);
- return -1;
+ print_error(1, ERR_SITU_SYNC_GET_DIRLIST, ERR_REASON_GENERAL_CONNECTION_FAIL, src_dir, strerror(errno));
}
if(msg.dent.id == sync_done) {
- return fd;
+ LOG_INFO("getting list of remote file 'fd:%d' '%s' is done\n", fd, src_dir);
+ return 0;
}
if(msg.dent.id != sync_dent) {
- fprintf(stderr,"received dent msg '%d' is not DENT\n", msg.dent.id);
- return -1;
+ char expected[5];
+ char result[5];
+ MKCHAR(expected, sync_dent);
+ MKCHAR(result, msg.dent.id);
+
+ print_error(1, ERR_SITU_SYNC_GET_DIRLIST, ERR_REASON_GENERAL_PROTOCOL_WRONG_ID, src_dir, expected, result);
}
len = ltohl(msg.dent.namelen);
if(len > 256) {
- fprintf(stderr,"some file in the remote '%s' exceeds 256\n", src_dir);
- return -1;
+ fprintf(stderr,"error: name of a file in the remote directory '%s' exceeds 256\n", src_dir);
+ continue;
}
char file_name[257];
if(readx(fd, file_name, len)) {
- fprintf(stderr,"cannot read file in the remote directory '%s'\n", src_dir);
- return -1;
+ print_error(1, ERR_SITU_SYNC_GET_DIRLIST, ERR_REASON_GENERAL_CONNECTION_FAIL, src_dir, strerror(errno));
}
file_name[len] = 0;
}
}
- char* src_full_path = (char*)malloc(sizeof(char)*PATH_MAX);
- append_file(src_full_path, src_dir, file_name);
+ len = strlen(src_dir) + strlen(file_name) + 2;
+ char* src_full_path = (char*)malloc(sizeof(char)*len);
+ append_file(src_full_path, src_dir, file_name, len);
- char* dst_full_path = (char*)malloc(sizeof(char)*PATH_MAX);
- append_file(dst_full_path, dst_dir, file_name);
+ len = strlen(dst_dir) + strlen(file_name) + 2;
+ char* dst_full_path = (char*)malloc(sizeof(char)*len);
+ append_file(dst_full_path, dst_dir, file_name, len);
COPY_INFO* info;
create_copy_info(&info, src_full_path, dst_full_path);
prepend(dirlist, info);
}
- D("getting list of remote file 'fd:%d' '%s' is done\n", fd, src_dir);
- return fd;
-}
-
-static int sync_readstat(int fd, const char *path, struct stat* st) {
- SYNC_MSG msg;
- int len = strlen(path);
- msg.req.id = sync_stat;
- msg.req.namelen = htoll(len);
-
- if(writex(fd, &msg.req, sizeof(msg.req)) ||
- writex(fd, path, len)) {
- LOG_ERROR("fail to send request ID_STAT with name length %d\n", len);
- return -1;
- }
-
- if(readx(fd, &msg.stat, sizeof(msg.stat))) {
- LOG_ERROR("fail to read response of ID_STAT with name length %d\n", len);
- return -1;
- }
- if(msg.stat.id != sync_stat) {
- return -1;
- }
- st->st_mode = ltohl(msg.stat.mode);
-
- if(!st->st_mode) {
- LOG_ERROR("fail to stat remote file: '%s'", path);
- return -1;
- }
- st->st_size = ltohl(msg.stat.size);
- D("remote stat: mode %u, size %u\n", st->st_mode, st->st_size);
return 0;
}
+
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
int _stat_local(int fd, char* path, struct stat* st, int show_error);
int _stat_remote(int fd, char* path, struct stat* st, int show_error);
-int is_directory_common(char* path, struct stat* st, int show_error);
+int is_directory_common(char* path, struct stat* st);
int readopen_local(int fd, char* srcp, struct stat* st);
int readopen_remote(int fd, char* srcp, struct stat* st);
int local;
int(*initialize)(char* path);
void(*finalize)(int fd);
+
int(*_stat)(int fd, char* path, struct stat* st, int show_error);
- int(*is_dir)(char* path, struct stat* st, int show_error);
int(*readopen)(int fd, char* dstp, struct stat* st);
+ int(*is_dir)(char* path, struct stat* st);
int(*readclose)(int fd);
int(*writeopen)(int fd, char* dstp, struct stat* st);
int(*writeclose)(int fd, char* dstp, struct stat* st);
#define htoll(x) (x)
#define ltohl(x) (x)
#define MKSYNC(a,b,c,d) ( (d << 24) | (c << 16) | (b << 8) | a )
+#define MKCHAR(buf, a) \
+ buf[0] = (char)(a & 0x000000ff); \
+ buf[1] = (char)((a & 0x0000ff00) >> 8); \
+ buf[2] = (char)((a & 0x00ff0000) >> 16); \
+ buf[3] = (char)((a & 0xff000000) >> 24); \
+ buf[4] = '\0' \
extern const unsigned sync_stat;
extern const unsigned sync_list;
va_end(args);
}
+void print_error(int fatal, const char* situation, const char* reason, ...) {
+
+ char error_buf_format[ERR_LENGTH];
+ snprintf(error_buf_format, ERR_LENGTH, ERR_FORMAT, ERR_TAG, situation, reason);
+
+ va_list args;
+ va_start(args, reason);
+
+ char error_buf[ERR_LENGTH];
+ vsnprintf(error_buf, ERR_LENGTH, error_buf_format, args);
+ fprintf(stderr, "%s", error_buf);
+ va_end(args);
+
+ if(fatal) {
+ LOG_ERROR("FATAL\n");
+ fflush(stderr);
+ exit(255);
+ }
+}
+
static void log_parse(char* args) {
char *level, *levels, *next;
#define SDB_TRACE 1
#define DEBUG_ENV "SDB_DEBUG"
#define TRACE_PACKET "SDB_TRACE_PACKET"
+#define ERR_LENGTH 255
+#define ERR_FORMAT "%s: %s: %s\n" //tag:situation:reason
+#define ERR_TAG "sdb"
+
extern int loglevel_mask;
extern int trace_packet;
#define LOG_ASSERT(cond) do { if (!(cond)) LOG_FATAL( "assertion failed '%s'\n", #cond); } while (0)
-
#define LOG_ERROR(args...) \
do { if ((loglevel_mask & (1 << SDBLOG_ERROR)) != 0) { \
logging(SDBLOG_ERROR, __FILE__, __FUNCTION__, __LINE__, args); } } while(0)
void log_init(void);
void logging(LogLevel level, const char *filename, const char *funcname, int line_number, const char *fmt, ...);
void logging_hex(char* hex, char* asci);
+void print_error(int fatal, const char* situation, const char* reason, ...);
// define for a while for testing
#undef D
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
const char* STATE_UNKNOWN = "unknown";
const char* STATE_SUSPENDED = "suspended";
- const char* TRANSPORT_ERR_MORE_THAN_ONE_TARGET = "There are more than one target. Please specify the target using -s option.";
- const char* TRANSPORT_ERR_MORE_THAN_ONE_EMUL = "There are more than one emulator. Please specify the emulator using -s option.";
- const char* TRANSPORT_ERR_MORE_THAN_ONE_DEV = "There are more than one device. Please specify the device using -s option.";
- const char* TRANSPORT_ERR_TARGET_OFFLINE = "target offline";
- const char* TRANSPORT_ERR_TARGET_SUSPENDED = "emulator is in suspended mode";
- const char* TRANSPORT_ERR_TARGET_NOT_FOUND = "target not found";
-
- const char* FORWARD_ERR_UNKNOWN_LOCAL_PORT = "wrong local port format";
- const char* FORWARD_ERR_UNKNOWN_REMOTE_PORT = "wrong remote port format";
- const char* FORWARD_ERR_INSTALL_FAIL = "cannot install listener";
- const char* FORWARD_ERR_REMOVE_FAIL = "cannot remove listener";
+ const char* ERR_REASON_GENERAL_PROTOCOL_WRONG_ID = "protocol error. expected '%s' but get '%s'";
+ const char* ERR_REASON_GENERAL_PROTOCOL_DATA_OVERRUN = "protocol error. data length '%d' overruns '%d'";
+ const char* ERR_REASON_GENERAL_CONNECTION_FAIL = "connection fails. %s";
+ const char* ERR_REASON_GENERAL_UNKNOWN = "unknown reason";
+ const char* ERR_REASON_SYNC_NOT_FILE = "'%s' is not a file";
+
+ const char* ERR_SITU_SYNC_OPEN_CHANNEL = "fail to open sync channel";
+ const char* ERR_SITU_SYNC_STAT_FILE = "fail to stat '%s'";
+ const char* ERR_SITU_SYNC_GET_DIRLIST = "fail to read dirlist of '%s'";
+ const char* ERR_SITU_SYNC_READ_FILE = "fail to read '%s'";
+ const char* ERR_SITU_SYNC_OPEN_FILE = "fail to open '%s'";
+ const char* ERR_SITU_SYNC_CREATE_FILE = "fail to create '%s'";
+ const char* ERR_SITU_SYNC_CLOSE_FILE = "fail to close '%s'";
+ const char* ERR_SITU_SYNC_WRITE_FILE = "fail to write '%s'";
+
+ const char* ERR_TRANSPORT_MORE_THAN_ONE_TARGET = "error: there are more than one target. Please specify the target using -s option.";
+ const char* ERR_TRANSPORT_MORE_THAN_ONE_EMUL = "error: there are more than one emulator. Please specify the emulator using -s option.";
+ const char* ERR_TRANSPORT_MORE_THAN_ONE_DEV = "error: there are more than one device. Please specify the device using -s option.";
+ const char* ERR_TRANSPORT_TARGET_OFFLINE = "error: target offline";
+ const char* ERR_TRANSPORT_TARGET_SUSPENDED = "error: emulator is in suspended mode";
+ const char* ERR_TRANSPORT_TARGET_NOT_FOUND = "error: target not found";
+
+ const char* ERR_FORWARD_UNKNOWN_LOCAL_PORT = "error: wrong local port format";
+ const char* ERR_FORWARD_UNKNOWN_REMOTE_PORT = "error: wrong remote port format";
+ const char* ERR_FORWARD_INSTALL_FAIL = "error: cannot install listener";
+ const char* ERR_FORWARD_REMOVE_FAIL = "error: cannot remove listener";
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
extern const char* STATE_UNKNOWN;
extern const char* STATE_SUSPENDED;
- extern const char* TRANSPORT_ERR_MORE_THAN_ONE_TARGET;
- extern const char* TRANSPORT_ERR_MORE_THAN_ONE_EMUL;
- extern const char* TRANSPORT_ERR_MORE_THAN_ONE_DEV;
- extern const char* TRANSPORT_ERR_TARGET_OFFLINE;
- extern const char* TRANSPORT_ERR_TARGET_SUSPENDED;
- extern const char* TRANSPORT_ERR_TARGET_NOT_FOUND;
-
- extern const char* FORWARD_ERR_UNKNOWN_LOCAL_PORT;
- extern const char* FORWARD_ERR_UNKNOWN_REMOTE_PORT;
- extern const char* FORWARD_ERR_INSTALL_FAIL;
- extern const char* FORWARD_ERR_REMOVE_FAIL;
+ extern const char* ERR_REASON_GENERAL_PROTOCOL_WRONG_ID;
+ extern const char* ERR_REASON_GENERAL_PROTOCOL_DATA_OVERRUN;
+ extern const char* ERR_REASON_GENERAL_CONNECTION_FAIL;
+ extern const char* ERR_REASON_GENERAL_UNKNOWN;
+ extern const char* ERR_REASON_SYNC_NOT_FILE;
+
+ extern const char* ERR_SITU_SYNC_OPEN_CHANNEL;
+ extern const char* ERR_SITU_SYNC_STAT_FILE;
+ extern const char* ERR_SITU_SYNC_GET_DIRLIST;
+ extern const char* ERR_SITU_SYNC_READ_FILE;
+ extern const char* ERR_SITU_SYNC_OPEN_FILE;
+ extern const char* ERR_SITU_SYNC_CREATE_FILE;
+ extern const char* ERR_SITU_SYNC_CLOSE_FILE;
+ extern const char* ERR_SITU_SYNC_WRITE_FILE;
+
+ extern const char* ERR_TRANSPORT_MORE_THAN_ONE_TARGET;
+ extern const char* ERR_TRANSPORT_MORE_THAN_ONE_EMUL;
+ extern const char* ERR_TRANSPORT_MORE_THAN_ONE_DEV;
+ extern const char* ERR_TRANSPORT_TARGET_OFFLINE;
+ extern const char* ERR_TRANSPORT_TARGET_SUSPENDED;
+ extern const char* ERR_TRANSPORT_TARGET_NOT_FOUND;
+
+ extern const char* ERR_FORWARD_UNKNOWN_LOCAL_PORT;
+ extern const char* ERR_FORWARD_UNKNOWN_REMOTE_PORT;
+ extern const char* ERR_FORWARD_INSTALL_FAIL;
+ extern const char* ERR_FORWARD_REMOVE_FAIL;
#endif /* SDB_CONSTANTS_H_*/
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions andㄴ
+* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
char* serial = host_str + prefix_len;
char* end = strchr(serial, ':');
if(end == NULL) {
- *err_str = (char*)TRANSPORT_ERR_TARGET_NOT_FOUND;
+ *err_str = (char*)ERR_TRANSPORT_TARGET_NOT_FOUND;
return 0;
}
if (t == NULL || t->connection_state == CS_OFFLINE) {
if(t != NULL) {
- forward_err = (char*)TRANSPORT_ERR_TARGET_OFFLINE;
+ forward_err = (char*)ERR_TRANSPORT_TARGET_OFFLINE;
}
else {
forward_err = err_str;
*remote++ = 0;
if(strncmp("tcp:", local, 4)){
- forward_err = (char*)FORWARD_ERR_UNKNOWN_LOCAL_PORT;
+ forward_err = (char*)ERR_FORWARD_UNKNOWN_LOCAL_PORT;
goto sendfail;
}
if(strncmp("tcp:", remote, 4)){
- forward_err = (char*)FORWARD_ERR_UNKNOWN_REMOTE_PORT;
+ forward_err = (char*)ERR_FORWARD_UNKNOWN_REMOTE_PORT;
goto sendfail;
}
return 0;
}
else {
- forward_err = (char*)FORWARD_ERR_INSTALL_FAIL;
+ forward_err = (char*)ERR_FORWARD_INSTALL_FAIL;
goto sendfail;
}
} else {
writex(socket->fd, "OKAYOKAY", 8);
return 0;
} else {
- forward_err = (char*)FORWARD_ERR_REMOVE_FAIL;
+ forward_err = (char*)ERR_FORWARD_REMOVE_FAIL;
goto sendfail;
}
}
} else {
if(t != NULL) {
if(t->suspended) {
- err_str =(char*)TRANSPORT_ERR_TARGET_SUSPENDED;
+ err_str =(char*)ERR_TRANSPORT_TARGET_SUSPENDED;
}
else {
- err_str = (char*)TRANSPORT_ERR_TARGET_OFFLINE;
+ err_str = (char*)ERR_TRANSPORT_TARGET_OFFLINE;
}
}
LOG_ERROR("LS(%X) get no transport", s->local_id);
} else {
if(ttype == kTransportAny) {
if (result) {
- *error_out = (char*)TRANSPORT_ERR_MORE_THAN_ONE_TARGET;
+ *error_out = (char*)ERR_TRANSPORT_MORE_THAN_ONE_TARGET;
result = NULL;
goto exit;
}
(ttype == kTransportLocal && transport_->type == kTransportConnect)) {
if (result) {
if(ttype == kTransportUsb) {
- *error_out = (char*)TRANSPORT_ERR_MORE_THAN_ONE_DEV;
+ *error_out = (char*)ERR_TRANSPORT_MORE_THAN_ONE_DEV;
}
else if(ttype == kTransportLocal) {
- *error_out = (char*)TRANSPORT_ERR_MORE_THAN_ONE_EMUL;
+ *error_out = (char*)ERR_TRANSPORT_MORE_THAN_ONE_EMUL;
}
result = NULL;
goto exit;
}
if (result == NULL ) {
- *error_out = (char*)TRANSPORT_ERR_TARGET_NOT_FOUND;
+ *error_out = (char*)ERR_TRANSPORT_TARGET_NOT_FOUND;
}
exit:
}
else if(cmd == A_CNXN) {
D("T(%s) gets CNXN\n", t->serial);
- if(t->connection_state != CS_OFFLINE) {
- t->connection_state = CS_OFFLINE;
- run_transport_close(t);
- }
+ /*
+ * Can receive A_CNXN multiple times if we apply connection timeout
+ * Block code which kills connection when it gets A_CNXN multiple times
+ */
+// if(t->connection_state != CS_OFFLINE) {
+// t->connection_state = CS_OFFLINE;
+// run_transport_close(t);
+// }
parse_banner((char*) p->data, t);
}
else if(cmd == A_STAT) {
}
}
-void append_file(char* result_path, char* dir, char* append_dir) {
+void append_file(char* result_path, char* dir, char* append_dir, int length) {
char* tmp_append;
int len = strlen(append_dir);
int dir_len = strlen(dir);
if(dir_len > 0 && dir[dir_len -1] != '/' && dir[dir_len -1] != '\\') {
- snprintf(result_path, PATH_MAX, "%s/%s",dir, tmp_append);
+ snprintf(result_path, length, "%s/%s",dir, tmp_append);
}
else {
- snprintf(result_path, PATH_MAX, "%s%s",dir, tmp_append);
+ snprintf(result_path, length, "%s%s",dir, tmp_append);
}
}
//returns 1 if path is directory, returns 0 if path is file, returns -1 if error occurred.
int is_directory(char* path);
int mkdirs(char *name);
-void append_file(char* result_path, char* dir, char* append_dir);
+void append_file(char* result_path, char* dir, char* append_dir, int len);
long long NOW();
void dup_quote(char* result_string, const char *source, int max_len);