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 // whether str1 is an abbreviation of str2
31
32 int case_table[256] =
33 {
34 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
35 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
36 95, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
37 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
38 64,
39 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
40 91, 92, 93, 94,
41 95, 96,
42 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
43 123, 124, 125, 126, 127,
44 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
45 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
46 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
47 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
48 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
49 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
50 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
51 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
52 };
53
is_abbrev(char * str1,char * str2)54 int is_abbrev(char *str1, char *str2)
55 {
56 char buf[NUMBER_SIZE], *str3;
57
58 str3 = buf;
59
60 if (*str1 == 0)
61 {
62 return FALSE;
63 }
64
65 if (*str2 == 0)
66 {
67 tintin_printf2(gtd->ses, "\e[1;31mis_abbrev(%s,%s)", str1, str2);
68
69 dump_stack();
70
71 return FALSE;
72 }
73
74 while (TRUE)
75 {
76 if (*str1 == 0)
77 {
78 *str3 = 0;
79
80 strcpy(gtd->is_result, buf);
81
82 return TRUE;
83 }
84
85 if (case_table[(int) *str1] != case_table[(int) *str2])
86 {
87 return FALSE;
88 }
89 str1++;
90
91 *str3++ = *str2++;
92 }
93 }
94
is_member(char * str1,char * str2)95 int is_member(char *str1, char *str2)
96 {
97 char *pt1, *pt2;
98
99 if (*str1 == 0)
100 {
101 return FALSE;
102 }
103
104 if (*str2 == 0)
105 {
106 tintin_printf2(gtd->ses, "\e[1;31mis_member(%s,%s)", str1, str2);
107
108 dump_stack();
109
110 return FALSE;
111 }
112
113 while (*str1)
114 {
115 if (case_table[(int) *str1] == case_table[(int) *str2])
116 {
117 pt1 = str1;
118 pt2 = str2;
119
120 while (case_table[(int) *pt1] == case_table[(int) *pt2])
121 {
122 pt1++;
123 pt2++;
124
125 if (*pt1 == ' ' || *pt1 == 0)
126 {
127 return TRUE;
128 }
129 }
130 }
131
132 while (*str1 && *str1 != ' ')
133 {
134 str1++;
135 }
136
137 if (*str1)
138 {
139 str1++;
140 }
141 }
142 return FALSE;
143 }
144
filename_string(char * input,char * output)145 void filename_string(char *input, char *output)
146 {
147 while (*input)
148 {
149 *output++ = (char) case_table[(int) *input++];
150 }
151 *output = 0;
152 }
153
is_vowel(char * str)154 int is_vowel(char *str)
155 {
156 switch (case_table[(int) *str])
157 {
158 case 'a':
159 case 'e':
160 case 'i':
161 case 'o':
162 case 'u':
163 return TRUE;
164 }
165 return FALSE;
166 }
167
168
parse_input(struct session * ses,char * input)169 struct session *parse_input(struct session *ses, char *input)
170 {
171 char *line;
172
173 push_call("parse_input(%s,%s)",ses->name,input);
174 /*
175 if (*input == 0)
176 {
177 write_mud(ses, input, SUB_EOL);
178
179 pop_call();
180 return ses;
181 }
182 */
183 line = str_alloc_stack(0);
184
185 if (VERBATIM(ses))
186 {
187 sub_arg_all(ses, input, line, 1, SUB_SEC);
188
189 if (check_all_aliases(ses, line))
190 {
191 ses = script_driver(ses, LIST_ALIAS, line);
192 }
193 else if (HAS_BIT(ses->config_flags, CONFIG_FLAG_SPEEDWALK) && is_speedwalk(ses, line))
194 {
195 process_speedwalk(ses, line);
196 }
197 else
198 {
199 write_mud(ses, line, SUB_EOL|SUB_ESC);
200 }
201
202 pop_call();
203 return ses;
204 }
205
206 if (*input == gtd->verbatim_char)
207 {
208 write_mud(ses, input+1, SUB_EOL);
209
210 pop_call();
211 return ses;
212 }
213
214 do
215 {
216 input = space_out(input);
217
218 input = get_arg_all(ses, input, line, 0);
219
220 if (parse_command(ses, line))
221 {
222 ses = script_driver(ses, LIST_COMMAND, line);
223 }
224 else if (check_all_aliases(ses, line))
225 {
226 ses = script_driver(ses, LIST_ALIAS, line);
227 }
228 else if (HAS_BIT(ses->config_flags, CONFIG_FLAG_SPEEDWALK) && is_speedwalk(ses, line))
229 {
230 process_speedwalk(ses, line);
231 }
232 else
233 {
234 write_mud(ses, line, SUB_VAR|SUB_FUN|SUB_ESC|SUB_EOL);
235 }
236
237 if (*input == COMMAND_SEPARATOR)
238 {
239 input++;
240 }
241 }
242 while (*input);
243
244 pop_call();
245 return ses;
246 }
247
248 /*
249 Deal with variables and functions used as commands.
250 */
251
parse_command(struct session * ses,char * input)252 struct session *parse_command(struct session *ses, char *input)
253 {
254 char *arg, *arg1;
255
256 push_call("parse_command(%p,%p)",ses,input);
257
258 arg1 = str_alloc_stack(0);
259
260 arg = sub_arg_stop_spaces(ses, input, arg1, GET_ONE, SUB_VAR|SUB_FUN);
261
262 if (!strncmp(input, arg1, strlen(arg1)))
263 {
264 pop_call();
265 return NULL;
266 }
267
268 if (*arg)
269 {
270 cat_sprintf(arg1, " %s", arg);
271 }
272 strcpy(input, arg1);
273
274 pop_call();
275 return ses;
276 }
277
substitute_speedwalk(struct session * ses,char * input,char * output)278 char *substitute_speedwalk(struct session *ses, char *input, char *output)
279 {
280 char num[NUMBER_SIZE], name[BUFFER_SIZE], *pti, *ptn, *pto;
281 int cnt, max;
282
283 pti = input;
284 pto = output;
285
286 while (*pti && pto - output < INPUT_SIZE)
287 {
288 if (is_space(*pti))
289 {
290 return input;
291 }
292
293 if (is_digit(*pti))
294 {
295 ptn = num;
296
297 while (is_digit(*pti))
298 {
299 if (ptn - num < 4)
300 {
301 *ptn++ = *pti++;
302 }
303 else
304 {
305 pti++;
306 }
307 }
308 *ptn = 0;
309
310 max = atoi(num);
311
312 if (*pti == 0)
313 {
314 return input;
315 }
316 }
317 else
318 {
319 max = 1;
320 }
321
322 pti = get_arg_stop_digits(ses, pti, name, GET_ONE);
323
324 if (*name == 0 || !is_pathdir(ses, name))
325 {
326 return input;
327 }
328
329 for (cnt = 0 ; cnt < max ; cnt++)
330 {
331 if (output != pto)
332 {
333 *pto++ = COMMAND_SEPARATOR;
334 }
335 pto += sprintf(pto, "%s", name);
336 }
337
338 if (*pti == COMMAND_SEPARATOR)
339 {
340 pti++;
341 }
342 }
343 *pto = 0;
344
345 return output;
346 }
347
is_speedwalk(struct session * ses,char * input)348 int is_speedwalk(struct session *ses, char *input)
349 {
350 int digit = 0, flag = FALSE;
351
352 while (*input)
353 {
354 switch (*input)
355 {
356 case 'n':
357 case 'e':
358 case 's':
359 case 'w':
360 case 'u':
361 case 'd':
362 if (digit > 3)
363 {
364 return FALSE;
365 }
366 digit = 0;
367 flag = TRUE;
368 break;
369
370 case '0':
371 case '1':
372 case '2':
373 case '3':
374 case '4':
375 case '5':
376 case '6':
377 case '7':
378 case '8':
379 case '9':
380 digit++;
381 flag = FALSE;
382 break;
383
384 default:
385 return FALSE;
386 }
387 input++;
388 }
389 return flag;
390 }
391
392
process_speedwalk(struct session * ses,char * input)393 void process_speedwalk(struct session *ses, char *input)
394 {
395 char dir[2];
396 int cnt, i;
397
398 for (dir[1] = 0 ; *input ; input++)
399 {
400 if (is_digit(*input))
401 {
402 sscanf(input, "%d%c", &cnt, dir);
403
404 for (i = 0 ; i < cnt ; i++)
405 {
406 write_mud(ses, dir, SUB_EOL);
407 }
408
409 while (*input != dir[0])
410 {
411 input++;
412 }
413 }
414 else
415 {
416 dir[0] = *input;
417
418 write_mud(ses, dir, SUB_EOL);
419 }
420 }
421 return;
422 }
423
424 /*
425 Deals with all # stuff
426 */
427
parse_tintin_command(struct session * ses,char * input)428 struct session *parse_tintin_command(struct session *ses, char *input)
429 {
430 char line[BUFFER_SIZE];
431 struct session *sesptr;
432
433 input = sub_arg_in_braces(ses, input, line, GET_ONE, SUB_VAR|SUB_FUN);
434
435 if (is_number(line))
436 {
437 int cnt = atoi(line);
438
439 input = get_arg_in_braces(ses, input, line, GET_ALL);
440
441 while (cnt-- > 0)
442 {
443 ses = script_driver(ses, LIST_COMMAND, line);
444 }
445 return ses;
446 }
447
448 sesptr = find_session(line);
449
450 if (sesptr)
451 {
452 if (*input)
453 {
454 input = get_arg_in_braces(ses, input, line, GET_ALL);
455
456 substitute(ses, line, line, SUB_VAR|SUB_FUN);
457
458 script_driver(sesptr, LIST_COMMAND, line);
459
460 return ses;
461 }
462 else
463 {
464 return activate_session(sesptr);
465 }
466 }
467
468 if (*line == '!')
469 {
470 show_error(ses, LIST_COMMAND, "#!%s %s", line + 1, input);
471
472 return ses;
473 }
474
475 tintin_printf2(ses, "#ERROR: #UNKNOWN TINTIN-COMMAND '%s'.", line);
476
477 check_all_events(ses, SUB_SEC|EVENT_FLAG_SYSTEM, 0, 1, "UNKNOWN COMMAND", line);
478
479 return ses;
480 }
481
482
cnt_arg_all(struct session * ses,char * string,int flag)483 int cnt_arg_all(struct session *ses, char *string, int flag)
484 {
485 char *arg, tmp[BUFFER_SIZE];
486 int cnt;
487
488 arg = string;
489 cnt = 0;
490
491 while (*arg)
492 {
493 cnt++;
494
495 arg = get_arg_in_braces(ses, arg, tmp, flag);
496
497 if (*arg == COMMAND_SEPARATOR)
498 {
499 arg++;
500 }
501 }
502 return cnt;
503 }
504
505 /*
506 get all arguments - only check for unescaped command separators
507 */
508
get_arg_all(struct session * ses,char * string,char * result,int verbatim)509 char *get_arg_all(struct session *ses, char *string, char *result, int verbatim)
510 {
511 char *pto, *pti;
512 int skip, nest = 0;
513
514 pti = string;
515 pto = result;
516
517 if (*pti == gtd->verbatim_char)
518 {
519 while (*pti)
520 {
521 *pto++ = *pti++;
522 }
523 *pto = 0;
524
525 return pti;
526 }
527
528 while (*pti)
529 {
530 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
531 {
532 *pto++ = *pti++;
533 *pto++ = *pti++;
534 continue;
535 }
536
537 skip = find_secure_color_code(pti);
538
539 if (skip)
540 {
541 while (skip--)
542 {
543 *pto++ = *pti++;
544 }
545 continue;
546 }
547
548 if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
549 {
550 *pto++ = *pti++;
551 }
552 else if (*pti == COMMAND_SEPARATOR && nest == 0 && !verbatim)
553 {
554 break;
555 }
556 else if (*pti == DEFAULT_OPEN)
557 {
558 nest++;
559 }
560 else if (*pti == DEFAULT_CLOSE)
561 {
562 nest--;
563 }
564 *pto++ = *pti++;
565
566 if (pto - result >= BUFFER_SIZE - 3)
567 {
568 tintin_printf2(ses, "#ERROR: INPUT BUFFER OVERFLOW.");
569
570 pto--;
571
572 break;
573 }
574 }
575 *pto = '\0';
576
577 return pti;
578 }
579
sub_arg_all(struct session * ses,char * string,char * result,int verbatim,int sub)580 char *sub_arg_all(struct session *ses, char *string, char *result, int verbatim, int sub)
581 {
582 char *buffer;
583
584 if (*string == 0)
585 {
586 *result = 0;
587
588 return string;
589 }
590
591 push_call("sub_arg_all(%p,%p,%p,%d,%d)",ses,string,result,verbatim,sub);
592
593 buffer = str_alloc_stack(strlen(string));
594
595 string = get_arg_all(ses, string, buffer, verbatim);
596
597 substitute(ses, buffer, result, sub);
598
599 pop_call();
600 return string;
601 }
602
603 /*
604 Braces are stripped in braced arguments leaving all else as is.
605 */
606
get_arg_in_braces(struct session * ses,char * string,char * result,int flag)607 char *get_arg_in_braces(struct session *ses, char *string, char *result, int flag)
608 {
609 char *pti, *pto;
610 int skip, nest = 1;
611
612 pti = space_out(string);
613 pto = result;
614
615 if (*pti != DEFAULT_OPEN)
616 {
617 if (!HAS_BIT(flag, GET_ALL))
618 {
619 pti = get_arg_stop_spaces(ses, pti, result, flag);
620 }
621 else
622 {
623 pti = get_arg_with_spaces(ses, pti, result, flag);
624 }
625 return pti;
626 }
627
628 pti++;
629
630 while (*pti)
631 {
632 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
633 {
634 *pto++ = *pti++;
635 *pto++ = *pti++;
636 continue;
637 }
638
639 skip = find_secure_color_code(pti);
640
641 if (skip)
642 {
643 while (skip--)
644 {
645 *pto++ = *pti++;
646 }
647 continue;
648 }
649
650 if (*pti == DEFAULT_OPEN)
651 {
652 nest++;
653 }
654 else if (*pti == DEFAULT_CLOSE)
655 {
656 nest--;
657
658 if (nest == 0)
659 {
660 break;
661 }
662 }
663 *pto++ = *pti++;
664 }
665
666 if (*pti == 0)
667 {
668 show_error(ses, LIST_COMMAND, "#ERROR: GET BRACED ARGUMENT: UNMATCHED BRACE.");
669 }
670 else
671 {
672 pti++;
673 }
674 *pto = '\0';
675
676 return pti;
677 }
678
sub_arg_in_braces(struct session * ses,char * string,char * result,int flag,int sub)679 char *sub_arg_in_braces(struct session *ses, char *string, char *result, int flag, int sub)
680 {
681 char *buffer;
682
683 if (*string == 0)
684 {
685 *result = 0;
686
687 return string;
688 }
689
690 push_call("sub_arg_in_braces(%p,%p,%p,%d,%d)",ses,string,result,flag,sub);
691
692 buffer = str_alloc_stack(strlen(string) * 2);
693
694 string = get_arg_in_braces(ses, string, buffer, flag);
695
696 substitute(ses, buffer, result, sub);
697
698 pop_call();
699 return string;
700 }
701
702 /*
703 get all arguments
704 */
705
get_arg_with_spaces(struct session * ses,char * string,char * result,int flag)706 char *get_arg_with_spaces(struct session *ses, char *string, char *result, int flag)
707 {
708 char *pto, *pti;
709 int skip, nest = 0;
710
711 pti = space_out(string);
712 pto = result;
713
714 while (*pti)
715 {
716 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
717 {
718 *pto++ = *pti++;
719 *pto++ = *pti++;
720 continue;
721 }
722
723 skip = find_secure_color_code(pti);
724
725 if (skip)
726 {
727 while (skip--)
728 {
729 *pto++ = *pti++;
730 }
731 continue;
732 }
733
734 if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
735 {
736 *pto++ = *pti++;
737 }
738 else if (*pti == COMMAND_SEPARATOR && nest == 0)
739 {
740 break;
741 }
742 else if (*pti == DEFAULT_OPEN)
743 {
744 nest++;
745 }
746 else if (*pti == DEFAULT_CLOSE)
747 {
748 nest--;
749 }
750 *pto++ = *pti++;
751 }
752 *pto = '\0';
753
754 return pti;
755 }
756
757 /*
758 get one arg, stop at spaces
759 */
760
get_arg_stop_spaces(struct session * ses,char * string,char * result,int flag)761 char *get_arg_stop_spaces(struct session *ses, char *string, char *result, int flag)
762 {
763 char *pto, *pti;
764 int skip, nest = 0;
765
766 pti = space_out(string);
767 pto = result;
768
769 while (*pti)
770 {
771 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
772 {
773 *pto++ = *pti++;
774 *pto++ = *pti++;
775 continue;
776 }
777
778 skip = find_secure_color_code(pti);
779
780 if (skip)
781 {
782 while (skip--)
783 {
784 *pto++ = *pti++;
785 }
786 continue;
787 }
788
789
790 if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
791 {
792 *pto++ = *pti++;
793 }
794 else if (*pti == COMMAND_SEPARATOR && nest == 0)
795 {
796 break;
797 }
798 else if (is_space(*pti) && nest == 0)
799 {
800 pti++;
801 break;
802 }
803 else if (*pti == DEFAULT_OPEN)
804 {
805 nest++;
806 }
807 else if (*pti == '[' && HAS_BIT(flag, GET_NST))
808 {
809 nest++;
810 }
811 else if (*pti == DEFAULT_CLOSE)
812 {
813 nest--;
814 }
815 else if (*pti == ']' && HAS_BIT(flag, GET_NST))
816 {
817 nest--;
818 }
819 *pto++ = *pti++;
820 }
821 *pto = '\0';
822
823 return pti;
824 }
825
sub_arg_stop_spaces(struct session * ses,char * string,char * result,int flag,int sub)826 char *sub_arg_stop_spaces(struct session *ses, char *string, char *result, int flag, int sub)
827 {
828 char *buffer;
829
830 if (*string == 0)
831 {
832 *result = 0;
833
834 return string;
835 }
836
837 push_call("sub_arg_stop_braces(%p,%p,%p,%d,%d)",ses,string,result,flag,sub);
838
839 buffer = str_alloc_stack(strlen(string) * 2);
840
841 string = get_arg_stop_spaces(ses, string, buffer, flag);
842
843 substitute(ses, buffer, result, sub);
844
845 pop_call();
846 return string;
847 }
848
849 // Get one arg, stop at numbers, used for speedwalks
850
get_arg_stop_digits(struct session * ses,char * string,char * result,int flag)851 char *get_arg_stop_digits(struct session *ses, char *string, char *result, int flag)
852 {
853 char *pto, *pti;
854 int nest = 0;
855
856 pti = space_out(string);
857 pto = result;
858
859 while (*pti)
860 {
861 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
862 {
863 *pto++ = *pti++;
864 *pto++ = *pti++;
865 continue;
866 }
867
868 if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
869 {
870 *pto++ = *pti++;
871 }
872 else if (*pti == COMMAND_SEPARATOR && nest == 0)
873 {
874 break;
875 }
876 else if (is_digit(*pti) && nest == 0)
877 {
878 break;
879 }
880 else if (*pti == DEFAULT_OPEN)
881 {
882 nest++;
883 }
884 else if (*pti == '[' && HAS_BIT(flag, GET_NST))
885 {
886 nest++;
887 }
888 else if (*pti == DEFAULT_CLOSE)
889 {
890 nest--;
891 }
892 else if (*pti == ']' && HAS_BIT(flag, GET_NST))
893 {
894 nest--;
895 }
896 *pto++ = *pti++;
897 }
898 *pto = '\0';
899
900 return pti;
901 }
902
903 /*
904 advance ptr to next none-space
905 */
906
space_out(char * string)907 char *space_out(char *string)
908 {
909 while (is_space(*string))
910 {
911 string++;
912 }
913 return string;
914 }
915
916 /*
917 For variable handling
918 */
919
get_arg_to_brackets(struct session * ses,char * string,char * result)920 char *get_arg_to_brackets(struct session *ses, char *string, char *result)
921 {
922 char *pti, *pto, *ptii, *ptoo;
923 int nest1 = 0, nest2 = 0, nest3 = 0;
924
925 pti = space_out(string);
926 pto = result;
927 ptii = ptoo = NULL;
928
929 while (*pti)
930 {
931 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
932 {
933 *pto++ = *pti++;
934 *pto++ = *pti++;
935 continue;
936 }
937
938 if (*pti == '[')
939 {
940 nest2++;
941
942 if (nest1 == 0 && ptii == NULL)
943 {
944 ptii = pti;
945 ptoo = pto;
946 }
947 }
948 else if (*pti == ']')
949 {
950 if (nest2)
951 {
952 nest2--;
953 }
954 else
955 {
956 nest3 = 1;
957 }
958
959 if (*(pti+1) == 0 && ptii && nest1 == 0 && nest2 == 0 && nest3 == 0)
960 {
961 *ptoo = 0;
962
963 return ptii;
964 }
965 }
966 else if (*pti == DEFAULT_OPEN)
967 {
968 nest1++;
969 }
970 else if (*pti == DEFAULT_CLOSE)
971 {
972 nest1--;
973 }
974 *pto++ = *pti++;
975 }
976 *pto = 0;
977
978 return pti;
979 }
980
get_arg_at_brackets(struct session * ses,char * string,char * result)981 char *get_arg_at_brackets(struct session *ses, char *string, char *result)
982 {
983 char *pti, *pto;
984 int nest = 0;
985
986 pti = string;
987 pto = result;
988
989 if (*pti != '[')
990 {
991 *pto = 0;
992
993 return pti;
994 }
995
996 while (*pti)
997 {
998 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
999 {
1000 *pto++ = *pti++;
1001 *pto++ = *pti++;
1002 continue;
1003 }
1004
1005 if (*pti == '[')
1006 {
1007 nest++;
1008 }
1009 else if (*pti == ']')
1010 {
1011 if (nest)
1012 {
1013 nest--;
1014 }
1015 else
1016 {
1017 break;
1018 }
1019 }
1020 else if (nest == 0)
1021 {
1022 break;
1023 }
1024 *pto++ = *pti++;
1025 }
1026
1027 if (nest)
1028 {
1029 show_error(ses, LIST_COMMAND, "#ERROR: GET BRACKETED VARIABLE: UNMATCHED BRACKET.");
1030 }
1031 *pto = 0;
1032
1033 return pti;
1034 }
1035
get_arg_in_brackets(struct session * ses,char * string,char * result)1036 char *get_arg_in_brackets(struct session *ses, char *string, char *result)
1037 {
1038 char *pti, *pto;
1039 int nest = 1;
1040
1041 pti = string;
1042 pto = result;
1043
1044 if (*pti != '[')
1045 {
1046 *pto = 0;
1047
1048 return pti;
1049 }
1050
1051 pti++;
1052
1053 while (*pti)
1054 {
1055 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
1056 {
1057 *pto++ = *pti++;
1058 *pto++ = *pti++;
1059 continue;
1060 }
1061
1062 if (*pti == '[')
1063 {
1064 nest++;
1065 }
1066 else if (*pti == ']')
1067 {
1068 nest--;
1069
1070 if (nest == 0)
1071 {
1072 break;
1073 }
1074 }
1075 *pto++ = *pti++;
1076 }
1077
1078 if (*pti == 0)
1079 {
1080 show_error(ses, LIST_COMMAND, "#ERROR: GET BRACKETED ARGUMENT: UNMATCHED BRACKET.");
1081 }
1082 else
1083 {
1084 pti++;
1085 }
1086 *pto = 0;
1087
1088 return pti;
1089 }
1090
get_char(struct session * ses,char * string,char * result)1091 char *get_char(struct session *ses, char *string, char *result)
1092 {
1093 char *pti = string;
1094
1095 if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
1096 {
1097 pti += sprintf(result, "%c%c", pti[0], pti[1]);
1098 }
1099 else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(pti))
1100 {
1101 pti += sprintf(result, "%.*s", get_utf8_size(pti), pti);
1102 }
1103 else
1104 {
1105 pti += sprintf(result, "%c", pti[0]);
1106 }
1107
1108 return pti;
1109 }
1110
1111 /*
1112 send command to the mud
1113 */
1114
write_mud(struct session * ses,char * command,int flags)1115 void write_mud(struct session *ses, char *command, int flags)
1116 {
1117 char output[BUFFER_SIZE];
1118 int size;
1119
1120 size = substitute(ses, command, output, flags);
1121
1122 if (gtd->level->ignore == 0 && HAS_BIT(ses->flags, SES_FLAG_PATHMAPPING))
1123 {
1124 if (ses->map == NULL || ses->map->nofollow == 0)
1125 {
1126 check_append_path(ses, command, NULL, 0.0, 0, 1);
1127 }
1128 }
1129
1130 if (gtd->level->ignore == 0 && ses->map && ses->map->in_room && ses->map->nofollow == 0)
1131 {
1132 int quiet, follow;
1133
1134 quiet = HAS_BIT(ses->map->flags, MAP_FLAG_QUIET);
1135
1136 gtd->level->input += quiet;
1137
1138 follow = follow_map(ses, command);
1139
1140 gtd->level->input -= quiet;
1141
1142 if (follow)
1143 {
1144 return;
1145 }
1146 }
1147
1148 write_line_mud(ses, output, size);
1149 }
1150
1151
1152 /*
1153 Check line for triggers
1154 */
1155
do_one_line(char * line,struct session * ses)1156 void do_one_line(char *line, struct session *ses)
1157 {
1158 char *strip, *buf;
1159
1160 if (gtd->level->ignore)
1161 {
1162 return;
1163 }
1164
1165 push_call("do_one_line(%s,%p)",ses->name,line);
1166
1167 push_script_stack(ses, LIST_VARIABLE);
1168
1169 strip = str_alloc_stack(0);
1170 buf = str_alloc_stack(0);
1171
1172 strip_vt102_codes(line, strip);
1173
1174 if (!HAS_BIT(ses->list[LIST_ACTION]->flags, LIST_FLAG_IGNORE))
1175 {
1176 check_all_actions(ses, line, strip, buf);
1177 }
1178
1179 if (!HAS_BIT(ses->list[LIST_PROMPT]->flags, LIST_FLAG_IGNORE))
1180 {
1181 check_all_prompts(ses, line, strip);
1182 }
1183
1184 if (!HAS_BIT(ses->list[LIST_GAG]->flags, LIST_FLAG_IGNORE))
1185 {
1186 check_all_gags(ses, line, strip);
1187 }
1188
1189 if (!HAS_BIT(ses->list[LIST_SUBSTITUTE]->flags, LIST_FLAG_IGNORE))
1190 {
1191 check_all_substitutions(ses, line, strip);
1192 }
1193
1194 if (!HAS_BIT(ses->list[LIST_HIGHLIGHT]->flags, LIST_FLAG_IGNORE))
1195 {
1196 check_all_highlights(ses, line, strip);
1197 }
1198
1199 if (HAS_BIT(ses->log->mode, LOG_FLAG_NEXT))
1200 {
1201 logit(ses, line, ses->log->next_file, LOG_FLAG_LINEFEED);
1202
1203 DEL_BIT(ses->log->mode, LOG_FLAG_NEXT);
1204 }
1205
1206 pop_script_stack();
1207
1208 pop_call();
1209 return;
1210 }
1211