182 lines
4.8 KiB
C
182 lines
4.8 KiB
C
#include "client.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <netinet/tcp.h>
|
|
|
|
#define BUFFER_SIZE 4096
|
|
|
|
// 读取完整消息
|
|
ssize_t readMessage(int sock, char *buffer, size_t maxSize) {
|
|
uint32_t messageLen;
|
|
// 先读取消息长度
|
|
if (read(sock, &messageLen, sizeof(messageLen)) != sizeof(messageLen)) {
|
|
return -1;
|
|
}
|
|
|
|
// 检查buffer大小是否足够
|
|
if (messageLen >= maxSize) {
|
|
return -1;
|
|
}
|
|
|
|
// 读取完整消息
|
|
size_t totalRead = 0;
|
|
while (totalRead < messageLen) {
|
|
ssize_t n = read(sock, buffer + totalRead, messageLen - totalRead);
|
|
if (n <= 0) return -1;
|
|
totalRead += n;
|
|
}
|
|
buffer[messageLen] = '\0';
|
|
return messageLen;
|
|
}
|
|
|
|
int send_exec_params(const char *filename, char *const argv[],
|
|
char *const envp[], const char *logPath) {
|
|
char abs_path[PATH_MAX];
|
|
char pwd[PATH_MAX];
|
|
|
|
// 获取当前工作目录
|
|
if (getcwd(pwd, sizeof(pwd)) == NULL) {
|
|
perror("getcwd");
|
|
return -1;
|
|
}
|
|
|
|
if (logPath[0] != '/') { // 相对路径
|
|
size_t pwd_len = strlen(pwd);
|
|
size_t log_len = strlen(logPath);
|
|
if (pwd_len + log_len + 2 > PATH_MAX) {
|
|
errno = ENAMETOOLONG;
|
|
perror("path too long");
|
|
return -1;
|
|
}
|
|
|
|
strncpy(abs_path, pwd, PATH_MAX - 1);
|
|
abs_path[PATH_MAX - 1] = '\0';
|
|
strncat(abs_path, "/", PATH_MAX - strlen(abs_path) - 1);
|
|
strncat(abs_path, logPath, PATH_MAX - strlen(abs_path) - 1);
|
|
|
|
char real_path[PATH_MAX];
|
|
if (realpath(abs_path, real_path) == NULL) {
|
|
perror("realpath");
|
|
return -1;
|
|
}
|
|
strncpy(abs_path, real_path, PATH_MAX - 1);
|
|
abs_path[PATH_MAX - 1] = '\0';
|
|
} else {
|
|
strncpy(abs_path, logPath, PATH_MAX - 1);
|
|
abs_path[PATH_MAX - 1] = '\0';
|
|
}
|
|
|
|
size_t path_len = strlen(abs_path);
|
|
|
|
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
if (sock == -1) {
|
|
perror("socket");
|
|
return -1;
|
|
}
|
|
|
|
// 设置TCP_NODELAY
|
|
// int flag = 1;
|
|
// setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
|
|
|
|
struct sockaddr_un addr;
|
|
memset(&addr, 0, sizeof(addr));
|
|
addr.sun_family = AF_UNIX;
|
|
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
|
|
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
|
|
|
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
|
perror("connect");
|
|
close(sock);
|
|
return -1;
|
|
}
|
|
|
|
// 发送文件名
|
|
size_t filename_len = strlen(filename);
|
|
write(sock, &filename_len, sizeof(size_t));
|
|
write(sock, filename, filename_len);
|
|
|
|
// 发送当前工作目录
|
|
size_t pwd_len = strlen(pwd);
|
|
write(sock, &pwd_len, sizeof(size_t));
|
|
write(sock, pwd, pwd_len);
|
|
|
|
// 发送argv
|
|
int argc = 0;
|
|
while (argv[argc] != NULL) argc++;
|
|
write(sock, &argc, sizeof(int));
|
|
|
|
for (int i = 0; i < argc; i++) {
|
|
size_t arg_len = strlen(argv[i]);
|
|
write(sock, &arg_len, sizeof(size_t));
|
|
write(sock, argv[i], arg_len);
|
|
}
|
|
|
|
// 发送envp
|
|
int envc = 0;
|
|
while (envp[envc] != NULL) envc++;
|
|
write(sock, &envc, sizeof(int));
|
|
|
|
for (int i = 0; i < envc; i++) {
|
|
size_t env_len = strlen(envp[i]);
|
|
write(sock, &env_len, sizeof(size_t));
|
|
write(sock, envp[i], env_len);
|
|
}
|
|
|
|
// 发送logPath
|
|
write(sock, &path_len, sizeof(size_t));
|
|
write(sock, abs_path, path_len);
|
|
|
|
// 接收服务器响应
|
|
char buffer[BUFFER_SIZE];
|
|
char display_buffer[BUFFER_SIZE];
|
|
ssize_t bytes_read;
|
|
int started = 0;
|
|
|
|
// 等待接收[sthttp]标记
|
|
while (!started) {
|
|
bytes_read = readMessage(sock, buffer, BUFFER_SIZE);
|
|
if (bytes_read <= 0) {
|
|
perror("Failed to read start marker");
|
|
close(sock);
|
|
return -1;
|
|
}
|
|
|
|
if (strstr(buffer, "[sthttp]")) {
|
|
started = 1;
|
|
}
|
|
}
|
|
|
|
// 持续读取消息直到收到[end]
|
|
while (1) {
|
|
bytes_read = readMessage(sock, buffer, BUFFER_SIZE);
|
|
if (bytes_read <= 0) {
|
|
break;
|
|
}
|
|
|
|
if (strstr(buffer, "[end]")) {
|
|
break;
|
|
}
|
|
|
|
// 处理[res]...[wait]消息
|
|
char *res_start = strstr(buffer, "[res]");
|
|
char *wait_end = strstr(buffer, "[wait]");
|
|
|
|
if (res_start && wait_end) {
|
|
size_t content_len = wait_end - (res_start + strlen("[res]"));
|
|
if (content_len < BUFFER_SIZE) {
|
|
strncpy(display_buffer, res_start + strlen("[res]"), content_len);
|
|
display_buffer[content_len] = '\0';
|
|
printf("%s\n", display_buffer);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
}
|
|
|
|
close(sock);
|
|
return 0;
|
|
}
|