netatalk 4.5.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
afp_dsi.c File Reference
`#include <arpa/inet.h>`
`#include <errno.h>`
`#include <fcntl.h>`
`#include <netinet/in.h>`
`#include <netinet/tcp.h>`
`#include <signal.h>`
`#include <stdbool.h>`
`#include <stdio.h>`
`#include <stdlib.h>`
`#include <string.h>`
`#include <sys/socket.h>`
`#include <sys/stat.h>`
`#include <poll.h>`
`#include <sys/time.h>`
`#include <sys/types.h>`
`#include <sys/wait.h>`
`#include <time.h>`
`#include <unistd.h>`
`#include <atalk/afp_util.h>`
`#include <atalk/compat.h>`
`#include <atalk/dsi.h>`
`#include <atalk/fce_api.h>`
`#include <atalk/globals.h>`
`#include <atalk/logger.h>`
`#include <atalk/netatalk_conf.h>`
`#include <atalk/server_ipc.h>`
`#include <atalk/spotlight.h>`
`#include <atalk/util.h>`
`#include <atalk/uuid.h>`
`#include "auth.h"`
`#include "dircache.h"`
`#include "directory.h"`
`#include "fork.h"`
`#include "idle_worker.h"`
`#include "switch.h"`

## Data Structures
struct | rc_elem_t

## Macros
#define | SOL_TCP IPPROTO_TCP

## Functions
static void | sigpipe_init (void)
static void | sigpipe_notify (void)
| Write a single byte to the self-pipe.
static void | sigpipe_drain (void)
| Drain all pending bytes from the self-pipe.
static void | afp_dsi_close (AFPObj *obj)
static void | afp_dsi_die (int sig)
| SIGTERM: Terminate the AFP session and exit.
static void | afp_dsi_transfer_handler (int sig)
static void | handle_transfer_session (AFPObj *obj)
| Process deferred SIGURG: primary reconnect.
static void | afp_dsi_die_handler (int sig)
static void | afp_dsi_timedown_handler (int sig)
static void | handle_timedown (AFPObj *obj)
| Process deferred SIGUSR1: server going down in 5 minutes.
static void | afp_dsi_reload (int sig)
static void | afp_dsi_debug (int sig)
static void | afp_dsi_getmesg_handler (int sig)
static void | handle_getmesg (AFPObj *obj)
| Process deferred SIGUSR2: server message.
static void | alarm_handler (int sig)
| SIGALRM handler — async-signal-safe.
static void | handle_alarm (AFPObj *obj)
| Process deferred SIGALRM: tickle/timeout management.
static void | child_handler (int sig)
static int | process_deferred_signals (AFPObj *obj)
| Process all pending deferred signals.
static void | pending_request (DSI *dsi)
void | afp_over_dsi_sighandlers (AFPObj *obj)
void | afp_over_dsi (AFPObj *obj)

## Variables
AFPObj * | AFPobj = NULL
static rc_elem_t | replaycache [REPLAYCACHE_SIZE]
static volatile sig_atomic_t | alarm_pending = 0
static volatile sig_atomic_t | transfer_pending = 0
static volatile sig_atomic_t | timedown_pending = 0
static volatile sig_atomic_t | getmesg_pending = 0
volatile sig_atomic_t | die_pending = 0
static int | sigpipe_fd [2] = {-1, -1}
| Self-pipe for waking poll() from signal handlers.
volatile sig_atomic_t | reload_request = 0
static volatile sig_atomic_t | debug_request = 0

## Macro Definition Documentation

## ◆ SOL_TCP

#define SOL_TCP IPPROTO_TCP

## Function Documentation

## ◆ afp_dsi_close()

void afp_dsi_close | ( | AFPObj * | obj | ) |
| static

## ◆ afp_dsi_debug()

void afp_dsi_debug | ( | int | sig | ) |
| static

## ◆ afp_dsi_die()

void afp_dsi_die | ( | int | sig | ) |
| static

SIGTERM: Terminate the AFP session and exit.

Wraps afp_dsi_close() + exit() with pre-flight checks and a shutdown attention to notify the client. Other call sites in this file invoke afp_dsi_close() + exit() directly — a future cleanup could funnel all exit paths through here.

Parameters

  sig | signal number or EXITERR_* code; 0 for maintenance shutdown.

## ◆ afp_dsi_die_handler()

void afp_dsi_die_handler | ( | int | sig | ) |
| static

SIGTERM/SIGQUIT handler — async-signal-safe

## ◆ afp_dsi_getmesg_handler()

void afp_dsi_getmesg_handler | ( | int | sig | ) |
| static

SIGUSR2 handler — async-signal-safe

## ◆ afp_dsi_reload()

void afp_dsi_reload | ( | int | sig | ) |
| static

## ◆ afp_dsi_timedown_handler()

void afp_dsi_timedown_handler | ( | int | sig | ) |
| static

SIGUSR1 handler — async-signal-safe

## ◆ afp_dsi_transfer_handler()

void afp_dsi_transfer_handler | ( | int | sig | ) |
| static

SIGURG handler (primary reconnect) — async-signal-safe

## ◆ afp_over_dsi()

void afp_over_dsi | ( | AFPObj * | obj | ) |

## ◆ afp_over_dsi_sighandlers()

void afp_over_dsi_sighandlers | ( | AFPObj * | obj | ) |

## ◆ alarm_handler()

void alarm_handler | ( | int | sig | ) |
| static

SIGALRM handler — async-signal-safe.

Only restarts the timer (setitimer is async-signal-safe) and sets a flag. All tickle/timeout logic is deferred to handle_alarm().

## ◆ child_handler()

void child_handler | ( | int | sig | ) |
| static

## ◆ handle_alarm()

void handle_alarm | ( | AFPObj * | obj | ) |
| static

Process deferred SIGALRM: tickle/timeout management.

Called from the main event loop where LOG/malloc/syslog are safe.

## ◆ handle_getmesg()

void handle_getmesg | ( | AFPObj * | obj | ) |
| static

Process deferred SIGUSR2: server message.

Called from the main event loop.

## ◆ handle_timedown()

void handle_timedown | ( | AFPObj * | obj | ) |
| static

Process deferred SIGUSR1: server going down in 5 minutes.

Called from the main event loop.

## ◆ handle_transfer_session()

void handle_transfer_session | ( | AFPObj * | obj | ) |
| static

Process deferred SIGURG: primary reconnect.

Called from the main event loop where non-signal-safe functions are permitted.

## ◆ pending_request()

void pending_request | ( | DSI * | dsi | ) |
| static

## ◆ process_deferred_signals()

int process_deferred_signals | ( | AFPObj * | obj | ) |
| static

Process all pending deferred signals.

Returns
  1 if the caller should restart the outer event loop (primary reconnect), 0 otherwise.

Note
  Must be called from the main event loop, never from signal context.

## ◆ sigpipe_drain()

void sigpipe_drain | ( | void |  | ) |
| static

Drain all pending bytes from the self-pipe.

Called from the main loop after poll() returns.

## ◆ sigpipe_init()

void sigpipe_init | ( | void |  | ) |
| static

## ◆ sigpipe_notify()

void sigpipe_notify | ( | void |  | ) |
| static

Write a single byte to the self-pipe.

Called from signal handlers — async-signal-safe.

## Variable Documentation

## ◆ AFPobj

AFPObj* AFPobj = NULL

We generally pass this from afp_over_dsi to all afp_* funcs, so it should already be available everywhere. Unfortunately some funcs (eg acltoownermode) need acces to it but are deeply nested in the function chain with the caller already without acces to it. Changing this would require adding a reference to the caller which itself might be called in many places (eg acltoownermode is called from accessmode). The only sane way out is providing a copy of it here:

## ◆ alarm_pending

volatile sig_atomic_t alarm_pending = 0
| static

## ◆ debug_request

volatile sig_atomic_t debug_request = 0
| static

SIGINT: enable max_debug LOGging — async-signal-safe

## ◆ die_pending

volatile sig_atomic_t die_pending = 0

## ◆ getmesg_pending

volatile sig_atomic_t getmesg_pending = 0
| static

## ◆ reload_request

volatile sig_atomic_t reload_request = 0

SIGHUP: reload configuration file — async-signal-safe

## ◆ replaycache

rc_elem_t replaycache[REPLAYCACHE_SIZE]
| static

AFP replay cache:

- fix sized array
- indexed just by taking DSIreqID mod REPLAYCACHE_SIZE

## ◆ sigpipe_fd

int sigpipe_fd[2] = {-1, -1}
| static

Self-pipe for waking poll() from signal handlers.

Signal handlers write a single byte to sigpipe_fd[1]. The read end sigpipe_fd[0] is included in the poll() set so that the main loop wakes up promptly even when SA_RESTART would otherwise cause poll() to be restarted transparently.

Although POSIX says poll() is not affected by SA_RESTART, some platforms (Solaris, illumos) have historically restarted it. The self-pipe makes wake-up behaviour portable and deterministic.

## ◆ timedown_pending

volatile sig_atomic_t timedown_pending = 0
| static

## ◆ transfer_pending

volatile sig_atomic_t transfer_pending = 0
| static