static int unpack_file(FILE *pack) { _cleanup_close_ int fd = -1; char fn[PATH_MAX]; bool any = false; struct stat st; uint64_t inode; assert(pack); if (!fgets(fn, sizeof(fn), pack)) return 0; char_array_0(fn); truncate_nl(fn); fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW); if (fd < 0) { if (errno != ENOENT && errno != EPERM && errno != EACCES && errno != ELOOP) log_warning("open(%s) failed: %m", fn); } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) fd = safe_close(fd); if (fread(&inode, sizeof(inode), 1, pack) != 1) { log_error("Premature end of pack file."); return -EIO; } if (fd >= 0) { /* If the inode changed the file got deleted, so just * ignore this entry */ if (st.st_ino != (uint64_t) inode) fd = safe_close(fd); } for (;;) { uint32_t b, c; if (fread(&b, sizeof(b), 1, pack) != 1 || fread(&c, sizeof(c), 1, pack) != 1) { log_error("Premature end of pack file."); return -EIO; } if (b == 0 && c == 0) break; if (c <= b) { log_error("Invalid pack file."); return -EIO; } log_debug("%s: page %u to %u", fn, b, c); any = true; if (fd >= 0) { if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) { log_warning("posix_fadvise() failed: %m"); return -errno; } } } if (!any && fd >= 0) { /* if no range is encoded in the pack file this is * intended to mean that the whole file shall be * read */ if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) { log_warning("posix_fadvise() failed: %m"); return -errno; } } return 0; }
int main(int argc, char *argv[]) { if(argc != 2) { printf("usage : %s <ipaddress>\n", argv[0]); return -1; } strcpy(server_address, argv[1]); sleep_us(500000); /* * configure the client. */ if(client_configure(master_port, transmit_port, ssl_certificate, ssl_key) < 0) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "client configured"); return -1; } printf("%-60s[\033[;32mOK\033[0m]\n", "client configured"); sleep_us(500000); /* * initialize the SSL */ ctx_server = ssl_server_init(ssl_certificate, ssl_key); if(ctx_server == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL server initialize"); return -1; } ctx_client = ssl_client_init(); if(ctx_client == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL client initialize"); return -1; } printf("%-60s[\033[;32mOK\033[0m]\n", "SSL initialize"); sleep_us(500000); /* * connect to the master server. */ char temp[MAXLINE]; snprintf(temp, MAXLINE, "connect to master server: %s", argv[1]); int masterfd = client_connect(argv[1], master_port); if(masterfd == -1) { printf("%-60s[\033[;31mFAILED\033[0m]\n", temp); return -1; } sockaddr_in clientaddr; socklen_t len = sizeof(clientaddr); memset(&clientaddr, 0, len); getsockname(masterfd, (sockaddr*)&clientaddr, &len); inet_ntop(AF_INET, (void *)&clientaddr.sin_addr, ip_address, MAXLINE); printf("%-60s[\033[;32mOK\033[0m]\n", temp); sleep_us(500000); SSL *ssl = ssl_client(ctx_client, masterfd); if(ssl == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "ssl_client\n"); return -1; } /* * verify the executable client to judge if it's a fake one. */ char *ver_buf = file_verify(argv[0]); if(ver_buf == NULL) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client"); return -1; } int k = SSL_write(ssl, ver_buf, strlen(ver_buf)); if( k != (int)strlen(ver_buf)) { printf("SSL_write error\n"); return -1; } k = SSL_read(ssl, temp, MAXLINE); if(k < 0) { printf("SSL_read error"); return -1; } temp[k] = '\0'; if(strcmp(temp, "verify client unsuccessfully") == 0) { printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client"); return -1; } free(ver_buf); sleep_us(500000); /* * Listen to the transmit port to upload/download files */ snprintf(temp, MAXLINE, "listen to transmit port: %s", transmit_port); int listenfd = server_listen(transmit_port); if(listenfd == -1) { printf("%-60s[\033[;31mFAILED\033[0m]\n", temp); return -1; } printf("%-60s[\033[;32mOK\033[0m]\n", temp); sleep_us(500000); /* * create transmit_thread to handle upload/download files request * from the slave server. */ pthread_t thread; int ret = pthread_create(&thread, NULL, transmit_thread, static_cast<void*>(new int(listenfd))); if(ret == 0) printf("%-60s[\033[;32mOK\033[0m]\n", "transmit_thread create"); else { printf("%-60s[\033[;31FAILED\033[0m]\n", "transmit_thread create"); return -1; } /* * initialize the download/upload mutex. */ pthread_mutex_init(&download_mutex, NULL); pthread_mutex_init(&upload_mutex, NULL); char command_line[MAXLINE]; snprintf(cmd_line, MAXLINE,"%s:%s> ", argv[1], master_port); while(!stop) { printf(cmd_line); fflush(stdin); //read the command inputed by the user. fgets(command_line, MAXLINE, stdin); int len = strlen(command_line); if(command_line[len-1] == '\n') command_line[len-1] = '\0'; command_parse(ssl, command_line); } SSL_shutdown(ssl); // send SSL/TLS close_notify */ close(masterfd); SSL_free(ssl); SSL_CTX_free(ctx_server); SSL_CTX_free(ctx_client); return 0; }