misc.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. *
  3. */
  4. #include <assert.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <sys/utsname.h>
  12. #include <faux/conv.h>
  13. #include <faux/str.h>
  14. #include <faux/list.h>
  15. #include <faux/sysdb.h>
  16. #include <klish/kcontext.h>
  17. #include <klish/ksession.h>
  18. #include <klish/kpath.h>
  19. int klish_nop(kcontext_t *context)
  20. {
  21. context = context; // Happy compiler
  22. return 0;
  23. }
  24. // Symbol for testing purposes
  25. int klish_tsym(kcontext_t *context)
  26. {
  27. const char *script = NULL;
  28. script = kcontext_script(context);
  29. if (faux_str_is_empty(script)) {
  30. kcontext_printf(context, "[<empty>]\n");
  31. kcontext_fprintf(context, stderr, "Empty item\n");
  32. return -1;
  33. }
  34. kcontext_printf(context, "[%s]\n", script);
  35. return 0;
  36. }
  37. // Print content of ACTION script
  38. int klish_printl(kcontext_t *context)
  39. {
  40. const char *script = NULL;
  41. script = kcontext_script(context);
  42. if (faux_str_is_empty(script))
  43. script = "";
  44. kcontext_printf(context, "%s\n", script);
  45. return 0;
  46. }
  47. // Print content of ACTION script. Without additional '/n'
  48. int klish_print(kcontext_t *context)
  49. {
  50. const char *script = NULL;
  51. script = kcontext_script(context);
  52. if (faux_str_is_empty(script))
  53. script = "";
  54. kcontext_printf(context, "%s", script);
  55. return 0;
  56. }
  57. // Template for easy prompt string generation
  58. int klish_prompt(kcontext_t *context)
  59. {
  60. const char *script = NULL;
  61. const char *start = NULL;
  62. const char *pos = NULL;
  63. char *prompt = NULL;
  64. bool_t is_macro = BOOL_FALSE;
  65. script = kcontext_script(context);
  66. if (faux_str_is_empty(script))
  67. return 0;
  68. pos = script;
  69. start = script;
  70. while (*pos != '\0') {
  71. if (is_macro) {
  72. switch (*pos) {
  73. // Percent symbol itself
  74. case '%': {
  75. faux_str_cat(&prompt, "%");
  76. break;
  77. }
  78. // Backslash symbol itself
  79. case '\\': {
  80. faux_str_cat(&prompt, "\\");
  81. break;
  82. }
  83. // Escape character
  84. case 'e': {
  85. faux_str_cat(&prompt, "\x1b");
  86. break;
  87. }
  88. // Hexadecimal byte
  89. case 'x': {
  90. char c;
  91. char hs[3] = {};
  92. if (*(pos + 1) == '\0')
  93. break;
  94. if (*(pos + 2) == '\0') {
  95. pos++;
  96. break;
  97. }
  98. hs[0] = *(pos + 1);
  99. hs[1] = *(pos + 2);
  100. pos += 2;
  101. if (!faux_conv_atouc(hs, &c, 16))
  102. break;
  103. faux_str_catn(&prompt, &c, 1);
  104. break;
  105. }
  106. // Hostname
  107. case 'h': {
  108. struct utsname buf;
  109. if (uname(&buf) == 0)
  110. faux_str_cat(&prompt, buf.nodename);
  111. break;
  112. }
  113. // Username
  114. case 'u': {
  115. const char *user = NULL;
  116. user = ksession_user(kcontext_session(context));
  117. if (user)
  118. faux_str_cat(&prompt, user);
  119. break;
  120. }
  121. }
  122. is_macro = BOOL_FALSE;
  123. start = pos + 1;
  124. } else if (*pos == '%' || *pos == '\\') {
  125. is_macro = BOOL_TRUE;
  126. if (pos > start)
  127. faux_str_catn(&prompt, start, pos - start);
  128. }
  129. pos++;
  130. }
  131. if (pos > start)
  132. faux_str_catn(&prompt, start, pos - start);
  133. kcontext_fwrite(context, stdout, prompt, strlen(prompt));
  134. faux_str_free(prompt);
  135. return 0;
  136. }