gchar* get_win_home(void){ gchar WinPath[257]; GetModuleFileName( NULL, WinPath, 256 ); return(my_dirname(WinPath)); }
static void proto_handle_get(conn_t* cn, const char* line) { struct stat st; // Reject filenames with just "." and ".." if(memcmp(line, ".\0", 2) == 0 || memcmp(line, "..\0", 3) == 0) { conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__); conn_abort(cn); return; } if(lstat(line,&st) == 0) { if(S_ISREG(st.st_mode)) { int fd; md5_state_t md5_state; md5_init(&md5_state); char buffer[PATH_MAX]; ssize_t size; char md5str[33]; char modestr[11]; #ifdef O_NOATIME if((fd = open(line,O_RDONLY|O_NOATIME))==-1) { #else if((fd = open(line,O_RDONLY))==-1) { #endif conn_perror(cn, "WARNING open()"); conn_printf(cn, "WARNING Can't open file: %s\n", line); return; } // Calcuate MD5 { unsigned char md5bin[16]; while((size = read(fd, buffer, sizeof buffer))) md5_append(&md5_state, (unsigned char*)buffer, size); md5_finish(&md5_state, (unsigned char*)md5bin); if(lseek(fd, SEEK_SET, 0)==-1) { conn_perror(cn, "ERROR lseek()"); conn_abort(cn); return; } md5bin2str(md5bin, md5str); } mode2str(st.st_mode, modestr); conn_printf(cn, "PUT %ld %s %s %ld %ld %ld %s\n", (long int)st.st_size, md5str, modestr, st.st_atime, st.st_ctime, st.st_mtime, line); while((size = read(fd, buffer, sizeof buffer))) conn_write(cn, buffer, size); close(fd); } else if(S_ISDIR(st.st_mode)) { char modestr[11]; mode2str(st.st_mode, modestr); conn_printf(cn, "MKDIR %s %ld %ld %ld %s\n", modestr, st.st_atime, st.st_ctime, st.st_mtime, line); } else if(S_ISLNK(st.st_mode)) { char buffer[PATH_MAX]; conn_printf(cn, "SLNK %s\n", line); ssize_t l; if((l=readlink(line, buffer, sizeof buffer))==-1) { conn_perror(cn, "WARNING readlink()"); return; } buffer[l] = '\0'; conn_printf(cn, "%s\n", buffer); } else { conn_printf(cn, "WARNING Ignored %s\n", line); } } } static void proto_handle_put(conn_t* cn, const char* line) { const char* delim = " "; char* saveptr = NULL; char* token; char* ptr = (char*)line; int c = 0; ssize_t size = 0; mode_t mode = 0; time_t mtime = 0; time_t ctime = 0; time_t atime = 0; char* name = NULL; char* md5 = NULL; while((token = strtok_r(ptr, delim, &saveptr))) { switch(c) { case 0: size = atol(token); break; case 1: md5 = token; break; case 2: mode = str2mode(token); break; case 3: atime = atol(token); break; case 4: ctime = atol(token); break; case 5: mtime = atol(token); break; case 6: name = token; break; } c++; ptr = NULL; } if(c != 7) { conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__); conn_abort(cn); return ; } int fd = creat(name, O_CREAT|O_TRUNC); if(fd == -1) { conn_perror(cn, "WARNING creat()"); return; } if(chmod(name,mode)==-1) { perror("WARNING chmod()"); } struct utimbuf t; t.actime = atime; t.modtime = mtime; if(utime(name,&t)==-1) { perror("WARNING utime"); } // CONTENT int bytes_left = size; int r; md5_state_t md5_state; unsigned char md5bin[16]; char md5str[33]; md5_init(&md5_state); while(!cn->abort && bytes_left) { if(cn->rbuf_len == 0) (void)conn_read(cn); r = MIN(bytes_left, cn->rbuf_len); if(r) { write(fd, cn->rbuf, r); md5_append(&md5_state, (unsigned char*)cn->rbuf, r); conn_shift(cn,r); bytes_left -= r; } assert(bytes_left >= 0); } close(fd); md5_finish(&md5_state, (unsigned char*)md5bin); md5bin2str(md5bin, md5str); // Check md5 if(strcmp(md5str,md5)!=0) { // Mismatch! conn_printf(cn, "WARNING %s md5-mismatch (%s <-> %s), removing file\n", name, md5str, md5); if(unlink(name)==-1) { perror("WARNING: unlink()"); } } else { struct utimbuf t; t.actime = atime; t.modtime = mtime; if(utime(name,&t)==-1) { perror("utime"); conn_printf(cn, "WARNING Can't timestamp on directory: %s\n", name); } // md5 is fine conn_printf(cn, "GET %s\n", name); } } static void proto_handle_slnk(conn_t* cn, const char* line) { char curdir[PATH_MAX]; // read next line to get target char target[PATH_MAX]; if(!conn_readline(cn, target, sizeof target)) return; getcwd(curdir, sizeof curdir); // Make sure it dosnt exist unlink(line); if(chdir(my_dirname(line))==-1) { conn_perror(cn, "WARNING chdir()"); return; } if(symlink(target, my_basename(line))==-1) { conn_perror(cn, "ERROR symlink()"); conn_abort(cn); return; } chdir(curdir); conn_printf(cn, "GET %s\n", line); }