1 /******************************************************************************
2 * This file is part of TinTin++ *
3 * *
4 * Copyright 2004-2019 Igor van den Hoven *
5 * *
6 * TinTin++ is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with TinTin++. If not, see https://www.gnu.org/licenses. *
19 ******************************************************************************/
20
21 /******************************************************************************
22 * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
23 * *
24 * coded by Peter Unold 1992 *
25 * recoded by Igor van den Hoven 2005 *
26 ******************************************************************************/
27
28 #include "tintin.h"
29
30
DO_COMMAND(do_showme)31 DO_COMMAND(do_showme)
32 {
33 char *out, *tmp;
34 int prompt;
35
36 out = str_alloc_stack(0);
37 tmp = str_alloc_stack(0);
38
39 arg = get_arg_in_braces(ses, arg, arg1, GET_ALL);
40
41 prompt = is_suffix(arg1, "\\") && !is_suffix(arg1, "\\\\");
42
43 substitute(ses, arg1, tmp, SUB_VAR|SUB_FUN);
44 substitute(ses, tmp, arg1, SUB_COL|SUB_ESC);
45
46 arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN);
47 arg = sub_arg_in_braces(ses, arg, arg3, GET_ONE, SUB_VAR|SUB_FUN);
48
49 do_one_line(arg1, ses);
50
51 if (ses->gagline > 0)
52 {
53 ses->gagline--;
54
55 show_debug(ses, LIST_GAG, "#DEBUG GAG {%d} {%s}", ses->gagline + 1, arg1);
56
57 return ses;
58 }
59
60 if (*arg2)
61 {
62 split_show(ses, arg1, arg2, arg3);
63
64 return ses;
65 }
66
67 str_cpy_printf(&out, "%s%s%s", COLOR_TEXT, arg1, COLOR_TEXT);
68
69 tintin_puts3(ses, out, prompt);
70
71 return ses;
72 }
73
DO_COMMAND(do_echo)74 DO_COMMAND(do_echo)
75 {
76 char *result, *out;
77 int prompt;
78
79 result = arg2;
80
81 out = str_alloc_stack(0);
82
83 arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
84
85 format_string(ses, arg1, arg, result);
86
87 arg = get_arg_in_braces(ses, result, arg1, GET_ALL);
88
89 prompt = is_suffix(arg1, "\\") && !is_suffix(arg1, "\\\\");
90
91 substitute(ses, arg1, arg1, SUB_COL|SUB_ESC);
92
93 arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN);
94 arg = sub_arg_in_braces(ses, arg, arg3, GET_ONE, SUB_VAR|SUB_FUN);
95
96 if (*arg2)
97 {
98 split_show(ses, arg1, arg2, arg3);
99
100 return ses;
101 }
102
103 str_cpy_printf(&out, "%s%s%s", COLOR_TEXT, arg1, COLOR_TEXT);
104
105 tintin_puts3(ses, out, prompt);
106
107 return ses;
108 }
109
show_message(struct session * ses,int index,char * format,...)110 void show_message(struct session *ses, int index, char *format, ...)
111 {
112 struct listroot *root;
113 char *buffer;
114 va_list args;
115
116 push_call("show_message(%p,%p,%p)",ses,index,format);
117
118 root = ses->list[index];
119
120 if (gtd->level->verbose || gtd->level->debug)
121 {
122 goto display;
123 }
124
125 if (HAS_BIT(root->flags, LIST_FLAG_DEBUG))
126 {
127 goto display;
128 }
129
130 if (!HAS_BIT(root->flags, LIST_FLAG_MESSAGE))
131 {
132 goto end;
133 }
134
135 if (gtd->level->input)
136 {
137 goto end;
138 }
139
140 display:
141
142 va_start(args, format);
143
144 if (vasprintf(&buffer, format, args) == -1)
145 {
146 syserr_printf(ses, "show_message: vasprintf1:");
147
148 pop_call();
149 return;
150 }
151
152 va_end(args);
153
154 tintin_puts2(ses, buffer);
155
156 free(buffer);
157
158 pop_call();
159 return;
160
161 end:
162
163 if (HAS_BIT(root->flags, LIST_FLAG_LOG))
164 {
165 if (ses->log->file)
166 {
167 va_start(args, format);
168
169 if (vasprintf(&buffer, format, args) == -1)
170 {
171 syserr_printf(ses, "print_lines: vasprintf2:");
172
173 pop_call();
174 return;
175 }
176 va_end(args);
177
178 logit(ses, buffer, ses->log->file, LOG_FLAG_LINEFEED);
179
180 free(buffer);
181 }
182 }
183
184 pop_call();
185 return;
186 }
187
show_error(struct session * ses,int index,char * format,...)188 void show_error(struct session *ses, int index, char *format, ...)
189 {
190 struct listroot *root;
191 char *buffer;
192 va_list args;
193
194 push_call("show_error(%p,%p,%p)",ses,index,format);
195
196 va_start(args, format);
197 if (vasprintf(&buffer, format, args) == -1)
198 {
199 syserr_printf(ses, "show_error: vasprintf:");
200
201 pop_call();
202 return;
203 }
204 va_end(args);
205
206 check_all_events(ses, SUB_SEC|EVENT_FLAG_SYSTEM, 0, 1, "RECEIVED ERROR", buffer);
207
208 if (gtd->level->verbose || gtd->level->debug)
209 {
210 tintin_puts2(ses, buffer);
211
212 goto end;
213 }
214
215 root = ses->list[index];
216
217 if (HAS_BIT(root->flags, LIST_FLAG_DEBUG))
218 {
219 tintin_puts2(ses, buffer);
220
221 goto end;
222 }
223
224 if (HAS_BIT(root->flags, LIST_FLAG_MESSAGE))
225 {
226 tintin_puts2(ses, buffer);
227
228 goto end;
229 }
230
231 if (HAS_BIT(root->flags, LIST_FLAG_LOG))
232 {
233 if (ses->log->file)
234 {
235 logit(ses, buffer, ses->log->file, LOG_FLAG_LINEFEED);
236 }
237 }
238
239 end:
240
241 free(buffer);
242
243 pop_call();
244 return;
245 }
246
show_debug(struct session * ses,int index,char * format,...)247 void show_debug(struct session *ses, int index, char *format, ...)
248 {
249 struct listroot *root;
250 char buf[STRING_SIZE];
251 va_list args;
252
253 push_call("show_debug(%p,%p,%p)",ses,index,format);
254
255 root = ses->list[index];
256
257 if (gtd->level->debug == 0 && !HAS_BIT(root->flags, LIST_FLAG_DEBUG) && !HAS_BIT(root->flags, LIST_FLAG_LOG))
258 {
259 pop_call();
260 return;
261 }
262
263 va_start(args, format);
264
265 vsprintf(buf, format, args);
266
267 va_end(args);
268
269 if (gtd->level->debug || HAS_BIT(root->flags, LIST_FLAG_DEBUG))
270 {
271 gtd->level->verbose++;
272
273 tintin_puts2(ses, buf);
274
275 gtd->level->verbose--;
276
277 pop_call();
278 return;
279 }
280
281 if (HAS_BIT(root->flags, LIST_FLAG_LOG))
282 {
283 if (ses->log->file)
284 {
285 logit(ses, buf, ses->log->file, LOG_FLAG_LINEFEED);
286 }
287 }
288 pop_call();
289 return;
290 }
291
show_info(struct session * ses,int index,char * format,...)292 void show_info(struct session *ses, int index, char *format, ...)
293 {
294 struct listroot *root;
295 char buf[STRING_SIZE];
296 va_list args;
297
298 push_call("show_info(%p,%p,%p)",ses,index,format);
299
300 root = ses->list[index];
301
302 if (gtd->level->info == 0 && !HAS_BIT(root->flags, LIST_FLAG_INFO))
303 {
304 pop_call();
305 return;
306 }
307
308 va_start(args, format);
309
310 vsprintf(buf, format, args);
311
312 va_end(args);
313
314 gtd->level->verbose++;
315
316 tintin_puts(ses, buf);
317
318 gtd->level->verbose--;
319
320 pop_call();
321 return;
322 }
323
print_lines(struct session * ses,int flags,char * format,...)324 void print_lines(struct session *ses, int flags, char *format, ...)
325 {
326 char *buffer, *str_buf;
327 va_list args;
328
329 push_call("print_lines(%p,%d,%p,...)",ses,flags,format);
330
331 va_start(args, format);
332
333 if (vasprintf(&buffer, format, args) == -1)
334 {
335 syserr_printf(ses, "print_lines: vasprintf:");
336
337 pop_call();
338 return;
339 }
340
341 va_end(args);
342
343 if (flags)
344 {
345 str_buf = str_alloc_stack(strlen(buffer) * 2);
346
347 substitute(ses, buffer, str_buf, flags);
348
349 show_lines(ses, str_buf);
350 }
351 else
352 {
353 show_lines(ses, buffer);
354 }
355
356 free(buffer);
357
358 pop_call();
359 return;
360 }
361
show_lines(struct session * ses,char * str)362 void show_lines(struct session *ses, char *str)
363 {
364 char *ptf;
365
366 push_call("show_lines(%p,%p,...)",ses,str);
367
368 while (*str)
369 {
370 ptf = strchr(str, '\n');
371
372 if (ptf == NULL)
373 {
374 break;
375 }
376 *ptf++ = 0;
377
378 tintin_puts3(ses, str, FALSE);
379
380 str = ptf;
381 }
382 pop_call();
383 return;
384 }
385
386
tintin_header(struct session * ses,int width,char * format,...)387 void tintin_header(struct session *ses, int width, char *format, ...)
388 {
389 char arg[BUFFER_SIZE], buf[BUFFER_SIZE];
390 va_list args;
391 int cols;
392
393 push_call("tintin_header(%p,%p)",ses,format);
394
395 va_start(args, format);
396 vsprintf(arg, format, args);
397 va_end(args);
398
399 if (width)
400 {
401 cols = UMIN(width, get_scroll_cols(ses));
402 }
403 else
404 {
405 cols = get_scroll_cols(ses);
406 }
407
408 if (cols < 2)
409 {
410 pop_call();
411 return;
412 }
413
414 if ((int) strlen(arg) > cols - 2)
415 {
416 arg[cols - 2] = 0;
417 }
418
419 if (HAS_BIT(ses->config_flags, CONFIG_FLAG_SCREENREADER))
420 {
421 memset(buf, ' ', cols);
422 }
423 else
424 {
425 memset(buf, '#', cols);
426 }
427
428 memcpy(&buf[(cols - strlen(arg)) / 2], arg, strlen(arg));
429
430 buf[cols] = 0;
431
432 tintin_puts2(ses, buf);
433
434 pop_call();
435 return;
436 }
437
tintin_printf2(struct session * ses,char * format,...)438 void tintin_printf2(struct session *ses, char *format, ...)
439 {
440 char *buffer;
441 va_list args;
442
443 push_call("tintin_printf2(%p,%p,...)",ses,format);
444
445 va_start(args, format);
446 if (vasprintf(&buffer, format, args) == -1)
447 {
448 syserr_printf(ses, "tintin_printf2: vasprintf:");
449
450 pop_call();
451 return;
452 }
453 va_end(args);
454
455 tintin_puts2(ses, buffer);
456
457 free(buffer);
458
459 pop_call();
460 return;
461 }
462
tintin_printf(struct session * ses,char * format,...)463 void tintin_printf(struct session *ses, char *format, ...)
464 {
465 char buffer[BUFFER_SIZE];
466 va_list args;
467
468 va_start(args, format);
469 vsprintf(buffer, format, args);
470 va_end(args);
471
472 tintin_puts(ses, buffer);
473 }
474
475 /*
476 Show string and fire triggers
477 */
478
tintin_puts(struct session * ses,char * string)479 void tintin_puts(struct session *ses, char *string)
480 {
481 if (ses == NULL)
482 {
483 ses = gtd->ses;
484 }
485
486 do_one_line(string, ses);
487
488 if (ses->gagline)
489 {
490 ses->gagline--;
491
492 gtd->level->ignore++;
493
494 show_debug(ses, LIST_GAG, "#DEBUG GAG {%d} {%s}", ses->gagline + 1, string);
495
496 gtd->level->ignore--;
497 }
498 else
499 {
500 tintin_puts2(ses, string);
501 }
502 }
503
504 /*
505 show string and don't fire triggers
506 */
507
tintin_puts2(struct session * ses,char * string)508 void tintin_puts2(struct session *ses, char *string)
509 {
510 char *output;
511
512 push_call("tintin_puts2(%p,%p)",ses,string);
513
514 output = str_alloc_stack(0);
515
516 str_cpy_printf(&output, "%s%s%s", COLOR_TEXT, string, COLOR_TEXT);
517
518 tintin_puts3(ses, output, FALSE);
519
520 pop_call();
521 return;
522 }
523
524
525
526 /*
527 show string, no triggers, no color reset
528 */
529
tintin_puts3(struct session * ses,char * string,int prompt)530 void tintin_puts3(struct session *ses, char *string, int prompt)
531 {
532 char *output;
533
534 push_call("tintin_puts3(%p,%p,%d)",ses,string,prompt);
535
536 if (ses == NULL)
537 {
538 ses = gtd->ses;
539 }
540
541 if (ses->line_capturefile)
542 {
543 if (ses->line_captureindex == 1)
544 {
545 set_nest_node_ses(ses, ses->line_capturefile, "{%d}{%s}", ses->line_captureindex++, string);
546 }
547 else
548 {
549 add_nest_node_ses(ses, ses->line_capturefile, "{%d}{%s}", ses->line_captureindex++, string);
550 }
551 }
552
553 if (gtd->level->quiet && gtd->level->verbose == 0)
554 {
555 pop_call();
556 return;
557 }
558
559 output = str_alloc_stack(0);
560
561 if (strip_vt102_strlen(ses, ses->more_output) != 0)
562 {
563 str_cpy_printf(&output, "\n%s", string);
564 }
565 else
566 {
567 str_cpy(&output, string);
568 }
569
570 add_line_buffer(ses, output, prompt);
571
572 if (ses == gtd->ses)
573 {
574 if (!HAS_BIT(ses->flags, SES_FLAG_READMUD) && IS_SPLIT(ses))
575 {
576 save_pos(ses);
577
578 goto_pos(ses, ses->split->bot_row, ses->split->top_col);
579 }
580
581 print_line(ses, &output, prompt);
582
583 if (!HAS_BIT(ses->flags, SES_FLAG_READMUD) && IS_SPLIT(ses))
584 {
585 restore_pos(ses);
586 }
587 }
588
589 pop_call();
590 return;
591 }
592
593