home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / git-4.3 / git-4 / git-4.3.7 / src / git.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-18  |  79.3 KB  |  2,838 lines

  1. /* git.c -- the main git file. Performs most of the initializations + commands
  2.    expansion / execution. */
  3.  
  4. /* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
  5.  
  6.    This program 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 2, or (at your option)
  9.    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.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Written by Tudor Hulubei and Andrei Pitis.  */
  21.  
  22.  
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include <stdio.h>
  28.  
  29. #ifdef HAVE_STDLIB_H
  30. #include <stdlib.h>
  31. #else /* !HAVE_STDLIB_H */
  32. #include "ansi_stdlib.h"
  33. #endif /* !HAVE_STDLIB_H */
  34.  
  35. #include <sys/types.h>
  36. #include "file.h"
  37. #include <fcntl.h>
  38. #include <ctype.h>
  39. #include <signal.h>
  40. #include <pwd.h>
  41. #include <grp.h>
  42. #include <limits.h>
  43. #include <sys/wait.h>
  44.  
  45. #ifdef HAVE_UNISTD_H
  46. #include <unistd.h>
  47. #endif /* HAVE_UNISTD_H */
  48.  
  49. #include "stdc.h"
  50. #include "xstring.h"
  51. #include "xmalloc.h"
  52. #include "xio.h"
  53. #include "xtimer.h"
  54. #include "tty.h"
  55. #include "window.h"
  56. #include "inputline.h"
  57. #include "status.h"
  58. #include "panel.h"
  59. #include "configure.h"
  60. #include "signals.h"
  61. #include "system.h"
  62. #include "history.h"
  63. #include "tilde.h"
  64. #include "misc.h"
  65.  
  66.  
  67. extern int FrameDisplay;
  68. extern int suspend_allowed;
  69. extern int signals_status;
  70.  
  71.  
  72. #define MAX_STATIC_SIZE 50
  73.  
  74.  
  75. #ifdef HAVE_LINUX
  76. extern int LinuxConsole;
  77. #endif /* HAVE_LINUX */
  78.  
  79.  
  80. #ifdef HAVE_LINUX
  81. int AnsiColorSequences = ON;
  82. #else   /* !HAVE_LINUX */
  83. int AnsiColorSequences = OFF;
  84. #endif  /* !HAVE_LINUX */
  85.  
  86. int TypeSensitivity = ON;
  87.  
  88. /* These are the only possible current_mode values. Used while resuming
  89.    from suspended mode in order to correctly refresh the display. */
  90. #define GIT_SCREEN_MODE         0
  91. #define GIT_TERMINAL_MODE       1
  92.  
  93.  
  94. pid_t pid;
  95. char *home;
  96. char *program;
  97. int gitclock_xtimer;
  98. int two_panel_mode = 1;
  99. int SCREEN_X;
  100. int SCREEN_Y;
  101. int current_mode = GIT_SCREEN_MODE;
  102.  
  103. char cSection[]  = "[GIT-Color]";
  104. char bwSection[] = "[GIT-Monochrome]";
  105.  
  106. #ifdef HAVE_GCC
  107. char title[] = " "PRODUCT" "VERSION;
  108. #else
  109. char title[] = " GNU Interactive Tools 4.3.7";
  110. #endif /* !HAVE_GCC */
  111.  
  112. char login[] = "User:";
  113. char tty[] = "tty:";
  114.  
  115. char lock_think[] = "Wait, I am thinking...";
  116. char lock_ok[]    = "Wait, I am thinking... well, it looks good.";
  117. char lock_bad[]   = "Wait, I am thinking... well, lets try again.";
  118.  
  119. #ifdef HAVE_GCC
  120. char exit_msg[] = "Exit "PRODUCT" ? ";
  121. #else
  122. char exit_msg[] = "Exit GNU Interactive Tools ? ";
  123. #endif /* !HAVE_GCC */
  124.  
  125. char PS1[4] = " $ ";
  126. char *screen = NULL;
  127. panel_t *left_panel, *right_panel, *src_panel, *dest_panel, *temp_panel;
  128.  
  129. char *TempDirectory = "";
  130.  
  131. static char *NormalModeHelp      = "";
  132. static char *CommandLineModeHelp = "";
  133. static int  ConfirmOnExit;
  134.  
  135. /* Directory history stuff.  */
  136. char **dir_history;
  137. int dir_history_count;
  138. int dir_history_point;
  139.  
  140. #define BUILTIN_OPERATIONS                       73
  141.  
  142. #define BUILTIN_copy                            -1
  143. #define BUILTIN_move                            -2
  144. #define BUILTIN_make_directory                  -3
  145. #define BUILTIN_delete                          -4
  146. #define BUILTIN_exit                            -5
  147. #define BUILTIN_previous_history_element        -6
  148. #define BUILTIN_tty_mode                        -7
  149. #define BUILTIN_refresh                         -8
  150. #define BUILTIN_switch_panels                   -9
  151. #define BUILTIN_next_history_element            -10
  152. #define BUILTIN_panel_display_next_mode         -11
  153. #define BUILTIN_panel_display_owner_group       -12
  154. #define BUILTIN_panel_display_date_time         -13
  155. #define BUILTIN_panel_display_size              -14
  156. #define BUILTIN_panel_display_mode              -15
  157. #define BUILTIN_panel_display_full_name         -16
  158. #define BUILTIN_panel_sort_next_method          -17
  159. #define BUILTIN_panel_sort_by_name              -18
  160. #define BUILTIN_panel_sort_by_extension         -19
  161. #define BUILTIN_panel_sort_by_size              -20
  162. #define BUILTIN_panel_sort_by_date              -21
  163. #define BUILTIN_panel_sort_by_mode              -22
  164. #define BUILTIN_panel_sort_by_owner_id          -23
  165. #define BUILTIN_panel_sort_by_group_id          -24
  166. #define BUILTIN_panel_sort_by_owner_name        -25
  167. #define BUILTIN_panel_sort_by_group_name        -26
  168. #define BUILTIN_select_file                     -27
  169. #define BUILTIN_file_to_input_line              -28
  170. #define BUILTIN_beginning_of_panel              -29
  171. #define BUILTIN_end_of_panel                    -30
  172. #define BUILTIN_scroll_down                     -31
  173. #define BUILTIN_scroll_up                       -32
  174. #define BUILTIN_previous_line                   -33
  175. #define BUILTIN_next_line                       -34
  176. #define BUILTIN_other_panel                     -35
  177. #define BUILTIN_change_directory                -36
  178. #define BUILTIN_hard_refresh                    -37
  179. #define BUILTIN_select_files_matching_pattern   -38
  180. #define BUILTIN_unselect_files_matching_pattern -39
  181. #define BUILTIN_conform_current_directory       -40
  182. #define BUILTIN_conform_other_directory         -41
  183. #define BUILTIN_other_path_to_input_line        -42
  184. #define BUILTIN_selected_files_to_input_line    -43
  185. #define BUILTIN_backward_char                   -44
  186. #define BUILTIN_forward_char                    -45
  187. #define BUILTIN_backward_word                   -46
  188. #define BUILTIN_forward_word                    -47
  189. #define BUILTIN_beginning_of_line               -48
  190. #define BUILTIN_end_of_line                     -49
  191. #define BUILTIN_delete_char                     -50
  192. #define BUILTIN_backward_delete_char            -51
  193. #define BUILTIN_backward_kill_word              -52
  194. #define BUILTIN_kill_line                       -53
  195. #define BUILTIN_kill_to_beginning_of_line       -54
  196. #define BUILTIN_kill_to_end_of_line             -55
  197. #define BUILTIN_just_one_space                  -56
  198. #define BUILTIN_delete_horizontal_space         -57
  199. #define BUILTIN_action                          -58
  200. #define BUILTIN_set_mark                        -59
  201. #define BUILTIN_kill_region                     -60
  202. #define BUILTIN_kill_ring_save                  -61
  203. #define BUILTIN_yank                            -62
  204. #define BUILTIN_exchange_point_and_mark         -63
  205. #define BUILTIN_set_scroll_step                 -64
  206. #define BUILTIN_isearch_backward                -65
  207. #define BUILTIN_isearch_forward                 -66
  208. #define BUILTIN_previous_directory              -67
  209. #define BUILTIN_next_directory                  -68
  210. #define BUILTIN_reset_directory_history         -69
  211. #define BUILTIN_enlarge_panel                   -70
  212. #define BUILTIN_enlarge_other_panel             -71
  213. #define BUILTIN_two_panels                      -72
  214. #define BUILTIN_lock                            -73
  215.  
  216.  
  217. #define MAX_BUILTIN_NAME                         35
  218.  
  219.  
  220. char built_in[BUILTIN_OPERATIONS][MAX_BUILTIN_NAME] =
  221. {
  222.     "copy",
  223.     "move",
  224.     "make-directory",
  225.     "delete",
  226.     "exit",
  227.     "previous-history-element",
  228.     "tty-mode",
  229.     "refresh",
  230.     "switch-panels",
  231.     "next-history-element",
  232.     "panel-display-next-mode",
  233.     "panel-display-owner-group",
  234.     "panel-display-date-time",
  235.     "panel-display-size",
  236.     "panel-display-mode",
  237.     "panel-display-full-name",
  238.     "panel-sort-next-method",
  239.     "panel-sort-by-name",
  240.     "panel-sort-by-extension",
  241.     "panel-sort-by-size",
  242.     "panel-sort-by-date",
  243.     "panel-sort-by-mode",
  244.     "panel-sort-by-owner-id",
  245.     "panel-sort-by-group-id",
  246.     "panel-sort-by-owner-name", 
  247.     "panel-sort-by-group-name",
  248.     "select-file",
  249.     "file-to-input-line",
  250.     "beginning-of-panel",
  251.     "end-of-panel",
  252.     "scroll-down",
  253.     "scroll-up",
  254.     "previous-line",
  255.     "next-line",
  256.     "other-panel",
  257.     "change-directory",
  258.     "hard-refresh",
  259.     "select-files-matching-pattern",
  260.     "unselect-files-matching-pattern",
  261.     "conform-current-directory",
  262.     "conform-other-directory",
  263.     "other-path-to-input-line",
  264.     "selected-files-to-input-line",
  265.     "backward-char",
  266.     "forward-char",
  267.     "backward-word",
  268.     "forward-word",
  269.     "beginning-of-line",
  270.     "end-of-line",
  271.     "delete-char",
  272.     "backward-delete-char",
  273.     "backward-kill-word",
  274.     "kill-line",
  275.     "kill-to-beginning-of-line",
  276.     "kill-to-end-of-line",
  277.     "just-one-space",
  278.     "delete-horizontal-space",
  279.     "action",
  280.     "set-mark",
  281.     "kill-region",
  282.     "kill-ring-save",
  283.     "yank",
  284.     "exchange-point-and-mark",
  285.     "set-scroll-step",
  286.     "isearch-backward",
  287.     "isearch-forward",
  288.     "previous-directory",
  289.     "next-directory",
  290.     "reset-directory-history",
  291.     "enlarge-panel",
  292.     "enlarge-other-panel",
  293.     "two-panels",
  294.     "lock",
  295. };
  296.  
  297.  
  298. typedef struct
  299. {
  300.     char *name;         /* the command name.  */
  301.     char *body;         /* the unexpanded command body.  */
  302.     char *new_dir;      /* if exit code == 0, goto this directory.  */
  303.     char  save_screen;  /* save the screen contents (if possible).  */
  304.     char  pause;        /* wait for a key before restoring the panels.  */
  305.     char  hide;         /* hide the output, emulating a builtin command.  */
  306.     char  builtin;      /* this is a builtin command.  */
  307.     char *sequence;     /* the ascii representation of the key sequence on
  308.                            which the command is binded; used only for error
  309.                            reporting purposes.  */
  310.     xstack_t *history;  /* the history of the strings used to expand the
  311.                            command body.  */
  312. } command_t;
  313.  
  314.  
  315. #define MAX_KEYS        2048      /* enough ?   :-) */
  316. #define KEYSDATA_FIELDS    8
  317.  
  318.  
  319. #define TITLE_FIELDS    8
  320.  
  321. static char *TitleFields[TITLE_FIELDS] =
  322. {
  323.     "TitleForeground",
  324.     "TitleBackground",
  325.     "TitleBrightness",
  326.     "UserName",
  327.     "TtyName",
  328.     "ClockForeground",
  329.     "ClockBackground",
  330.     "ClockBrightness"
  331. };
  332.  
  333. #ifdef HAVE_LINUX
  334. static int TitleColors[TITLE_FIELDS] = 
  335. {
  336.     CYAN, BLUE, ON, YELLOW, YELLOW, BLACK, CYAN, OFF
  337. };
  338. #else   /* !HAVE_LINUX */
  339. static int TitleColors[TITLE_FIELDS] = 
  340. {
  341.     WHITE, BLACK, ON, WHITE, WHITE, BLACK, WHITE, OFF
  342. };
  343. #endif  /* !HAVE_LINUX */
  344.  
  345. #define TitleForeground TitleColors[0]
  346. #define TitleBackground TitleColors[1]
  347. #define TitleBrightness TitleColors[2]
  348. #define UserName        TitleColors[3]
  349. #define TtyName         TitleColors[4]
  350. #define ClockForeground TitleColors[5]
  351. #define ClockBackground TitleColors[6]
  352. #define ClockBrightness TitleColors[7]
  353.  
  354.  
  355.  
  356. /*****************************************/
  357. /* The GIT interface to the input line.  */
  358. /*****************************************/
  359.  
  360. #define IL_ISEARCH_BEGIN        0
  361. #define IL_ISEARCH_BACKWARD     1
  362. #define IL_ISEARCH_FORWARD      2
  363. #define IL_ISEARCH_END          3
  364.  
  365.  
  366. int   il_dispatch_commands __P((int, int));
  367. char *il_fix_text __P((char *));
  368. char *il_build_help_from_string __P((char *));
  369. char *il_isearch __P((char *, char **, int, int *));
  370. char  il_read_char __P((char *, char *, int));
  371. char *il_read_line __P((char *, char **, char *, xstack_t *));
  372.  
  373.  
  374. /* Adds a string to the history.  */
  375.  
  376. void
  377. il_history_add_entry(history, text)
  378.     xstack_t *history;
  379.     char *text;
  380. {
  381.     char *history_text;
  382.  
  383.     /* Avoid duplicates.  */
  384.     if (xstack_preview(history, &history_text, 1) &&
  385.         strcmp(history_text, text) == 0)
  386.         return;
  387.  
  388.     history_text = xstrdup(text);
  389.     xstack_push(history, &history_text);
  390. }
  391.  
  392.  
  393. /* Preview a history string.  */
  394.  
  395. char *
  396. il_history_view_entry(history, offset)
  397.     xstack_t *history;
  398.     int offset;
  399. {
  400.     char *history_text;
  401.  
  402.     return xstack_preview(history, &history_text, offset) ? history_text : NULL;
  403. }
  404.  
  405.  
  406. /* Dispatch input line commands. key is the actual command while flags is
  407.    a set of IL_*s or-ed together, allowing us to customize the  behaviour
  408.    of the input line.  If IL_MOVE is not specified, the  IL_EDIT  flag is
  409.    ignored.  Returns 1 if key has been processed and 0 otherwise.  */
  410.  
  411. int
  412. il_dispatch_commands(key, flags)
  413.     int key;
  414.     int flags;
  415. {
  416.     if ((flags & IL_MOVE) == 0)
  417.         return 0;
  418.  
  419.     switch (key)
  420.     {
  421.         case BUILTIN_backward_char:
  422.             il_backward_char();
  423.             break;
  424.  
  425.         case BUILTIN_forward_char:
  426.             il_forward_char();
  427.             break;
  428.  
  429.         case BUILTIN_backward_word:
  430.             il_backward_word();
  431.             break;
  432.  
  433.         case BUILTIN_forward_word:
  434.             il_forward_word();
  435.             break;
  436.  
  437.         case BUILTIN_beginning_of_line:
  438.             il_beginning_of_line();
  439.             break;
  440.  
  441.         case BUILTIN_end_of_line:
  442.             il_end_of_line();
  443.             break;
  444.  
  445.         case BUILTIN_delete_char:
  446.             if (flags & IL_EDIT)
  447.                 il_delete_char();
  448.             break;
  449.  
  450.         case BUILTIN_backward_delete_char:
  451.             if (flags & IL_EDIT)
  452.                 il_backward_delete_char();
  453.             break;
  454.  
  455.         case BUILTIN_backward_kill_word:
  456.             if (flags & IL_EDIT)
  457.                 il_backward_kill_word();
  458.             break;
  459.  
  460.         case BUILTIN_kill_line:
  461.             if (flags & IL_EDIT)
  462.                 il_kill_line(IL_STORE);
  463.             break;
  464.  
  465.         case BUILTIN_kill_to_beginning_of_line:
  466.             if (flags & IL_EDIT)
  467.                 il_kill_to_beginning_of_line();
  468.             break;
  469.  
  470.         case BUILTIN_kill_to_end_of_line:
  471.             if (flags & IL_EDIT)
  472.                 il_kill_to_end_of_line();
  473.             break;
  474.  
  475.         case BUILTIN_just_one_space:
  476.             if (flags & IL_EDIT)
  477.                 il_just_one_space();
  478.             break;
  479.  
  480.         case BUILTIN_delete_horizontal_space:
  481.             if (flags & IL_EDIT)
  482.                 il_delete_horizontal_space();
  483.             break;
  484.  
  485.         case BUILTIN_set_mark:
  486.             il_set_mark();
  487.             break;
  488.  
  489.         case BUILTIN_kill_region:
  490.             if (flags & IL_EDIT)
  491.                 il_kill_region();
  492.             break;
  493.  
  494.         case BUILTIN_kill_ring_save:
  495.             il_kill_ring_save();
  496.             break;
  497.  
  498.         case BUILTIN_yank:
  499.             if (flags & IL_EDIT)
  500.                 il_yank();
  501.             break;
  502.  
  503.         case BUILTIN_exchange_point_and_mark:
  504.             il_exchange_point_and_mark();
  505.             break;
  506.  
  507.         default:
  508.             if ((flags & IL_EDIT) && is_print(key))
  509.                 il_insert_char(key);
  510.             else
  511.                 return 0;
  512.             break;
  513.     }
  514.  
  515.     return 1;
  516. }
  517.  
  518.  
  519. /* Fix the text.  Replace non-printable characters with spaces and expand
  520.    tabs.  Return a malloc-ed pointer to the fixed text.  The caller should
  521.    free the new text.  */
  522.  
  523. char *
  524. il_fix_text(text)
  525.    char *text;
  526. {
  527.     int i, j;
  528.     char *fixed_text;
  529.     size_t fixed_text_length;
  530.  
  531.  
  532.     if (text == NULL)
  533.         return NULL;
  534.  
  535.     fixed_text = xmalloc(fixed_text_length = (strlen(text) + 1));
  536.  
  537.     for (i = 0, j = 0; text[i]; i++)
  538.         if (text[i] == '\t')
  539.         {
  540.             fixed_text = xrealloc(fixed_text, fixed_text_length += 8);
  541.             memcpy(&fixed_text[j], "        ", 8);
  542.             j += 8;
  543.         }
  544.         else
  545.             if (is_print(text[i]))
  546.                 fixed_text[j++] = text[i];
  547.             else
  548.                 fixed_text[j++] = ' ';
  549.  
  550.     fixed_text[j] = 0;
  551.  
  552.     return fixed_text;
  553. }
  554.  
  555.  
  556. char *
  557. il_build_help_from_string(char *options)
  558. {
  559.     size_t len = 0;
  560.     char *options_ptr = options;
  561.     char *help = xmalloc(1 + strlen(options) * 3 + 8);
  562.  
  563.     help[len++] = '(';
  564.  
  565.     for (; *(options_ptr + 1); options_ptr++)
  566.     {
  567.         help[len++] = *options_ptr;
  568.         help[len++] = ',';
  569.         help[len++] = ' ';
  570.     }
  571.     
  572.     help[len++] = *options_ptr;
  573.     help[len++] = ')';
  574.     help[len++] = ' ';
  575.     help[len++] = '\0';
  576.  
  577.     return help;
  578. }
  579.  
  580.  
  581. /* Read only one char from the input line.  message is a string explaining
  582.    what is this all about.  options is a string containing only those
  583.    characters that are valid answers, NULL if any character is a valid
  584.    answer.  The default char is the first char in the options string.
  585.    Returns 0 if it was interrupted, a valid character otherwise.  */
  586.  
  587. char
  588. il_read_char(message, options, flags)
  589.     char *message;
  590.     char *options;
  591.     int flags;
  592. {
  593.     char *help;
  594.     tty_key_t *ks;
  595.     int key, repeat_count;
  596.     command_t *command;
  597.     input_line_t *saved_il = NULL;
  598.  
  599.     if (flags & IL_SAVE)
  600.         saved_il = il_save();
  601.  
  602.     il_reset_line();
  603.  
  604.     if (message)
  605.     {
  606.         char *text = il_fix_text(message);
  607.  
  608.         if (flags & IL_ERROR)
  609.         {
  610.             il_insert_text("*** ");
  611.             il_set_error_flag(1);
  612.         }
  613.  
  614.         il_insert_text(text);
  615.  
  616.         xfree(text);
  617.  
  618.         if (options)
  619.         {
  620.             help = il_build_help_from_string(options);
  621.             il_insert_text(help);
  622.             xfree(help);
  623.         }
  624.     }
  625.  
  626.     il_full_update();
  627.  
  628.     if (flags & IL_BEEP)
  629.         tty_beep();
  630.  
  631.     while (1)
  632.     {
  633.         ks  = tty_get_key(&repeat_count);
  634.         key = ks->key_seq[0];
  635.  
  636.         command = (command_t *)ks->aux_data;
  637.  
  638.         if (command && command->builtin)
  639.             key = - 1 - (command->name - built_in[0]) / MAX_BUILTIN_NAME;
  640.  
  641.         switch (key)
  642.         {
  643.             case BUILTIN_action:
  644.                 if (options != NULL)
  645.                     key = *options;
  646.  
  647.             case key_INTERRUPT:
  648.                 goto done;
  649.  
  650.             default:
  651.                 while (repeat_count--)
  652.                     if (il_dispatch_commands(key, flags) == 0)
  653.                         goto il_error;
  654.  
  655.                 il_update();
  656.                 break;
  657.  
  658.               il_error:
  659.  
  660.                 if (options == NULL)
  661.                     goto done;
  662.  
  663.                 if (options && strchr(options, key))
  664.                         goto done;
  665.  
  666.                 tty_beep();
  667.                 break;
  668.         }
  669.  
  670.         il_update_point();
  671.     }
  672.  
  673.   done:
  674.  
  675.     il_set_error_flag(0);
  676.  
  677.     if ((flags & IL_SAVE) && saved_il)
  678.     {
  679.         il_restore(saved_il);
  680.         il_full_update();
  681.     }
  682.  
  683.     return (key == key_INTERRUPT) ? 0 : key;
  684. }
  685.  
  686.  
  687. /* WARNING: dest *must* be a pointer to a NULL pointer or a pointer to a
  688.    pointer allocated with xmalloc.  In  the  first case,  il_read_line()
  689.    will return a string allocated with xmalloc(). In the second case, it
  690.    will reallocate the pointer as needed using xrealloc. You should free
  691.    this pointer yourself.  */
  692.  
  693. char *
  694. il_read_line(static_text, dest, default_string, history)
  695.     char *static_text;
  696.     char **dest;
  697.     char *default_string;
  698.     xstack_t *history;
  699. {
  700.     tty_key_t *ks;
  701.     char *history_text;
  702.     command_t *command;
  703.     int key, repeat_count, offset = 0;
  704.  
  705.  
  706.     il_reset_line();
  707.  
  708.     if (static_text)
  709.         il_set_static_text(static_text);
  710.  
  711.     if (default_string)
  712.         il_insert_text(default_string);
  713.  
  714.     il_full_update();
  715.  
  716.     while (1)
  717.     {
  718.         ks  = tty_get_key(&repeat_count);
  719.         key = ks->key_seq[0];
  720.  
  721.         command = (command_t *)ks->aux_data;
  722.  
  723.         if (command && command->builtin)
  724.             key = - 1 - (command->name - built_in[0]) / MAX_BUILTIN_NAME;
  725.  
  726.         switch (key)
  727.         {
  728.             case BUILTIN_previous_line:
  729.             case BUILTIN_previous_history_element:
  730.                 if (history == NULL)
  731.                     break;
  732.  
  733.                 history_text = il_history_view_entry(history, ++offset);
  734.  
  735.                 if (history_text == NULL)
  736.                 {
  737.                     offset--;
  738.                     tty_beep();
  739.                 }
  740.                 else
  741.                 {
  742.                     il_kill_line(IL_DONT_STORE);
  743.                     il_insert_text(history_text);
  744.                     il_full_update();
  745.                 }
  746.                 break;
  747.  
  748.             case BUILTIN_next_line:
  749.             case BUILTIN_next_history_element:
  750.                 if (history == NULL)
  751.                     break;
  752.  
  753.                 if (offset == 0)
  754.                 {
  755.                     il_kill_line(IL_DONT_STORE);
  756.                     il_full_update();
  757.                     break;
  758.                 }
  759.  
  760.                 il_kill_line(IL_DONT_STORE);
  761.  
  762.                 offset--;
  763.  
  764.                 if (offset > 0)
  765.                 {
  766.                     history_text = il_history_view_entry(history, offset);
  767.                     il_insert_text(history_text);
  768.                 }
  769.  
  770.                 il_full_update();
  771.                 break;
  772.  
  773.             case BUILTIN_action:
  774.                 il_get_contents(dest);
  775.  
  776.             case key_INTERRUPT:
  777.                 goto done;
  778.  
  779.             default:
  780.                 while (repeat_count--)
  781.                     if (il_dispatch_commands(key, IL_MOVE | IL_EDIT) == 0)
  782.                     {
  783.                         tty_beep();
  784.                         break;
  785.                     }
  786.  
  787.                 il_update();
  788.                 break;
  789.         }
  790.  
  791.         il_update_point();
  792.     }
  793.  
  794.   done:
  795.  
  796.     if (key == BUILTIN_action)
  797.     {
  798.         if (history)
  799.             il_history_add_entry(history, *dest);
  800.         return *dest;
  801.     }
  802.     else
  803.         return NULL;
  804. }
  805.  
  806.  
  807. /* status = IL_ISEARCH_BEGIN    -> we are beginning to isearch; initialize
  808.    status = IL_ISEARCH_BACKWARD -> we are in the middle of an isearch-backward
  809.    status = IL_ISEARCH_FORWARD  -> we are in the middle of an isearch-forward
  810.    status = IL_ISEARCH_END      -> isearch complete; clean up
  811.  
  812.    *action = IL_ISEARCH_ACTION_DECREASE -> the user pressed the backspace key
  813.                                            so if there is no matching element
  814.                                            in the panel stack, we should delete
  815.                                            the last character in the input line
  816.    *action = IL_ISEARCH_ACTION_RETRY    -> the user pressed the isearch-forward
  817.                                            character again, so we should try to
  818.                                            find a new match for the current
  819.                                            string
  820.    *action = IL_ISEARCH_ACTION_INCREASE -> a new character has been inserted
  821.                                            into the input line so we should try
  822.                                            to find a match for the new string
  823.  */
  824.  
  825. char *
  826. il_isearch(static_text, dest, status, action)
  827.     char *static_text;
  828.     char **dest;
  829.     int status;
  830.     int *action;
  831. {
  832.     int key;
  833.     tty_key_t *ks;
  834.     static input_line_t *saved_il;
  835.     command_t *command;
  836.  
  837.  
  838.     if (status == IL_ISEARCH_BEGIN)
  839.     {
  840.         saved_il = il_save();
  841.         il_reset_line();
  842.  
  843.         if (static_text)
  844.             il_set_static_text(static_text);
  845.  
  846.         return NULL;
  847.     }
  848.  
  849.     if (status == IL_ISEARCH_END)
  850.     {
  851.         il_restore(saved_il);
  852.         il_full_update();
  853.         return NULL;
  854.     }
  855.  
  856.     if (action == NULL)
  857.         return NULL;
  858.  
  859.     *action = IL_ISEARCH_ACTION_NONE;
  860.  
  861.     il_full_update();
  862.  
  863.     ks  = tty_get_key(NULL);
  864.     key = ks->key_seq[0];
  865.  
  866.     command = (command_t *)ks->aux_data;
  867.  
  868.     if (command && command->builtin)
  869.         key = - 1 - (command->name - built_in[0]) / MAX_BUILTIN_NAME;
  870.  
  871.     switch (key)
  872.     {
  873.         case BUILTIN_action:
  874.         case key_INTERRUPT:
  875.             break;
  876.  
  877.         case BUILTIN_backward_delete_char:
  878.             /* If the input line is empty, just beep.  */
  879.             if (il_is_empty())
  880.                 tty_beep();
  881.             else
  882.             {
  883.                 *action = IL_ISEARCH_ACTION_DECREASE;
  884.                 /* Don't call il_backward_delete_char().  There might be
  885.                    several history elements in the panel stack that match
  886.                    the current string so we have to delay the call to
  887.                    il_backward_delete_char() until all the matching elements
  888.                    have been pop-ed.  */
  889.             }
  890.  
  891.             break;
  892.  
  893.         default:
  894.             if ((key == BUILTIN_isearch_backward &&
  895.                  status == IL_ISEARCH_BACKWARD)         ||
  896.                 (key == BUILTIN_isearch_forward  &&
  897.                  status == IL_ISEARCH_FORWARD))
  898.             {
  899.                 if (!il_is_empty())
  900.                 {
  901.                     *action = IL_ISEARCH_ACTION_RETRY;
  902.                     break;
  903.                 }
  904.             }           
  905.  
  906.             if (is_print(key))
  907.             {
  908.                 il_insert_char(key);
  909.                 *action = IL_ISEARCH_ACTION_INCREASE;
  910.             }
  911.             else
  912.                 key = key_INTERRUPT;    /* Force a NULL return value.  */
  913.             break;
  914.     }
  915.  
  916.     il_full_update();
  917.     il_get_contents(dest);
  918.  
  919.     return (key == BUILTIN_action || key == key_INTERRUPT) ? NULL : *dest;
  920. }
  921.  
  922.  
  923. /****************************************/
  924. /* The directory history function set.  */
  925. /****************************************/
  926.  
  927.  
  928. void
  929. dir_history_reset()
  930. {
  931.     if (dir_history)
  932.     {
  933.         int i;
  934.  
  935.         for (i = 0; i < dir_history_count; i++)
  936.             xfree(dir_history[i]);
  937.  
  938.         xfree(dir_history);
  939.         dir_history = NULL;
  940.     }
  941.  
  942.     dir_history_count = 0;
  943.     dir_history_point = 0;
  944. }
  945.  
  946.  
  947. void
  948. dir_history_add(directory)
  949.     char *directory;
  950. {
  951.     dir_history_point = dir_history_count;
  952.  
  953.     dir_history = (char **)xrealloc(dir_history, ++dir_history_count *
  954.                                                  sizeof(char *));
  955.  
  956.     dir_history[dir_history_point] = xstrdup(directory);
  957. }
  958.  
  959.  
  960. void
  961. dir_history_next(this, link)
  962.     panel_t *this;
  963.     panel_t *link;
  964. {
  965.     if (dir_history_point < dir_history_count - 1)
  966.         panel_action(this, act_CHDIR, link,
  967.                      dir_history[++dir_history_point], 1);
  968.     else
  969.         tty_beep();
  970. }
  971.  
  972.  
  973. void
  974. dir_history_prev(this, link)
  975.     panel_t *this;
  976.     panel_t *link;
  977. {
  978.     if (dir_history_point)
  979.         panel_action(this, act_CHDIR, link,
  980.                      dir_history[--dir_history_point], 1);
  981.     else
  982.         tty_beep();
  983. }
  984.  
  985.  
  986. void
  987. clean_up()
  988. {
  989.     tty_exit();
  990.  
  991.     /* It is better not to do this here.  It can lead to an endless loop
  992.        if xmalloc fails in write_history because xmalloc will call fatal
  993.        and fatal will call clean_up again...  */
  994. #if 0
  995.     if (il)
  996.         il_end();
  997. #endif
  998.  
  999.     status_end();
  1000.     removelog();
  1001. }
  1002.  
  1003.  
  1004. void
  1005. fatal(postmsg)
  1006.     char *postmsg;
  1007. {
  1008.     clean_up();
  1009.     fprintf(stderr, "%s: fatal error: %s.\n", program, postmsg);
  1010.     exit(1);
  1011. }
  1012.  
  1013.  
  1014. void
  1015. settitle()
  1016. {
  1017.     char *buf;
  1018.     size_t len;
  1019.     tty_status_t status;
  1020.     window_t *title_win = window_init(0, 0, 1, SCREEN_X);
  1021.  
  1022.     tty_save(&status);
  1023.     tty_cursor(OFF);
  1024.  
  1025.     tty_colors(TitleBrightness, TitleForeground, TitleBackground);
  1026.  
  1027.     window_cursormove_notify(title_win, 0, 0);
  1028.     window_write(title, strlen(title));
  1029.  
  1030.     buf = xmalloc(SCREEN_X + 1);
  1031.  
  1032.     len = (sizeof(login) - 1) + 1 + login_name_len + 2 +
  1033.           (sizeof(tty)   - 1) + 1 + tty_name_len;
  1034.  
  1035.     memset(buf, ' ', len = SCREEN_X - strlen(title) - len - 2 - 6 - 1);
  1036.     window_cursormove_notify(title_win, 0, strlen(title));
  1037.     window_write(buf, len);
  1038.  
  1039.     xfree(buf);
  1040.  
  1041.     window_cursormove_notify(title_win, 0, strlen(title) + len);
  1042.     window_write(login, sizeof(login) - 1);
  1043.     window_putch(' ');
  1044.     tty_foreground(UserName);
  1045.     window_write(login_name, login_name_len);
  1046.     window_putch(' ');
  1047.     window_putch(' ');
  1048.     tty_foreground(TitleForeground);
  1049.     window_write(tty, sizeof(tty) - 1);
  1050.     window_putch(' ');
  1051.     tty_foreground(TtyName);
  1052.     window_write(tty_name, tty_name_len);
  1053.  
  1054.     tty_foreground(TitleForeground);
  1055.     window_putch(' ');
  1056.     window_putch(' ');
  1057.     window_cursormove_notify(title_win, 0, SCREEN_X - 1);
  1058.     window_putch(' ');
  1059.     
  1060.     tty_restore(&status);
  1061. }
  1062.  
  1063.  
  1064. void
  1065. gitclock_validate()
  1066. {
  1067.     xtimer_set_flags(gitclock_xtimer, XT_YES);
  1068. }
  1069.  
  1070.  
  1071. void
  1072. gitclock_invalidate()
  1073. {
  1074.     xtimer_set_flags(gitclock_xtimer, XT_NO);
  1075. }
  1076.  
  1077.  
  1078. void
  1079. gitclock(xtimerp, signum)
  1080.     xtimer_t *xtimerp;
  1081.     int signum;
  1082. {
  1083.     int hour;
  1084.     char buf[16];
  1085.     struct tm *time;    /* The broken-down time representation.  */
  1086.     tty_status_t status;
  1087.  
  1088.     time = get_local_time();
  1089.  
  1090.     tty_save(&status);
  1091.     tty_cursor(OFF);
  1092.  
  1093.     if ((hour = time->tm_hour % 12) == 0)
  1094.         hour = 12;
  1095.  
  1096.     sprintf(buf, "%2d:%02d%c", hour, time->tm_min,
  1097.             (time->tm_hour < 12) ? 'a' : 'p');
  1098.     tty_cursormove_notify(0, SCREEN_X - 7);
  1099.  
  1100.     tty_colors(ClockBrightness, ClockForeground, ClockBackground);
  1101.  
  1102.     tty_write(buf, strlen(buf));
  1103.     tty_restore(&status);
  1104.  
  1105.     /* Don't update the input_line point if not called within interrupt.  */
  1106.     if (xtimerp && signum)
  1107.         il_update_point();
  1108. }
  1109.  
  1110.  
  1111. /* This function is a mess. Don't try to understand what it does ... :-(
  1112.    It basically expands a configuration line macros.  The return value is
  1113.    0 on error, -1 if some condition failed (the command contains a %d but
  1114.    the current entry is not a directory), 1 if everything is ok, 2 if the
  1115.    command was correctly expanded and it contains a '%i' and 3 if it
  1116.    contains a '%I'.  */
  1117.  
  1118. int
  1119. command_expand(command, dest, p, l)
  1120.     command_t *command;
  1121.     char **dest;
  1122.     panel_t *p, *l;
  1123. {
  1124.     char c;
  1125.     uid_t uid;
  1126.     gid_t gid;
  1127.     panel_t *t;
  1128.     int retval;
  1129.     size_t len;
  1130.     struct group *grp;
  1131.     struct passwd *pwd;
  1132.     static int busy = 0;
  1133.     char *answer = NULL;
  1134.     char *question = NULL;
  1135.     int i_flag = 0, entry;
  1136.     size_t oldtmplen, tmplen;
  1137.     char *ptr, *tmp = NULL, *d, *flag;
  1138.     char *src = command->body, *save_body;
  1139.  
  1140.  
  1141.     d = *dest = xmalloc(len = (strlen(src) + 1));
  1142.  
  1143.     while (*src)
  1144.     {
  1145.         if (*src != '%')
  1146.             *d++ = *src++;
  1147.         else
  1148.         {
  1149.             t = islower(*++src) ? p : l;
  1150.  
  1151.             switch (*src)
  1152.             {
  1153.                 case '?':
  1154.  
  1155.                     if (busy)
  1156.                     {
  1157.                         busy = 0;
  1158.                         goto bad_command;
  1159.                     }
  1160.  
  1161.                     if (*++src != '{')
  1162.                         goto bad_command;
  1163.  
  1164.                     if ((ptr = strchr(++src, '}')) == NULL)
  1165.                         goto bad_command;
  1166.  
  1167.                     *ptr = 0;
  1168.                      c = il_read_char(src, "yn", IL_MOVE);
  1169.                     *ptr = '}';
  1170.  
  1171.                     if (c != 'y')
  1172.                         goto strings_dont_match;
  1173.  
  1174.                     src = ptr;
  1175.                     
  1176.                     break;
  1177.                     
  1178.                 case 's':
  1179.  
  1180.                     if (busy)
  1181.                     {
  1182.                         busy = 0;
  1183.                         goto bad_command;
  1184.                     }
  1185.  
  1186.                     if (*++src != '{')
  1187.                         goto bad_command;
  1188.                     
  1189.                     if ((ptr = strchr(++src, ',')) == NULL)
  1190.                         goto bad_command;
  1191.                     
  1192.                     *ptr = 0;
  1193.                     busy = 1;
  1194.  
  1195.                     save_body = command->body;
  1196.                     command->body = src;
  1197.                     retval = command_expand(command, &answer, p, l);
  1198.                     command->body = save_body;
  1199.  
  1200.                     busy = 0;
  1201.  
  1202.                     if (retval < 1)
  1203.                         if (retval == 0)
  1204.                             goto bad_command;
  1205.                         else
  1206.                             goto strings_dont_match;
  1207.  
  1208.                     question = xmalloc(16 + strlen(command->name) +
  1209.                                        strlen(answer) + 1);
  1210.                     sprintf(question, "%s: %s", command->name, answer);
  1211.                     xfree(answer);
  1212.                     answer =  NULL;
  1213.                     *ptr++ = ',';
  1214.  
  1215.                     if ((src = strchr(ptr, '}')) == NULL)
  1216.                         goto bad_command;
  1217.                     
  1218.                     *src = 0;
  1219.  
  1220.                     if (strlen(question) > MAX_STATIC_SIZE)
  1221.                         question[MAX_STATIC_SIZE] = 0;
  1222.  
  1223.                     busy = 1;
  1224.  
  1225.                     save_body = command->body;
  1226.                     command->body = ptr;
  1227.                     retval = command_expand(command, &answer, p, l);
  1228.                     command->body = save_body;
  1229.  
  1230.                     busy = 0;
  1231.  
  1232.                     if (retval < 1)
  1233.                     {
  1234.                         *src = '}';
  1235.                         xfree(question);
  1236.                         question = NULL;
  1237.                         if (retval == 0)
  1238.                             goto bad_command;
  1239.                         goto strings_dont_match;
  1240.                     }
  1241.  
  1242.                     flag = il_read_line(question, &tmp, answer,
  1243.                                         command->history);
  1244.  
  1245.                     xfree(question);
  1246.                     xfree(answer);
  1247.                     question = answer = NULL;
  1248.  
  1249.                     if (flag == NULL)
  1250.                     {
  1251.                         *src = '}';
  1252.                         goto strings_dont_match;
  1253.                     }
  1254.  
  1255.                     *src = '}';
  1256.                     break;
  1257.  
  1258.                 case 'f':
  1259.                 case 'F':
  1260.  
  1261.                     if (panel_get_current_file_type(t) != FILE_ENTRY)
  1262.                         goto strings_dont_match;
  1263.  
  1264.                   get_file_name:
  1265.  
  1266.                     ptr = panel_get_current_file_name(t);
  1267.                     tmp = xmalloc(1 + strlen(ptr) + 1 + 1);
  1268.                     sprintf(tmp, "\"%s\"", ptr);
  1269.                     break;
  1270.  
  1271.                 case 'd':
  1272.                 case 'D':
  1273.  
  1274.                     if (panel_get_current_file_type(t) != DIR_ENTRY)
  1275.                         goto strings_dont_match;
  1276.                     goto get_file_name;
  1277.  
  1278.                 case 'l':
  1279.                 case 'L':
  1280.  
  1281.                     if (panel_get_current_file_type(t) != SYMLINK_ENTRY)
  1282.                         goto strings_dont_match;
  1283.                     goto get_file_name;
  1284.  
  1285.                 case 't':
  1286.                 case 'T':
  1287.  
  1288.                     if (panel_get_current_file_type(t) != FIFO_ENTRY)
  1289.                         goto strings_dont_match;
  1290.                     goto get_file_name;
  1291.  
  1292.                 case 'z':
  1293.                 case 'Z':
  1294.  
  1295.                     if (panel_get_current_file_type(t) != SOCKET_ENTRY)
  1296.                         goto strings_dont_match;
  1297.                     goto get_file_name;
  1298.  
  1299.                 case 'a':
  1300.                 case 'A':
  1301.  
  1302.                     goto get_file_name;
  1303.  
  1304.                 case 'm':
  1305.                 case 'M':
  1306.  
  1307.                     tmp = xmalloc(16);
  1308.                     sprintf(tmp, "%o",
  1309.                             (int)panel_get_current_file_mode(t) & 07777);
  1310.                     break;
  1311.  
  1312.                 case 'o':
  1313.                 case 'O':
  1314.  
  1315.                     uid = panel_get_current_file_uid(t);
  1316.                     pwd = getpwuid(uid);
  1317.  
  1318.                     if (pwd)
  1319.                         tmp = xstrdup(pwd->pw_name);
  1320.                     else
  1321.                     {
  1322.                         tmp = xmalloc(16);
  1323.                         sprintf(tmp, "%o", (int)uid);
  1324.                     }
  1325.  
  1326.                     break;
  1327.  
  1328.                 case 'g':
  1329.                 case 'G':
  1330.  
  1331.                     gid = panel_get_current_file_gid(t);
  1332.                     grp = getgrgid(gid);
  1333.  
  1334.                     if (grp)
  1335.                         tmp = xstrdup(grp->gr_name);
  1336.                     else
  1337.                     {
  1338.                         tmp = xmalloc(16);
  1339.                         sprintf(tmp, "%o", (int)gid);
  1340.                     }
  1341.  
  1342.                     break;
  1343.  
  1344.                 case 'p':
  1345.                 case 'P':
  1346.  
  1347.                     tmp = xmalloc(1 + strlen(t->path) + 1 + 1);
  1348.                     sprintf(tmp, "\"%s\"", t->path);
  1349.                     break;
  1350.  
  1351.                 case 'b':
  1352.                 case 'B':
  1353.  
  1354.                     ptr = strrchr(t->path, '/');
  1355.                     ptr = (*++ptr) ? ptr : "/root";
  1356.                     tmp = xmalloc(1 + strlen(ptr) + 1 + 1);
  1357.                     sprintf(tmp, "\"%s\"", ptr);
  1358.                     break;
  1359.  
  1360.                 case 'i':
  1361.                 case 'I':
  1362.  
  1363.                     i_flag = (*src == 'i') ? 1 : 2;
  1364.  
  1365.                     if (busy && t->selected_files)
  1366.                     {
  1367.                         tmplen = 20;
  1368.                         tmp = xmalloc(tmplen + 1);
  1369.                         strcpy(tmp, "selected file(s)");
  1370.                         break;
  1371.                     }
  1372.  
  1373.                     tmp = NULL;
  1374.                     tmplen = 0;
  1375.  
  1376.                     panel_init_iterator(t);
  1377.  
  1378.                     while ((entry = panel_get_next(t)) != -1)
  1379.                     {
  1380.                         oldtmplen = tmplen;
  1381.                         tmplen += 1 + strlen(t->dir_entry[entry].name) + 1 + 1;
  1382.                         tmp = xrealloc(tmp, tmplen + 1);
  1383.                         tmp[oldtmplen] = '"';
  1384.                         strcpy(tmp + oldtmplen + 1, t->dir_entry[entry].name);
  1385.                         tmp[tmplen - 2] = '"';
  1386.                         tmp[tmplen - 1] = ' ';
  1387.                         tmp[tmplen    ] = 0;
  1388.                     }
  1389.  
  1390.                     break;
  1391.  
  1392.                 default :
  1393.  
  1394.                     goto bad_command;
  1395.             }
  1396.             
  1397.             src++;
  1398.             *d = 0;
  1399.             
  1400.             if (tmp)
  1401.             {
  1402.                 *dest = xrealloc(*dest, len += strlen(tmp));
  1403.                 strcat(*dest, tmp);
  1404.                 d = *dest + strlen(*dest);
  1405.                 xfree(tmp);
  1406.                 tmp = NULL;
  1407.             }
  1408.         }
  1409.     }
  1410.  
  1411.     *d = 0;
  1412.     return 1 + i_flag;
  1413.  
  1414.   bad_command:
  1415.  
  1416.     xfree(*dest);
  1417.     *dest = NULL;
  1418.     return 0;
  1419.  
  1420.   strings_dont_match:
  1421.  
  1422.     if (tmp)
  1423.         xfree(tmp);
  1424.  
  1425.     *dest = NULL;
  1426.     return -1;
  1427. }
  1428.  
  1429.  
  1430. void
  1431. refresh_after_suspend(mode)
  1432.     int mode;
  1433. {
  1434.     char *cmdln = NULL;
  1435.     char PWD[MAX_STATIC_SIZE + 1];
  1436.  
  1437.     if (mode == GIT_SCREEN_MODE)
  1438.     {
  1439.         /* switch back to noncanonical mode. */
  1440.         tty_set_mode(TTY_NONCANONIC);
  1441.  
  1442.         settitle();
  1443.         gitclock(NULL, 0);
  1444.  
  1445.         status(NULL, 0, 0, 1, MSG_OK, MSG_CENTERED);
  1446.  
  1447.         panel_no_optimizations(src_panel);
  1448.         panel_no_optimizations(dest_panel);
  1449.         panel_action(src_panel, act_REFRESH, dest_panel, (void *)-1, 1);
  1450.         panel_action(dest_panel, act_REFRESH, src_panel, (void *)-1, 1);
  1451.  
  1452.         panel_set_focus(src_panel, ON);
  1453.  
  1454.         il_get_contents(&cmdln);
  1455.         il_reset_line();
  1456.         il_set_static_text(strcat(
  1457.                                 truncate_string(panel_get_path(src_panel),
  1458.                                                 PWD, MAX_STATIC_SIZE),
  1459.                                   PS1));
  1460.         il_insert_text(cmdln);
  1461.         il_full_update();
  1462.  
  1463.         signals(SIG_ON);
  1464.     }
  1465.     else
  1466.     {
  1467.         /* switch back to noncanonical mode. */
  1468.         tty_set_mode(TTY_NONCANONIC);
  1469.  
  1470.         panel_no_optimizations(src_panel);
  1471.         panel_no_optimizations(dest_panel);
  1472.         tty_put_screen(screen);
  1473.         status(CommandLineModeHelp, 0, 0, 0, MSG_OK, MSG_CENTERED);
  1474.         il_full_update();
  1475.     }
  1476. }
  1477.  
  1478.  
  1479. void
  1480. add_to_environment(variable, alternate_variable, value)
  1481.     char *variable, *alternate_variable, *value;
  1482. {
  1483.     int result;
  1484.     char *alternate_value, *environment_string;
  1485.  
  1486.     if (getenv(variable) == NULL)
  1487.     {
  1488.         if (alternate_variable && (alternate_value=getenv(alternate_variable)))
  1489.         {
  1490. #ifdef HAVE_PUTENV
  1491.             environment_string = xmalloc(strlen(variable) + 1 +
  1492.                                          strlen(alternate_value) + 1);
  1493.             sprintf(environment_string, "%s=%s", variable, alternate_value);
  1494.             result = putenv(environment_string);
  1495. #else
  1496.             result = setenv(variable, alternate_value, 1);
  1497. #endif /* !HAVE_PUTENV */
  1498.         }
  1499.         else
  1500.         {
  1501. #ifdef HAVE_PUTENV
  1502.             environment_string = xmalloc(strlen(variable) + 1 +
  1503.                                          strlen(value) + 1);
  1504.             sprintf(environment_string, "%s=%s", variable, value);
  1505.             result = putenv(environment_string);
  1506. #else
  1507.             result = setenv(variable, value, 1);
  1508. #endif /* !HAVE_PUTENV */
  1509.         }
  1510.  
  1511.         if (result == -1)
  1512.             fprintf(stderr, "%s: warning: cannot add '%s' to environment\n",
  1513.                     program, variable);
  1514.     }
  1515. }
  1516.  
  1517.  
  1518. /* Reads keys from the current section ([GIT-Keys] is supposed to  be
  1519.    in use when read_keys() is called).  Returns the number of keys read.  */
  1520.  
  1521. int
  1522. read_keys(keys)
  1523.     int keys;
  1524. {
  1525.     int i, j, need_convertion;
  1526.     command_t *command;
  1527.     unsigned char key_seq[80];
  1528.     char *contents[KEYSDATA_FIELDS - 2];
  1529.  
  1530.  
  1531.     for (i = keys; i < MAX_KEYS; i++)
  1532.     {
  1533.         configuration_getvarinfo((char *)key_seq, contents,
  1534.                                  KEYSDATA_FIELDS - 2, NO_SEEK);
  1535.  
  1536.         if (*key_seq == 0)
  1537.             break;
  1538.  
  1539.         if (*key_seq != '^')
  1540.         {
  1541.             char *key_seq_ptr = tty_get_symbol_key_seq((char *)key_seq);
  1542.  
  1543.             if (!(need_convertion = key_seq_ptr == NULL))
  1544.                 strcpy((char *)key_seq, key_seq_ptr);
  1545.         }
  1546.         else
  1547.             need_convertion = 1;
  1548.  
  1549.         command = (command_t *)xcalloc(1, sizeof(command_t));
  1550.  
  1551.         if (contents[0])
  1552.             command->name = xstrdup(contents[0]);
  1553.         else
  1554.         {
  1555.             xfree(command);
  1556.             continue;
  1557.         }
  1558.  
  1559.         command->history = xstack_init(sizeof(char *));
  1560.  
  1561.         if (contents[2])
  1562.             command->new_dir = xstrdup(contents[2]);
  1563.  
  1564.         if (contents[1])
  1565.             command->body = xstrdup(contents[1]);
  1566.         else
  1567.             goto insert;
  1568.  
  1569.         if (contents[3])
  1570.             command->save_screen = ((tolower(contents[3][0])=='y')?1:0);
  1571.         else
  1572.             command->save_screen = 1;
  1573.  
  1574.         if (contents[4])
  1575.             command->pause = ((tolower(contents[4][0]) == 'y') ? 1:0);
  1576.  
  1577.         if (contents[5])
  1578.             command->hide = ((tolower(contents[5][0]) == 'y') ? 1:0);
  1579.  
  1580.       insert:
  1581.  
  1582.         /* This speeds up the process.  It is not a limitation because,
  1583.            by convention, all the build-in command names don't contain
  1584.            uppercase letters.  Avoid searching through the list of
  1585.            built-in command names.  */
  1586.         if (islower(command->name[0]))
  1587.             for (j = 0; j < BUILTIN_OPERATIONS; j++)
  1588.             {
  1589.                 if (strcmp(command->name, built_in[j]) == 0)
  1590.                 {
  1591.                     xfree(command->name);
  1592.                     command->name = built_in[j];
  1593.                     command->builtin = 1;
  1594.                     break;
  1595.                 }
  1596.             }
  1597.  
  1598.         command->sequence = xstrdup((char *)key_seq);
  1599.  
  1600.         if (command->builtin || command->body || command->new_dir)
  1601.             if (!need_convertion || tty_key_convert(key_seq))
  1602.                 tty_key_list_insert(key_seq, (void *)command);
  1603.     }
  1604.  
  1605.     return i;
  1606. }
  1607.  
  1608.  
  1609. int
  1610. main(argc, argv)
  1611.     int argc;
  1612.     char *argv[];
  1613. {
  1614.     tty_key_t *ks;
  1615.     command_t *command;
  1616.     size_t len = 0, ptrlen;
  1617.     char *StartupLeftPanelPath;
  1618.     char *StartupRightPanelPath;
  1619.     int previous_isearch_failed;
  1620.     input_line_t *saved_il = NULL;
  1621.     char PWD[MAX_STATIC_SIZE + 1];
  1622.     char *lock_password, *unlock_password;
  1623.     int child_exit_code, repeat_count, keys;
  1624.     int panel_no = 0, action_status, i, retval;
  1625.     char *data = NULL, *cmdln = NULL, *input = NULL, *ptr, *srcptr;
  1626.     int entry, key, app_end = 0, wait = 0, need_clrscr = 0, first_time = 1;
  1627.  
  1628.  
  1629.     /* Job control stuff. */
  1630.     signal(SIGTSTP, suspend);
  1631.     signal(SIGCONT, resume);
  1632.  
  1633.     signal(SIGSEGV, fatal_signal);
  1634.     signal(SIGHUP,  fatal_signal);
  1635.  
  1636.     signals(SIG_OFF);
  1637.     ignore_signals();
  1638.  
  1639.     xtimer(XT_OFF);
  1640.  
  1641. #ifdef HAVE_GCC
  1642.     printf(PRODUCT" "VERSION" (%s), %s %s\n",
  1643.            HOST, __TIME__, __DATE__);
  1644. #else
  1645.     printf("GNU Interactive Tools (%s)\n",
  1646.            HOST);
  1647. #endif /* !HAVE_GCC */
  1648.  
  1649.     printf("GIT is free software; you can redistribute it and/or modify it under the\n");
  1650.     printf("terms of the GNU General Public License as published by the Free Software\n");
  1651.     printf("Foundation; either version 2, or (at your option) any later version.\n");
  1652.     printf("Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.\n");
  1653.     printf("Written by Tudor Hulubei and Andrei Pitis, students at PUB, Romania\n");
  1654.  
  1655.     program = argv[0];
  1656.     pid     = getpid();
  1657.  
  1658.     if (argc != 1)
  1659.         fprintf(stderr, "%s: warning: ignoring command line argument(s)\n",
  1660.                 program);
  1661.  
  1662.     home = getenv("HOME");
  1663.     if (home == NULL)
  1664.         home = ".";
  1665.  
  1666.     get_tty_name();
  1667.     get_login_name();
  1668.  
  1669. /*
  1670.     Well, this seems to work differently on BSDs, so just forget about it.
  1671.     My guess is that you do have a command processor :-)
  1672.  
  1673.     if (system(NULL) == 0)
  1674.         fprintf(stderr, "%s: warning: cannot find a command processor\n",
  1675.                 program);
  1676. */
  1677.  
  1678.     add_to_environment("GIT_EDITOR",   "EDITOR", "vi");
  1679.     add_to_environment("GIT_SHELL",    "SHELL",  "/bin/sh");
  1680.     add_to_environment("GIT_RMAIL",    NULL,     "emacs -f rmail");
  1681.     add_to_environment("GIT_PAGER",    NULL,     "more");
  1682.     add_to_environment("GIT_COMPRESS", NULL,     "gzip -r9");
  1683.     add_to_environment("GIT_VMSTAT",   NULL,     "free");
  1684.  
  1685.     tty_get_capabilities();
  1686.     tty_kbdinit(TTY_RESTRICTED_INPUT);
  1687.  
  1688.     common_configuration_init();
  1689.     use_section("[GIT-FTI]");
  1690.     get_file_type_info();
  1691.     use_section("[GIT-Keys]");
  1692.     keys = read_keys(0);
  1693.     configuration_end();
  1694.  
  1695.     specific_configuration_init();
  1696.  
  1697.     tty_get_exit_colors();
  1698.  
  1699.  
  1700.     use_section("[Setup]");
  1701.  
  1702.     configuration_getvarinfo("TempDirectory", &data, 1, DO_SEEK);
  1703.     TempDirectory = data ? tilde_expand(data) : "/tmp";
  1704.  
  1705.     stdout_log_name = xmalloc(32 + strlen(TempDirectory) + 1);
  1706.     stderr_log_name = xmalloc(32 + strlen(TempDirectory) + 1);
  1707.     sprintf(stdout_log_name, "%s/git.1.%d", TempDirectory, (int)pid);
  1708.     sprintf(stderr_log_name, "%s/git.2.%d", TempDirectory, (int)pid);
  1709.  
  1710.     AnsiColorSequences = get_flag_var("AnsiColorSequences", OFF);
  1711.  
  1712.  
  1713.     use_section("[GIT-Setup]");
  1714.  
  1715.     TypeSensitivity     = get_flag_var("TypeSensitivity", ON);
  1716.     ConfirmOnExit       = get_flag_var("ConfirmOnExit", OFF);
  1717.     NormalModeHelp      = get_string_var("NormalModeHelp",      "");
  1718.     CommandLineModeHelp = get_string_var("CommandLineModeHelp", "");
  1719.  
  1720.     if (AnsiColorSequences == OFF)
  1721.     TypeSensitivity = OFF;
  1722.  
  1723.     configuration_getvarinfo("StartupLeftPanelPath", &data, 1, DO_SEEK);
  1724.     StartupLeftPanelPath = data ? tilde_expand(data) : ".";
  1725.  
  1726.     configuration_getvarinfo("StartupRightPanelPath", &data, 1, DO_SEEK);
  1727.     StartupRightPanelPath = data ? tilde_expand(data) : ".";
  1728.  
  1729.  
  1730.     use_section(AnsiColorSequences ? cSection : bwSection);
  1731.  
  1732.     get_colorset_var(TitleColors, TitleFields, TITLE_FIELDS);
  1733.  
  1734.     use_section("[GIT-FTI]");
  1735.     get_file_type_info();
  1736.  
  1737.     use_section("[GIT-Keys]");
  1738.     keys = read_keys(keys);
  1739.  
  1740.     if (keys == MAX_KEYS)
  1741.         fprintf(stderr, "%s: too many key sequences; only %d are allowed.\n",
  1742.                 program, MAX_KEYS);
  1743.  
  1744.     tty_get_size(&SCREEN_X, &SCREEN_Y);
  1745.     tty_startup();
  1746.  
  1747. #ifndef HAVE_LONG_FILE_NAMES
  1748.     fprintf(stderr, "%s: warning: your system doesn't support long file names.",
  1749.             program);
  1750. #endif /* !HAVE_LONG_FILE_NAMES */
  1751.  
  1752. #ifdef HAVE_LINUX
  1753.     if (LinuxConsole == ON)
  1754.         screen = xmalloc(4 + SCREEN_X * SCREEN_Y * 2);
  1755. #endif  /* HAVE_LINUX */
  1756.  
  1757.     status_init(SCREEN_X, SCREEN_Y - 1, NormalModeHelp);
  1758.  
  1759.     if (getuid() == 0)
  1760.         PS1[1] = '#';
  1761.  
  1762.     il_init(SCREEN_X, SCREEN_Y - 2);
  1763.  
  1764.     left_panel  = panel_init(0,             1, SCREEN_Y - 3, SCREEN_X >> 1,
  1765.                              StartupLeftPanelPath);
  1766.     right_panel = panel_init(SCREEN_X >> 1, 1, SCREEN_Y - 3, SCREEN_X >> 1,
  1767.                              StartupRightPanelPath);
  1768.  
  1769.     configuration_end();
  1770.  
  1771.     tty_get_screen(screen);
  1772.     tty_set_mode(TTY_NONCANONIC);
  1773.  
  1774.     /* Setup the clock and the tty hooks.  */
  1775.     gitclock_xtimer = xtimer_register(gitclock);
  1776.     tty_enter_idle_hook = gitclock_validate;
  1777.     tty_exit_idle_hook  = gitclock_invalidate;
  1778.  
  1779.     if (FrameDisplay == OFF)
  1780.     {
  1781.         tty_defaults();
  1782.         tty_clear();
  1783.     }
  1784.  
  1785.     dir_history       = NULL;
  1786.     dir_history_count = 0;
  1787.     dir_history_point = 0;
  1788.  
  1789. restart:
  1790.  
  1791.     signals(SIG_OFF);
  1792.  
  1793.     il_restore(saved_il);
  1794.  
  1795.     if (wait)
  1796.     {
  1797.         tty_get_key(NULL);
  1798.         wait = 0;
  1799.     }
  1800.  
  1801.     if (need_clrscr)
  1802.     {
  1803.         tty_defaults();
  1804.         tty_clear();
  1805.         need_clrscr = 0;
  1806.     }
  1807.  
  1808.     settitle();
  1809.     gitclock(NULL, 0);
  1810.  
  1811.     status(NULL, 0, 0, 1, MSG_OK, MSG_CENTERED);
  1812.  
  1813.     src_panel  = panel_no ? right_panel : left_panel;
  1814.     dest_panel = panel_no ?  left_panel : right_panel;
  1815.  
  1816.     /* Save the input line contents.  */
  1817.     saved_il = il_save();
  1818.  
  1819.     panel_action(src_panel, act_REFRESH, dest_panel, (void *)-1, 1);
  1820.     panel_action(dest_panel, act_REFRESH, src_panel, (void *)-1, 1);
  1821.  
  1822.     /* Restore the input line contents.  */
  1823.     il_restore(saved_il);
  1824.  
  1825.     panel_set_focus(src_panel, ON);
  1826.  
  1827.     if (first_time)
  1828.     {
  1829.         dir_history_add(panel_get_path(src_panel));
  1830.         first_time = 0;
  1831.     }
  1832.  
  1833.     signals(SIG_ON);
  1834.     xtimer(XT_ON);
  1835.     gitclock(NULL, 0);
  1836.  
  1837.     il_set_static_text(strcat(truncate_string(panel_get_path(src_panel),
  1838.                                               PWD,
  1839.                                               MAX_STATIC_SIZE),
  1840.                               PS1));
  1841.     saved_il = il_save();
  1842.  
  1843.     while(!app_end)
  1844.     {
  1845.         il_restore(saved_il);
  1846.         saved_il = il_save();
  1847.         il_full_update();
  1848.         il_get_contents(&cmdln);
  1849.  
  1850.         UserHeartAttack = 0;
  1851.         suspend_allowed = ON;
  1852.         ks  = tty_get_key(&repeat_count);
  1853.         key = ks->key_seq[0];
  1854.         suspend_allowed = OFF;
  1855.  
  1856.         signals(SIG_OFF);
  1857.  
  1858.         command = (command_t *)ks->aux_data;
  1859.  
  1860.         if (command)
  1861.             if (command->builtin)
  1862.                 key = - 1 - (command->name-built_in[0]) / MAX_BUILTIN_NAME;
  1863.          else
  1864.          {
  1865.             if (command->name)
  1866.             {
  1867.                 panel_no_optimizations(src_panel);
  1868.                 panel_no_optimizations(dest_panel);
  1869.  
  1870.                 if (command->body)
  1871.                 {
  1872.                     char *cmd = NULL;
  1873.  
  1874.                     retval = command_expand(command, &cmd,
  1875.                                             src_panel, dest_panel);
  1876.  
  1877.                     if (retval)
  1878.                     {
  1879.                         if (retval > 0)
  1880.                         {
  1881.                             size_t msglen = 32 + strlen(command->name) +
  1882.                                             strlen(cmd) + 1;
  1883.                             char *msg = xmalloc(msglen);
  1884.  
  1885.                             sprintf(msg, "%s: %s", command->name, cmd);
  1886.                             status(msg, 0, 0, 0, MSG_WARNING, MSG_CENTERED);
  1887.                             xfree(msg);
  1888.  
  1889.                             if (command->hide)
  1890.                             {
  1891.                                 msg = xmalloc(64 + strlen(command->name) + 1);
  1892.                                 sprintf(msg, "Wait, running %s command %s...",
  1893.                                         "user-defined", command->name);
  1894.                                 il_message(msg);
  1895.                                 xfree(msg);
  1896.                             }
  1897.  
  1898.                             child_exit_code = start(cmd, command->hide);
  1899.                             xfree(cmd);
  1900.  
  1901.                             if (command->hide)
  1902.                             {
  1903.                                 if (child_exit_code != 0)
  1904.                                 {
  1905.                                     tty_beep();
  1906.                                     display_errors(command->name);
  1907.                                 }
  1908.                             }
  1909.                             else
  1910.                             {
  1911.                                 if (command->save_screen)
  1912.                                     tty_get_screen(screen);
  1913.  
  1914.                                 tty_touch();
  1915.  
  1916.                                 if (FrameDisplay == OFF)
  1917.                                     need_clrscr = 1;
  1918.  
  1919.                                 if (command->pause)
  1920.                                     wait = 1;
  1921.                             }
  1922.  
  1923.                             if (child_exit_code == 0 && command->new_dir)
  1924.                             {
  1925.                                 char *expanded_dir =
  1926.                                     tilde_expand(command->new_dir);
  1927.  
  1928.                                 panel_action(src_panel, act_CHDIR,
  1929.                                              dest_panel, expanded_dir, 1);
  1930.                                 
  1931.                                 dir_history_add(panel_get_path(src_panel));
  1932.                                 xfree(expanded_dir);
  1933.                             }
  1934.  
  1935.                             if (child_exit_code == 0)
  1936.                                 if (retval == 2)
  1937.                                     panel_unselect_all(src_panel);
  1938.                                 else
  1939.                                     if (retval == 3)
  1940.                                         panel_unselect_all(dest_panel);
  1941.  
  1942.                             goto restart;
  1943.                         }
  1944.                         else
  1945.                             continue;
  1946.                     }
  1947.                     else
  1948.                     {
  1949.                         char *msg = xmalloc(80+strlen((char *)ks->key_seq)+1);
  1950.  
  1951.                         sprintf(msg,"%s: invalid command on key sequence %s !",
  1952.                                 command->name, command->sequence);
  1953.                         il_read_char(msg, NULL, IL_FREEZED | IL_BEEP |
  1954.                                                 IL_SAVE    | IL_ERROR);
  1955.                         xfree(msg);
  1956.                         continue;
  1957.                     }
  1958.                 }
  1959.                 else
  1960.                 {
  1961.                     if (command->new_dir)
  1962.                     {
  1963.                         char *expanded_dir = tilde_expand(command->new_dir);
  1964.  
  1965.                         panel_action(src_panel, act_CHDIR, dest_panel,
  1966.                                      expanded_dir, 1);
  1967.  
  1968.                         dir_history_add(panel_get_path(src_panel));
  1969.                         xfree(expanded_dir);
  1970.                     }
  1971.  
  1972.                     goto restart;
  1973.                 }
  1974.              }
  1975.         }
  1976.  
  1977.         signals(SIG_ON);
  1978.  
  1979.         switch (key)
  1980.         {
  1981.             case key_INTERRUPT:
  1982.                 il_free(saved_il);
  1983.                 il_kill_line(IL_DONT_STORE);
  1984.                 saved_il = il_save();
  1985.                 break;
  1986.  
  1987.             case BUILTIN_other_panel:
  1988.  
  1989.                 signals(SIG_OFF);
  1990.  
  1991.                 if (!two_panel_mode)
  1992.                     goto one_panel_mode;
  1993.  
  1994.                 if ((repeat_count & 1) == 0)
  1995.                     break;
  1996.  
  1997.                 panel_set_focus(src_panel, OFF);
  1998.  
  1999.                 temp_panel = src_panel;
  2000.                 src_panel  = dest_panel;
  2001.                 dest_panel = temp_panel;
  2002.  
  2003.                 panel_no = !panel_no;
  2004.                 panel_set_focus(src_panel, ON);
  2005.  
  2006.                 il_free(saved_il);
  2007.                 il_set_static_text(strcat(
  2008.                     truncate_string(panel_get_path(src_panel),  PWD,
  2009.                                     MAX_STATIC_SIZE),
  2010.                     PS1));
  2011.                 saved_il = il_save();
  2012.  
  2013.                 break;
  2014.  
  2015.             case BUILTIN_previous_line:
  2016.  
  2017.                 signals(SIG_OFF);
  2018.                 panel_action(src_panel,act_UP,dest_panel,NULL,repeat_count);
  2019.                 break;
  2020.  
  2021.             case BUILTIN_next_line:
  2022.  
  2023.                 signals(SIG_OFF);
  2024.                 panel_action(src_panel,act_DOWN,dest_panel,NULL,repeat_count);
  2025.                 break;
  2026.  
  2027.             case BUILTIN_action:
  2028.  
  2029.                 action_status = 0;
  2030.                 il_free(saved_il);
  2031.                 il_get_contents(&cmdln);
  2032.  
  2033.                 switch (*cmdln)
  2034.                 {
  2035.                     case '+':
  2036.                         action_status = panel_action(src_panel, act_SELECT_ALL,
  2037.                                                      dest_panel, NULL, 1);
  2038.                         break;
  2039.  
  2040.                     case '-':
  2041.                         action_status = panel_action(src_panel,
  2042.                                                      act_UNSELECT_ALL,
  2043.                                                      dest_panel, NULL, 1);
  2044.                         break;
  2045.  
  2046.                     case '*':
  2047.                         action_status = panel_action(src_panel, act_TOGGLE,
  2048.                                                      dest_panel, NULL, 1);
  2049.                         break;
  2050.  
  2051.                     case 0:
  2052.                         signals(SIG_OFF);
  2053.                         action_status = panel_action(src_panel, act_ENTER,
  2054.                                                      dest_panel, screen, 1);
  2055.                         break;
  2056.  
  2057.                     default:
  2058.                         {
  2059.                             char *output_string;
  2060.  
  2061.                             if (history_expand(cmdln, &output_string) >= 0)
  2062.                             {
  2063.                                 int bg_cmd = is_a_bg_command(output_string);
  2064.  
  2065.                                 il_kill_line(IL_DONT_STORE);
  2066.                                 il_insert_text(output_string);
  2067.                                 start(output_string, bg_cmd);
  2068.  
  2069.                                 if (!bg_cmd)
  2070.                                 {
  2071.                                     panel_no_optimizations(src_panel);
  2072.                                     panel_no_optimizations(dest_panel);
  2073.                                     tty_touch();
  2074.                                     action_status = -1; 
  2075.                                 }
  2076.                                 else
  2077.                                 {
  2078.                                     il_history(IL_RECORD);
  2079.                                     il_kill_line(IL_DONT_STORE);
  2080.                                 }
  2081.                             }
  2082.                             else
  2083.                             {
  2084.                                 il_read_char(output_string, NULL,
  2085.                                              IL_FREEZED | IL_BEEP |
  2086.                                              IL_SAVE    | IL_ERROR);
  2087.                             }
  2088.                         }
  2089.                         break;
  2090.                 }
  2091.  
  2092.                 if (action_status == 1)
  2093.                 {
  2094.                     il_set_static_text(
  2095.                         strcat(truncate_string(panel_get_path(src_panel), PWD,
  2096.                                                MAX_STATIC_SIZE),
  2097.                                PS1));
  2098.                     il_kill_line(IL_DONT_STORE);
  2099.                 }
  2100.                 else
  2101.                     if (action_status == -1)
  2102.                     {
  2103.                         tty_get_screen(screen);
  2104.                         il_history(IL_RECORD);
  2105.                         il_kill_line(IL_DONT_STORE);
  2106.  
  2107.                         if (FrameDisplay == OFF)
  2108.                             need_clrscr = 1;
  2109.  
  2110.                         saved_il = il_save();
  2111.                         goto restart;
  2112.                     }
  2113.  
  2114.                 saved_il = il_save();
  2115.                 break;
  2116.  
  2117.             case BUILTIN_select_file:
  2118.  
  2119.                 signals(SIG_OFF);
  2120.  
  2121.                 for (i = 0; i < repeat_count; i++)
  2122.                     panel_action(src_panel, act_SELECT, dest_panel, NULL, 1);
  2123.                 break;
  2124.  
  2125.             case BUILTIN_scroll_down:
  2126.  
  2127.                 signals(SIG_OFF);
  2128.  
  2129.                 for (i = 0; i < repeat_count; i++)
  2130.                     panel_action(src_panel, act_PGUP, dest_panel, NULL, 1);
  2131.                 
  2132.                 break;
  2133.  
  2134.             case BUILTIN_scroll_up:
  2135.  
  2136.                 signals(SIG_OFF);
  2137.  
  2138.                 for (i = 0; i < repeat_count; i++)
  2139.                     panel_action(src_panel, act_PGDOWN, dest_panel, NULL, 1);
  2140.                 break;
  2141.  
  2142.             case BUILTIN_beginning_of_panel:
  2143.  
  2144.                 signals(SIG_OFF);
  2145.                 panel_action(src_panel, act_HOME, dest_panel, NULL, 1);
  2146.                 break;
  2147.  
  2148.             case BUILTIN_end_of_panel:
  2149.  
  2150.                 signals(SIG_OFF);
  2151.                 panel_action(src_panel, act_END, dest_panel, NULL, 1);
  2152.                 break;
  2153.  
  2154.             case BUILTIN_hard_refresh:
  2155.             
  2156.                 tty_touch();
  2157.  
  2158.             case BUILTIN_refresh:
  2159.  
  2160.                 panel_no_optimizations(src_panel);
  2161.                 panel_no_optimizations(dest_panel);
  2162.  
  2163.                 if (FrameDisplay == OFF)
  2164.                     need_clrscr = 1;
  2165.  
  2166.                 goto restart;
  2167.  
  2168.             case BUILTIN_tty_mode:
  2169.  
  2170.                 if ((repeat_count & 1) == 0)
  2171.                     break;
  2172.  
  2173.                 tty_put_screen(screen);
  2174.                 status(CommandLineModeHelp, 0, 0, 0, MSG_OK, MSG_CENTERED);
  2175.                 gitclock(NULL, 0);
  2176.  
  2177.                 while (1)
  2178.                 {
  2179.                     il_restore(saved_il);
  2180.                     saved_il = il_save();
  2181.                     il_full_update();
  2182.                     il_get_contents(&cmdln);
  2183.  
  2184.                     current_mode = GIT_TERMINAL_MODE;
  2185.                     suspend_allowed = ON;
  2186.                     ks  = tty_get_key(&repeat_count);
  2187.                     key = ks->key_seq[0];
  2188.                     suspend_allowed = OFF;
  2189.  
  2190.                     command = (command_t *)ks->aux_data;
  2191.                     if (command && command->builtin)
  2192.                         key = - 1 - (command->name - built_in[0]) /
  2193.                                      MAX_BUILTIN_NAME;
  2194.  
  2195.                     if (key == BUILTIN_tty_mode && (repeat_count & 1))
  2196.                     {
  2197.                         il_free(saved_il);
  2198.                         saved_il = il_save();
  2199.                         break;
  2200.                     }
  2201.  
  2202.                     switch (key)
  2203.                     {
  2204.                         case key_INTERRUPT:
  2205.                             il_free(saved_il);
  2206.                             il_kill_line(IL_DONT_STORE);
  2207.                             saved_il = il_save();
  2208.                             break;
  2209.  
  2210.                         case BUILTIN_action:
  2211.  
  2212.                             if (*cmdln)
  2213.                             {
  2214.                                 char *output_string;
  2215.  
  2216.                                 il_free(saved_il);
  2217.  
  2218.                                 if (history_expand(cmdln, &output_string) < 0)
  2219.                                 {
  2220.                                     il_read_char(output_string, NULL,
  2221.                                                  IL_FREEZED | IL_BEEP |
  2222.                                                  IL_SAVE    | IL_ERROR);
  2223.                                     saved_il = il_save();
  2224.                                     break;
  2225.                                 }
  2226.  
  2227.                                 tty_put_screen(screen);
  2228.                                 il_kill_line(IL_DONT_STORE);
  2229.                                 il_insert_text(output_string);
  2230.                                 start(output_string, 0);
  2231.                                 tty_get_screen(screen);
  2232.                                 xtimer(XT_ON);
  2233.                                 gitclock(NULL, 0);
  2234.                                 il_history(IL_RECORD);
  2235.                                 status(CommandLineModeHelp, 0, 0, 0,
  2236.                                        MSG_OK, MSG_CENTERED);
  2237.                                 il_kill_line(IL_DONT_STORE);
  2238.                                 saved_il = il_save();
  2239.                             }
  2240.                             break;
  2241.  
  2242.                         case BUILTIN_previous_history_element:
  2243.                         case BUILTIN_previous_line:
  2244.  
  2245.                             il_free(saved_il);
  2246.  
  2247.                             for (i = 0; i < repeat_count; i++)
  2248.                                 il_history(IL_PREVIOUS);
  2249.  
  2250.                             saved_il = il_save();
  2251.                             break;
  2252.  
  2253.                         case BUILTIN_next_history_element:
  2254.                         case BUILTIN_next_line:
  2255.  
  2256.                             il_free(saved_il);
  2257.  
  2258.                             for (i = 0; i < repeat_count; i++)
  2259.                                 il_history(IL_NEXT);
  2260.  
  2261.                             saved_il = il_save();
  2262.                             break;
  2263.  
  2264.                         case BUILTIN_refresh:
  2265.  
  2266.                             panel_no_optimizations(src_panel);
  2267.                             panel_no_optimizations(dest_panel);
  2268.                             tty_put_screen(screen);
  2269.                             status(CommandLineModeHelp, 0, 0, 0,
  2270.                                    MSG_OK, MSG_CENTERED);
  2271.                             gitclock(NULL, 0);
  2272.                             break;
  2273.  
  2274.                         case BUILTIN_exit:
  2275.  
  2276.                             if (ConfirmOnExit == OFF ||
  2277.                                 il_read_char(exit_msg,"yn",IL_FREEZED) == 'y')
  2278.                             {
  2279.                                 app_end = 1;
  2280.                                 goto end_tty_mode;
  2281.                             }
  2282.  
  2283.                             status(CommandLineModeHelp, 0, 0, 0,
  2284.                                    MSG_OK, MSG_CENTERED);
  2285.                             break;
  2286.  
  2287.                         default:
  2288.  
  2289.                             if (key)
  2290.                             {
  2291.                                 il_free(saved_il);
  2292.  
  2293.                                 while (repeat_count--)
  2294.                                     il_dispatch_commands(key, IL_MOVE|IL_EDIT);
  2295.  
  2296.                                 saved_il = il_save();
  2297.                             }
  2298.                             break;
  2299.                     }
  2300.                 }
  2301.  
  2302.               end_tty_mode:
  2303.  
  2304.                 panel_no_optimizations(src_panel);
  2305.                 panel_no_optimizations(dest_panel);
  2306.                 tty_touch();
  2307.                 status(NULL, 0, 0, 1, MSG_OK, MSG_CENTERED);
  2308.  
  2309.                 current_mode = GIT_SCREEN_MODE;
  2310.  
  2311.                 if (app_end)
  2312.                     continue;
  2313.                 else
  2314.                 {
  2315.                     if (FrameDisplay == OFF)
  2316.                         need_clrscr = 1;
  2317.                     goto restart;
  2318.                 }
  2319.  
  2320.             case BUILTIN_copy:
  2321.  
  2322.                 panel_action(src_panel, act_COPY, dest_panel, NULL, 1);
  2323.                 break;
  2324.  
  2325.             case BUILTIN_move:
  2326.  
  2327.                 panel_action(src_panel, act_MOVE, dest_panel, NULL, 1);
  2328.                 break;
  2329.  
  2330.             case BUILTIN_make_directory:
  2331.  
  2332.                 signals(SIG_OFF);
  2333.                 panel_action(src_panel, act_MKDIR, dest_panel, NULL, 1);
  2334.                 break;
  2335.  
  2336.             case BUILTIN_delete:
  2337.  
  2338.                 panel_action(src_panel, act_DELETE, dest_panel, NULL, 1);
  2339.                 break;
  2340.  
  2341.             case BUILTIN_panel_display_next_mode:
  2342.  
  2343.             case BUILTIN_panel_display_owner_group:
  2344.             case BUILTIN_panel_display_date_time:
  2345.             case BUILTIN_panel_display_size:
  2346.             case BUILTIN_panel_display_mode:
  2347.             case BUILTIN_panel_display_full_name:
  2348.  
  2349.                 signals(SIG_OFF);
  2350.                 panel_action(src_panel,
  2351.                              act_DISPLAY_NEXT_MODE -
  2352.                              (key - BUILTIN_panel_display_next_mode),
  2353.                              NULL, NULL, 1);
  2354.                 break;
  2355.  
  2356.             case BUILTIN_panel_sort_next_method:
  2357.  
  2358.             case BUILTIN_panel_sort_by_name:
  2359.             case BUILTIN_panel_sort_by_extension:
  2360.             case BUILTIN_panel_sort_by_size:
  2361.             case BUILTIN_panel_sort_by_date:
  2362.             case BUILTIN_panel_sort_by_mode:
  2363.             case BUILTIN_panel_sort_by_owner_id:
  2364.             case BUILTIN_panel_sort_by_group_id:
  2365.             case BUILTIN_panel_sort_by_owner_name:
  2366.             case BUILTIN_panel_sort_by_group_name:
  2367.  
  2368.                 signals(SIG_OFF);
  2369.                 panel_action(src_panel,
  2370.                              act_SORT_NEXT_METHOD -
  2371.                              (key - BUILTIN_panel_sort_next_method),
  2372.                              NULL, NULL, 1);
  2373.                 break;
  2374.  
  2375.             case BUILTIN_exit:
  2376.  
  2377.                 signals(SIG_OFF);
  2378.  
  2379.                 if (ConfirmOnExit == OFF ||
  2380.                     il_read_char(exit_msg, "yn", IL_FREEZED) == 'y')
  2381.                     app_end = 1;
  2382.  
  2383.                 break;
  2384.  
  2385.             case BUILTIN_file_to_input_line:
  2386.  
  2387.                 signals(SIG_OFF);
  2388.                 len = strlen(cmdln);
  2389.  
  2390.                 srcptr = panel_get_current_file_name(src_panel);
  2391.                 ptr = xmalloc(ptrlen = 1 + 1 + strlen(srcptr) + 1 + 1 + 1);
  2392.  
  2393.               copy_to_cmdln:
  2394.  
  2395.                 il_free(saved_il);
  2396.                 sprintf(ptr, " \"%s\" ", srcptr);
  2397.                 cmdln = xrealloc(cmdln, len + ptrlen);
  2398.  
  2399.                 for (i = 0; ptr[i]; i++)
  2400.                     if (!is_print(ptr[i]))
  2401.                     {
  2402.                         tty_beep();
  2403.                         ptr[i] = 0;
  2404.                         break;
  2405.                     }
  2406.  
  2407.                 strcpy(&cmdln[len], ptr);
  2408.                 il_insert_text(ptr);
  2409.                 xfree(ptr);
  2410.                 saved_il = il_save();
  2411.                 break;
  2412.  
  2413.             case BUILTIN_other_path_to_input_line:
  2414.  
  2415.                 signals(SIG_OFF);
  2416.  
  2417.                 ptrlen = 1 + 1 + dest_panel->pathlen + 1 + 1 + 1;
  2418.                 ptr = xmalloc(ptrlen);
  2419.                 srcptr = dest_panel->path;
  2420.  
  2421.                 goto copy_to_cmdln;
  2422.  
  2423.             case BUILTIN_selected_files_to_input_line:
  2424.  
  2425.                 signals(SIG_OFF);
  2426.                 len = strlen(cmdln);
  2427.                 il_free(saved_il);
  2428.  
  2429.                 panel_init_iterator(src_panel);
  2430.  
  2431.                 while ((entry = panel_get_next(src_panel)) != -1)
  2432.                 {
  2433.                     srcptr = src_panel->dir_entry[entry].name;
  2434.                     ptr = xmalloc(ptrlen = 1 + 1 + strlen(srcptr) + 1 + 1 + 1);
  2435.                     sprintf(ptr, " \"%s\" ", srcptr);
  2436.                     cmdln = xrealloc(cmdln, len + ptrlen);
  2437.  
  2438.                     for (i = 0; ptr[i]; i++)
  2439.                         if (!is_print(ptr[i]))
  2440.                         {
  2441.                             tty_beep();
  2442.                             ptr[i] = 0;
  2443.                             saved_il = il_save();
  2444.                             break;
  2445.                         }
  2446.  
  2447.                     strcpy(&cmdln[len], ptr);
  2448.                     il_insert_text(ptr);
  2449.                     xfree(ptr);
  2450.                 }
  2451.  
  2452.                 saved_il = il_save();
  2453.                 break;
  2454.  
  2455.             case BUILTIN_previous_history_element:
  2456.  
  2457.                 signals(SIG_OFF);
  2458.                 il_free(saved_il);
  2459.  
  2460.                 for (i = 0; i < repeat_count; i++)
  2461.                     il_history(IL_PREVIOUS);
  2462.  
  2463.                 saved_il = il_save();
  2464.                 break;
  2465.  
  2466.             case BUILTIN_next_history_element:
  2467.  
  2468.                 signals(SIG_OFF);
  2469.                 il_free(saved_il);
  2470.  
  2471.                 for (i = 0; i < repeat_count; i++)
  2472.                     il_history(IL_NEXT);
  2473.  
  2474.                 saved_il = il_save();
  2475.                 break;
  2476.                 
  2477.             case BUILTIN_switch_panels:
  2478.  
  2479.                 if ((repeat_count & 1) == 0)
  2480.                     break;
  2481.  
  2482.                 signals(SIG_OFF);
  2483.                 panel_no_optimizations(src_panel);
  2484.                 panel_no_optimizations(dest_panel);
  2485.                 panel_action(src_panel, act_SWITCH, dest_panel, NULL, 1);
  2486.                 panel_action(dest_panel, act_REFRESH, src_panel, (void*)-1, 1);
  2487.                 panel_action(src_panel, act_REFRESH, dest_panel, (void*)-1, 1);
  2488.                 break;
  2489.  
  2490.             case BUILTIN_change_directory:
  2491.  
  2492.                 signals(SIG_OFF);
  2493.  
  2494.                 if (il_read_line("Directory: ", &input, NULL,
  2495.                                  command->history))
  2496.                 {
  2497.                     char *expanded_input;
  2498.  
  2499.                     if (input[0] == 0)
  2500.                         break;
  2501.  
  2502.                     panel_action(src_panel, act_CHDIR, dest_panel,
  2503.                                  expanded_input = tilde_expand(input), 1);
  2504.  
  2505.                     dir_history_add(panel_get_path(src_panel));
  2506.  
  2507.                     xfree(expanded_input);
  2508.                     xfree(input);
  2509.                     input = NULL;
  2510.                 }
  2511.  
  2512.                 break;
  2513.  
  2514.             case BUILTIN_select_files_matching_pattern:
  2515.  
  2516.                 signals(SIG_OFF);
  2517.  
  2518.                 if (il_read_line("Select files matching pattern: ",
  2519.                                  &input, NULL, command->history))
  2520.                 {
  2521.                     if (input[0] == 0)
  2522.                         break;
  2523.  
  2524.                     panel_action(src_panel, act_PATTERN_SELECT,
  2525.                                  dest_panel, input, 1);
  2526.  
  2527.                     xfree(input);
  2528.                     input = NULL;
  2529.                 }
  2530.  
  2531.                 break;
  2532.  
  2533.             case BUILTIN_unselect_files_matching_pattern:
  2534.  
  2535.                 signals(SIG_OFF);
  2536.  
  2537.                 if (il_read_line("Unselect files matching pattern: ",
  2538.                                  &input, NULL, command->history))
  2539.                 {
  2540.                     if (input[0] == 0)
  2541.                         break;
  2542.  
  2543.                     panel_action(src_panel, act_PATTERN_UNSELECT,
  2544.                                  dest_panel, input, 1);
  2545.  
  2546.                     xfree(input);
  2547.                     input = NULL;
  2548.                 }
  2549.  
  2550.                 break;
  2551.  
  2552.             case BUILTIN_conform_current_directory:
  2553.  
  2554.                 signals(SIG_OFF);
  2555.  
  2556.                 panel_action(src_panel, act_CHDIR, dest_panel,
  2557.                              dest_panel->path, 1);
  2558.  
  2559.                 dir_history_add(panel_get_path(src_panel));
  2560.  
  2561.                 break;
  2562.  
  2563.             case BUILTIN_conform_other_directory:
  2564.  
  2565.                 signals(SIG_OFF);
  2566.  
  2567.                 panel_action(dest_panel, act_CHDIR, src_panel,
  2568.                              src_panel->path, 1);
  2569.  
  2570.                 dir_history_add(panel_get_path(dest_panel));
  2571.  
  2572.                 break;
  2573.             
  2574.             case BUILTIN_set_scroll_step:
  2575.  
  2576.                 signals(SIG_OFF);
  2577.  
  2578.                 if (il_read_line("Scroll step: ", &input, NULL,
  2579.                                  command->history))
  2580.                 {
  2581.                     if (input[0] == 0)
  2582.                         break;
  2583.  
  2584.                     panel_action(src_panel, act_SET_SCROLL_STEP,
  2585.                                  dest_panel, input, 1);
  2586.  
  2587.                     xfree(input);
  2588.                     input = NULL;
  2589.                 }
  2590.  
  2591.                 break;
  2592.  
  2593.             case BUILTIN_isearch_backward:
  2594.  
  2595.                 signals(SIG_OFF);
  2596.  
  2597.                 previous_isearch_failed = 0;
  2598.                 il_isearch("I-search backward: ",NULL,IL_ISEARCH_BEGIN,NULL);
  2599.                 panel_action(src_panel, act_ISEARCH_BEGIN,
  2600.                              dest_panel, NULL, 1);
  2601.  
  2602.                 for(;;)
  2603.                 {
  2604.                     isearch_aux_t iai;
  2605.  
  2606.                     if (il_isearch(NULL, &input, IL_ISEARCH_BACKWARD,
  2607.                                    &iai.action) == NULL)
  2608.                         break;
  2609.  
  2610.                     /* Wrap around.  */
  2611.                     if (iai.action == IL_ISEARCH_ACTION_RETRY &&
  2612.                         previous_isearch_failed)
  2613.                     {
  2614.                         panel_set_wrapped_isearch_flag(src_panel);
  2615.                         previous_isearch_failed = 0;
  2616.                     }
  2617.  
  2618.                     iai.string = input;
  2619.                     panel_action(src_panel, act_ISEARCH_BACKWARD,
  2620.                                  dest_panel, &iai, 1);
  2621.  
  2622.                     if (iai.action == IL_ISEARCH_ACTION_FAILED)
  2623.                     {
  2624.                         previous_isearch_failed = 1;
  2625.                         tty_beep();
  2626.                     }
  2627.                     else
  2628.                         if (iai.length < strlen(input))
  2629.                         {
  2630.                             il_backward_delete_char();
  2631.                             il_full_update();
  2632.                         }
  2633.                 }
  2634.  
  2635.                 panel_action(src_panel, act_ISEARCH_END, dest_panel, NULL, 1);
  2636.                 il_isearch(NULL, NULL, IL_ISEARCH_END, NULL);
  2637.                 break;
  2638.  
  2639.             case BUILTIN_isearch_forward:
  2640.  
  2641.                 signals(SIG_OFF);
  2642.  
  2643.                 previous_isearch_failed = 0;
  2644.                 il_isearch("I-search: ", NULL, IL_ISEARCH_BEGIN, NULL);
  2645.                 panel_action(src_panel,act_ISEARCH_BEGIN,dest_panel,NULL,1);
  2646.  
  2647.                 for(;;)
  2648.                 {
  2649.                     isearch_aux_t iai;
  2650.  
  2651.                     if (il_isearch(NULL, &input, IL_ISEARCH_FORWARD,
  2652.                                    &iai.action) == NULL)
  2653.                         break;
  2654.  
  2655.                     /* Wrap around.  */
  2656.                     if (iai.action == IL_ISEARCH_ACTION_RETRY &&
  2657.                         previous_isearch_failed)
  2658.                     {
  2659.                         panel_set_wrapped_isearch_flag(src_panel);
  2660.                         previous_isearch_failed = 0;
  2661.                     }
  2662.  
  2663.                     iai.string = input;
  2664.                     panel_action(src_panel, act_ISEARCH_FORWARD,
  2665.                                  dest_panel, &iai, 1);
  2666.  
  2667.                     if (iai.action == IL_ISEARCH_ACTION_FAILED)
  2668.                     {
  2669.                         previous_isearch_failed = 1;
  2670.                         tty_beep();
  2671.                     }
  2672.                     else
  2673.                         if (iai.length < strlen(input))
  2674.                         {
  2675.                             il_backward_delete_char();
  2676.                             il_full_update();
  2677.                         }
  2678.                 }
  2679.  
  2680.                 panel_action(src_panel, act_ISEARCH_END, dest_panel, NULL, 1);
  2681.                 il_isearch(NULL, NULL, IL_ISEARCH_END, NULL);
  2682.                 break;
  2683.  
  2684.             case BUILTIN_reset_directory_history:
  2685.  
  2686.                 signals(SIG_OFF);
  2687.  
  2688.                 dir_history_reset();
  2689.                 dir_history_add(panel_get_path(src_panel));
  2690.                 break;
  2691.  
  2692.             case BUILTIN_previous_directory:
  2693.  
  2694.                 signals(SIG_OFF);
  2695.  
  2696.                 dir_history_prev(src_panel, dest_panel);
  2697.                 break;
  2698.  
  2699.             case BUILTIN_next_directory:
  2700.  
  2701.                 signals(SIG_OFF);
  2702.  
  2703.                 dir_history_next(src_panel, dest_panel);
  2704.                 break;
  2705.  
  2706.             case BUILTIN_enlarge_other_panel:
  2707.  
  2708.                 signals(SIG_OFF);
  2709.  
  2710.               one_panel_mode:
  2711.  
  2712.                 panel_set_focus(src_panel, OFF);
  2713.  
  2714.                 temp_panel = src_panel;
  2715.                 src_panel  = dest_panel;
  2716.                 dest_panel = temp_panel;
  2717.  
  2718.                 panel_no = !panel_no;
  2719.                 panel_set_focus(src_panel, ON);
  2720.                 panel_activate(src_panel);
  2721.  
  2722.                 il_free(saved_il);
  2723.                 il_set_static_text(strcat(
  2724.                     truncate_string(panel_get_path(src_panel),  PWD,
  2725.                                     MAX_STATIC_SIZE),
  2726.                     PS1));
  2727.                 saved_il = il_save();
  2728.  
  2729.             case BUILTIN_enlarge_panel:
  2730.  
  2731.                 signals(SIG_OFF);
  2732.  
  2733.                 panel_no_optimizations(src_panel);
  2734.                 panel_no_optimizations(dest_panel);
  2735.                 tty_touch();
  2736.                 panel_deactivate(dest_panel);
  2737.                 panel_resize(src_panel, 0, 1, SCREEN_Y - 3, SCREEN_X);
  2738.  
  2739.                 two_panel_mode = 0;
  2740.                 panel_action(src_panel,  act_DISPLAY_ALL, NULL, NULL, 1);
  2741.                 panel_action(dest_panel, act_DISPLAY_ALL, NULL, NULL, 1);
  2742.  
  2743.                 break;
  2744.  
  2745.             case BUILTIN_two_panels:
  2746.  
  2747.                 signals(SIG_OFF);
  2748.  
  2749.                 panel_no_optimizations(src_panel);
  2750.                 panel_no_optimizations(dest_panel);
  2751.                 tty_touch();
  2752.                 panel_activate(dest_panel);
  2753.                 panel_resize(src_panel, 0, 1,
  2754.                              SCREEN_Y - 3, SCREEN_X >> 1);
  2755.                 panel_resize(dest_panel, SCREEN_X >> 1, 1,
  2756.                              SCREEN_Y - 3, SCREEN_X >> 1);
  2757.  
  2758.                 two_panel_mode = 1;
  2759.                 panel_action(src_panel,  act_DISPLAY_SIZE, NULL, NULL, 1);
  2760.                 panel_action(dest_panel, act_DISPLAY_SIZE, NULL, NULL, 1);
  2761.  
  2762.                 break;
  2763.  
  2764.             case BUILTIN_lock:
  2765.  
  2766.                 /* Turn echo off.  */
  2767.                 il_echo(0);
  2768.  
  2769.                 lock_password = NULL;
  2770.                 il_read_line("Enter a password: ", &lock_password, NULL, NULL);
  2771.  
  2772.                 if (lock_password == NULL || *lock_password == '\0')
  2773.                 {
  2774.                     il_echo(1);
  2775.                     break;
  2776.                 }
  2777.  
  2778.                 for (unlock_password = NULL;;)
  2779.                 {
  2780.                     il_read_line("Enter password to unlock: ",
  2781.                                  &unlock_password, NULL, NULL);
  2782.                     il_message(lock_think);
  2783.                     sleep(1);
  2784.  
  2785.                     if (unlock_password &&
  2786.                         strcmp(lock_password, unlock_password) == 0)
  2787.                         break;
  2788.  
  2789.                     il_message(lock_bad);
  2790.                     tty_beep();
  2791.                     sleep(2);
  2792.                 }
  2793.  
  2794.                 il_message(lock_ok);
  2795.                 sleep(1);
  2796.                 xfree(lock_password);
  2797.                 xfree(unlock_password);
  2798.  
  2799.                 /* Turn echo back on.  */
  2800.                 il_echo(1);
  2801.                 break;
  2802.  
  2803.             default:
  2804.  
  2805.                 signals(SIG_OFF);
  2806.  
  2807.                 if (key)
  2808.                 {
  2809.                     il_free(saved_il);
  2810.  
  2811.                     while (repeat_count--)
  2812.                         il_dispatch_commands(key, IL_MOVE | IL_EDIT);
  2813.  
  2814.                     saved_il = il_save();
  2815.                 }
  2816.                 break;
  2817.         }
  2818.  
  2819.         signals(SIG_ON);
  2820.     }
  2821.  
  2822.     signals(SIG_OFF);
  2823.     panel_end(left_panel);
  2824.     panel_end(right_panel);
  2825.     tty_set_mode(TTY_CANONIC);
  2826.  
  2827.     if (il)
  2828.         il_end();
  2829.  
  2830.     status_end();
  2831.     removelog();
  2832.  
  2833.     tty_defaults();
  2834.     tty_clear();
  2835.  
  2836.     return 0;
  2837. }
  2838.