netatalk  4.4.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
dsi_stream.c File Reference
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <atalk/dsi.h>
#include <atalk/logger.h>
#include <atalk/util.h>

Macros

#define MSG_MORE   0x8000
#define MSG_DONTWAIT   0x40

Functions

static void dsi_header_pack_reply (const DSI *dsi, char *buf)
static int dsi_peek (DSI *dsi)
 Check if we can write to the DSI socket.
static size_t from_buf (DSI *dsi, uint8_t *buf, size_t count)
static ssize_t buf_read (DSI *dsi, uint8_t *buf, size_t count)
 Get bytes from buffer dsi->buffer or read from socket.
static size_t dsi_buffered_stream_read (DSI *dsi, uint8_t *data, const size_t length)
 Get "length" bytes from buffer and/or socket.
static void block_sig (DSI *dsi)
static void unblock_sig (DSI *dsi)
int dsi_disconnect (DSI *dsi)
 Communication error with the client, enter disconnected state.
ssize_t dsi_stream_write (DSI *dsi, void *data, const size_t length, int mode)
 write raw DSI data
ssize_t dsi_stream_read_file (DSI *dsi, const int fromfd, off_t offset, const size_t length, const int err)
size_t dsi_stream_read (DSI *dsi, void *data, const size_t length)
 Read data from DSI buffer.
int dsi_stream_send (DSI *dsi, void *buf, size_t length)
 write data.
int dsi_stream_receive (DSI *dsi)
 Read DSI command and data.

Macro Definition Documentation

◆ MSG_DONTWAIT

#define MSG_DONTWAIT   0x40

◆ MSG_MORE

#define MSG_MORE   0x8000

Function Documentation

◆ block_sig()

void block_sig ( DSI * dsi)
static

◆ buf_read()

ssize_t buf_read ( DSI * dsi,
uint8_t * buf,
size_t count )
static

Get bytes from buffer dsi->buffer or read from socket.

  1. Check if there are bytes in the the dsi->buffer buffer.
  2. Return bytes from (1) if yes. Note: this may return fewer bytes then requested in count !!
  3. If the buffer was empty, read from the socket.

◆ dsi_buffered_stream_read()

size_t dsi_buffered_stream_read ( DSI * dsi,
uint8_t * data,
const size_t length )
static

Get "length" bytes from buffer and/or socket.

In order to avoid frequent small reads this tries to read larger chunks (8192 bytes) into a buffer.

◆ dsi_disconnect()

int dsi_disconnect ( DSI * dsi)

Communication error with the client, enter disconnected state.

  1. close the socket
  2. set the DSI_DISCONNECTED flag, remove possible sleep flags
Returns
0 if successfully entered disconnected state
-1 if ppid is 1 which means afpd master died, or euid == 0 i.e. where still running as root (unauthenticated session)

◆ dsi_header_pack_reply()

void dsi_header_pack_reply ( const DSI * dsi,
char * buf )
static

Pack a DSI header in wire format

◆ dsi_peek()

int dsi_peek ( DSI * dsi)
static

Check if we can write to the DSI socket.

afpd is sleeping too much while trying to send something. May be there's no reader or the reader is also sleeping in write, look if there's some data for us to read, hopefully it will wake up the reader so we can write again.

Returns
0 when is possible to send again, -1 on error

◆ dsi_stream_read()

size_t dsi_stream_read ( DSI * dsi,
void * data,
const size_t length )

Read data from DSI buffer.

Essentially a loop around buf_read() to ensure "length" bytes are read from dsi->buffer and/or the socket.

Returns
length on success, some value smaller than length indicates an error

◆ dsi_stream_read_file()

ssize_t dsi_stream_read_file ( DSI * dsi,
const int fromfd,
off_t offset,
const size_t length,
const int err )

◆ dsi_stream_receive()

int dsi_stream_receive ( DSI * dsi)

Read DSI command and data.

Parameters
dsi(rw) DSI handle
Returns
DSI function on success, 0 on failure

◆ dsi_stream_send()

int dsi_stream_send ( DSI * dsi,
void * buf,
size_t length )

write data.

Returns
0 on failure.
Note
this assumes that dsi_len will never cause an overflow in the data buffer.

◆ dsi_stream_write()

ssize_t dsi_stream_write ( DSI * dsi,
void * data,
const size_t length,
int mode )

write raw DSI data

Checks against EINTR aren't necessary if all of the signals have SA_RESTART specified.

Returns
actual bytes written, -1 on error

◆ from_buf()

size_t from_buf ( DSI * dsi,
uint8_t * buf,
size_t count )
static

Return all bytes up to count from dsi->buffer if there are any buffered there

◆ unblock_sig()

void unblock_sig ( DSI * dsi)
static