Sambex.Connection (sambex v0.3.0)
View SourceGenServer for maintaining persistent SMB connections.
This module provides a connection-based API that stores credentials securely in GenServer state and avoids passing them on every operation. Connections can be anonymous (referenced by PID) or named (referenced by atom) for easy access throughout your application.
Benefits of Connection API
- Security: Credentials stored in process state, not passed around
- Performance: Avoids reconnection overhead on each operation
- Fault Tolerance: Full OTP supervision support with automatic restarts
- Multiple Shares: Easy management of connections to different SMB shares
- Elixir Idioms: Follows GenServer and OTP patterns
Connection Types
Anonymous Connections
Referenced by PID, suitable for short-lived operations:
{:ok, conn} = Sambex.Connection.connect("smb://server/share", "user", "pass")
Sambex.Connection.list_dir(conn, "/")
Sambex.Connection.disconnect(conn)
Named Connections
Referenced by atom, ideal for long-lived application connections:
{:ok, _} = Sambex.Connection.start_link([
url: "smb://fileserver/documents",
username: "user",
password: "pass",
name: :documents
])
# Use throughout your application
Sambex.Connection.read_file(:documents, "/report.pdf")
Supervised Connections
Managed by the connection supervisor for production use:
{:ok, conn} = Sambex.ConnectionSupervisor.start_connection([
url: "smb://server/share",
username: "user",
password: "pass",
name: :production_share
])
Complete Example
# Start named connections for different purposes
{:ok, _} = Sambex.Connection.start_link([
url: "smb://fileserver/app-data",
username: System.get_env("SMB_USER"),
password: System.get_env("SMB_PASS"),
name: :app_data
])
{:ok, _} = Sambex.Connection.start_link([
url: "smb://backup-server/backups",
username: System.get_env("BACKUP_USER"),
password: System.get_env("BACKUP_PASS"),
name: :backups
])
# Perform operations using named connections
{:ok, files} = Sambex.Connection.list_dir(:app_data, "/uploads")
for {filename, :file} <- files do
# Process each file
{:ok, content} = Sambex.Connection.read_file(:app_data, "/uploads/#{filename}")
# Backup processed files
processed = process_file(content)
Sambex.Connection.write_file(:backups, "/processed/#{filename}", processed)
end
Error Handling
All functions return standard {:ok, result}
or {:error, reason}
tuples:
case Sambex.Connection.read_file(:docs, "/important.pdf") do
{:ok, content} ->
save_to_local(content)
{:error, :enoent} ->
Logger.warn("File not found: /important.pdf")
{:error, :eacces} ->
Logger.error("Permission denied accessing /important.pdf")
{:error, reason} ->
Logger.error("Unexpected error: #{inspect(reason)}")
end
Path Handling
All file paths are relative to the share root specified in the connection URL:
# Connection to smb://server/documents
{:ok, conn} = Sambex.Connection.connect("smb://server/documents", "user", "pass")
# These paths are relative to /documents on the server
Sambex.Connection.list_dir(conn, "/") # Lists /documents/
Sambex.Connection.read_file(conn, "/file.txt") # Reads /documents/file.txt
Sambex.Connection.list_dir(conn, "/reports") # Lists /documents/reports/
Production Integration
For production applications, integrate connections into your supervision tree:
# In your application.ex
children = [
{Sambex.Connection, [
url: "smb://production-server/app-files",
username: Application.get_env(:my_app, :smb_username),
password: Application.get_env(:my_app, :smb_password),
name: :app_files
]}
]
Connection Lifecycle
Connections are GenServer processes that:
- Initialize with SMB credentials and URL
- Handle calls for SMB operations, forwarding to the underlying NIF
- Maintain state with connection details for the session
- Clean up automatically when the process terminates
The actual SMB connection is managed by the underlying libsmbclient library.
Summary
Functions
Returns a specification to start this module under a supervisor.
Convenience function to start a connection and return the PID.
Delete a file from the SMB share.
Stop a connection.
Download a file from the SMB share to local filesystem.
Get file statistics/metadata from the SMB share.
List files and directories in an SMB directory.
Create a directory on the SMB share.
Move/rename a file on the SMB share.
Read a file from the SMB share.
Start a connection GenServer.
Upload a local file to the SMB share.
Write a file to the SMB share.
Types
Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
Convenience function to start a connection and return the PID.
Examples
{:ok, conn} = Sambex.Connection.connect("smb://server/share", "user", "pass")
Sambex.Connection.list_dir(conn, "/")
Delete a file from the SMB share.
Parameters
conn_or_name
- Connection PID or registered namepath
- Path to the file relative to share root
Examples
:ok = Sambex.Connection.delete_file(conn, "/temp.txt")
@spec disconnect(connection_ref()) :: :ok
Stop a connection.
Examples
:ok = Sambex.Connection.disconnect(conn)
:ok = Sambex.Connection.disconnect(:my_share)
Download a file from the SMB share to local filesystem.
Parameters
conn_or_name
- Connection PID or registered nameremote_path
- Remote path relative to share rootlocal_path
- Local file path
Examples
:ok = Sambex.Connection.download_file(conn, "/remote/file.txt", "/local/file.txt")
Get file statistics/metadata from the SMB share.
Parameters
conn_or_name
- Connection PID or registered namepath
- Path to the file relative to share root
Examples
{:ok, stats} = Sambex.Connection.get_file_stats(conn, "/file.txt")
List files and directories in an SMB directory.
Parameters
conn_or_name
- Connection PID or registered namepath
- Path relative to the share root
Examples
Sambex.Connection.list_dir(conn, "/")
Sambex.Connection.list_dir(:my_share, "/documents")
@spec mkdir(connection_ref(), String.t()) :: :ok | {:error, any()}
Create a directory on the SMB share.
Parameters
conn_or_name
- Connection PID or registered namepath
- Path to the directory to create (relative to share root)
Returns
:ok
on success{:error, reason}
on failure
Examples
{:ok, conn} = Sambex.Connection.connect("smb://server/share", "user", "pass")
:ok = Sambex.Connection.mkdir(conn, "/new_folder")
# Create nested directories (parent must exist first)
:ok = Sambex.Connection.mkdir(:my_share, "/reports")
:ok = Sambex.Connection.mkdir(:my_share, "/reports/2025")
Move/rename a file on the SMB share.
Parameters
conn_or_name
- Connection PID or registered namesource_path
- Source path relative to share rootdest_path
- Destination path relative to share root
Examples
:ok = Sambex.Connection.move_file(conn, "/old.txt", "/new.txt")
Read a file from the SMB share.
Parameters
conn_or_name
- Connection PID or registered namepath
- Path to the file relative to share root
Examples
{:ok, content} = Sambex.Connection.read_file(conn, "/readme.txt")
Start a connection GenServer.
Options
:url
- SMB URL (required):username
- Username for authentication (required):password
- Password for authentication (required):name
- Optional name for the connection process
Examples
# Anonymous connection
{:ok, pid} = Sambex.Connection.start_link(
url: "smb://server/share",
username: "user",
password: "pass"
)
# Named connection
{:ok, pid} = Sambex.Connection.start_link(
url: "smb://server/share",
username: "user",
password: "pass",
name: :my_share
)
Upload a local file to the SMB share.
Parameters
conn_or_name
- Connection PID or registered namelocal_path
- Local file pathremote_path
- Remote path relative to share root
Examples
:ok = Sambex.Connection.upload_file(conn, "/local/file.txt", "/remote/file.txt")
Write a file to the SMB share.
Parameters
conn_or_name
- Connection PID or registered namepath
- Path to the file relative to share rootcontent
- Binary content to write
Examples
:ok = Sambex.Connection.write_file(conn, "/output.txt", "Hello World")