system.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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. * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
  22. * *
  23. * coded by Igor van den Hoven 2007 *
  24. ******************************************************************************/
  25. #include "tintin.h"
  26. #ifdef HAVE_PTY_H
  27. #include <pty.h>
  28. #else
  29. #ifdef HAVE_UTIL_H
  30. #include <util.h>
  31. #endif
  32. #endif
  33. DO_COMMAND(do_run)
  34. {
  35. char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], temp[BUFFER_SIZE], file[BUFFER_SIZE];
  36. int desc, pid;
  37. struct winsize size;
  38. struct termios run_terminal;
  39. char *argv[4] = {"sh", "-c", "", NULL};
  40. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  41. arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
  42. arg = sub_arg_in_braces(ses, arg, file, GET_ONE, SUB_VAR|SUB_FUN);
  43. if (*arg1 == 0 || *arg2 == 0)
  44. {
  45. show_error(ses, LIST_COMMAND, "#SYNTAX: #RUN {NAME} {SYSTEM SHELL COMMAND}");
  46. return ses;
  47. }
  48. size.ws_row = get_scroll_size(ses);
  49. size.ws_col = gtd->screen->cols;
  50. pid = forkpty(&desc, temp, &gtd->old_terminal, &size);
  51. switch (pid)
  52. {
  53. case -1:
  54. syserr_printf(ses, "do_run: forkpty");
  55. break;
  56. case 0:
  57. sprintf(temp, "exec %s", arg2);
  58. argv[2] = temp;
  59. execv("/bin/sh", argv);
  60. tcgetattr(0, &run_terminal);
  61. break;
  62. default:
  63. sprintf(temp, "{%s} {%d} {%s}", arg2, pid, file);
  64. ses = new_session(ses, arg1, temp, desc, 0);
  65. // memcpy(&ses->cur_terminal, &run_terminal, sizeof(run_terminal));
  66. // refresh_session_terminal(ses);
  67. break;
  68. }
  69. return ses;
  70. }
  71. DO_COMMAND(do_script)
  72. {
  73. char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], *cptr, buf[BUFFER_SIZE], var[BUFFER_SIZE], tmp[BUFFER_SIZE];
  74. FILE *script;
  75. int index;
  76. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  77. arg = sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_VAR|SUB_FUN);
  78. if (*arg1 == 0)
  79. {
  80. show_error(ses, LIST_COMMAND, "#SCRIPT: ONE ARGUMENT REQUIRED.");
  81. }
  82. else if (*arg2 == 0)
  83. {
  84. script = popen(arg1, "r");
  85. if (script)
  86. {
  87. while (fgets(buf, BUFFER_SIZE - 1, script))
  88. {
  89. cptr = strchr(buf, '\n');
  90. if (cptr)
  91. {
  92. *cptr = 0;
  93. }
  94. ses = script_driver(ses, LIST_COMMAND, buf);
  95. }
  96. pclose(script);
  97. }
  98. else
  99. {
  100. syserr_printf(ses, "do_script: popen 1");
  101. }
  102. }
  103. else
  104. {
  105. index = 1;
  106. script = popen(arg2, "r");
  107. if (script)
  108. {
  109. var[0] = 0;
  110. while (fgets(buf, BUFFER_SIZE - 1, script))
  111. {
  112. cptr = strchr(buf, '\n');
  113. if (cptr)
  114. {
  115. *cptr = 0;
  116. }
  117. substitute(ses, buf, tmp, SUB_SEC);
  118. cat_sprintf(var, "{%d}{%s}", index++, tmp);
  119. }
  120. set_nest_node(ses->list[LIST_VARIABLE], arg1, "%s", var);
  121. pclose(script);
  122. }
  123. else
  124. {
  125. syserr_printf(ses, "do_script: popen 2");
  126. }
  127. }
  128. refresh_session_terminal(ses);
  129. return ses;
  130. }
  131. DO_COMMAND(do_suspend)
  132. {
  133. suspend_handler(0);
  134. return ses;
  135. }
  136. DO_COMMAND(do_system)
  137. {
  138. char arg1[BUFFER_SIZE];
  139. sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
  140. if (*arg1 == 0)
  141. {
  142. show_error(ses, LIST_COMMAND, "#SYNTAX: #SYSTEM {COMMAND}.");
  143. return ses;
  144. }
  145. show_message(ses, LIST_COMMAND, "#OK: EXECUTING '%s'", arg1);
  146. if (!HAS_BIT(gtd->ses->flags, SES_FLAG_READMUD) && IS_SPLIT(gtd->ses))
  147. {
  148. save_pos(gtd->ses);
  149. goto_rowcol(gtd->ses, gtd->ses->bot_row, 1);
  150. }
  151. fflush(stdout);
  152. system(arg1);
  153. if (!HAS_BIT(gtd->ses->flags, SES_FLAG_READMUD) && IS_SPLIT(gtd->ses))
  154. {
  155. restore_pos(gtd->ses);
  156. }
  157. fflush(stdout);
  158. refresh_session_terminal(gtd->ses);
  159. return ses;
  160. }
  161. DO_COMMAND(do_textin)
  162. {
  163. FILE *fp;
  164. char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], buffer[BUFFER_SIZE], *cptr;
  165. arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
  166. arg = get_arg_in_braces(ses, arg, arg2, GET_ALL);
  167. if ((fp = fopen(arg1, "r")) == NULL)
  168. {
  169. show_error(ses, LIST_COMMAND, "#ERROR: #TEXTIN {%s} - FILE NOT FOUND.", arg1);
  170. return ses;
  171. }
  172. while (fgets(buffer, BUFFER_SIZE - 1, fp))
  173. {
  174. cptr = strchr(buffer, '\n');
  175. if (cptr)
  176. {
  177. *cptr = 0;
  178. }
  179. write_mud(ses, buffer, SUB_EOL);
  180. if (*arg2)
  181. {
  182. usleep((long long) (get_number(ses, arg2) * 1000000));
  183. }
  184. }
  185. fclose(fp);
  186. show_message(ses, LIST_COMMAND, "#TEXTIN {%s} - FILE READ.", arg1);
  187. return ses;
  188. }