aboutsummaryrefslogtreecommitdiff
path: root/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'ssh')
-rw-r--r--ssh/client.c37
-rw-r--r--ssh/tomsg_clientlib.c41
-rw-r--r--ssh/tomsg_clientlib.h13
3 files changed, 84 insertions, 7 deletions
diff --git a/ssh/client.c b/ssh/client.c
index 52f26c6..a262d6f 100644
--- a/ssh/client.c
+++ b/ssh/client.c
@@ -199,7 +199,7 @@ static bool handle_line(
if (state->focus_room != NULL) {
char *message = NULL;
sv_copy(line, &message);
- enum tomsg_retval ret = tomsg_send(client, state->focus_room, message, NULL);
+ enum tomsg_retval ret = tomsg_send(client, state->focus_room, message, -1, NULL);
free(message);
if (ret != TOMSG_OK) return true;
return false;
@@ -253,7 +253,15 @@ static bool handle_line(
} else if (sv_equals(command, "s") || sv_equals(command, "send")) {
if (parse_args(line, args, num_args = 2, true)) {
autocomplete_roomname(state, &args[0]);
- ret = tomsg_send(client, args[0], args[1], NULL);
+ ret = tomsg_send(client, args[0], args[1], -1, NULL);
+ }
+
+ } else if (sv_equals(command, "r") || sv_equals(command, "reply")) {
+ int64_t replyid;
+ if (parse_args(line, args, num_args = 3, true) &&
+ parse_i64(args[1], &replyid)) {
+ autocomplete_roomname(state, &args[0]);
+ ret = tomsg_send(client, args[0], args[2], replyid, NULL);
}
} else if (sv_equals(command, "ping")) {
@@ -277,6 +285,14 @@ static bool handle_line(
ret = tomsg_history(client, args[0], count, msgid);
}
+ } else if (sv_equals(command, "get") ||
+ sv_equals(command, "get_message")) {
+ int64_t msgid;
+ if (parse_args(line, args, num_args = 1, false) &&
+ parse_i64(args[0], &msgid)) {
+ ret = tomsg_get_message(client, msgid);
+ }
+
} else if (sv_equals(command, "on") ||
sv_equals(command, "is_online")) {
if (parse_args(line, args, num_args = 1, false)) {
@@ -314,9 +330,11 @@ static bool handle_line(
" create_room\n"
" invite <room> <user>\n"
" s/send <room> <message...>\n"
+ " r/reply <room> <msgid> <message...>\n"
" ping\n"
" hist/history <room> <count>\n"
" histb/history_before <room> <count> <before_msgid>\n"
+ " get/get_message <msgid>\n"
" on/is_online <user>\n"
" act/user_active <y/n>\n"
" help\n"
@@ -352,6 +370,7 @@ static const char* event_type_descr(enum tomsg_event_type type) {
case TOMSG_EV_INVITE: return "invite";
case TOMSG_EV_SEND: return "send";
case TOMSG_EV_HISTORY: return "history";
+ case TOMSG_EV_GET_MESSAGE: return "get_message";
case TOMSG_EV_PING: return "ping";
case TOMSG_EV_IS_ONLINE: return "is_online";
case TOMSG_EV_USER_ACTIVE: return "user_active";
@@ -365,8 +384,12 @@ static const char* event_type_descr(enum tomsg_event_type type) {
}
static void print_history_message(const struct history_message msg) {
- printf("%" PRIi64 " \x1B[90m%" PRIi64 "\x1B[0m <%s> %s\n",
- msg.msgid, msg.timestamp, msg.username, msg.message);
+ printf("%" PRIi64 " \x1B[90m%" PRIi64 "\x1B[0m <%s> ",
+ msg.msgid, msg.timestamp, msg.username);
+ if (msg.replyid != -1) {
+ printf("\x1B[32m[%" PRIi64 "<-]\x1B[0m ", msg.replyid);
+ }
+ printf("%s\n", msg.message);
}
static void handle_event(struct state *state, const struct tomsg_event event) {
@@ -438,6 +461,12 @@ static void handle_event(struct state *state, const struct tomsg_event event) {
}
break;
+ case TOMSG_EV_GET_MESSAGE:
+ printf(" %" PRIi64 " is in room %s:\n ",
+ event.get_message.message.msgid, event.get_message.room_name);
+ print_history_message(event.get_message.message);
+ break;
+
case TOMSG_EV_PING:
printf(" Pong\n");
break;
diff --git a/ssh/tomsg_clientlib.c b/ssh/tomsg_clientlib.c
index c14d5c5..e6d3684 100644
--- a/ssh/tomsg_clientlib.c
+++ b/ssh/tomsg_clientlib.c
@@ -178,7 +178,7 @@ const char* tomsg_strerror(enum tomsg_retval code) {
static enum tomsg_retval version_negotiation(struct tomsg_client *client) {
if (!client->conn) return TOMSG_ERR_CLOSED;
- const enum sshnc_retval retssh = sshnc_send(client->conn, "ver version 1\n", 14);
+ const enum sshnc_retval retssh = sshnc_send(client->conn, "ver version 2\n", 14);
if (retssh == SSHNC_EOF) return TOMSG_ERR_CLOSED;
if (retssh != SSHNC_OK) return TOMSG_ERR_TRANSPORT;
@@ -635,6 +635,11 @@ void tomsg_event_nullify(struct tomsg_event event) {
free(event.history.messages);
break;
+ case TOMSG_EV_GET_MESSAGE:
+ free(event.get_message.room_name);
+ history_message_nullify(event.get_message.message);
+ break;
+
case TOMSG_EV_PUSH_MESSAGE:
free(event.push_message.room_name);
history_message_nullify(event.push_message.message);
@@ -691,6 +696,7 @@ static enum tomsg_retval handle_line(
PARSE_WORD(push_message.message.username);
PARSE_I64(push_message.message.timestamp);
PARSE_I64(push_message.message.msgid);
+ PARSE_I64(push_message.message.replyid);
PARSE_RESTSTRING(push_message.message.message);
return TOMSG_OK;
} else if (sv_equals(command, "online")) {
@@ -809,6 +815,11 @@ static enum tomsg_retval handle_line(
inflight.event.history.messages = calloc(count, sizeof(struct history_message));
if (!inflight.event.history.messages) CLEANUP_RETURN(TOMSG_ERR_MEMORY);
+ // If there are no history_message's coming, complete early
+ if (count == 0) {
+ SUCCESS_RETURN();
+ }
+
// Re-add the tag for the history_message events
enum tomsg_retval ret = add_inflight(client, tag, inflight.event);
if (ret != TOMSG_OK) return ret;
@@ -822,11 +833,12 @@ static enum tomsg_retval handle_line(
// (and everywhere): the messages buffer has been allocated with
// calloc(), so tomsg_event_nullify() will cleanup up precisely
// everything that we haven't filled in yet.
- struct history_message *msg = &inflight.event.history.messages[index];;
+ struct history_message *msg = &inflight.event.history.messages[index];
if (!sv_equals(sv_tokenise_word(&line), inflight.event.history.room_name)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
if (!sv_copy(sv_tokenise_word(&line), &msg->username)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
if (!sv_parse_i64(sv_tokenise_word(&line), &msg->timestamp)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
if (!sv_parse_i64(sv_tokenise_word(&line), &msg->msgid)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_parse_i64(sv_tokenise_word(&line), &msg->replyid)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
if (!sv_copy(line, &msg->message)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
// If there are more history_message events coming, re-add the tag for them
@@ -841,6 +853,16 @@ static enum tomsg_retval handle_line(
CLEANUP_RETURN(TOMSG_ERR_PARSE);
}
+ case TOMSG_EV_GET_MESSAGE:
+ if (!sv_equals(command, "message")) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_copy(sv_tokenise_word(&line), &inflight.event.get_message.room_name)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_copy(sv_tokenise_word(&line), &inflight.event.get_message.message.username)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_parse_i64(sv_tokenise_word(&line), &inflight.event.get_message.message.timestamp)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_parse_i64(sv_tokenise_word(&line), &inflight.event.get_message.message.msgid)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_parse_i64(sv_tokenise_word(&line), &inflight.event.get_message.message.replyid)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ if (!sv_copy(line, &inflight.event.get_message.message.message)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
+ SUCCESS_RETURN();
+
case TOMSG_EV_PING:
if (!sv_equals(command, "pong")) CLEANUP_RETURN(TOMSG_ERR_PARSE);
if (!sv_is_empty(line)) CLEANUP_RETURN(TOMSG_ERR_PARSE);
@@ -1018,13 +1040,15 @@ enum tomsg_retval tomsg_invite(
enum tomsg_retval tomsg_send(
struct tomsg_client *client, const char *room_name, const char *message,
+ int64_t replyid,
int64_t *tagp //output
) {
if (!client->conn) return TOMSG_ERR_CLOSED;
if (hasspacelf(room_name)) return TOMSG_ERR_SPACE;
if (haslf(message)) return TOMSG_ERR_SPACE;
const int64_t tag = client->next_tag++;
- SEND_FMT(client, tag, "send %s %s", room_name, message);
+ if (replyid < 0) replyid = -1;
+ SEND_FMT(client, tag, "send %s %" PRIi64 " %s", room_name, replyid, message);
const struct tomsg_event event = (struct tomsg_event){
.type = TOMSG_EV_SEND,
.send.tag = tag,
@@ -1055,6 +1079,17 @@ enum tomsg_retval tomsg_history(
return add_inflight(client, tag, event);
}
+enum tomsg_retval tomsg_get_message(struct tomsg_client *client, int64_t msgid) {
+ if (!client->conn) return TOMSG_ERR_CLOSED;
+ if (msgid < -1) msgid = -1;
+ const int64_t tag = client->next_tag++;
+ const struct tomsg_event event = (struct tomsg_event){
+ .type = TOMSG_EV_GET_MESSAGE,
+ };
+ SEND_FMT(client, tag, "get_message %" PRIi64, msgid);
+ return add_inflight(client, tag, event);
+}
+
enum tomsg_retval tomsg_ping(struct tomsg_client *client) {
if (!client->conn) return TOMSG_ERR_CLOSED;
const int64_t tag = client->next_tag++;
diff --git a/ssh/tomsg_clientlib.h b/ssh/tomsg_clientlib.h
index ab1bde5..8a4aae4 100644
--- a/ssh/tomsg_clientlib.h
+++ b/ssh/tomsg_clientlib.h
@@ -126,6 +126,7 @@ enum tomsg_event_type {
TOMSG_EV_INVITE, // join
TOMSG_EV_SEND, // send
TOMSG_EV_HISTORY, // history
+ TOMSG_EV_GET_MESSAGE, // get_message
TOMSG_EV_PING, // -
TOMSG_EV_IS_ONLINE, // is_online
TOMSG_EV_USER_ACTIVE, // user_active
@@ -139,6 +140,7 @@ struct history_message {
char *username;
int64_t timestamp;
int64_t msgid;
+ int64_t replyid; // -1 if normal message, the replied-to message id otherwise
char *message;
};
@@ -180,6 +182,10 @@ struct tomsg_event {
struct history_message *messages;
} history;
struct {
+ char *room_name;
+ struct history_message message;
+ } get_message;
+ struct {
char *username;
int64_t online_count;
} is_online;
@@ -245,8 +251,12 @@ enum tomsg_retval tomsg_invite(
// If 'tag' is not NULL, will write the message request tag to the referenced
// location. This tag will also be given in the TOMSG_EV_SEND response, so that
// the response can be linked to the original message.
+// If 'replyid' is -1, will send a normal message. If not, it must be the id of
+// an earlier message in the same room, and this will send a reply to the
+// indicated message.
enum tomsg_retval tomsg_send(
struct tomsg_client *client, const char *room_name, const char *message,
+ int64_t replyid,
int64_t *tag // output
);
@@ -257,6 +267,9 @@ enum tomsg_retval tomsg_history(
struct tomsg_client *client, const char *room_name,
int64_t count, int64_t before_msgid);
+// Send a get_message command to the server.
+enum tomsg_retval tomsg_get_message(struct tomsg_client *client, int64_t msgid);
+
// Send a ping command to the server.
enum tomsg_retval tomsg_ping(struct tomsg_client *client);