Overview
The main() function serves as the unified entry point for the ascii-chat application, implementing a mode dispatcher that routes execution to either server or client mode based on command-line arguments. This design consolidates both server and client functionality into a single binary, simplifying deployment and ensuring version consistency.
Implementation: src/main.c
Key Features:
- Unified binary dispatcher for server and client modes
- Command-line argument parsing and mode selection
- Help and version information display
- Extensible mode registration system
- Clean separation of concerns between dispatcher and modes
Unified Binary Architecture
ascii-chat consolidates server and client into one executable:
Command Syntax:
ascii-chat <mode> [options...]
ascii-chat --help
ascii-chat --version
Available Modes:
- server - Multi-client video chat server with ASCII frame mixing
- client - Video chat client with webcam capture and terminal display
Design Benefits:
- Single binary simplifies installation and deployment
- Shared library code reduces disk space usage
- Unified versioning eliminates client/server mismatch issues
- Easier testing and packaging (one artifact to build)
- Consistent version reporting across modes
Dispatching Logic
The dispatcher implements clean separation of concerns:
Help and Version
if (argc == 1 || (argc == 2 && strcmp(argv[1], "--help") == 0)) {
print_top_level_help();
exit(0);
}
if (argc == 2 && strcmp(argv[1], "--version") == 0) {
print_version();
exit(0);
}
Mode Selection
const char *mode_name = argv[1];
if (!mode) {
fprintf(stderr, "Unknown mode: %s\n", mode_name);
print_top_level_help();
}
exit(result);
mode_entry_point_t entry_point
Mode Interaction
The dispatcher forwards execution to mode-specific entry points:
Server Mode
When server mode is selected:
int server_main(void)
Server mode entry point for unified binary.
Server Entry Point (src/server/main.c):
- Initializes server subsystems (crypto, audio mixer, buffer pools)
- Binds to listening sockets (IPv4 and IPv6)
- Accepts client connections in main loop
- Coordinates per-client threading (receive, send, render threads)
- Handles graceful shutdown and cleanup
Client Mode
When client mode is selected:
int client_main(void)
Client mode entry point for unified binary.
Client Entry Point (src/client/main.c):
- Initializes client subsystems (display, capture, audio)
- Establishes connection to server with exponential backoff
- Starts worker threads (protocol, keepalive, capture, audio)
- Implements reconnection logic on connection loss
- Handles graceful shutdown and cleanup
Mode Registration System
The dispatcher uses a function pointer table pattern for extensibility:
typedef struct {
const char *name;
const char *description;
{
"server",
"Multi-client video chat server",
server_main },
{ NULL, NULL, NULL }
};
int(* mode_entry_point_t)(void)
Adding New Modes:
- Implement
int new_mode_main(int argc, char *argv[])
- Add entry to modes[] table
- Mode automatically appears in help and becomes available
Implementation Details
Command-Line Parsing
The dispatcher handles top-level commands before mode dispatch:
--help (no mode): Shows mode selection help
--version: Shows unified binary version
<mode> --help: Forwarded to mode-specific entry point
<mode> [options...]: Forwarded to mode-specific entry point
Error Handling
Invalid Mode:
- Prints error message to stderr
- Shows top-level help
- Exits with
ERROR_USAGE
Mode Execution Failure:
- Returns mode's error code unchanged
- Dispatcher exits with same code
- Allows mode-specific exit codes to propagate
Version Reporting
Both modes report the same version:
printf("ascii-chat version %s\n", VERSION_STRING);
This ensures server and client always know they're compatible.
Platform Compatibility
The unified binary works identically across all platforms:
- Linux/Unix:
./ascii-chat server or ./ascii-chat client
- macOS: Same as Linux/Unix
- Windows:
ascii-chat.exe server or ascii-chat.exe client
Optional Backwards Compatibility:
- Symlinks can provide mode-specific aliases:
ascii-chat-server → ascii-chat server
ascii-chat-client → ascii-chat client
- Environment-specific wrappers can provide convenience aliases
Design Rationale
Why Unified Binary?
- Simplified Deployment: One binary instead of two
- Version Consistency: No client/server version mismatches
- Shared Codebase: Common library code in lib/
- Easier Testing: Single artifact to build and test
- Packaging Simplicity: One package instead of two
Why Mode Dispatcher?
- Clean Separation: Dispatcher logic separate from mode logic
- Extensibility: Easy to add new modes (relay, proxy, etc.)
- Help System: Centralized help with mode-specific details
- Maintainability: Mode code can evolve independently
Integration Points
**Dispatcher (src/main.c)**:
- Provides top-level entry point
- Parses mode argument
- Routes to appropriate mode entry point
**Server Mode (src/server/main.c)**:
- Implements server_main() entry point
- Coordinates server subsystems
- Manages multi-client connections
**Client Mode (src/client/main.c)**:
- Implements client_main() entry point
- Coordinates client subsystems
- Manages connection and media capture
**Shared Library (lib/)**:
- Common functionality used by both modes
- Platform abstraction, networking, crypto, video processing
- No mode-specific dependencies
- See also
- src/main.c
-
src/server/main.c
-
src/client/main.c
-
Server Overview
-
Client Overview