Skip to content
Snippets Groups Projects
Commit d649ba72 authored by Eric Oulashin's avatar Eric Oulashin
Browse files

Merge remote-tracking branch 'origin/master' into...

Merge remote-tracking branch 'origin/master' into dd_msg_reader_indexed_newscan_no_snap_selection_bug_fix
parents d3a24a1a a1c5e191
No related branches found
No related tags found
1 merge request!480DDMsgReader: Bug fix - For indexed newscan without snap-to-new, ensure it remembers the user's previously selected sub-board (reported by Keyop)
Pipeline #7332 passed
......@@ -31,6 +31,16 @@ function archive_date(file)
return t;
}
function proper_lib_name(name)
{
for(var i in file_area.lib_list) {
var lib = file_area.lib_list[i];
if(lib.name.toLowerCase() == name.toLowerCase())
return lib.name;
}
return name;
}
var uploader;
var listfile;
var date_fmt;
......@@ -47,29 +57,36 @@ for(var i = 0; i < argc; i++) {
while(opt[0] == '-')
opt = opt.slice(1);
if(opt == '?' || opt.toLowerCase() == "help") {
writeln("usage: [-options] [dir-code] [listfile] [desc-off]");
writeln("usage: [dir-spec] [-options] [listfile] [desc-off]");
writeln();
writeln("dir-spec:");
writeln(" -all Add files in all directories of all libraries (implies -auto)");
writeln(" -lib=<name> * Add files in all directories of specified library (implies -auto)");
writeln(" -dir=<code>,... * Add files in multiple specified directories");
writeln(" dir-code Internal code of (one and only) directory to add files to");
writeln(" * indicates parameters that can be combined and/or specified multiple times");
writeln(" Note: If no directories are specified, one will be prompted for.");
writeln();
writeln("options:");
writeln(" -all add files in all libraries/directories (implies -auto)");
writeln(" -lib=<name> add files in all directories of specified library (implies -auto)");
writeln(" -auto add files only to directories that have Auto-ADDFILES enabled");
writeln(" -from=<name> specify uploader's user name (may require quotes)");
writeln(" -file=<name> specify files to add (wildcards supported, default: *)");
writeln(" -ex=<filename> add to excluded filename list");
writeln(" -auto Add files only to directories that have Auto-ADDFILES enabled (in SCFG)");
writeln(" -from=<name> Specify uploader's user name (may require quotes)");
writeln(" -file=<name> Specify files to add (wildcards supported, default: *)");
writeln(" -ex=<filename> Add to excluded filename list");
writeln(" (default: " + default_excludes.join(',') + ")");
writeln(" -diz always extract/use description in archive");
writeln(" -update update existing file entries (default is to skip them)");
writeln(" -readd re-add existing file entries (so they appear as newly-uploaded");
writeln(" -date[=fmt] include today's date in description");
writeln(" -fdate[=fmt] include file's date in description");
writeln(" -adate[=fmt] include newest archived file date in description");
writeln(" -diz Always extract/use description in archive (e.g. FILE_ID.DIZ)");
writeln(" -update Update existing file entries (default is to skip them)");
writeln(" -readd Re-add existing file entries (so they appear as newly-uploaded");
writeln(" -date[=fmt] Include today's date in description");
writeln(" -fdate[=fmt] Include file's date in description");
writeln(" -adate[=fmt] Include newest archived file date in description");
writeln(" (fmt = optional strftime date/time format string)");
writeln(" -delete delete list after import");
writeln(" -v increase verbosity of output");
writeln(" -debug enable debug output");
writeln("optional:");
writeln(" dir-code: File directory internal code");
writeln(" listfile: Name of listfile (e.g. FILES.BBS)");
writeln(" desc-off: Description character offset (number)");
writeln(" -delete Delete list after import");
writeln(" -v Increase verbosity of output");
writeln(" -debug Enable debug output");
writeln();
writeln("optional listfile parameters:");
writeln(" listfile Name of listfile to import (e.g. FILES.BBS)");
writeln(" desc-off Description character-offset in listfile (e.g. 40)");
exit(0);
}
if(opt.indexOf("ex=") == 0) {
......@@ -77,9 +94,12 @@ for(var i = 0; i < argc; i++) {
continue;
}
if(opt.indexOf("lib=") == 0) {
var libname = opt.slice(4);
var libname = proper_lib_name(opt.slice(4));
if(!file_area.lib[libname]) {
alert("Library not found: " + libname);
writeln("Valid library names:");
for(var i in file_area.lib)
writeln("\t" + file_area.lib[i].name);
exit(1);
}
for(var j = 0; j < file_area.lib[libname].dir_list.length; j++)
......@@ -87,6 +107,10 @@ for(var i = 0; i < argc; i++) {
options.auto = true;
continue;
}
if(opt.indexOf("dir=") == 0) {
dir_list.push.apply(dir_list, opt.slice(4).split(','));
continue;
}
if(opt.indexOf("file=") == 0) {
include = opt.slice(5);
continue;
......@@ -111,6 +135,7 @@ for(var i = 0; i < argc; i++) {
continue;
}
if(opt == "all") {
dir_list.length = 0;
for(var dir in file_area.dir)
dir_list.push(dir);
options.auto = true;
......@@ -154,7 +179,7 @@ var renamed = 0;
var missing = [];
for(var d = 0; d < dir_list.length; d++) {
var code = dir_list[d];
var code = dir_list[d].toLowerCase();
var dir = file_area.dir[code];
if(!dir) {
alert("Directory '" + code + "' does not exist in configuration");
......@@ -208,7 +233,6 @@ for(var d = 0; d < dir_list.length; d++) {
}
file_list = file_list.filter(function(obj) { return wildmatch(obj.name, include); });
for(var i = 0; i < file_list.length; i++) {
var file = file_list[i];
file.from = uploader;
......
......@@ -362,15 +362,27 @@ bool comSetBits(COM_HANDLE handle, size_t byteSize, size_t stopBits)
switch(byteSize) {
case 5:
t.c_cflag |= CS5;
#ifdef ISTRIP
t.c_iflag |= ISTRIP;
#endif
break;
case 6:
t.c_cflag |= CS6;
#ifdef ISTRIP
t.c_iflag |= ISTRIP;
#endif
break;
case 7:
t.c_cflag |= CS7;
#ifdef ISTRIP
t.c_iflag |= ISTRIP;
#endif
break;
default:
t.c_cflag |= CS8;
#ifdef ISTRIP
t.c_iflag &= ~(ISTRIP);
#endif
break;
}
if(stopBits == 2)
......
......@@ -271,14 +271,19 @@ void sbbs_t::logch(char ch, bool comma)
void sbbs_t::errormsg(int line, const char* function, const char *src, const char* action, const char *object
,int access, const char *extinfo)
{
char str[2048];
char repeat[128] = "";
char errno_str[128];
char errno_info[256] = "";
static const char* lastfunc;
static int lastline;
static time_t lasttime;
static uint repeat_count;
/* prevent recursion */
if(errormsg_inside)
return;
errormsg_inside=true;
now=time(NULL);
if(errno != 0 && strcmp(action, ERR_CHK) != 0)
safe_snprintf(errno_info, sizeof(errno_info), "%d (%s) "
......@@ -291,25 +296,36 @@ void sbbs_t::errormsg(int line, const char* function, const char *src, const cha
#endif
);
safe_snprintf(str,sizeof(str),"ERROR %s"
int level = LOG_ERR;
if(function == lastfunc && line == lastline) {
++repeat_count;
snprintf(repeat, sizeof repeat, "[x%u]", repeat_count + 1);
// De-duplicate by reducing severity of log messages
if((now - lasttime) < 12*60*60)
level = LOG_WARNING;
} else
repeat_count = 0;
lastfunc = function;
lastline = line;
lasttime = now;
lprintf(level, "!ERROR%s %s"
"in %s line %u (%s) %s \"%s\" access=%d %s%s"
,repeat
,errno_info
,src, line, function, action, object, access
,extinfo==NULL ? "":"info="
,extinfo==NULL ? "":extinfo);
lprintf(LOG_ERR, "!%s", str);
if(online == ON_REMOTE) {
int savatr=curatr;
attr(cfg.color[clr_err]);
bprintf("\7\r\n!ERROR %s %s\r\n", action, object); /* tell user about error */
bprintf("\7\r\n!ERROR%s %s %s\r\n", repeat, action, object); /* tell user about error */
bputs("\r\nThe sysop has been notified.\r\n");
pause();
attr(savatr);
CRLF;
}
safe_snprintf(str,sizeof(str),"ERROR %s %s", action, object);
if(cfg.node_num>0) {
if(repeat_count == 0 && cfg.node_num>0) {
if(getnodedat(cfg.node_num,&thisnode, true)) {
if(thisnode.errors<UCHAR_MAX)
thisnode.errors++;
......@@ -317,12 +333,14 @@ void sbbs_t::errormsg(int line, const char* function, const char *src, const cha
putnodedat(cfg.node_num,&thisnode);
}
}
now=time(NULL);
if(logfile_fp!=NULL) {
if(logcol!=1)
fputs(log_line_ending, logfile_fp);
fprintf(logfile_fp,"!! %s%s", str, log_line_ending);
fprintf(logfile_fp,"%s!! ERROR%s %s %s%s"
,logcol == 1 ? "" : log_line_ending
,repeat
,action
,object
,log_line_ending);
logcol=1;
fflush(logfile_fp);
}
......
......@@ -32,4 +32,7 @@ target_link_libraries(deuce-ssh_static INTERFACE stdthreads)
target_link_libraries(deuce-ssh_shared PRIVATE ${OPENSSL_CRYPTO_LIBRARIES})
target_link_libraries(deuce-ssh_shared PRIVATE stdthreads)
add_executable(client EXCLUDE_FROM_ALL client.c)
target_link_libraries(client PRIVATE stdthreads deuce-ssh)
install(TARGETS deuce-ssh FILE_SET HEADERS)
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include "ssh.h"
int sock = -1;
size_t txbufsz;
size_t txbuflen;
uint8_t *txbuf;
atomic_bool *tx_terminate;
cnd_t tx_cnd;
mtx_t tx_mtx;
struct deuce_ssh_session sess;
int
tx_thread(void *arg)
{
while ((tx_terminate == NULL || *tx_terminate == false) && (sock != -1)) {
mtx_lock(&tx_mtx);
if (txbufsz == 0)
cnd_wait(&tx_cnd, &tx_mtx);
mtx_unlock(&tx_mtx);
struct pollfd fd = {
.fd = sock,
.events = POLLOUT | POLLRDHUP,
.revents = 0,
};
if (poll(&fd, 1, 5000) == 1) {
if (fd.revents & POLLOUT) {
mtx_lock(&tx_mtx);
ssize_t sent = send(sock, txbuf, txbuflen, MSG_NOSIGNAL);
if (sent > 0) {
memmove(txbuf, &txbuf[sent], txbuflen - sent);
txbuflen -= sent;
}
else if (sent == -1) {
switch(errno) {
case EAGAIN:
case ENOBUFS:
break;
default:
shutdown(sock, SHUT_WR);
*tx_terminate = true;
break;
}
}
mtx_unlock(&tx_mtx);
}
if (fd.revents & (POLLHUP | POLLRDHUP)) {
shutdown(sock, SHUT_WR);
*tx_terminate = true;
}
}
}
return 0;
}
static int
tx(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata)
{
mtx_lock(&tx_mtx);
if (txbuflen + bufsz > txbufsz) {
uint8_t *nb = realloc(txbuf, txbuflen + bufsz);
if (nb == NULL) {
mtx_unlock(&tx_mtx);
return DEUCE_SSH_ERROR_ALLOC;
}
else {
tx_terminate = terminate;
txbuf = nb;
memcpy(&txbuf[txbuflen], buf, bufsz);
txbufsz = txbuflen + bufsz;
if (txbuflen == 0)
cnd_signal(&tx_cnd);
txbuflen += bufsz;
}
}
mtx_unlock(&tx_mtx);
return 0;
}
static int
rx(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata)
{
size_t rxlen = 0;
while ((*terminate == false) && (sock != -1) && rxlen < bufsz) {
struct pollfd fd = {
.fd = sock,
.events = POLLIN | POLLRDHUP,
.revents = 0,
};
if (poll(&fd, 1, 5000) == 1) {
if (fd.revents & POLLIN) {
ssize_t received = recv(sock, &buf[rxlen], bufsz - rxlen, MSG_DONTWAIT);
if (received > 0) {
rxlen += received;
}
else if (received == -1) {
switch(errno) {
case EAGAIN:
case EINTR:
break;
default:
shutdown(sock, SHUT_RD);
*terminate = true;
break;
}
}
}
if (fd.revents & (POLLHUP | POLLRDHUP)) {
shutdown(sock, SHUT_RD);
*terminate = true;
}
}
}
return 0;
}
static int
rxline(uint8_t *buf, size_t bufsz, size_t *bytes_received, atomic_bool *terminate, void *cbdata)
{
size_t pos = 0;
bool lastcr = false;
for (;;) {
int res = rx(&buf[pos], 1, terminate, cbdata);
if (res < 0)
return res;
if (buf[pos] == '\r')
lastcr = true;
if (buf[pos] == '\n' && lastcr) {
*bytes_received = pos + 1;
return 0;
}
if (pos + 1 < bufsz)
pos++;
}
}
static int
extra_line(uint8_t *buf, size_t bufsz, void *cbdata)
{
fprintf(stdout, "%.*s\n", (int)bufsz, buf);
return 0;
}
int main(int argc, char **argv)
{
struct sockaddr_in sa = {
.sin_len = sizeof(struct sockaddr_in),
.sin_family = AF_INET,
.sin_port = htons(22),
.sin_addr = htonl(0x7f000001),
};
mtx_init(&tx_mtx, mtx_plain);
cnd_init(&tx_cnd);
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1)
return 1;
if (connect(sock, (struct sockaddr *)&sa, sa.sin_len) == -1)
return 1;
if (deuce_ssh_transport_set_callbacks(tx, rx, rxline, extra_line) != 0)
return 1;
thrd_t thr;
thrd_create(&thr, tx_thread, NULL);
deuce_ssh_session_init(&sess);
int res;
thrd_join(thr, &res);
}
......@@ -5,7 +5,22 @@
#include "ssh.h"
#include "ssh-trans.h"
typedef struct deuce_ssh_transport_global_config {
atomic_bool used;
const char *software_version;
const char *version_comment;
size_t kex_entries;
char **kex_name;
deuce_ssh_kex_handler_t *kex_handler;
deuce_ssh_kex_cleanup_t *kex_cleanup;
int (*tx)(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata);
int (*rx)(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata);
int (*rx_line)(uint8_t *buf, size_t bufsz, size_t *bytes_received, atomic_bool *terminate, void *cbdata);
int (*extra_line_cb)(uint8_t *buf, size_t bufsz, void *cbdata);
} *deuce_ssh_transport_global_config_t;
static const char * const sw_ver = "DeuceSSH-0.0";
static struct deuce_ssh_transport_global_config gconf;
static inline bool
has_nulls(uint8_t *buf, size_t buflen)
......@@ -17,7 +32,7 @@ static inline bool
missing_crlf(uint8_t *buf, size_t buflen)
{
assert(buflen >= 2);
return (buf[buflen - 1] == '\n' && buf[buflen - 2] == '\r');
return (buf[buflen - 1] != '\n' || buf[buflen - 2] != '\r');
}
static inline bool
......@@ -33,7 +48,7 @@ is_20(uint8_t *buf, size_t buflen)
{
if (buflen < 8)
return false;
return (buf[4] == '2' && buf[5] != '.' && buf[6] != '0' && buf[7] != '-');
return (buf[4] == '2' && buf[5] == '.' && buf[6] == '0' && buf[7] == '-');
}
static inline void *
......@@ -53,7 +68,7 @@ version_ex(deuce_ssh_session_t sess)
uint8_t line[256];
while (!sess->terminate) {
res = sess->rx_line(line, sizeof(line) - 1, &received, &sess->terminate, sess->rx_line_cbdata);
res = gconf.rx_line(line, sizeof(line) - 1, &received, &sess->terminate, sess->rx_line_cbdata);
if (res < 0) {
sess->terminate = true;
return res;
......@@ -83,9 +98,9 @@ version_ex(deuce_ssh_session_t sess)
assert(res == thrd_success);
return 0;
}
if (sess->extra_line_cb) {
if (gconf.extra_line_cb) {
line[received] = 0;
res = sess->extra_line_cb(line, received, sess->extra_line_cbdata);
res = gconf.extra_line_cb(line, received, sess->extra_line_cbdata);
if (res < 0) {
sess->terminate = true;
return res;
......@@ -122,38 +137,44 @@ tx_handshake(void *arg)
{
deuce_ssh_session_t sess = arg;
int res;
uint8_t line[255];
size_t sz = 0;
/* Handshake */
res = sess->tx((uint8_t *)"SSH-2.0-", 8, &sess->terminate, sess->tx_cbdata);
if (res < 0) {
sess->terminate = true;
return res;
}
size_t sz = strlen(sess->software_version);
res = sess->tx((uint8_t *)sess->software_version, sz, &sess->terminate, sess->tx_cbdata);
if (res < 0) {
sess->terminate = true;
return res;
}
if (sess->version_comment != NULL) {
res = sess->tx((uint8_t *)" ", 1, &sess->terminate, sess->tx_cbdata);
if (res < 0) {
sess->terminate = true;
return res;
}
sz = strlen(sess->version_comment);
res = sess->tx((uint8_t *)sess->software_version, sz, &sess->terminate, sess->tx_cbdata);
memcpy(line, "SSH-2.0-", 8);
sz += 8;
size_t asz = strlen(gconf.software_version);
if (sz + asz + 2 > 255)
return DEUCE_SSH_ERROR_TOOLONG;
memcpy(&line[sz], gconf.software_version, asz);
sz += asz;
if (gconf.version_comment != NULL) {
memcpy(&line[sz], " ", 1);
sz += 1;
asz = strlen(gconf.version_comment);
if (sz + asz + 2 > 255)
return DEUCE_SSH_ERROR_TOOLONG;
memcpy(&line[sz], gconf.version_comment, asz);
sz += asz;
}
memcpy(&line[sz], "\r\n", 2);
sz += 2;
res = gconf.tx(line, sz, &sess->terminate, sess->tx_cbdata);
if (res < 0) {
sess->terminate = true;
return res;
}
}
return 0;
}
void
deuce_ssh_transport_cleanup(deuce_ssh_session_t sess)
{
if (sess->trans->kex_selected != SIZE_MAX) {
if (gconf.kex_cleanup[sess->trans->kex_selected] != NULL)
gconf.kex_cleanup[sess->trans->kex_selected](sess);
sess->trans->kex_selected = SIZE_MAX;
}
free(sess->remote_software_version);
sess->remote_software_version = NULL;
free(sess->remote_version_comment);
......@@ -163,9 +184,13 @@ deuce_ssh_transport_cleanup(deuce_ssh_session_t sess)
int
deuce_ssh_transport_init(deuce_ssh_session_t sess)
{
if (sess->software_version == NULL)
sess->software_version = sw_ver;
gconf.used = true;
if (gconf.software_version == NULL)
gconf.software_version = sw_ver;
sess->trans = calloc(1, sizeof(struct deuce_ssh_transport_state));
if (sess->trans == NULL)
return DEUCE_SSH_ERROR_ALLOC;
thrd_t thrd;
if (thrd_create(&thrd, rx_thread, sess) != thrd_success)
return DEUCE_SSH_ERROR_INIT;
......@@ -176,7 +201,55 @@ deuce_ssh_transport_init(deuce_ssh_session_t sess)
thrd_join(thrd, &tres);
return res;
}
sess->trans->kex_selected = SIZE_MAX;
sess->trans->kex_state = 0;
sess->trans->transport_thread = thrd;
return 0;
}
int
deuce_ssh_transport_register_kex(const char *name, deuce_ssh_kex_handler_t kex_handler, deuce_ssh_kex_cleanup_t kex_cleanup)
{
if (gconf.used)
return DEUCE_SSH_ERROR_TOOLATE;
if (gconf.kex_entries + 1 == SIZE_MAX)
return DEUCE_SSH_ERROR_TOOMANY;
char **newnames = realloc(gconf.kex_name, sizeof(gconf.kex_name[0]) * (gconf.kex_entries + 1));
if (newnames == NULL)
return DEUCE_SSH_ERROR_ALLOC;
gconf.kex_name = newnames;
gconf.kex_name[gconf.kex_entries] = strdup(name);
deuce_ssh_kex_handler_t *newhandlers = realloc(gconf.kex_handler, sizeof(gconf.kex_handler[0]) * (gconf.kex_entries + 1));
if (newhandlers == NULL) {
free(gconf.kex_name[gconf.kex_entries]);
return DEUCE_SSH_ERROR_ALLOC;
}
gconf.kex_handler = newhandlers;
gconf.kex_handler[gconf.kex_entries] = kex_handler;
deuce_ssh_kex_cleanup_t *newcleanup = realloc(gconf.kex_cleanup, sizeof(gconf.kex_cleanup[0]) * (gconf.kex_entries + 1));
if (newcleanup == NULL) {
free(gconf.kex_name[gconf.kex_entries]);
return DEUCE_SSH_ERROR_ALLOC;
}
gconf.kex_cleanup = newcleanup;
gconf.kex_cleanup[gconf.kex_entries] = kex_cleanup;
gconf.kex_entries++;
return 0;
}
int
deuce_ssh_transport_set_callbacks(deuce_ssh_transport_io_cb_t tx, deuce_ssh_transport_io_cb_t rx, deuce_ssh_transport_rxline_cb_t rx_line, deuce_ssh_transport_extra_line_cb_t extra_line_cb)
{
if (gconf.used)
return DEUCE_SSH_ERROR_TOOLATE;
gconf.tx = tx;
gconf.rx = rx;
gconf.rx_line = rx_line;
gconf.extra_line_cb = extra_line_cb;
sess->transport_thread = thrd;
return 0;
}
// RFC-4253
#include "ssh.h"
#include "ssh-arch.h"
#ifndef DEUCE_SSH_TRANS_H
......@@ -33,19 +34,41 @@
#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
struct deuce_ssh_transport_packet {
typedef struct deuce_ssh_transport_packet {
deuce_ssh_string_t payload;
deuce_ssh_string_t random_padding;
deuce_ssh_string_t mac;
deuce_ssh_uint32_t packet_length;
deuce_ssh_byte_t padding;
};
} *deuce_ssh_transport_packet_t;
struct deuce_ssh_transport_state {
typedef int (*deuce_ssh_kex_handler_t)(deuce_ssh_transport_packet_t pkt, deuce_ssh_session_t sess);
typedef void (*deuce_ssh_kex_cleanup_t)(deuce_ssh_session_t sess);
typedef struct deuce_ssh_transport_state {
uint32_t tx_seq;
uint32_t rx_seq;
bool client;
};
/* Transport options */
thrd_t transport_thread;
/* KEX options */
void *kex_cbdata;
uint32_t kex_state;
size_t kex_selected;
/* KEX outputs */
size_t shared_secret_sz;
uint8_t *shared_secret;
size_t exchange_hash_sz;
uint8_t *exchange_hash;
size_t enc_selected;
size_t mac_selected;
size_t comp_selected;
} *deuce_ssh_transport_state_t;
int deuce_ssh_transport_init(deuce_ssh_session_t sess);
void deuce_ssh_transport_cleanup(deuce_ssh_session_t sess);
......
......@@ -9,9 +9,8 @@ deuce_ssh_session_init(deuce_ssh_session_t sess)
return DEUCE_SSH_ERROR_INIT;
res = deuce_ssh_transport_init(sess);
if (res < 0) {
if (res < 0)
return res;
}
sess->initialized = true;
return 0;
......@@ -24,7 +23,7 @@ deuce_ssh_session_terminate(deuce_ssh_session_t sess)
if (atomic_compare_exchange_strong(&sess->initialized, &t, false)) {
sess->terminate = true;
int tres;
thrd_join(sess->transport_thread, &tres);
thrd_join(sess->trans->transport_thread, &tres);
sess->terminate = false;
return true;
}
......
......@@ -20,6 +20,14 @@ _Static_assert(0, "threads.h support required");
#define DEUCE_SSH_ERROR_ALLOC -3
#define DEUCE_SSH_ERROR_INIT -4
#define DEUCE_SSH_ERROR_TERMINATED -5
#define DEUCE_SSH_ERROR_TOOLATE -6
#define DEUCE_SSH_ERROR_TOOMANY -7
#define DEUCE_SSH_ERROR_TOOLONG -8
typedef struct deuce_ssh_transport_state *deuce_ssh_transport_state_t;
typedef int (*deuce_ssh_transport_io_cb_t)(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata);
typedef int (*deuce_ssh_transport_rxline_cb_t)(uint8_t *buf, size_t bufsz, size_t *bytes_received, atomic_bool *terminate, void *cbdata);
typedef int (*deuce_ssh_transport_extra_line_cb_t)(uint8_t *buf, size_t bufsz, void *cbdata);
typedef struct deuce_ssh_session {
/* Global */
......@@ -27,26 +35,22 @@ typedef struct deuce_ssh_session {
atomic_bool initialized;
atomic_bool terminate;
/* Transport options */
const char *software_version;
const char *version_comment;
/* Transport Remote information */
char *remote_software_version;
char *remote_version_comment;
void *tx_cbdata;
int (*tx)(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata);
void *rx_cbdata;
int (*rx)(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata);
void *rx_line_cbdata;
int (*rx_line)(uint8_t *buf, size_t bufsz, size_t *bytes_received, atomic_bool *terminate, void *cbdata);
void *extra_line_cbdata;
int (*extra_line_cb)(uint8_t *buf, size_t bufsz, void *cbdata);
thrd_t transport_thread;
/* Transport Remote information */
char *remote_software_version;
char *remote_version_comment;
deuce_ssh_transport_state_t trans;
} *deuce_ssh_session_t;
int deuce_ssh_session_init(deuce_ssh_session_t sess);
bool deuce_ssh_session_terminate(deuce_ssh_session_t sess);
void deuce_ssh_session_cleanup(deuce_ssh_session_t sess);
int deuce_ssh_transport_set_callbacks(deuce_ssh_transport_io_cb_t tx, deuce_ssh_transport_io_cb_t rx, deuce_ssh_transport_rxline_cb_t rx_line, deuce_ssh_transport_extra_line_cb_t extra_line_cb);
#endif
......@@ -70,24 +70,28 @@ off_t filelength(int fd)
return(st.st_size);
}
/*************************************/
/* Use OFD fcntl() locks when we can */
/*************************************/
#if defined __linux__
#define USE_FCNTL_LOCKS
// See https://patchwork.kernel.org/patch/9289177/
#if defined(F_OFD_SETLK) && _FILE_OFFSET_BITS != 64
#if defined F_OFD_SETLK && _FILE_OFFSET_BITS != 64
#undef F_OFD_SETLK
#endif
#if defined(__linux__) && !defined(F_OFD_SETLK)
#warning Linux OFD locks not enabled!
#endif
#if defined(F_OFD_SETLK)
#if defined F_OFD_SETLK
#undef F_SETLK
#define F_SETLK F_OFD_SETLK
#else
#warning Linux OFD locks not enabled!
#endif
#endif
/* Sets a lock on a portion of a file */
int lock(int fd, off_t pos, off_t len)
{
#if !defined(BSD)
#if defined USE_FCNTL_LOCKS
struct flock alock = {0};
// fcntl() will return EBADF if we try to set a write lock a file opened O_RDONLY
......@@ -117,7 +121,7 @@ int lock(int fd, off_t pos, off_t len)
int unlock(int fd, off_t pos, off_t len)
{
#if !defined(BSD)
#if defined USE_FCNTL_LOCKS
struct flock alock = {0};
alock.l_type = F_UNLCK; /* remove the lock */
......@@ -195,7 +199,7 @@ int sopen(const char *fn, int sh_access, int share, ...)
if (share == SH_DENYNO || share == SH_COMPAT) /* no lock needed */
return fd;
#if !defined(BSD)
#if defined USE_FCNTL_LOCKS
struct flock alock = {0}; // lock entire file from offset 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment