AmendHub

Download:

jcs

/

subtext

/

amendments

/

191

session: A few fixes and improvements

Make session_menu a bit more helpful and hide options with a null key
set, don't repeat "Invalid option" more than once
 
Add session_get_char for file transfers

jcs made amendment 191 about 1 year ago
--- session.c Wed Jun 29 11:22:41 2022 +++ session.c Tue Jul 12 11:32:47 2022 @@ -120,7 +120,7 @@ session_run(struct uthread *uthread, void *arg) if (s->node_funcs->setup) s->node_funcs->setup(s); - + if (!session_output_view(s, DB_TEXT_ISSUE_ID)) { session_printf(s, "\r\n" "Welcome to %s (%s)\r\n" @@ -407,7 +407,7 @@ session_printf(struct session *session, const char *fo size_t len, n, en; bool stop = false; - /* avoid a full session_expand_template just for {{B}} and {{/B}} */ + /* avoid a full session_expand_template for {{B}}, {{/B}}, and {{#}} */ session_printf_ebuf[0] = '\0'; for (n = 0, en = 0; format[n] != '\0'; n++) { if (!stop) { @@ -511,6 +511,37 @@ session_idled_out(struct session *session) return false; } +short +session_get_char(struct session *session, unsigned char *b) +{ + if (session->ibuflen == 0) { + if (session_idled_out(session)) + return 0; + + uthread_yield(); + session->node_funcs->input(session); + + if (session->ending || session->abort_input) + return 0; + if (session->ibuflen == 0) + return 0; + } + + session->last_input_at = Time; + + *b = session->ibuf[session->ibufoff]; + + if (session->ibuflen == 1) { + session->ibuflen = 0; + session->ibufoff = 0; + } else { + session->ibuflen--; + session->ibufoff++; + } + + return 1; +} + bool session_wait_for_chars(struct session *session, unsigned short timeout_ms, unsigned short num_chars) @@ -624,12 +655,12 @@ idled_out: void session_clear_input(struct session *session) { - session->ibuflen = 0; + uthread_yield(); + session->node_funcs->input(session); + uthread_yield(); + session->node_funcs->input(session); - /* - * TODO: provide a node-specific way to do this since nodes might - * have their own input buffers - */ + session->ibuflen = 0; } /* @@ -655,7 +686,7 @@ session_field_input(struct session *session, unsigned if (initial_input) { ipos = ilen = strlcpy(field, initial_input, size); /* TODO: handle initial value being longer than width */ - session_printf(session, field); + session_output(session, field, ilen); session_flush(session); } @@ -1179,11 +1210,18 @@ session_expand_var(struct session *session, char *ivar } void -session_pause_return(struct session *s, short enforce, char *msg) +session_pause_return(struct session *s, char enforce, char *msg) { unsigned char c; - session_printf(s, "{{/B}}Press {{B}}<Enter>{{/B}} "); + session_printf(s, "{{/B}}Press "); + if (enforce == 0 || enforce == '\r') + session_printf(s, "{{B}}<Enter>{{/B}} "); + else if (enforce == CONTROL_C) + session_printf(s, "{{B}}^C{{/B}} "); + else + session_printf(s, "{{B}}%c{{/B}} ", enforce); + if (msg) session_printf(s, msg); else @@ -1196,7 +1234,7 @@ session_pause_return(struct session *s, short enforce, return; if (c == 0) continue; - if (!enforce || c == '\r') + if (enforce == 0 || enforce == c) break; } session_output(s, "\r\n", 2); @@ -1329,12 +1367,12 @@ session_who(struct session *s) char session_menu(struct session *s, char *title, char *prompt, - struct session_menu_option *opts, size_t nopts, bool show_opts) + const struct session_menu_option *opts, size_t nopts, bool show_opts) { - struct session_menu_option *opt; size_t n; short j; unsigned short c; + bool last_invalid = false; if (show_opts) { session_printf(s, "{{B}}%s{{/B}}\r\n", title); @@ -1344,9 +1382,10 @@ session_menu(struct session *s, char *title, char *pro print_options: if (show_opts) { for (n = 0; n < nopts; n++) { - opt = &opts[n]; - session_printf(s, "{{B}}%c{{/B}}: %s\r\n", opt->key[0], - opt->title); + if (opts[n].key[0] == '\0') + continue; + session_printf(s, "{{B}}%c{{/B}}: %s\r\n", opts[n].key[0], + opts[n].title); } session_flush(s); } @@ -1356,31 +1395,41 @@ print_options: session_flush(s); get_menu_option: + uthread_yield(); c = session_input_char(s); if (s->ending) return 0; if (c == '\r' || c == 0 || c > 255) goto get_menu_option; - - session_printf(s, "%c\r\n", c); - session_flush(s); - + for (n = 0; n < nopts; n++) { - opt = &opts[n]; - for (j = 0; ; j++) { - if (opt->key[j] == '\0') + if (opts[n].key[j] == '\0') break; - if (opt->ret == '#') { - if (opt->key[j] == c && c != '#') + if (opts[n].ret == '#') { + if (opts[n].key[j] == c && c != '#') { + session_printf(s, "%c\r\n", c); + session_flush(s); return c - '0'; /* return actual number */ - } else if (opt->key[j] == c) { - return opt->ret; + } + } else if (opts[n].key[j] == c) { + session_printf(s, "%c\r\n", c); + session_flush(s); + return opts[n].ret; } } } - session_printf(s, "Invalid option\r\n"); + /* + * Avoid a constant back-and-forth of the user's session spewing + * bogus characters and us having to print 'invalid option' over + * and over. + */ + if (last_invalid) + goto get_menu_option; + + session_printf(s, "%c\r\nInvalid option (press ? for help)\r\n", c); session_flush(s); + last_invalid = true; } } --- session.h Fri Jun 24 11:26:42 2022 +++ session.h Tue Jul 12 11:27:29 2022 @@ -67,32 +67,35 @@ struct session_log { }; struct session { - char node[10]; - char via[10]; - unsigned char obuf[512]; /* telnet.obuf must be double this */ - unsigned char ibuf[64]; + char node[16]; + char via[16]; + unsigned char obuf[512]; + unsigned char ibuf[512]; short obuflen; short ibuflen; - enum session_input_state input_state; + short ibufoff; unsigned long established_at; - bool logged_in; - bool ending; - bool abort_input; - bool ban_node_source; + char autologin_username[DB_USERNAME_LENGTH + 1]; + char terminal_type[24]; + enum session_input_state input_state; unsigned short last_input; unsigned long last_input_at; unsigned short terminal_columns; unsigned short terminal_lines; - char terminal_type[20]; unsigned short tspeed; + bool logged_in; + bool ending; + bool abort_input; + bool ban_node_source; bool vt100; bool vt52; bool color; bool cp437; - bool chatting; + bool transferring_file; + bool is_telnet; unsigned char chatting_with_node[10]; + bool chatting; struct session_log log; - char autologin_username[DB_USERNAME_LENGTH + 1]; struct user *user; void *cookie; struct node_funcs *node_funcs; @@ -120,6 +123,7 @@ struct session * session_create(char *node, char *via, struct node_funcs *node_funcs); void session_close(struct session *session); void session_idle(struct session *session); +short session_get_char(struct session *session, unsigned char *b); bool session_wait_for_chars(struct session *session, unsigned short timeout_ms, unsigned short num_chars); unsigned short session_input_char(struct session *session); @@ -135,10 +139,10 @@ size_t session_expand_template(struct session *session char * session_field_input(struct session *session, unsigned short size, unsigned short width, char *initial_input, bool multiline, char mask); char * session_bar(struct session *s, char *left_str, char *right_str); -void session_pause_return(struct session *s, short enforce, char *msg); +void session_pause_return(struct session *s, char enforce, char *msg); void session_recents(struct session *s); void session_who(struct session *s); char session_menu(struct session *s, char *title, char *prompt, - struct session_menu_option *opts, size_t nopts, bool show_opts); + const struct session_menu_option *opts, size_t nopts, bool show_opts); #endif /* __SESSION_H__ */