AmendHub

Download

jcs

/

subtext

/

user_settings.c

 

(View History)

jcs   user_settings: Accept capital X in terminal cols/lines response Latest amendment: 578 on 2024-01-10

1 /*
2 * Copyright (c) 2022 joshua stein <jcs@jcs.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "subtext.h"
23 #include "ansi.h"
24 #include "session.h"
25 #include "user.h"
26 #include "user_settings.h"
27 #include "util.h"
28
29 void user_settings_password(struct session *s);
30 void user_settings_username(struct session *s);
31
32 void
33 user_settings_renegotiate(struct session *s)
34 {
35 unsigned short c;
36 short cols, lines;
37 char *tsize;
38
39 session_printf(s,
40 "Does this terminal support VT100 escape sequences? [Y/n] ");
41 session_flush(s);
42
43 try_again:
44 c = session_input_char(s);
45 if (s->ending)
46 return;
47 if (c == 0 || c > 255)
48 goto try_again;
49 if (c == 'n' || c == 'N') {
50 session_printf(s, "%c\r\n", c == 'N' ? 'N' : 'n');
51 session_flush(s);
52 s->vt100 = false;
53 } else if (c == '\r' || c == 'Y' || c == 'y') {
54 session_printf(s, "%c\r\n", c == 'Y' ? 'Y' : 'y');
55 session_flush(s);
56 s->vt100 = true;
57 }
58
59 if (!s->vt100) {
60 session_printf(s,
61 "Does this terminal support VT52 escape sequences? [Y/n] ");
62 session_flush(s);
63
64 try_again2:
65 c = session_input_char(s);
66 if (s->ending)
67 return;
68 if (c == 0 || c > 255)
69 goto try_again2;
70 if (c == 'n' || c == 'N') {
71 session_printf(s, "%c\r\n", c == 'N' ? 'N' : 'n');
72 session_flush(s);
73 s->vt52 = false;
74 } else if (c == '\r' || c == 'Y' || c == 'y') {
75 session_printf(s, "%c\r\n", c == 'Y' ? 'Y' : 'y');
76 session_flush(s);
77 s->vt52 = true;
78 }
79 }
80
81 if (s->vt100)
82 ansi_probe_screen_size(s);
83
84 get_terminal_size:
85 session_printf(s,
86 "Terminal size (columns x rows) [%dx%d] ", s->terminal_columns,
87 s->terminal_lines);
88 session_flush(s);
89
90 tsize = session_field_input(s, 10, 10, NULL, false, 0);
91 if (tsize == NULL)
92 return;
93 session_output(s, "\r\n", 2);
94 session_flush(s);
95 if (tsize[0] == '\0') {
96 xfree(&tsize);
97 return;
98 }
99
100 if (sscanf(tsize, "%d%*[xX]%d", &cols, &lines) != 2) {
101 session_printf(s, "Invalid response, must be in format %dx%d\r\n",
102 s->terminal_columns, s->terminal_lines);
103 session_flush(s);
104 xfree(&tsize);
105 goto get_terminal_size;
106 }
107
108 if (cols < MIN_TERMINAL_COLUMNS || lines < MIN_TERMINAL_LINES) {
109 session_printf(s, "Terminal too small, must be at least "
110 "%dx%d\r\n", MIN_TERMINAL_COLUMNS, MIN_TERMINAL_LINES);
111 session_flush(s);
112 xfree(&tsize);
113 goto get_terminal_size;
114 }
115
116 s->terminal_columns = cols;
117 s->terminal_lines = lines;
118 session_logf(s, "Changed terminal size to %dx%d", cols, lines);
119 }
120
121 void
122 user_settings_username(struct session *s)
123 {
124 char *username = NULL, *error = NULL;
125
126 if (!s->user) {
127 session_printf(s, "{{B}}Error{{/B}}: Guest accounts "
128 "cannot change username\r\n");
129 return;
130 }
131
132 while (!s->ending) {
133 session_printf(s, "{{B}}Username:{{/B}} ");
134 session_flush(s);
135 username = session_field_input(s, DB_USERNAME_LENGTH,
136 DB_USERNAME_LENGTH, s->user->username, false, 0);
137 session_output(s, "\r\n", 2);
138 session_flush(s);
139
140 if (username == NULL || s->ending)
141 break;
142
143 if (username[0] == '\0') {
144 session_printf(s, "{{B}}Error:{{/B}} "
145 "Username cannot be blank\r\n");
146 xfree(&username);
147 username = NULL;
148 continue;
149 }
150
151 if (strcmp(s->user->username, username) == 0)
152 break;
153
154 if (user_valid_username(s->user, username, &error) != 1) {
155 session_printf(s, "{{B}}Error:{{/B}} %s\r\n", error);
156 xfree(&error);
157 xfree(&username);
158 username = NULL;
159 continue;
160 }
161
162 session_logf(s, "User changed username from %s to %s",
163 s->user->username, username);
164 strlcpy(s->user->username, username, sizeof(s->user->username));
165 user_save(s->user);
166 user_cache_usernames();
167 session_printf(s, "{{B}}Your username has been "
168 "changed to %s{{/B}}\r\n", s->user->username);
169 break;
170 }
171
172 if (username != NULL)
173 xfree(&username);
174 }
175
176 void
177 user_settings_menu(struct session *s)
178 {
179 static const struct session_menu_option opts[] = {
180 { 'r', "Rr", "Renegotiate terminal" },
181 { 'p', "Pp", "Change password" },
182 { 'u', "Uu", "Change username" },
183 { 'q', "QqXx", "Return to main menu" },
184 { '?', "?", "List menu options" },
185 };
186 static const char prompt_help[] =
187 "R:Renegotiate P:Password U:Username Q:Return ?:Help";
188 char c;
189 bool show_help = true;
190 bool done = false;
191
192 session_logf(s, "User settings menu");
193
194 while (!done) {
195 c = session_menu(s, "Settings", "Settings", (char *)prompt_help,
196 opts, nitems(opts), show_help, NULL, NULL);
197 show_help = false;
198
199 switch (c) {
200 case 'r':
201 user_settings_renegotiate(s);
202 break;
203 case 'p':
204 user_change_password(s, s->user);
205 break;
206 case 'u':
207 user_settings_username(s);
208 break;
209 case '?':
210 show_help = true;
211 break;
212 default:
213 done = true;
214 break;
215 }
216 }
217 }