redmine

Continued work on libclsync

# dynamical headers:
/revision.h
# objects:
# complied:
*.o
# linked:
*.lo
*.la
/clsync
/clsync-debug
/.libs
#debian:
/debian/clsync/
/debian/*clsync*.log
/debian/files
/debian/*.ex
/debian/*.debhelper
# other:
test.c
... ... @@ -20,25 +28,25 @@ log*
from/
to/
.clsync-list.*
/debian/clsync/
/debian/clsync.debhelper.log
/debian/clsync.substvars
/debian/files
/debian/*.ex
/debian/*.debhelper
/examples/rules
/examples/testdir/
/examples/*.so
/doc/
*.swp
tmp
# autotools build debris
/compile
/libtool
/ltmain.sh
/.deps/
/aclocal.m4
/autom4te.cache/
/config.h*
/config.log
/config.status
/config.guess
/config.sub
/configure
/depcomp
/install-sh
... ...
... ... @@ -33,17 +33,19 @@ int control_procclsyncconn(socket_procconnproc_arg_t *arg, sockcmd_t *sockcmd_p)
options_t *options_p = (options_t *)arg->arg;
switch(sockcmd_p->cmd_id) {
case SOCKCMD_INFO: {
socket_send(clsyncconn_p, SOCKCMD_INFO, options_p->config_block, options_p->label, options_p->flags, options_p->flags_set);
case SOCKCMD_REQUEST_INFO: {
socket_send(clsyncconn_p, SOCKCMD_REPLY_INFO, options_p->config_block, options_p->label, options_p->flags, options_p->flags_set);
break;
}
case SOCKCMD_DIE: {
case SOCKCMD_REQUEST_DIE: {
sync_term(SIGTERM);
break;
}
default:
return EINVAL;
}
return EINVAL;
return 0;
}
static inline void closecontrol(options_t *options_p) {
... ...
usr/include/clsync/*.h
... ...
usr/share/doc/clsync/*
... ...
usr/include/libclsync/*.h
... ...
usr/lib/libclsync*
... ...
/*
libclsyncmgr - clsync control socket API
Copyright (C) 2014 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common.h"
#include <sys/un.h> // for "struct sockaddr_un"
#include "socket.h"
#include "malloc.h"
#if 0
struct clsync {
int s;
};
typedef struct clsync clsync_t;
static inline int socketcheck(int sock) {
int error_code, ret;
socklen_t error_code_len = sizeof(error_code);
if((ret=getsockopt(sock, SOL_SOCKET, SO_ERROR, &error_code, &error_code_len))) {
return errno;
}
if(error_code) {
errno = error_code;
return error_code;
}
return 0;
}
int clsyncsock_send(clsync_t *clsync, sockcmd_id_t cmd_id, ...) {
va_list ap;
int ret;
va_start(ap, cmd_id);
char prebuf0[SOCKET_BUFSIZ], prebuf1[SOCKET_BUFSIZ], sendbuf[SOCKET_BUFSIZ];
ret = 0;
switch(clsync->prot) {
case 0:
switch(clsync->subprot) {
case SUBPROT0_TEXT: {
va_list ap_copy;
if(textmessage_args[cmd_id]) {
va_copy(ap_copy, ap);
vsprintf(prebuf0, textmessage_args[cmd_id], ap_copy);
} else
*prebuf0 = 0;
va_copy(ap_copy, ap);
vsprintf(prebuf1, textmessage_descr[cmd_id], ap);
size_t sendlen = sprintf(sendbuf, "%03u %s :%s\n", cmd_id, prebuf0, prebuf1);
send(clsync->sock, sendbuf, sendlen, 0);
break;
}
/* case SUBPROT0_BINARY:
break;*/
default:
printf_e("Error: socket_send(): Unknown subprotocol with id %u.\n", clsync->subprot);
ret = EINVAL;
goto l_socket_send_end;
}
break;
default:
printf_e("Error: socket_send(): Unknown protocol with id %u.\n", clsync->prot);
ret = EINVAL;
goto l_socket_send_end;
}
l_socket_send_end:
va_end(ap);
return ret;
}
static inline int socket_overflow_fix(char *buf, char **data_start_p, char **data_end_p) {
printf_ddd("Debug3: socket_overflow_fix(): buf==%p; data_start==%p; data_end==%p\n", buf, *data_start_p, *data_end_p);
if(buf == *data_start_p)
return 0;
size_t ptr_diff = *data_start_p - buf;
if(*data_start_p != *data_end_p) {
*data_start_p = buf;
*data_end_p = buf;
return ptr_diff;
}
size_t data_length = *data_end_p - *data_start_p;
memmove(buf, *data_start_p, data_length);
*data_start_p = buf;
*data_end_p = &buf[data_length];
return ptr_diff;
}
static char *recv_stps[SOCKET_MAX_LIBCLSYNC];
static char *recv_ptrs[SOCKET_MAX_LIBCLSYNC];
int clsyncsock_recv(clsync_t *clsync, sockcmd_t *sockcmd) {
static char bufs[SOCKET_MAX_LIBCLSYNC][SOCKET_BUFSIZ];
char *buf, *ptr, *start, *end;
int clsync_sock;
size_t filled_length, rest_length, recv_length, filled_length_new;
clsync_sock = clsync->sock;
buf = bufs[clsync_sock];
start = recv_stps[clsync_sock];
start = (start==NULL ? buf : start);
ptr = recv_ptrs[clsync_sock];
ptr = (ptr==NULL ? buf : ptr);
printf_ddd("Debug3: socket_recv(): buf==%p; start==%p; ptr==%p\n", buf, start, ptr);
while(1) {
filled_length = ptr-buf;
rest_length = SOCKET_BUFSIZ-filled_length-16;
if(rest_length <= 0) {
if(!socket_overflow_fix(buf, &start, &ptr)) {
printf_d("Debug: socket_recv(): Got too big message. Ignoring.\n");
ptr = buf;
}
continue;
}
recv_length = recv(clsync_sock, ptr, rest_length, 0);
filled_length_new = filled_length + recv_length;
if(recv_length <= 0)
return errno;
switch(clsync->prot) {
case 0: {
// Checking if binary
uint16_t cmd_id_binary = *(uint16_t *)buf;
clsync->subprot = (cmd_id_binary == SOCKCMD_NEGOTIATION) ? SUBPROT0_BINARY : SUBPROT0_TEXT;
// Processing
switch(clsync->subprot) {
case SUBPROT0_TEXT:
if((end=strchr(ptr, '\n'))!=NULL) {
if(sscanf(start, "%03u", (unsigned int *)&sockcmd->cmd_id) != 1)
return EBADRQC;
// TODO Process message here
goto l_socket_recv_end;
}
break;
default:
return ENOPROTOOPT;
}
break;
}
default:
return ENOPROTOOPT;
}
}
l_socket_recv_end:
// ----------------------------------
// buf ptr end filled
// cut: ---------------
// start ptr
// new new
start = &end[1];
ptr = &buf[filled_length_new];
// No data buffered. Reset "start" and "ptr".
if(start == ptr) {
start = buf;
ptr = buf;
}
// Remembering the values
recv_stps[clsync_sock] = start;
recv_ptrs[clsync_sock] = ptr;
printf_ddd("Debug3: socket_recv(): buf==%p; ptr==%p; end==%p, filled=%p, buf_end==%p\n", buf, ptr, end, &buf[filled_length_new], &buf[SOCKET_BUFSIZ]);
sockcmd->cmd_num++;
return 0;
}
clsync_t *clsyncsock_connect_unix(const char const *socket_path) {
clsync_t clsync = xmalloc
return
}
#endif
... ...
... ... @@ -19,8 +19,9 @@
#include <regex.h>
#define OPTION_LONGOPTONLY (1<<9)
#define OPTION_CONFIGONLY (1<<8)
#define OPTION_FLAGS (1<<10)
#define OPTION_LONGOPTONLY (1<<9)
#define OPTION_CONFIGONLY (1<<8)
enum flags_enum {
WATCHDIR = 'W',
SYNCHANDLER = 'S',
... ... @@ -160,8 +161,8 @@ struct options {
int children; // Used only for non-pthread mode
rule_t rules[MAXRULES];
dev_t st_dev;
int flags[1<<10];
int flags_set[1<<10];
int flags[OPTION_FLAGS];
int flags_set[OPTION_FLAGS];
char *config_path;
char *config_block;
char *label;
... ...
... ... @@ -42,28 +42,30 @@ char clsyncconn_busy[SOCKET_MAX+1] = {0};
static char *recv_stps[SOCKET_MAX];
static char *recv_ptrs[SOCKET_MAX];
const char *const textmessage_args[1000] = {
[SOCKCMD_NEGOTIATION] = "%u",
[SOCKCMD_ACK] = "%03u %lu",
[SOCKCMD_EINVAL] = "%03u %lu",
[SOCKCMD_VERSION] = "%u %u %s",
[SOCKCMD_INFO] = "%s\003/ %s\003/ %x %x",
[SOCKCMD_UNKNOWNCMD] = "%03u %lu",
[SOCKCMD_INVALIDCMDID] = "%lu",
const char *const textmessage_args[SOCKCMD_MAXID] = {
[SOCKCMD_REQUEST_NEGOTIATION] = "%u",
[SOCKCMD_REPLY_NEGOTIATION] = "%u",
[SOCKCMD_REPLY_ACK] = "%03u %lu",
[SOCKCMD_REPLY_EINVAL] = "%03u %lu",
[SOCKCMD_REPLY_VERSION] = "%u %u %s",
[SOCKCMD_REPLY_INFO] = "%s\003/ %s\003/ %x %x",
[SOCKCMD_REPLY_UNKNOWNCMD] = "%03u %lu",
[SOCKCMD_REPLY_INVALIDCMDID] = "%lu",
};
const char *const textmessage_descr[1000] = {
[SOCKCMD_NEGOTIATION] = "Protocol version is %u.",
[SOCKCMD_ACK] = "Acknowledged command: id == %03u; num == %lu.",
[SOCKCMD_EINVAL] = "Rejected command: id == %03u; num == %lu. Invalid arguments: %s.",
[SOCKCMD_LOGIN] = "Enter your login and password, please.",
[SOCKCMD_UNEXPECTEDEND] = "Need to go, sorry. :)",
[SOCKCMD_DIE] = "Okay :(",
[SOCKCMD_BYE] = "Bye.",
[SOCKCMD_VERSION] = "clsync v%u.%u%s",
[SOCKCMD_INFO] = "config_block == \"%s\"; label == \"%s\"; flags == %x; flags_set == %x.",
[SOCKCMD_UNKNOWNCMD] = "Unknown command.",
[SOCKCMD_INVALIDCMDID] = "Invalid command id. Required: 0 <= cmd_id < 1000.",
const char *const textmessage_descr[SOCKCMD_MAXID] = {
[SOCKCMD_REQUEST_NEGOTIATION] = "Protocol version is %u.",
[SOCKCMD_REPLY_NEGOTIATION] = "Protocol version is %u.",
[SOCKCMD_REPLY_ACK] = "Acknowledged command: id == %03u; num == %lu.",
[SOCKCMD_REPLY_EINVAL] = "Rejected command: id == %03u; num == %lu. Invalid arguments: %s.",
[SOCKCMD_REPLY_LOGIN] = "Enter your login and password, please.",
[SOCKCMD_REPLY_UNEXPECTEDEND] = "Need to go, sorry. :)",
[SOCKCMD_REPLY_DIE] = "Okay :(",
[SOCKCMD_REPLY_BYE] = "Bye.",
[SOCKCMD_REPLY_VERSION] = "clsync v%u.%u%s",
[SOCKCMD_REPLY_INFO] = "config_block == \"%s\"; label == \"%s\"; flags == %x; flags_set == %x.",
[SOCKCMD_REPLY_UNKNOWNCMD] = "Unknown command.",
[SOCKCMD_REPLY_INVALIDCMDID] = "Invalid command id. Required: 0 <= cmd_id < 1000.",
};
int socket_check_bysock(int sock) {
... ... @@ -225,6 +227,69 @@ static inline int socket_overflow_fix(char *buf, char **data_start_p, char **dat
return ptr_diff;
}
#define PARSE_TEXT_DATA_SSCANF(dat_t, ...) {\
sockcmd_p->data = xmalloc(sizeof(dat_t));\
dat_t *d = (dat_t *)sockcmd_p->data;\
if(sscanf(args, textmessage_args[sockcmd_p->cmd_id], __VA_ARGS__) < min_args)\
return EINVAL;\
}
static inline int parse_text_data(sockcmd_t *sockcmd_p, char *args, size_t args_len) {
if(!args_len)
return 0;
int min_args = 0;
const char *ptr = (const char *)textmessage_args[sockcmd_p->cmd_id];
if(ptr != NULL) {
while(*ptr) {
if(*ptr == '%') {
if(ptr[1] == '%')
ptr++;
else
min_args++;
}
ptr++;
}
}
switch(sockcmd_p->cmd_id) {
case SOCKCMD_REQUEST_NEGOTIATION:
case SOCKCMD_REPLY_NEGOTIATION:
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_negotiation_t, &d->prot, &d->subprot);
break;
case SOCKCMD_REPLY_ACK:
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_ack_t, &d->cmd_id, &d->cmd_num);
break;
case SOCKCMD_REPLY_EINVAL:
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_einval_t, &d->cmd_id, &d->cmd_num);
break;
case SOCKCMD_REPLY_VERSION:
if(args_len > sizeof(1<<8))
args[args_len=1<<8] = 0;
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_version_t, &d->major, &d->minor, &d->revision);
break;
case SOCKCMD_REPLY_INFO:
if(args_len > sizeof(1<<8))
args[args_len=1<<8] = 0;
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_info_t, &d->config_block, &d->label, &d->flags, &d->flags_set);
break;
case SOCKCMD_REPLY_UNKNOWNCMD:
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_unknowncmd_t, &d->cmd_id, &d->cmd_num);
break;
case SOCKCMD_REPLY_INVALIDCMDID:
PARSE_TEXT_DATA_SSCANF(sockcmd_dat_invalidcmd_t, &d->cmd_num);
break;
default:
sockcmd_p->data = xmalloc(args_len+1);
memcpy(sockcmd_p->data, args, args_len);
sockcmd_p->data[args_len] = 0;
break;
}
return 0;
}
int socket_recv(clsyncconn_t *clsyncconn, sockcmd_t *sockcmd_p) {
static char bufs[SOCKET_MAX][SOCKET_BUFSIZ];
char *buf, *ptr, *start, *end;
... ... @@ -265,7 +330,11 @@ int socket_recv(clsyncconn_t *clsyncconn, sockcmd_t *sockcmd_p) {
case 0: {
// Checking if binary
uint16_t cmd_id_binary = *(uint16_t *)buf;
clsyncconn->subprot = (cmd_id_binary == SOCKCMD_NEGOTIATION) ? SUBPROT0_BINARY : SUBPROT0_TEXT;
clsyncconn->subprot = (
cmd_id_binary == SOCKCMD_REQUEST_NEGOTIATION ||
cmd_id_binary == SOCKCMD_REPLY_NEGOTIATION
)
? SUBPROT0_BINARY : SUBPROT0_TEXT;
// Processing
switch(clsyncconn->subprot) {
... ... @@ -274,6 +343,10 @@ int socket_recv(clsyncconn_t *clsyncconn, sockcmd_t *sockcmd_p) {
if(sscanf(start, "%03u", (unsigned int *)&sockcmd_p->cmd_id) != 1)
return EBADRQC;
char *str_args = &start[3+1];
parse_text_data(sockcmd_p, str_args, end-str_args);
// TODO Process message here
goto l_socket_recv_end;
... ... @@ -323,13 +396,12 @@ l_socket_recv_end:
static inline int socket_sendinvalid(clsyncconn_t *clsyncconn_p, sockcmd_t *sockcmd_p) {
if(sockcmd_p->cmd_id >= 1000)
return socket_send(clsyncconn_p, SOCKCMD_INVALIDCMDID, sockcmd_p->cmd_num);
return socket_send(clsyncconn_p, SOCKCMD_REPLY_INVALIDCMDID, sockcmd_p->cmd_num);
else
return socket_send(clsyncconn_p, SOCKCMD_UNKNOWNCMD, sockcmd_p->cmd_id, sockcmd_p->cmd_num);
return socket_send(clsyncconn_p, SOCKCMD_REPLY_UNKNOWNCMD, sockcmd_p->cmd_id, sockcmd_p->cmd_num);
}
int socket_procclsyncconn(socket_procconnproc_arg_t *arg) {
#define SL(a) a,sizeof(a)-1
// clsyncconn_t clsyncconn = {0};
char _sockcmd_buf[SOCKET_BUFSIZ]={0};
... ... @@ -350,7 +422,7 @@ int socket_procclsyncconn(socket_procconnproc_arg_t *arg) {
printf_ddd("Debug3: socket_procclsyncconn(): Started new thread for new connection.\n");
arg->state = (arg->authtype == SOCKAUTH_NULL) ? CLSTATE_MAIN : CLSTATE_AUTH;
socket_send(clsyncconn_p, SOCKCMD_NEGOTIATION);
socket_send(clsyncconn_p, SOCKCMD_REQUEST_NEGOTIATION, clsyncconn_p->prot, clsyncconn_p->subprot);
while(*arg->running && (arg->state==CLSTATE_AUTH || arg->state==CLSTATE_MAIN)) {
printf_ddd("Debug3: socket_procclsyncconn(): Iteration.\n");
... ... @@ -368,41 +440,50 @@ int socket_procclsyncconn(socket_procconnproc_arg_t *arg) {
// Processing the message
switch(sockcmd_p->cmd_id) {
case SOCKCMD_NEGOTIATION: {
struct sockcmd_negotiation *data = (struct sockcmd_negotiation *)sockcmd_p->data;
case SOCKCMD_REPLY_NEGOTIATION:
case SOCKCMD_REQUEST_NEGOTIATION: {
sockcmd_dat_negotiation_t *data = (sockcmd_dat_negotiation_t *)sockcmd_p->data;
switch(data->prot) {
case 0:
switch(data->subprot) {
case SUBPROT0_TEXT:
case SUBPROT0_BINARY:
clsyncconn_p->subprot = data->subprot;
socket_send(clsyncconn_p, SOCKCMD_ACK, sockcmd_p->cmd_id, sockcmd_p->cmd_num);
if(sockcmd_p->cmd_id == SOCKCMD_REQUEST_NEGOTIATION)
socket_send(clsyncconn_p, SOCKCMD_REPLY_NEGOTIATION, data->prot, data->subprot);
else {
socket_send(clsyncconn_p, SOCKCMD_REPLY_ACK, sockcmd_p->cmd_id, sockcmd_p->cmd_num);
printf_d("Debug2: socket_procclsyncconn(): Negotiated proto: %u %u\n", data->prot, data->subprot);
}
break;
default:
socket_send(clsyncconn_p, SOCKCMD_EINVAL, sockcmd_p->cmd_id, sockcmd_p->cmd_num, "Incorrect subprotocol id");
socket_send(clsyncconn_p, SOCKCMD_REPLY_EINVAL, sockcmd_p->cmd_id, sockcmd_p->cmd_num, "Incorrect subprotocol id");
}
break;
default:
socket_send(clsyncconn_p, SOCKCMD_EINVAL, sockcmd_p->cmd_id, sockcmd_p->cmd_num, "Incorrect protocol id");
socket_send(clsyncconn_p, SOCKCMD_REPLY_EINVAL, sockcmd_p->cmd_id, sockcmd_p->cmd_num, "Incorrect protocol id");
}
break;
}
case SOCKCMD_VERSION: {
socket_send(clsyncconn_p, SOCKCMD_VERSION, VERSION_MAJ, VERSION_MIN, REVISION);
case SOCKCMD_REQUEST_VERSION: {
socket_send(clsyncconn_p, SOCKCMD_REPLY_VERSION, VERSION_MAJ, VERSION_MIN, REVISION);
break;
}
case SOCKCMD_QUIT: {
socket_send(clsyncconn_p, SOCKCMD_BYE);
case SOCKCMD_REQUEST_QUIT: {
socket_send(clsyncconn_p, SOCKCMD_REPLY_BYE);
arg->state = CLSTATE_DYING;
break;
}
default:
l_socket_procclsyncconn_sw_default:
if(!procfunct(arg, sockcmd_p))
if(procfunct(arg, sockcmd_p))
socket_sendinvalid(clsyncconn_p, sockcmd_p);
break;
}
if(sockcmd_p->data != NULL)
free(sockcmd_p->data);
// Check if the socket is still alive
if(socket_check(clsyncconn_p)) {
printf_d("Debug: clsyncconn socket error: %s\n", strerror(errno));
... ... @@ -413,7 +494,7 @@ l_socket_procclsyncconn_sw_default:
switch(arg->state) {
case CLSTATE_AUTH:
if(!(auth_flags&AUTHFLAG_ENTERED_LOGIN))
socket_send(clsyncconn_p, SOCKCMD_LOGIN);
socket_send(clsyncconn_p, SOCKCMD_REQUEST_LOGIN);
break;
default:
break;
... ... @@ -427,7 +508,6 @@ l_socket_procclsyncconn_sw_default:
arg->state = CLSTATE_DIED;
return 0;
#undef SL
}
int socket_init() {
... ...
... ... @@ -37,11 +37,6 @@ enum subprot0 {
};
typedef enum subprot0 subprot0_t;
struct sockcmd_negotiation {
uint16_t prot;
uint16_t subprot;
};
enum clsyncconn_state {
CLSTATE_NONE = 0,
CLSTATE_AUTH,
... ... @@ -52,26 +47,69 @@ enum clsyncconn_state {
typedef enum clsyncconn_state clsyncconn_state_t;
enum sockcmd_id {
SOCKCMD_NEGOTIATION = 00,
SOCKCMD_ACK = 50,
SOCKCMD_UNKNOWNCMD = 60,
SOCKCMD_INVALIDCMDID = 61,
SOCKCMD_EINVAL = 62,
SOCKCMD_LOGIN = 100,
SOCKCMD_VERSION = 201,
SOCKCMD_INFO = 202,
SOCKCMD_DIE = 210,
SOCKCMD_UNEXPECTEDEND = 300,
SOCKCMD_QUIT = 301,
SOCKCMD_BYE = 350,
SOCKCMD_REQUEST_NEGOTIATION = 000,
SOCKCMD_REPLY_NEGOTIATION = 001,
SOCKCMD_REPLY_ACK = 150,
SOCKCMD_REPLY_UNKNOWNCMD = 160,
SOCKCMD_REPLY_INVALIDCMDID = 161,
SOCKCMD_REPLY_EINVAL = 162,
SOCKCMD_REQUEST_LOGIN = 200,
SOCKCMD_REQUEST_VERSION = 201,
SOCKCMD_REQUEST_INFO = 202,
SOCKCMD_REQUEST_DIE = 210,
SOCKCMD_REQUEST_QUIT = 250,
SOCKCMD_REPLY_LOGIN = 300,
SOCKCMD_REPLY_VERSION = 301,
SOCKCMD_REPLY_INFO = 302,
SOCKCMD_REPLY_DIE = 310,
SOCKCMD_REPLY_UNEXPECTEDEND = 300,
SOCKCMD_REPLY_QUIT = 301,
SOCKCMD_REPLY_BYE = 350,
SOCKCMD_MAXID
};
typedef enum sockcmd_id sockcmd_id_t;
struct sockcmd_dat_negotiation {
uint16_t prot;
uint16_t subprot;
};
typedef struct sockcmd_dat_negotiation sockcmd_dat_negotiation_t;
struct sockcmd_dat_ack {
uint64_t cmd_num;
uint16_t cmd_id;
};
typedef struct sockcmd_dat_ack sockcmd_dat_ack_t;
#define sockcmd_dat_einval sockcmd_dat_ack
#define sockcmd_dat_einval_t sockcmd_dat_ack_t
#define sockcmd_dat_unknowncmd sockcmd_dat_ack
#define sockcmd_dat_unknowncmd_t sockcmd_dat_ack_t
struct sockcmd_dat_invalidcmd {
uint64_t cmd_num;
};
typedef struct sockcmd_dat_invalidcmd sockcmd_dat_invalidcmd_t;
struct sockcmd_dat_version {
int major;
int minor;
char revision[1<<8];
};
typedef struct sockcmd_dat_version sockcmd_dat_version_t;
struct sockcmd_dat_info {
char config_block[1<<8];
char label[1<<8];
char flags[OPTION_FLAGS];
char flags_set[OPTION_FLAGS];
};
typedef struct sockcmd_dat_info sockcmd_dat_info_t;
struct sockcmd {
uint64_t cmd_num;
uint16_t cmd_id;
size_t data_len;
char data[1];
uint64_t cmd_num;
uint16_t cmd_id;
size_t data_len;
char *data;
};
typedef struct sockcmd sockcmd_t;
... ...