1 /*
2 	+---------------------------------------------------------------+
3 	|								|
4 	|	Hugh F. Mahon						|
5 	|	begun Nov. 22, 1985					|
6 	|								|
7 	|	ae (another editor)					|
8 	+---------------------------------------------------------------+
9 
10 	$Header: /home/hugh/sources/aee/RCS/aee.c,v 1.82 2010/07/18 21:52:26 hugh Exp hugh $
11 
12 */
13 
14 /*
15  |	An easy to use, simple screen oriented editor.
16  |
17  |	THIS MATERIAL IS PROVIDED "AS IS".  THERE ARE
18  |	NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
19  |	MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
20  |	IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  |	FITNESS FOR A PARTICULAR PURPOSE.  Neither
22  |	Hewlett-Packard nor Hugh Mahon shall be liable
23  |	for errors contained herein, nor for
24  |	incidental or consequential damages in
25  |	connection with the furnishing, performance or
26  |	use of this material.  Neither Hewlett-Packard
27  |	nor Hugh Mahon assumes any responsibility for
28  |	the use or reliability of this software or
29  |	documentation.  This software and
30  |	documentation is totally UNSUPPORTED.  There
31  |	is no support contract available.  Hewlett-
32  |	Packard has done NO Quality Assurance on ANY
33  |	of the program or documentation.  You may find
34  |	the quality of the materials inferior to
35  |	supported materials.
36  |
37  |	This software is not a product of Hewlett-Packard, Co., or any
38  |	other company.  No support is implied or offered with this software.
39  |	You've got the source, and you're on your own.
40  |
41  |	This software may be distributed under the terms of Larry Wall's
42  |	Artistic license, a copy of which is included in this distribution.
43  |
44  |	This notice must be included with this software and any derivatives.
45  |
46  |	This software and documentation contains
47  |	proprietary information which is protected by
48  |	copyright.  All rights are reserved.
49  |
50  */
51 char *copyright_notice = "Copyright (c) 1986 - 1988, 1991 - 2002, 2009, 2010 Hugh Mahon.";
52 
53 char *long_notice[] = {
54 	"This software and documentation contains",
55 	"proprietary information which is protected by",
56 	"copyright.  All rights are reserved."
57 	};
58 
59 #include "aee_version.h"
60 
61 char *version_string = "@(#) aee (another easy editor) version "  AEE_VERSION  " " DATE_STRING " $Revision: 1.82 $";
62 
63 #include "aee.h"
64 
65 int eightbit;			/* eight bit character flag		*/
66 
67 struct stat buf;
68 
69 #ifndef NO_CATGETS
70 nl_catd catalog;
71 #endif /* NO_CATGETS */
72 
73 extern int errno;
74 
75 struct text *first_line;	/* first line of current buffer		*/
76 struct text *dlt_line;		/* structure for info on deleted line	*/
77 struct text *curr_line;		/* current line cursor is on		*/
78 struct text *fpste_line;	/* first line of select buffer		*/
79 struct text *cpste_line;	/* current paste/select line		*/
80 struct text *paste_buff;	/* first line of paste buffer		*/
81 struct text *pste_tmp;		/* temporary paste pointer		*/
82 struct text *tmp_line;		/* temporary line pointer		*/
83 struct text *srch_line;		/* temporary pointer for search routine */
84 
85 struct files *top_of_stack;
86 
87 struct bufr *first_buff;	/* first buffer in list			*/
88 struct bufr *curr_buff;		/* pointer to current buffer		*/
89 struct bufr *t_buff;		/* temporary pointer for buffers	*/
90 
91 struct tab_stops *tabs;
92 
93 struct del_buffs *undel_first;
94 struct del_buffs *undel_current;
95 
96 WINDOW *com_win;		/* command window			*/
97 WINDOW *help_win;		/* window for help facility		*/
98 int windows;			/* flag for windows or no windows	*/
99 WINDOW *info_win;
100 
101 int lines_moved;		/* number of lines moved in search	*/
102 int d_wrd_len;			/* length of deleted word		*/
103 int value;			/* temporary integer value		*/
104 int tmp_pos;			/* temporary position			*/
105 int tmp_vert;			/* temporary vertical position		*/
106 int tmp_horz;			/* temporary horizontal position	*/
107 int repl_length;		/* length of string to replace		*/
108 int pst_pos;			/* position in cpste_line->line		*/
109 int gold_count;			/* number of times to execute pressed key */
110 int fildes;			/* file descriptor			*/
111 int get_fd;			/* get file descriptor			*/
112 int write_fd;			/* write file descriptor		*/
113 int num_of_bufs;		/* the number of buffers that exist	*/
114 int temp_stdin;			/* temporary storage for stdin		*/
115 int temp_stdout;		/* temp storage for stdout descriptor	*/
116 int temp_stderr;		/* temp storage for stderr descriptor	*/
117 int pipe_out[2];		/* pipe file desc for output		*/
118 int pipe_in[2];			/* pipe file descriptors for input	*/
119 int line_wrap;			/* should line extend forever?		*/
120 int right_margin;		/* right margin	(if observ_margins = TRUE) */
121 int left_margin;		/* left margin				*/
122 int info_type;
123 int info_win_height = INFO_WIN_HEIGHT_DEF;
124 int local_LINES = 0;		/* copy of LINES, to detect when win resizes */
125 int local_COLS = 0;		/* copy of COLS, to detect when win resizes  */
126 int bit_bucket;			/* file descriptor to /dev/null		*/
127 int tab_spacing = 8;		/* spacing for tabs			*/
128 
129 /*
130  |	boolean flags
131  */
132 
133 char mark_text;			/* flag to indicate if MARK is active	*/
134 char journ_on;			/* flag for journaling			*/
135 char input_file;		/* indicate to read input file		*/
136 char recv_file;			/* indicate reading a file		*/
137 char edit;			/* continue executing while true	*/
138 char gold;			/* 'gold' function key pressed		*/
139 char recover;			/* set true if recover operation to occur */
140 char case_sen;			/* case sensitive search flag		*/
141 char change;			/* indicate changes have been made to file*/
142 char go_on;			/* loop control for help function	*/
143 char clr_cmd_line;		/* flag set to clear command line	*/
144 char literal;		/* is search string to be interpreted literally? */
145 char forward;	/* if TRUE, search after cursor, else search before cursor */
146 char echo_flag;			/* allow/disallow echo in init file	*/
147 char status_line;		/* place status info in the bottom line	*/
148 char overstrike;		/* overstrike / insert mode flag	*/
149 char indent;			/* auto-indent mode flag		*/
150 char expand;			/* expand tabs flag			*/
151 char shell_fork;
152 char out_pipe = FALSE;		/* flag that info is piped out		*/
153 char in_pipe = FALSE;		/* flag that info is piped in		*/
154 char observ_margins = FALSE;	/* should margins be observed		*/
155 char right_justify = FALSE;	/* justify right margin when formatting */
156 char free_d_line = FALSE;	/* free d_line (already freed from del list) */
157 char free_d_word = FALSE;	/* free d_word (already freed from del list) */
158 char info_window = TRUE;	/* is info window displayed?		*/
159 char auto_format = FALSE;	/* automatically format paragraph	*/
160 char formatted = FALSE;		/* has paragraph been formatted?	*/
161 char window_resize = FALSE;	/* flag to indicate a resize has occurred */
162 char change_dir_allowed = TRUE;	/* flag to indicate if chdir is allowed */
163 char restricted = FALSE;	/* flag to indicate restricted mode	*/
164 char com_win_initialized = FALSE;
165 char text_only = TRUE;		/* editor is to treat file being read as
166 				   text only (not a binary file)	*/
167 char ee_mode_menu = FALSE;	/* make main menu look more like ee's	*/
168 
169 long mask;			/* mask for sigblock			*/
170 #ifdef XAE
171 int win_width;			/* width and height of edit session window */
172 int win_height;
173 extern char *xsrch_string;
174 extern char *xold_string;
175 extern char *xnew_string;
176 extern Window testwin;
177 #endif
178 
179 char in_string[513];		/* input buffer string			*/
180 char *pst_line;			/* start of paste line			*/
181 char *pst_pnt;			/* current position within paste line	*/
182 char *pste1;			/* temporary pointers for cut/paste ops */
183 char *pste2;
184 char *pste3;
185 char *old_string;		/* old string to be replaced		*/
186 char *u_old_string;		/* upper case verson of old_string	*/
187 char *new_string;		/* new string to insert instead of old	*/
188 char *srch_str;			/* pointer for search string		*/
189 char *u_srch_str;		/* pointer to non-case sensitive search */
190 char *in_file_name;		/* name of input file and path		*/
191 char *short_file_name;		/* name of input file only		*/
192 char *journ;			/* name of journal file			*/
193 char *journal_dir = "";		/* name of journal directory		*/
194 char *out_file;			/* name of output file if not input file*/
195 char *tmp_file;			/* temporary file name			*/
196 char d_char;			/* deleted character			*/
197 char *d_word;			/* deleted word				*/
198 char *d_line;			/* deleted line				*/
199 char *term_type;		/* type of terminal being used		*/
200 char *help_line;			/* input line for help facility		*/
201 char *sline;			/* temporary line pointer for help fac	*/
202 char *subject;			/* subject user wants to learn about	*/
203 char *start_of_string;		/* start of search string		*/
204 char match_char;		/* character found by search for match	*/
205 char in_buff_name[128];		/* input buffer name			*/
206 char out_buff_name[128];	/* output buffer name			*/
207 char *start_at_line;		/* move to this line at start of session*/
208 char *print_command = "lp";	/* string to hold command for printing file */
209 char nohighlight = FALSE;
210 
211 char *ctr[32];			/* control key strings			*/
212 char ctr_changed[32];		/* control key strings changed flags	*/
213 char *g_ctr[32];		/* gold control key strings		*/
214 char g_ctr_changed[32];	/* gold control key strings changed 	*/
215 char *f[64];			/* function key strings			*/
216 char f_changed[64];		/* function key strings			*/
217 char *g_f[64];			/* gold function key strings		*/
218 char g_f_changed[64];		/* gold function key strings		*/
219 char *ctrl_table[] = {
220 	"^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G",
221 	"^H", "\t", "^J", "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R",
222 	"^S", "^T", "^U", "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]",
223 	"^^", "^_", "^?"
224 	};
225 char *keypads[5];		/* keypad keys from terminfo		*/
226 char *g_keypads[5];		/* keypad keys from terminfo		*/
227 
228 int in;				/* input character			*/
229 
230 FILE *fp;			/* file pointer for input		*/
231 FILE *outp;			/* pointer for output file		*/
232 FILE *temp_fp;			/* temporary file pointer		*/
233 FILE *get_fp;			/* read file pointer			*/
234 FILE *write_fp;			/* write file pointer			*/
235 
236 char info_data[MAX_HELP_LINES][MAX_HELP_COLS];
237 
238 struct edit_keys assignment[] = {
239 { "", "",  0, 0, 0, 0 },
240 { "", "",  0, 0, 0, 0 },
241 { "", "",  0, 0, 0, 0 },
242 { "", "",  0, 0, 0, 0 },
243 { "", "",  0, 0, 0, 0 },
244 { "", "",  0, 0, 0, 0 },
245 { "", "",  0, 0, 0, 0 },
246 { "", "",  0, 0, 0, 0 },
247 { "", "",  0, 0, 0, 0 },
248 { "", "",  0, 0, 0, 0 },
249 { "", "",  0, 0, 0, 0 },
250 { "", "",  0, 0, 0, 0 },
251 { "", "",  0, 0, 0, 0 },
252 { "", "",  0, 0, 0, 0 },
253 { "", "",  0, 0, 0, 0 },
254 { "", "",  0, 0, 0, 0 },
255 { "", "",  0, 0, 0, 0 },
256 { "", "",  0, 0, 0, 0 },
257 { "", "",  0, 0, 0, 0 },
258 { "", "",  0, 0, 0, 0 },
259 { "", "",  0, 0, 0, 0 },
260 { "", "",  0, 0, 0, 0 },
261 { "", "",  0, 0, 0, 0 },
262 { "", "",  0, 0, 0, 0 },
263 { "", "",  0, 0, 0, 0 },
264 { "", "",  0, 0, 0, 0 },
265 { "", "",  0, 0, 0, 0 },
266 { "", "",  0, 0, 0, 0 },
267 { "", "",  0, 0, 0, 0 },
268 { "", "",  0, 0, 0, 0 },
269 { "", "",  0, 0, 0, 0 },
270 { "", "",  0, 0, 0, 0 },
271 { "", "",  0, 0, 0, 0 },
272 { "", "",  0, 0, 0, 0 },
273 { "", "",  0, 0, 0, 0 },
274 { "", "",  0, 0, 0, 0 },
275 { "", "",  0, 0, 0, 0 },
276 { "", "",  0, 0, 0, 0 },
277 { "", "",  0, 0, 0, 0 },
278 { "", "",  0, 0, 0, 0 },
279 { "", "",  0, 0, 0, 0 },
280 { "", "",  0, 0, 0, 0 },
281 { "", "",  0, 0, 0, 0 },
282 { "", "",  0, 0, 0, 0 },
283 { "", "",  0, 0, 0, 0 },
284 { "", "",  0, 0, 0, 0 },
285 { "", "",  0, 0, 0, 0 },
286 { "", "",  0, 0, 0, 0 },
287 { "", "",  0, 0, 0, 0 },
288 { "", "",  0, 0, 0, 0 },
289 { "", "",  0, 0, 0, 0 },
290 { "", "",  0, 0, 0, 0 },
291 { "", "",  0, 0, 0, 0 },
292 { "", "",  0, 0, 0, 0 },
293 { "", "",  0, 0, 0, 0 },
294 { "", "",  0, 0, 0, 0 },
295 { "", "",  0, 0, 0, 0 },
296 { "", "",  0, 0, 0, 0 },
297 { "", "",  0, 0, 0, 0 },
298 { "", "",  0, 0, 0, 0 },
299 { "", "",  0, 0, 0, 0 },
300 { "", "",  0, 0, 0, 0 },
301 { "", "",  0, 0, 0, 0 },
302 { "", "",  0, 0, 0, 0 },
303 { "", "",  0, 0, 0, 0 },
304 { "", "",  0, 0, 0, 0 },
305 { "", "",  0, 0, 0, 0 },
306 { "", "",  0, 0, 0, 0 }
307 };
308 
309 
310 /*
311  |	allocate space here for the strings that will be in the menu
312  */
313 
314 struct menu_entries modes_menu[] = {
315 	{"", NULL, NULL, NULL, NULL, 0}, 	/* 0 title		*/
316 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 1      		*/
317 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 2      		*/
318 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 3      		*/
319 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 4      		*/
320 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 5      		*/
321 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 6      		*/
322 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 7      		*/
323 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 8      		*/
324 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 9      		*/
325 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 10     		*/
326 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 11     		*/
327 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 12     		*/
328 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 13     		*/
329 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 14     		*/
330 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 15 text/binary mode  */
331 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 16 dos/ux text file  */
332 	{"", NULL, NULL, NULL, NULL, -1}, 	/* 17 save configuration */
333 	{NULL, NULL, NULL, NULL, NULL, -1}
334 	};
335 
336 int modes_initialized = FALSE;
337 
338 char *mode_strings[NUM_MODES_ITEMS];
339 
340 struct menu_entries config_dump_menu[] = {
341 	{"", NULL, NULL, NULL, NULL, 0},
342 	{"", NULL, NULL, NULL, NULL, -1},
343 	{"", NULL, NULL, NULL, NULL, -1},
344 	{NULL, NULL, NULL, NULL, NULL, -1}
345 	};
346 
347 struct menu_entries leave_menu[] = {
348 	{"", NULL, NULL, NULL, NULL, 0},
349 	{"", NULL, NULL, NULL, NULL, -1},
350 	{"", NULL, NULL, NULL, NULL, -1},
351 	{NULL, NULL, NULL, NULL, NULL, -1}
352 	};
353 
354 struct menu_entries leave_menu_2[] = {
355 	{"", NULL, NULL, NULL, NULL, 0},
356 	{"", NULL, NULL, NULL, NULL, -1},
357 	{"", NULL, NULL, NULL, NULL, -1},
358 	{NULL, NULL, NULL, NULL, NULL, -1}
359 	};
360 
361 struct menu_entries file_menu[] = {
362 	{"", NULL, NULL, NULL, NULL, 0},
363 	{"", NULL, NULL, file_op, NULL, READ_FILE},
364 	{"", NULL, NULL, file_op, NULL, WRITE_FILE},
365 	{"", NULL, NULL, file_op, NULL, SAVE_FILE},
366 	{"", NULL, NULL, NULL, print_buffer, -1},
367 	{"", NULL, NULL, NULL, recover_op, -1},
368 	{NULL, NULL, NULL, NULL, NULL, -1}
369 	};
370 
371 struct menu_entries search_menu[] = {
372 	{"", NULL, NULL, NULL, NULL, 0},
373 	{"", NULL, NULL, search_prompt, NULL, TRUE},
374 	{"", NULL, NULL, NULL, search_op, -1},
375 	{"", NULL, NULL, repl_prompt, NULL, TRUE},
376 	{"", NULL, NULL, NULL, replace, -1},
377 	{NULL, NULL, NULL, NULL, NULL, -1}
378 	};
379 
380 struct menu_entries spell_menu[] = {
381 	{"", NULL, NULL, NULL, NULL, 0},
382 	{"", NULL, NULL, NULL, spell_op, -1},
383 	{"", NULL, NULL, NULL, ispell_op, -1},
384 	{NULL, NULL, NULL, NULL, NULL, -1}
385 	};
386 
387 struct menu_entries misc_menu[] = {
388 	{"", NULL, NULL, NULL, NULL, 0},
389 	{"", NULL, NULL, NULL, Format, -1},
390 	{"", NULL, NULL, NULL, shell_op, -1},
391 	{"", menu_op, spell_menu, NULL, NULL, -1},
392 	{NULL, NULL, NULL, NULL, NULL, -1}
393 	};
394 
395 struct menu_entries edit_menu[] = {
396 	{"", NULL, NULL, NULL, NULL, 0},
397 	{"", NULL, NULL, slct, NULL, Mark},
398 	{"", NULL, NULL, NULL, copy, -1},
399 	{"", NULL, NULL, NULL, cut, -1},
400 	{"", NULL, NULL, NULL, paste, -1},
401 	{NULL, NULL, NULL, NULL, NULL, -1}
402 	};
403 
404 char *main_menu_strings[10];
405 char *ee_mode_main_menu_strings[10];
406 
407 struct menu_entries main_menu[] = {
408 	{"", NULL, NULL, NULL, NULL, 0},
409 	{"", NULL, NULL, NULL, leave_op, -1},
410 	{"", NULL, NULL, NULL, help, -1},
411 	{"", menu_op, edit_menu, NULL, NULL, -1},
412 	{"", menu_op, file_menu, NULL, NULL, -1},
413 	{"", NULL, NULL, NULL, redraw, -1},
414 	{"", NULL, NULL, NULL, modes_op, -1},
415 	{"", menu_op, search_menu, NULL, NULL, -1},
416 	{"", menu_op, misc_menu, NULL, NULL, -1},
417 	{NULL, NULL, NULL, NULL, NULL, -1}
418 	};
419 
420 struct menu_entries del_buff_menu[] = {
421 	{"", NULL, NULL, NULL, NULL, MENU_WARN},
422 	{"", NULL, NULL, file_op, NULL, SAVE_FILE},
423 	{"", NULL, NULL, NULL, NULL, -1},
424 	{"", NULL, NULL, NULL, NULL, -1},
425 	{NULL, NULL, NULL, NULL, NULL, -1}
426 	};
427 
428 struct menu_entries rae_err_menu[] = {
429 	{"", NULL, NULL, NULL, NULL, MENU_WARN},
430 	{"", NULL, NULL, NULL, NULL, -1},
431 	{NULL, NULL, NULL, NULL, NULL, -1}
432 	};
433 
434 
435 char *commands[72];
436 char *init_strings[41];
437 
438 /*
439  |	memory debugging macros
440  */
441 
442 #ifdef DEBUG
443 FILE *error_fp;
444 #endif /* DEBUG */
445 
446 /*
447  |	declaration for localizable strings
448  */
449 
450 char *ae_help_file, *SL_line_str, *SL_col_str, *SL_lit_str, *SL_nolit_str;
451 char *SL_fwd_str, *SL_rev_str, *SL_over_str, *SL_insrt_str, *SL_indent_str;
452 char *SL_noindnt_str, *SL_marg_str, *SL_nomarg_str, *SL_mark_str, *ascii_code_str;
453 char *left_err_msg, *right_err_msg, *help_err_msg, *prompt_for_more, *topic_prompt;
454 char *topic_err_msg, *continue_prompt, *printing_msg, *EXPAND_str, *NOEXPAND_str;
455 char *NOJUSTIFY_str, *JUSTIFY_str, *EXIT_str, *QUIT_str, *AUTOFORMAT_str;
456 char *NOAUTOFORMAT_str, *INFO_str, *NOINFO_str, *TABS_str, *UNTABS_str;
457 char *WRITE_str, *READ_str, *SAVE_str, *LITERAL_str, *NOLITERAL_str;
458 char *STATUS_str, *NOSTATUS_str, *MARGINS_str, *NOMARGINS_str, *INDENT_str;
459 char *NOINDENT_str, *OVERSTRIKE_str, *NOOVERSTRIKE_str, *LEFTMARGIN_str, *RIGHTMARGIN_str;
460 char *LINE_str, *FILE_str, *COPYRIGHT_str, *CHARACTER_str, *REDRAW_str;
461 char *RESEQUENCE_str, *AUTHOR_str, *VERSION_str, *CASE_str, *NOCASE_str;
462 char *EIGHT_str, *NOEIGHT_str, *WINDOWS_str, *NOWINDOWS_str, *DEFINE_str;
463 char *SHOW_str, *HELP_str, *PRINT_str, *BUFFER_str, *DELETE_str;
464 char *GOLD_str, *tab_msg, *file_write_prompt_str, *file_read_prompt_str, *left_mrg_err_msg;
465 char *right_mrg_err_msg, *left_mrg_setting, *right_mrg_setting, *line_num_str, *lines_from_top;
466 char *total_lines_str, *current_file_str, *char_str, *key_def_msg, *unkn_syntax_msg;
467 char *current_buff_msg, *unkn_cmd_msg, *usage_str, *read_only_msg, *no_rcvr_fil_msg;
468 char *cant_opn_rcvr_fil_msg, *fin_read_file_msg, *rcvr_op_comp_msg, *file_is_dir_msg, *path_not_a_dir_msg;
469 char *access_not_allowed_msg, *new_file_msg, *cant_open_msg, *bad_rcvr_msg, *reading_file_msg;
470 char *file_read_lines_msg, *other_buffs_exist_msg, *changes_made_prompt, *no_write_access_msg, *file_exists_prompt;
471 char *cant_creat_fil_msg, *writing_msg, *file_written_msg, *searching_msg, *fwd_srch_msg;
472 char *rev_srch_msg, *str_str, *not_fnd_str, *search_prompt_str, *mark_not_actv_str;
473 char *mark_active_str, *mark_alrdy_actv_str, *no_buff_named_str, *press_ret_to_cont_str, *fn_GOLD_str;
474 char *fn_DL_str, *fn_DC_str, *fn_CL_str, *fn_NP_str, *fn_PP_str;
475 char *fn_NB_str, *fn_PB_str, *fn_UDL_str, *fn_UDC_str, *fn_DW_str;
476 char *fn_UDW_str, *fn_UND_str, *fn_EOL_str, *fn_BOL_str, *fn_BOT_str;
477 char *fn_EOT_str, *fn_FORMAT_str, *fn_MARGINS_str, *fn_NOMARGINS_str, *fn_IL_str;
478 char *fn_PRP_str, *fn_RP_str, *fn_MC_str, *fn_PSRCH_str, *fn_SRCH_str;
479 char *fn_AL_str, *fn_AW_str, *fn_AC_str, *fn_PW_str, *fn_CUT_str;
480 char *fn_FWD_str, *fn_REV_str, *fn_MARK_str, *fn_UNMARK_str, *fn_APPEND_str;
481 char *fn_PREFIX_str, *fn_COPY_str, *fn_CMD_str, *fn_PST_str, *fn_RD_str;
482 char *fn_UP_str, *fn_DOWN_str, *fn_LEFT_str, *fn_RIGHT_str, *fn_BCK_str;
483 char *fn_CR_str, *fn_EXPAND_str, *fn_NOEXPAND_str, *fn_EXIT_str, *fn_QUIT_str;
484 char *fn_LITERAL_str, *fn_NOLITERAL_str, *fn_STATUS_str, *fn_NOSTATUS_str, *fn_INDENT_str;
485 char *fn_NOINDENT_str, *fn_OVERSTRIKE_str, *fn_NOOVERSTRIKE_str, *fn_CASE_str, *fn_NOCASE_str;
486 char *fn_WINDOWS_str, *fn_NOWINDOWS_str, *fn_HELP_str, *fn_MENU_str, *fwd_mode_str;
487 char *rev_mode_str, *ECHO_str, *cmd_prompt, *PRINTCOMMAND_str, *replace_action_prompt;
488 char *replace_prompt_str, *replace_r_char, *replace_skip_char, *replace_all_char, *quit_char;
489 char *yes_char, *no_char, *cant_find_match_str, *fmting_par_msg, *cancel_string;
490 char *menu_too_lrg_msg, *shell_cmd_prompt, *shell_echo_msg, *spell_in_prog_msg, *left_marg_prompt;
491 char *left_mrgn_err_msg, *right_mrgn_prompt, *right_mrgn_err_msg, *cant_redef_msg, *buff_msg;
492 char *cant_chng_while_mark_msg, *too_many_parms_msg, *buff_is_main_msg, *cant_del_while_mark, *main_buffer_name;
493 char *cant_del_buf_msg, *HIGHLIGHT_str, *NOHIGHLIGHT_str;
494 char *non_unique_cmd_msg;
495 char *ON, *OFF;
496 char *save_file_name_prompt, *file_not_saved_msg, *cant_reopen_journ;
497 char *write_err_msg, *jrnl_dir, *CD_str ;
498 char *no_dir_entered_msg,  *path_not_dir_msg, *path_not_permitted_msg;
499 char *path_chng_failed_msg, *no_chng_dir_msg, *SPACING_str, *SPACING_msg;
500 char *help_file_str;
501 char *pwd_cmd_str, *pwd_err_msg;
502 char *no_file_string, *no_chng_no_save, *changes_made_title;
503 char *save_then_delete, *dont_delete, *delete_anyway_msg;
504 char *edit_cmd_str, *edit_err_msg, *restricted_msg, *rae_no_file_msg;
505 char *more_above_str, *more_below_str, *recover_name_prompt;
506 char *no_file_name_string, *recover_menu_title, *other_recover_file_str;
507 char *info_win_height_prompt, *info_win_height_err, *info_win_height_cmd_str;
508 char *info_win_height_msg_str;
509 char *conf_not_saved_msg;	/* message if unable to save configuration */
510 char *conf_dump_err_msg;
511 char *conf_dump_success_msg;
512 char *info_help_msg;
513 char *unix_text_msg, *dos_text_msg;
514 char *text_cmd, *binary_cmd;
515 char *text_msg, *binary_msg, *dos_msg, *unix_msg;
516 char *DIFF_str;
517 char *ee_mode_str;
518 char *journal_str, *journal_err_str;
519 
520 int
main(argc,argv)521 main(argc, argv)		/* beginning of main program		*/
522 int argc;
523 char *argv[];
524 {
525 #ifdef DEBUG
526 	error_fp = fopen("/tmp/ae.mem_debug", "w");
527 #endif /* DEBUG */
528 
529 #ifdef DIAG_DBG
530 		if (!strcmp(argv[argc-1], "-DEBUG"))
531 		{
532 /*
533  |	The following code will start an xterm which will in turn execute
534  |	a debugger and "adopt" the process, so it can be debugged.
535  |
536  |	To compile to allow debug, use the command:
537  |
538  |		CFLAGS='-DDIAG_DBG -g' make
539  |
540  */
541 
542 			int child_id;
543 			char command_line[256];
544 
545 			child_id = getpid();
546 			if (!fork())
547 			{
548 				sprintf(command_line,
549 	      			"xterm -geom =80x40 -fg wheat -bg DarkSlateGrey -n %s -e gdb %s %d",
550 					"hello",  argv[0], child_id);
551 				printf("command_line=%s\n", command_line);
552 				execl("/bin/sh", "sh", "-c", command_line, NULL);
553 				fprintf(stderr, "could not exec new window\n");
554 				exit(1);
555 			}
556 
557 /*
558  |	When in debugger, set child_id to zero (p child_id=0) to continue
559  |	executing the software.
560  */
561 
562 			while (child_id != 0)
563 				;
564 			argc--;
565 		}
566 #endif
567 
568 	eightbit = FALSE;
569 #ifndef DIAG_DBG
570 	mask = 077777777 & (~020000) & (~02);
571 	for (value = 1; value < 24; value++)
572 	{
573 		if ((value != SIGCHLD) && (value != SIGALRM) && (value != SIGSEGV)
574 #ifdef XAE
575 		   && (value != SIGTSTP)
576 #endif /* XAE */
577 
578 		)
579 			signal(value, SIG_IGN);
580 		else
581 			signal(value, SIG_DFL);
582 	}
583 #endif	/* ifndef DIAG	*/
584 	signal(SIGINT, abort_edit);
585 #ifdef XAE
586 	win_width = 0;
587 	win_height = 0;
588 #endif
589 
590 
591 
592 	start_at_line = NULL;
593 	d_word = NULL;
594 	d_wrd_len = 0;
595 	d_line = xalloc(1);
596 	*d_line = '\0';
597 	tabs = (struct tab_stops *) xalloc(sizeof( struct tab_stops));
598 	tabs->next_stop = NULL;
599 	tabs->column = 0;
600 	dlt_line = txtalloc();
601 	dlt_line->line = d_line;
602 	dlt_line->line_length = 1;
603 	paste_buff = NULL;
604 	status_line = FALSE;
605 	srch_str = u_srch_str = NULL;
606 	u_old_string = new_string = old_string = NULL;
607 
608 	/*
609 	 |	initialize literal strings
610 	 */
611 
612 	strings_init();
613 
614 	first_buff = curr_buff = buf_alloc();
615 	first_buff->name = main_buffer_name;
616 	first_buff->first_line = txtalloc();
617 	curr_buff->curr_line = curr_buff->first_line;
618 	first_buff->next_buff = NULL;
619 	first_buff->footer = NULL;
620 	first_buff->main_buffer = TRUE;
621 	first_buff->edit_buffer = TRUE;
622 	curr_buff->curr_line->line = curr_buff->pointer = xalloc(10);
623 	curr_buff->curr_line->line_length = 1;
624 	curr_buff->curr_line->max_length = 10;
625 	curr_buff->curr_line->prev_line = NULL;
626 	curr_buff->curr_line->next_line = NULL;
627 	curr_buff->curr_line->line_number = 1;
628 	curr_buff->curr_line->vert_len = 1;
629 	curr_buff->num_of_lines = 1;
630 	curr_buff->absolute_lin = 1;
631 	num_of_bufs = 1;
632 	curr_buff->position = 1;
633 	curr_buff->abs_pos = curr_buff->scr_pos = 0;
634 	curr_buff->scr_vert = 0;
635 	curr_buff->scr_horz = 0;
636 	bit_bucket = open("/dev/null", O_WRONLY);
637 	forward = windows = edit = TRUE;
638 	observ_margins = literal = FALSE;
639 	expand = indent = overstrike = FALSE;
640 	clr_cmd_line = change = mark_text = gold = case_sen = FALSE;
641 	in_pipe = out_pipe = FALSE;
642 	shell_fork = TRUE;
643 	left_margin = 0;
644 	right_margin = 0;
645 	gold_count = 0;
646 	info_type = CONTROL_KEYS;
647 	top_of_stack = NULL;
648 	echo_flag = TRUE;
649 	journ_on = TRUE;
650 	input_file = FALSE;
651 	recv_file = FALSE;
652 	recover = FALSE;
653 	undel_init();
654 	init_keys();
655 	ae_init();
656 	get_options(argc, argv);
657 	set_up_term();		/* initialize terminal		*/
658 	get_key_assgn();
659 	com_win = newwin(1, COLS, LINES-1, 0);
660 	com_win_initialized = TRUE;
661 	curr_buff->last_col = COLS - 1;
662 	curr_buff->last_line = LINES - 2;
663 	first_buff->lines = LINES - 1;
664 	curr_buff->window_top = 0;
665 	if (info_window)
666 	{
667 		info_win = newwin(info_win_height, COLS, 0, 0);
668 		paint_info_win();
669 		curr_buff->window_top = info_win_height;
670 		first_buff->win = newwin(LINES-info_win_height-1, COLS, info_win_height, 0);
671 		first_buff->lines = LINES - info_win_height - 1;
672 		curr_buff->last_line = first_buff->lines - 1;
673 	}
674 	else
675 		first_buff->win = newwin(LINES-1, COLS, 0, 0);
676 	keypad(curr_buff->win, TRUE);
677 	nodelay(curr_buff->win, FALSE);
678 	idlok(curr_buff->win, TRUE);
679 
680 	/*
681 	 |	If restricted mode, there must have been a file specified on
682 	 |	the invoking command line.
683 	 */
684 	if ((restrict_mode()) && (top_of_stack == NULL))
685 	{
686 		wmove(com_win, 0, 0);
687 		werase(com_win);
688 		wrefresh(com_win);
689 		menu_op(rae_err_menu);
690 		abort_edit(0);
691 	}
692 
693 
694 	if (top_of_stack != NULL)
695 		tmp_file = top_of_stack->name;
696 	else
697 		tmp_file = "";
698 	input_file = TRUE;
699 	recv_file = TRUE;
700 
701 	if (top_of_stack != NULL)
702 		top_of_stack = top_of_stack->next_name;
703 
704 	value = check_fp();
705 
706 	input_file = FALSE;
707 	recv_file = FALSE;
708 
709 	if (right_margin == 0)
710 		right_margin = COLS - 1;
711 
712 	wmove(curr_buff->win, curr_buff->last_line, 0);
713 	wstandout(curr_buff->win);
714 	wprintw(curr_buff->win, "aee, %s", copyright_notice);
715 	wstandend(curr_buff->win);
716 	wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
717 	wrefresh(curr_buff->win);
718 	midscreen(curr_buff->scr_vert, curr_buff->position);
719 
720 	while (edit)
721 	{
722 		get_input(curr_buff->win);
723 		if (clr_cmd_line)
724 		{
725 			clr_cmd_line = FALSE;
726 			werase(com_win);
727 			wrefresh(com_win);
728 		}
729 		keyboard();
730 		status_display();
731 		wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
732 		wrefresh(curr_buff->win);
733 	}
734 	exit(0);
735 }
736 
737 void
get_input(win_ptr)738 get_input(win_ptr)
739 WINDOW *win_ptr;
740 {
741 	int value;
742 #ifndef XAE
743 	static int counter = 0;
744 	pid_t parent_pid;
745 #endif /* XAE */
746 
747 	resize_check();
748 
749 #ifdef XAE
750 	event_manage();
751 #endif /* XAE */
752 
753 	in = wgetch(win_ptr);
754 	value = alarm(0);
755 	signal(SIGALRM, dummy);
756 
757 	if (in == EOF)		/* somehow lost contact with input	*/
758 		abort_edit(0);
759 
760 #ifndef XAE
761 	/*
762 	 |	The above check used to work to detect if the parent
763 	 |	process died, but now it seems we need a more
764 	 |	sophisticated check.
765 	 |
766 	 |	Note that this check is only required for the terminal
767 	 |	version, and may be undesireable for xae, so is ifdef'd
768 	 |	accordingly.
769 	 */
770 	if (counter > 50)
771 	{
772 		parent_pid = getppid();
773 		if (parent_pid == 1)
774 			abort_edit(0);
775 		else
776 			counter = 0;
777 	}
778 	else
779 		counter++;
780 #endif /* !XAE */
781 }
782 
783 void
status_display()784 status_display()	/* display status line			*/
785 {
786 	if ((status_line) && (!clr_cmd_line))
787 	{
788 		werase(com_win);
789 		wmove(com_win, 0, 0);
790 
791 		if (curr_buff->edit_buffer)
792 		{
793 			if (curr_buff->file_name != NULL)
794 				wprintw(com_win, "%c%s  ", CHNG_SYMBOL(curr_buff->changed), curr_buff->file_name);
795 			else
796 				wprintw(com_win, "%c[%s]  ", CHNG_SYMBOL(curr_buff->changed), no_file_string);
797 		}
798 		else
799 		{
800 			if (curr_buff->name != NULL)
801 				wprintw(com_win, "%c->%s  ", CHNG_SYMBOL(curr_buff->changed), curr_buff->name);
802 			else
803 				wprintw(com_win, "%c[%s]  ", CHNG_SYMBOL(curr_buff->changed), no_file_string);
804 		}
805 
806 		wmove(com_win, 0, 16);
807 		wclrtoeol(com_win);
808 		wmove(com_win, 0, 18);
809 		wprintw(com_win, SL_line_str, curr_buff->curr_line->line_number);
810 		wmove(com_win, 0, 30);
811 		wprintw(com_win, SL_col_str, curr_buff->scr_pos);
812 		wmove(com_win, 0, 40);
813 		if (literal)
814 			wprintw(com_win, SL_lit_str);
815 		else
816 			wprintw(com_win, SL_nolit_str);
817 		if (forward)
818 			wprintw(com_win, SL_fwd_str);
819 		else
820 			wprintw(com_win, SL_rev_str);
821 		if (overstrike)
822 			wprintw(com_win, SL_over_str);
823 		else
824 			wprintw(com_win, SL_insrt_str);
825 		if (indent)
826 			wprintw(com_win, SL_indent_str);
827 		else
828 			wprintw(com_win, SL_noindnt_str);
829 		if (observ_margins)
830 			wprintw(com_win, SL_marg_str);
831 		else
832 			wprintw(com_win, SL_nomarg_str);
833 		if (mark_text)
834 		{
835 			wstandout(com_win);
836 			wprintw(com_win, SL_mark_str);
837 			wstandend(com_win);
838 		}
839 		else if (text_only)
840 		{
841 			wprintw(com_win, "%s",
842 			  curr_buff->dos_file ? dos_text_msg : unix_text_msg);
843 		}
844 
845 		if (curr_buff->footer != NULL)
846 		{
847 			wmove(curr_buff->footer, 0,0);
848 			wstandout(curr_buff->footer);
849 			wprintw(curr_buff->footer, "%c", CHNG_SYMBOL(curr_buff->changed) );
850 			wstandend(curr_buff->footer);
851 			wrefresh(curr_buff->footer);
852 		}
853 		wrefresh(com_win);
854 	}
855 }
856 
857 char *
858 #ifndef DEBUG
xalloc(size)859 xalloc(size)	/* allocate memory, report if errors	*/
860 int size;	/* size of memory to allocate		*/
861 #else
862 dxalloc(size, line_num)
863 int size;
864 int line_num;
865 #endif /* DEBUG */
866 {
867 	int counter;
868 	char *memory;
869 
870 #ifdef DEBUG
871 	fprintf(error_fp, "m s=%d, l#=%d\n", size, line_num);
872 	fflush(error_fp);
873 #endif /*	DEBUG */
874 
875 	if (size == 0)
876 		size++;
877 	if ((memory = malloc(size)) == NULL)
878 	{
879 		counter = 0;
880 		werase(com_win);
881 		wmove(com_win, 0,0);
882 		wstandout(com_win);
883 		wprintw(com_win, "memory allocation errors, please wait");
884 		wstandend(com_win);
885 		wrefresh(com_win);
886 		clr_cmd_line = TRUE;
887 		while (((memory = malloc(size)) == NULL) && (counter < 10000))
888 			counter++;
889 		if (memory == NULL)
890 			abort_edit(0);
891 		werase(com_win);
892 	}
893 	return(memory);
894 }
895 
896 char *
897 #ifndef DEBUG
resiz_line(factor,rline,rpos)898 resiz_line(factor, rline, rpos)	/* resize the line to length + factor*/
899 int factor;		/* resize factor				*/
900 struct text *rline;	/* pointer to line structure			*/
901 int rpos;		/* position in line				*/
902 #else
903 dresiz_line(factor, rline, rpos, line_num)
904 int factor;		/* resize factor				*/
905 struct text *rline;	/* pointer to line structure			*/
906 int rpos;		/* position in line				*/
907 int line_num;
908 #endif
909 {
910 	char *rpoint;
911 	int resiz_var;
912 
913 #ifdef DEBUG
914 	fprintf(error_fp, "r s=%d, l#=%d\n", factor, line_num);
915 	fflush(error_fp);
916 #endif /*	DEBUG */
917 
918 	rline->max_length += factor;
919 	while ((rpoint = realloc(rline->line, rline->max_length )) == NULL)
920 		;
921 	rline->line = rpoint;
922 	for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++)
923 		rpoint++;
924 	return(rpoint);
925 }
926 
927 void
dummy(foo)928 dummy(foo)
929 int foo;
930 {/*this is a dummy function to eliminate any unresolved signals		*/
931 }
932 
933 void
insert(character)934 insert(character)		/* insert character into line		*/
935 int character;			/* new character			*/
936 {
937 	int counter;
938 	char *temp;		/* temporary pointer			*/
939 	char *temp2;		/* temporary pointer			*/
940 	int temp_overstrike;
941 
942 	if ((observ_margins) && (curr_buff->scr_pos < left_margin))
943 	{
944 		temp_overstrike = overstrike;
945 		overstrike = FALSE;
946 		counter = left_margin;
947 		left_margin = 0;
948 		while (curr_buff->scr_pos < counter)
949 			insert(' ');
950 		left_margin = counter;
951 		overstrike = temp_overstrike;
952 	}
953 	change = TRUE;
954 	curr_buff->curr_line->changed = TRUE;
955 	curr_buff->changed = TRUE;
956 	if ((!overstrike) || (curr_buff->position == curr_buff->curr_line->line_length))
957 	{
958 		if ((curr_buff->curr_line->max_length - curr_buff->curr_line->line_length) < 5)
959 			curr_buff->pointer = resiz_line(10, curr_buff->curr_line, curr_buff->position);
960 		curr_buff->curr_line->line_length++;
961 		temp = curr_buff->pointer;
962 		counter = curr_buff->position;
963 		while (counter < curr_buff->curr_line->line_length)	/* find end of line */
964 		{
965 			counter++;
966 			temp++;
967 		}
968 		temp++;			/* increase length of line by one	*/
969 		while (curr_buff->pointer < temp)
970 		{
971 			temp2=temp - 1;
972 			*temp= *temp2;	/* shift characters over by one		*/
973 			temp--;
974 		}
975 	}
976 	*curr_buff->pointer = character;	/* insert new character			*/
977 	if (curr_buff->position != (curr_buff->curr_line->line_length - 1))
978 		counter = (scanline(curr_buff->curr_line, curr_buff->curr_line->line_length) / COLS) + 1;
979 	else
980 		counter = ((curr_buff->scr_pos + len_char(*curr_buff->pointer, curr_buff->scr_pos)) / COLS) + 1;
981 	if (counter > curr_buff->curr_line->vert_len)
982 	{
983 		curr_buff->curr_line->vert_len = counter;
984 		if (curr_buff->scr_vert < curr_buff->last_line)
985 		{
986 			wmove(curr_buff->win, (curr_buff->scr_vert+1), 0);
987 			winsertln(curr_buff->win);
988 		}
989 	}
990 	wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
991 	wclrtoeol(curr_buff->win);
992 	if ((mark_text) && (((pst_pos == cpste_line->line_length) && (cpste_line->next_line == NULL)) || (overstrike)))
993 		right(TRUE);
994 	else
995 	{
996 		counter = curr_buff->scr_horz + len_char(character, curr_buff->scr_pos);
997 		if (counter > curr_buff->last_col)
998 		{
999 			counter = curr_buff->scr_vert + 1;
1000 			if (counter > curr_buff->last_line)
1001 			{
1002 				wmove(curr_buff->win, 0, 0);
1003 				wdeleteln(curr_buff->win);
1004 				wmove(curr_buff->win, curr_buff->scr_vert-1, curr_buff->scr_horz);
1005 			}
1006 		}
1007 		if ((character < 32) || (character > 126))
1008 			curr_buff->scr_horz += out_char(curr_buff->win, character, curr_buff->scr_pos, curr_buff->scr_vert, 0);
1009 		else
1010 		{
1011 			waddch(curr_buff->win, character);
1012 			curr_buff->scr_horz++;
1013 		}
1014 		curr_buff->abs_pos = curr_buff->scr_pos += len_char(*curr_buff->pointer, curr_buff->scr_pos);
1015 		curr_buff->pointer++;
1016 		curr_buff->position++;
1017 		if (curr_buff->scr_horz > curr_buff->last_col)
1018 		{
1019 			curr_buff->scr_horz = curr_buff->scr_pos % COLS;
1020 			if (curr_buff->scr_vert < curr_buff->last_line)
1021 				curr_buff->scr_vert++;
1022 		}
1023 	}
1024 	draw_line(curr_buff->scr_vert, curr_buff->scr_pos, curr_buff->pointer, curr_buff->position, curr_buff->curr_line);
1025 	if ((observ_margins) && (right_margin < curr_buff->scr_pos))
1026 	{
1027 		counter = curr_buff->position;
1028 		while (curr_buff->scr_pos > right_margin)
1029 			prev_word();
1030 		if (curr_buff->scr_pos == 0)
1031 		{
1032 			while (curr_buff->position < counter)
1033 				right(TRUE);
1034 		}
1035 		else
1036 		{
1037 			counter -= curr_buff->position;
1038 			insert_line(TRUE);
1039 			for (value = 0; value < counter; value++)
1040 				right(TRUE);
1041 		}
1042 	}
1043 
1044 	if ((auto_format) && ((character == '\t') || ((character == ' ') && (!formatted))))
1045 		Auto_Format();
1046 	else if ((character != ' ') && (character != '\t'))
1047 		formatted = FALSE;
1048 }
1049 
1050 int
scanline(m_line,pos)1051 scanline(m_line, pos)	/* find the proper horizontal position for the current position in the line */
1052 struct text *m_line;
1053 int pos;
1054 {
1055 	int temp;
1056 	int count;
1057 	char *ptr;
1058 
1059 	ptr = m_line->line;
1060 	count = 1;
1061 	temp = 0;
1062 	while (count < pos)
1063 	{
1064 		if ((*ptr >= 0) && (*ptr <= 8))
1065 			temp += 2;
1066 		else if (*ptr == 9)
1067 			temp += tabshift(temp);
1068 		else if ((*ptr >= 10) && (*ptr <= 31))
1069 			temp += 2;
1070 		else if ((*ptr >= 32) && (*ptr < 127))
1071 			temp++;
1072 		else if (*ptr == 127)
1073 			temp += 2;
1074 		else if (!eightbit)
1075 			temp += 5;
1076 		else
1077 			temp++;
1078 		ptr++;
1079 		count++;
1080 	}
1081 	return(temp);
1082 }
1083 
1084 void
tab_insert()1085 tab_insert()	/* insert a tab or spaces according to value of 'expand' */
1086 {
1087 	int temp;
1088 	int counter;
1089 
1090 	if (expand)
1091 	{
1092 		counter = tabshift(curr_buff->scr_pos);
1093 		for (temp = 0; temp < counter; temp++)
1094 			insert(' ');
1095 		if (auto_format)
1096 			Auto_Format();
1097 	}
1098 	else
1099 		insert('\t');
1100 }
1101 
1102 void
unset_tab(string)1103 unset_tab(string)	/* remove tab setting			*/
1104 char *string;
1105 {
1106 	char *pointer;
1107 	int column;
1108 	int loop_on;
1109 	struct tab_stops *temp_stack_point;
1110 	struct tab_stops *stack_point;
1111 
1112 	pointer = string;
1113 	while (*pointer != '\0')
1114 	{
1115 		while (((*pointer < '0') || (*pointer > '9')) && (*pointer != '\0'))
1116 			pointer++;
1117 		column = atoi(pointer);
1118 		temp_stack_point = tabs;
1119 		if (column > 0)
1120 		{
1121 			loop_on = TRUE;
1122 			while ((temp_stack_point->next_stop != NULL) && (loop_on))
1123 			{
1124 				if (temp_stack_point->next_stop->column != column)
1125 					temp_stack_point = temp_stack_point->next_stop;
1126 				else
1127 					loop_on = FALSE;
1128 			}
1129 			if (temp_stack_point->next_stop != NULL)
1130 			{
1131 				stack_point = temp_stack_point->next_stop;
1132 				temp_stack_point->next_stop = stack_point->next_stop;
1133 				free(stack_point);
1134 			}
1135 		}
1136 		while (((*pointer >= '0') && (*pointer <= '9')) && (*pointer != '\0'))
1137 			pointer++;
1138 	}
1139 }
1140 
1141 void
tab_set(string)1142 tab_set(string)	/* get tab settings from the string (columns)	*/
1143 char *string;
1144 {
1145 	char *pointer;
1146 	int column;
1147 	int loop_on;
1148 	struct tab_stops *temp_stack_point;
1149 	struct tab_stops *stack_point;
1150 
1151 	pointer = string;
1152 	while (*pointer != '\0')
1153 	{
1154 		while (((*pointer < '0') || (*pointer > '9')) && (*pointer != '\0'))
1155 			pointer++;
1156 		column = atoi(pointer);
1157 		temp_stack_point = tabs;
1158 		if (column > 0)
1159 		{
1160 			loop_on = TRUE;
1161 			while ((temp_stack_point->next_stop != NULL) && (loop_on))
1162 			{
1163 				if (temp_stack_point->next_stop->column <= column)
1164 					temp_stack_point = temp_stack_point->next_stop;
1165 				else
1166 					loop_on = FALSE;
1167 			}
1168 			if ((column > temp_stack_point->column) && (column != temp_stack_point->column))
1169 			{
1170 				stack_point = (struct tab_stops *) xalloc(sizeof( struct tab_stops));
1171 				stack_point->column = column;
1172 				stack_point->next_stop = temp_stack_point->next_stop;
1173 				temp_stack_point->next_stop = stack_point;
1174 			}
1175 		}
1176 		while (((*pointer >= '0') && (*pointer <= '9')) && (*pointer != '\0'))
1177 			pointer++;
1178 	}
1179 }
1180 
1181 int
tabshift(temp_int)1182 tabshift(temp_int)	/* give the number of spaces to shift to the next
1183 			   tab stop					*/
1184 int temp_int;	/* current column	*/
1185 {
1186 	int leftover;
1187 	struct tab_stops *stack_point;
1188 
1189 	stack_point = tabs;
1190 	while ((stack_point != NULL) && (stack_point->column <= temp_int))
1191 		stack_point = stack_point->next_stop;
1192 	if (stack_point != NULL)
1193 	{
1194 		leftover = (stack_point->column - temp_int);
1195 		return(leftover);
1196 	}
1197 	leftover = ((temp_int + 1) % tab_spacing);
1198 	if (leftover == 0)
1199 		return (1);
1200 	else
1201 		return ((tab_spacing + 1) - leftover);
1202 }
1203 
1204 int
out_char(window,character,abscolumn,row,offset)1205 out_char(window, character, abscolumn, row, offset)	/* output non-printing character */
1206 WINDOW *window;
1207 char character;
1208 int abscolumn;
1209 int row;
1210 int offset;
1211 {
1212 	int i1, i2, iter;
1213 	int column;
1214 	int space;
1215 	char *string;
1216 	char *tmp;
1217 
1218 	column = abscolumn % COLS;
1219 	space = FALSE;
1220 	if ((character >= 0) && (character < 32))
1221 	{
1222 		if (character == '\t')
1223 		{
1224 			i1 = tabshift(abscolumn);
1225 			for (i2=1; (i2 <= i1)&&((((i2+column)<=curr_buff->last_col)&&(row==curr_buff->last_line))||(row<curr_buff->last_line)); i2++)
1226 				waddch(window, ' ');
1227 			return(i1);
1228 		}
1229 		else
1230 			string = ctrl_table[(int)character];
1231 	}
1232 	else if ((character < 0) || (character >= 127))
1233 	{
1234 		if (character == 127)
1235 			string = "^?";
1236 		else if (!eightbit)
1237 		{
1238 			space = TRUE;
1239 			tmp = string = xalloc(6);
1240 			*tmp = '<';
1241 			tmp++;
1242 			if ((i1=character) < 0)
1243 				i1 = 256 + character;
1244 			i2 = i1 / 100;
1245 			i1 -=i2 * 100;
1246 			*tmp = i2 + '0';
1247 			tmp++;
1248 			i2 = i1 / 10;
1249 			i1 -= i2 * 10;
1250 			*tmp = i2 + '0';
1251 			tmp++;
1252 			i2 = i1;
1253 			*tmp = i2 + '0';
1254 			tmp++;
1255 			*tmp = '>';
1256 			tmp++;
1257 			*tmp = '\0';
1258 		}
1259 		else
1260 		{
1261 			waddch(window, (unsigned char) character);
1262 			return(1);
1263 		}
1264 	}
1265 	tmp = string;
1266 	for (iter=0; (iter < offset) && (tmp != NULL) && (character != '\t'); iter++)
1267 		tmp++;
1268 	for (iter = column;
1269 	     (((iter <= curr_buff->last_col) && (row == curr_buff->last_line)) ||
1270 	     (row < curr_buff->last_line)) && (*tmp != '\0'); iter++, tmp++)
1271 		waddch(window, *tmp);
1272 	iter -= column;
1273 	if (space)
1274 		free(string);
1275 	return(iter);
1276 }
1277 
1278 void
draw_line(vertical,horiz,ptr,t_pos,dr_l)1279 draw_line(vertical, horiz, ptr, t_pos, dr_l)	/* redraw line from current position */
1280 int vertical;
1281 int horiz;
1282 char *ptr;
1283 int t_pos;
1284 struct text *dr_l;
1285 {
1286 	int d;
1287 	char *temp;
1288 	int abs_column;
1289 	int column;
1290 	int row;
1291 	int tp_pos;
1292 	int posit;
1293 	int highlight;
1294 	int offset;
1295 
1296 	highlight = FALSE;
1297 	abs_column = horiz;
1298 	column = abs_column % COLS;
1299 	row = vertical;
1300 	temp = ptr;
1301 	d = 0;
1302 	posit = t_pos;
1303 	if (row < 0)
1304 	{
1305 		while (row < 0)
1306 		{
1307 			abs_column += d =  len_char(*temp, abs_column);
1308 			column += d;
1309 			if (column > curr_buff->last_col)
1310 			{
1311 				row++;
1312 				if ((d > 1) && (row == 0))
1313 				{
1314 					d = d - (column - COLS);
1315 					abs_column -= column - COLS;
1316 				}
1317 				else
1318 				{
1319 					posit++;
1320 					temp++;
1321 					d = 0;
1322 				}
1323 				column %= COLS;
1324 			}
1325 			else
1326 			{
1327 				posit++;
1328 				temp++;
1329 			}
1330 		}
1331 		column = 0;
1332 	}
1333 	wmove(curr_buff->win, row, column);
1334 	wclrtoeol(curr_buff->win);
1335 	if ((mark_text) && (pst_pos == 1) && (curr_buff->pointer == ptr) &&
1336 			(cpste_line->line_length > 1))
1337 	{
1338 		highlight = TRUE;
1339 		tp_pos = pst_pos;
1340 	}
1341 	else if (mark_text)
1342 		wstandend(curr_buff->win);
1343 	while ((posit < dr_l->line_length) && (((column <= curr_buff->last_col) &&
1344 			(row == curr_buff->last_line)) || (row < curr_buff->last_line)))
1345 	{
1346 		if ((mark_text) && (pst_pos == 1) && (curr_buff->pointer == ptr) && (highlight))
1347 		{
1348 			if (tp_pos < cpste_line->line_length)
1349 				wstandout(curr_buff->win);
1350 			else
1351 				wstandend(curr_buff->win);
1352 			tp_pos++;
1353 		}
1354 		if ((*temp < 32) || (*temp > 126))
1355 		{
1356 			offset = out_char(curr_buff->win, *temp, abs_column, row, d);
1357 			column += offset;
1358 			abs_column += offset;
1359 			d = 0;
1360 		}
1361 		else
1362 		{
1363 			abs_column++;
1364 			column++;
1365 			waddch(curr_buff->win, *temp);
1366 		}
1367 		if (column > curr_buff->last_col)
1368 		{
1369 			column = column % COLS;
1370 			row++;
1371 		}
1372 		posit++;
1373 		temp++;
1374 	}
1375 	if (((column < curr_buff->last_col) && (row == curr_buff->last_line)) || (row < curr_buff->last_line))
1376 		wclrtoeol(curr_buff->win);
1377 	wstandend(curr_buff->win);
1378 	wmove(curr_buff->win, vertical, horiz);
1379 }
1380 
1381 void
insert_line(disp)1382 insert_line(disp)	/* insert new line into file and if disp=TRUE,
1383 			reorganize screen accordingly	*/
1384 int disp;
1385 {
1386 	int temp_pos;
1387 	int temp_pos2;
1388 	int i;
1389 	char *temp;
1390 	char *extra;
1391 	struct text *temp_nod;	/* temporary pointer to new line	*/
1392 	int temp_overstrike;
1393 
1394 	i = curr_buff->curr_line->vert_len;
1395 	wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
1396 	wclrtoeol(curr_buff->win);
1397 	change = TRUE;
1398 	temp_nod= txtalloc();
1399 	temp_nod->line = extra = xalloc(6 + curr_buff->curr_line->line_length - curr_buff->position);
1400 	temp_nod->line_length = 1 + curr_buff->curr_line->line_length - curr_buff->position;
1401 	temp_nod->vert_len = 1;
1402 	temp_nod->max_length = temp_nod->line_length + 5;
1403 	if (curr_buff->position == 1)
1404 		temp_nod->line_number = curr_buff->curr_line->line_number;
1405 	else
1406 		temp_nod->line_number = curr_buff->curr_line->line_number + 1;
1407 	temp_nod->next_line = curr_buff->curr_line->next_line;
1408 	if (temp_nod->next_line != NULL)
1409 		temp_nod->next_line->prev_line = temp_nod;
1410 	temp_nod->prev_line = curr_buff->curr_line;
1411 	curr_buff->curr_line->next_line = temp_nod;
1412 	temp_pos2 = curr_buff->position;
1413 	temp = curr_buff->pointer;
1414 	if (temp_pos2 != curr_buff->curr_line->line_length)
1415 	{
1416 		temp_pos = 1;
1417 		while (temp_pos2 < curr_buff->curr_line->line_length)
1418 		{
1419 			temp_pos++;
1420 			temp_pos2++;
1421 			*extra= *temp;
1422 			extra++;
1423 			temp++;
1424 		}
1425 		temp = curr_buff->pointer;
1426 		*temp = '\0';
1427 		temp = resiz_line((1 - temp_nod->line_length), curr_buff->curr_line, curr_buff->position);
1428 		curr_buff->curr_line->line_length = curr_buff->position;
1429 		curr_buff->curr_line->vert_len = (scanline(curr_buff->curr_line, curr_buff->curr_line->line_length) / COLS) + 1;
1430 		curr_buff->curr_line->changed = TRUE;
1431 	}
1432 	curr_buff->curr_line->line_length = curr_buff->position;
1433 	curr_buff->curr_line = temp_nod;
1434 	curr_buff->curr_line->vert_len = (scanline(curr_buff->curr_line, curr_buff->curr_line->line_length) / COLS) + 1;
1435 	*extra = '\0';
1436 	curr_buff->position = 1;
1437 	curr_buff->pointer = curr_buff->curr_line->line;
1438 	curr_buff->num_of_lines++;
1439 	curr_buff->absolute_lin++;
1440 	curr_buff->curr_line->changed = TRUE;
1441 	curr_buff->changed = TRUE;
1442 
1443 	if (curr_buff->journalling)
1444 	{
1445 		write_journal(curr_buff, curr_buff->curr_line);
1446 		if (curr_buff->curr_line->prev_line->changed)
1447 			write_journal(curr_buff, curr_buff->curr_line->prev_line);
1448 	}
1449 
1450 	if (disp)
1451 	{
1452 		i = (curr_buff->curr_line->vert_len + curr_buff->curr_line->prev_line->vert_len) - i;
1453 		if (curr_buff->scr_vert < curr_buff->last_line)
1454 		{
1455 			curr_buff->scr_vert++;
1456 			wclrtoeol(curr_buff->win);
1457 			wmove(curr_buff->win, curr_buff->scr_vert, 0);
1458 			if (i > 0)
1459 				winsertln(curr_buff->win);
1460 		}
1461 		else
1462 		{
1463 			wmove(curr_buff->win, 0, 0);
1464 			wdeleteln(curr_buff->win);
1465 			wmove(curr_buff->win, curr_buff->last_line, 0);
1466 			wclrtobot(curr_buff->win);
1467 		}
1468 		curr_buff->abs_pos = curr_buff->scr_pos = curr_buff->scr_horz = 0;
1469 		draw_line(curr_buff->scr_vert, curr_buff->scr_pos, curr_buff->pointer, curr_buff->position, curr_buff->curr_line);
1470 	}
1471 	curr_buff->abs_pos = curr_buff->scr_pos = curr_buff->scr_horz = 0;
1472 	if ((mark_text) && (cpste_line->line_length == pst_pos))
1473 	{
1474 		i = mark_text;
1475 		mark_text = FALSE;
1476 		left(TRUE);
1477 		mark_text = i;
1478 		right(TRUE);
1479 	}
1480 	if (indent)
1481 	{
1482 		int temp_lm = left_margin;
1483 
1484 		left_margin = 0;
1485 		if (curr_buff->curr_line->prev_line != NULL)
1486 		{
1487 			temp = curr_buff->curr_line->prev_line->line;
1488 			i = overstrike;
1489 			overstrike = FALSE;
1490 			while ((*temp == ' ') || (*temp == '\t'))
1491 			{
1492 				insert(*temp);
1493 				temp++;
1494 			}
1495 			overstrike = i;
1496 		}
1497 		left_margin = temp_lm;
1498 	}
1499 	if ((observ_margins) && (left_margin != 0) && (curr_buff->scr_pos < left_margin))
1500 	{
1501 		temp_overstrike = overstrike;
1502 		overstrike = FALSE;
1503 		i = left_margin;
1504 		left_margin = 0;
1505 		while (curr_buff->scr_pos < i)
1506 			insert(' ');
1507 		left_margin = i;
1508 		overstrike = temp_overstrike;
1509 	}
1510 }
1511 
txtalloc()1512 struct text *txtalloc()		/* allocate space for line structure	*/
1513 {
1514 	struct text *txt_tmp;
1515 
1516 	txt_tmp = (struct text *) xalloc(sizeof( struct text));
1517 	txt_tmp->changed = FALSE;
1518 	txt_tmp->file_info.info_location = NO_FURTHER_LINES;
1519 	txt_tmp->file_info.prev_info = NO_FURTHER_LINES;
1520 	txt_tmp->file_info.next_info = NO_FURTHER_LINES;
1521 	return(txt_tmp);
1522 }
1523 
name_alloc()1524 struct files *name_alloc()	/* allocate space for file name list node */
1525 {
1526 	struct files *temp_name;
1527 
1528 	temp_name = (struct files *) xalloc(sizeof( struct files));
1529 	return(temp_name);
1530 }
1531 
buf_alloc()1532 struct bufr *buf_alloc()	/* allocate space for buffers		*/
1533 {
1534 	struct bufr *temp_buf;
1535 
1536 	temp_buf = (struct bufr *) xalloc(sizeof(struct bufr));
1537 	temp_buf->journal_file = NULL;
1538 	temp_buf->file_name = NULL;
1539 	temp_buf->full_name = "";
1540 	temp_buf->orig_dir = NULL;
1541 	temp_buf->journalling = FALSE;
1542 	temp_buf->changed = FALSE;
1543 	temp_buf->main_buffer = FALSE;
1544 	temp_buf->edit_buffer = FALSE;
1545 	temp_buf->dos_file = FALSE;
1546 	temp_buf->journ_fd = '\0';
1547 	return (temp_buf);
1548 }
1549 
next_word(string)1550 char *next_word(string)		/* move to next word in string		*/
1551 char *string;
1552 {
1553 	while ((*string != '\0') && ((*string != 32) && (*string != 9)))
1554 		string++;
1555 	while ((*string != '\0') && ((*string == 32) || (*string == 9)))
1556 		string++;
1557 	return(string);
1558 }
1559 
1560 int
scan(line,offset,column)1561 scan(line, offset, column)	/* determine horizontal position for get_string	*/
1562 char *line;
1563 int offset;
1564 int column;
1565 {
1566 	char *stemp;
1567 	int i;
1568 	int j;
1569 
1570 	stemp = line;
1571 	i = 0;
1572 	j = column;
1573 	while (i < offset)
1574 	{
1575 		i++;
1576 		j += len_char(*stemp, j);
1577 		stemp++;
1578 	}
1579 	return(j);
1580 }
1581 
get_string(prompt,advance)1582 char *get_string(prompt, advance)	/* read string from input on command line */
1583 char *prompt;		/* string containing user prompt message	*/
1584 int advance;		/* if true, skip leading spaces and tabs	*/
1585 {
1586 	char *string;
1587 	char *tmp_string;
1588 	char *nam_str;
1589 	char *g_point;
1590 	int tmp_int;
1591 	int g_horz, g_position, g_pos;
1592 	int esc_flag;
1593 
1594 	g_point = tmp_string = xalloc(512);
1595 	wmove(com_win,0,0);
1596 	wclrtoeol(com_win);
1597 	waddstr(com_win, prompt);
1598 	wrefresh(com_win);
1599 	nam_str = tmp_string;
1600 	clr_cmd_line = TRUE;
1601 	g_horz = g_position = scan(prompt, strlen(prompt), 0);
1602 	g_pos = 0;
1603 	do
1604 	{
1605 		esc_flag = FALSE;
1606 		get_input(com_win);
1607 		if (((in == 8) || (in == 127) || (in == KEY_BACKSPACE)) && (g_pos > 0))
1608 		{
1609 			tmp_int = g_horz;
1610 			g_pos--;
1611 			g_horz = scan(g_point, g_pos, g_position);
1612 				tmp_int = tmp_int - g_horz;
1613 			for (; 0 < tmp_int; tmp_int--)
1614 			{
1615 				if ((g_horz+tmp_int) < (curr_buff->last_col - 1))
1616 				{
1617 					waddch(com_win, '\010');
1618 					waddch(com_win, ' ');
1619 					waddch(com_win, '\010');
1620 				}
1621 			}
1622 			nam_str--;
1623 		}
1624 		else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r') && (in < 256))
1625 		{
1626 			if (in == '\026')	/* control-v, accept next character verbatim	*/
1627 			{			/* allows entry of ^m, ^j, and ^h	*/
1628 				esc_flag = TRUE;
1629 				get_input(com_win);
1630 			}
1631 			*nam_str = in;
1632 			g_pos++;
1633 			if (((in < 32) || (in > 126)) && (g_horz < (curr_buff->last_col - 1)))
1634 				g_horz += out_char(com_win, in, g_horz, curr_buff->last_line, 0);
1635 			else
1636 			{
1637 				g_horz++;
1638 				if (g_horz < (curr_buff->last_col - 1))
1639 					waddch(com_win, in);
1640 			}
1641 			nam_str++;
1642 		}
1643 		wrefresh(com_win);
1644 		if (esc_flag)
1645 			in = '\0';
1646 	} while ((in != '\n') && (in != '\r'));
1647 	*nam_str = '\0';
1648 	nam_str = tmp_string;
1649 	if (((*nam_str == ' ') || (*nam_str == 9)) && (advance))
1650 		nam_str = next_word(nam_str);
1651 	string = xalloc(strlen(nam_str) + 1);
1652 	copy_str(nam_str, string);
1653 	free(tmp_string);
1654 	wrefresh(com_win);
1655 	return(string);
1656 }
1657 
1658 int
len_char(character,column)1659 len_char(character, column)	/* return the length of the character	*/
1660 char character;
1661 int column;	/* the column must be known to provide spacing for tabs	*/
1662 {
1663 	int length;
1664 
1665 	if (character == '\t')
1666 		length = tabshift(column);
1667 	else if ((character >= 0) && (character < 32))
1668 		length = 2;
1669 	else if ((character >= 32) && (character <= 126))
1670 		length = 1;
1671 	else if (character == 127)
1672 		length = 2;
1673 	else if (((character > 126) || (character < 0)) && (!eightbit))
1674 		length = 5;
1675 	else
1676 		length = 1;
1677 
1678 	return(length);
1679 }
1680 
1681 void
ascii()1682 ascii()		/* get ascii code from user and insert into file	*/
1683 {
1684 	int i;
1685 	char *string, *t;
1686 
1687 	i = 0;
1688 	t = string = get_string(ascii_code_str, TRUE);
1689 	if (*t != '\0')
1690 	{
1691 		while ((*string >= '0') && (*string <= '9'))
1692 		{
1693 			i= i * 10 + (*string - '0');
1694 			string++;
1695 		}
1696 		in = i;
1697 		wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
1698 		insert(in);
1699 	}
1700 	free(t);
1701 }
1702 
1703 void
print_buffer()1704 print_buffer()
1705 {
1706 	char buffer[256];
1707 
1708 	sprintf(buffer, ">!%s", print_command);
1709 	wmove(com_win, 0, 0);
1710 	wclrtoeol(com_win);
1711 	wprintw(com_win, printing_msg, curr_buff->name, print_command);
1712 	wrefresh(com_win);
1713 	command(buffer);
1714 }
1715 
1716 int
compare(string1,string2,sensitive)1717 compare(string1, string2, sensitive)	/* compare two strings	*/
1718 char *string1;
1719 char *string2;
1720 int sensitive;
1721 {
1722 	char *strng1;
1723 	char *strng2;
1724 	int tmp;
1725 	int equal;
1726 
1727 	strng1 = string1;
1728 	strng2 = string2;
1729 	tmp = 0;
1730 	if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == '\0') || (*strng2 == '\0'))
1731 		return(FALSE);
1732 	equal = TRUE;
1733 	while (equal)
1734 	{
1735 		if (sensitive)
1736 		{
1737 			if (*strng1 != *strng2)
1738 				equal = FALSE;
1739 		}
1740 		else
1741 		{
1742 			if (toupper(*strng1) != toupper(*strng2))
1743 				equal = FALSE;
1744 		}
1745 		strng1++;
1746 		strng2++;
1747 		if ((*strng1 == '\0') || (*strng2 == '\0') || (*strng1 == ' ') || (*strng2 == ' '))
1748 			break;
1749 		tmp++;
1750 	}
1751 	return(equal);
1752 }
1753 
1754 void
goto_line(cmd_str)1755 goto_line(cmd_str)	/* goto first line with the given number	*/
1756 char *cmd_str;
1757 {
1758 	int number;
1759 	int i;
1760 	char *ptr;
1761 	char *direction;
1762 	struct text *t_line;
1763 
1764 	ptr = cmd_str;
1765 	i= 0;
1766 	while ((*ptr >='0') && (*ptr <= '9'))
1767 	{
1768 		i= i * 10 + (*ptr - '0');
1769 		ptr++;
1770 	}
1771 	number = i;
1772 	i = 0;
1773 	t_line = curr_buff->curr_line;
1774 	while ((t_line->line_number > number) && (t_line->prev_line != NULL))
1775 	{
1776 		i++;
1777 		t_line = t_line->prev_line;
1778 		direction = "u";
1779 	}
1780 	if (i == 0)
1781 	{
1782 		while ((t_line->line_number < number) && (t_line->next_line != NULL))
1783 		{
1784 			i++;
1785 			direction = "d";
1786 			t_line = t_line->next_line;
1787 		}
1788 	}
1789 	if (i != 0)
1790 		move_rel(direction, i);
1791 	wmove(com_win,0,0);
1792 	wclrtoeol(com_win);
1793 	wprintw(com_win, line_num_str, curr_buff->curr_line->line_number);
1794 	wrefresh(com_win);
1795 	clr_cmd_line = TRUE;
1796 	wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
1797 }
1798 
1799 void
make_win()1800 make_win()		/* allow windows		*/
1801 {
1802 	if (((!windows) && (!mark_text)) && (num_of_bufs <= ((LINES - 1)/2)))
1803 	{
1804 		windows = TRUE;
1805 		if (num_of_bufs > 1)
1806 		{
1807 			werase(first_buff->win);
1808 			wrefresh(first_buff->win);
1809 			delwin(first_buff->win);
1810 			t_buff = first_buff;
1811 			while (t_buff != NULL)
1812 			{
1813 				t_buff->win = NULL;
1814 				t_buff = t_buff->next_buff;
1815 			}
1816 			redo_win();
1817 			new_screen();
1818 			curr_buff->win = curr_buff->win;
1819 		}
1820 	}
1821 }
1822 
1823 void
no_windows()1824 no_windows()		/* disallow windows		*/
1825 {
1826 	int temp;
1827 
1828 	if ((windows) && (!mark_text))
1829 	{
1830 		windows = FALSE;
1831 		if (num_of_bufs > 1)
1832 		{
1833 			t_buff = first_buff;
1834 			werase(t_buff->win);
1835 			wrefresh(t_buff->win);
1836 			delwin(t_buff->win);
1837 			werase(t_buff->footer);
1838 			wrefresh(t_buff->footer);
1839 			delwin(t_buff->footer);
1840 			t_buff->footer = NULL;
1841 			if (info_window)
1842 			{
1843 				temp = info_win_height;
1844 				if (info_win == NULL)
1845 				{
1846 					info_win = newwin(info_win_height, COLS, 0, 0);
1847 					paint_info_win();
1848 				}
1849 			}
1850 			else
1851 				temp = 0;
1852 			t_buff->win = newwin(LINES - temp - 1, COLS, temp, 0);
1853 			t_buff->window_top = temp;
1854 			keypad(t_buff->win, TRUE);
1855 			idlok(t_buff->win, TRUE);
1856 			t_buff->lines = LINES - temp - 1;
1857 			t_buff->last_col = COLS - 1;
1858 			t_buff->last_line = t_buff->lines - 1;
1859 			t_buff = t_buff->next_buff;
1860 			while (t_buff != NULL)
1861 			{
1862 				werase(t_buff->win);
1863 				wrefresh(t_buff->win);
1864 				werase(t_buff->footer);
1865 				wrefresh(t_buff->footer);
1866 				delwin(t_buff->footer);
1867 				delwin(t_buff->win);
1868 				t_buff->footer = NULL;
1869 				t_buff->win = first_buff->win;
1870 				t_buff->window_top = first_buff->window_top;
1871 				t_buff->lines = first_buff->lines;
1872 				t_buff->last_line = first_buff->last_line;
1873 				t_buff->last_col = first_buff->last_col;
1874 				t_buff = t_buff->next_buff;
1875 			}
1876 			new_screen();
1877 		}
1878 	}
1879 }
1880 
1881 void
midscreen(line,count)1882 midscreen(line, count)	/* repaint window with current line at the specified line	*/
1883 int line;
1884 int count;
1885 {
1886 	struct text *mid_line;
1887 	struct text *a_line;
1888 	struct text *b_line;
1889 	char *tp;		/* temporary pointer		*/
1890 	int abs_column;	/* the number of columns from start of line	*/
1891 	int ti;			/* temporary integer		*/
1892 	int ti1;		/* another temporary integer	*/
1893 	int tppos;		/* temporary paste position	*/
1894 	int m;
1895 	int i;
1896 
1897 	mid_line = curr_buff->curr_line;
1898 
1899 	/*
1900 	 |	find the first line visible on the screen (from the top)
1901 	 */
1902 
1903 	i = (curr_buff->scr_pos / COLS);
1904 	while ((i < line) && (curr_buff->curr_line->prev_line != NULL) && (i < curr_buff->last_line))
1905 	{
1906 		curr_buff->curr_line = curr_buff->curr_line->prev_line;
1907 		i += curr_buff->curr_line->vert_len;
1908 	}
1909 
1910 	/*
1911 	 |	set up temporary pointers to store the current information
1912 	 */
1913 
1914 	tp = curr_buff->curr_line->line;
1915 	tppos = 1;
1916 	ti1 = ti = 0;
1917 	curr_buff->scr_vert = curr_buff->scr_horz = 0;
1918 	wmove(curr_buff->win, 0, 0);
1919 	a_line = curr_buff->curr_line;
1920 	if (i > line)
1921 		ti = line - i;
1922 	else
1923 		ti = 0;
1924 
1925 	/*
1926 	 |	erase the window and paint the information
1927 	 */
1928 
1929 	werase(curr_buff->win);
1930 	while ((a_line != NULL) && (ti <= curr_buff->last_line))
1931 	{
1932 		draw_line(ti, 0, tp, 1, a_line);
1933 		ti += a_line->vert_len;
1934 		a_line = a_line->next_line;
1935 		if (a_line != NULL)
1936 			tp = a_line->line;
1937 	}
1938 	if (i > line)
1939 		curr_buff->scr_vert = line;
1940 	else
1941 		curr_buff->scr_vert = i;
1942 	curr_buff->curr_line = mid_line;
1943 
1944 	/*
1945 	 |	Now highlight areas that have been marked.
1946 	 */
1947 
1948 	if (mark_text)		/* paint selected text	*/
1949 	{
1950 		b_line = cpste_line;
1951 		a_line = curr_buff->curr_line;
1952 		tppos = pst_pos;
1953 
1954 		/*
1955 		 |	if the marked areas are before the cursor...
1956 		 */
1957 
1958 		if ((pst_pos == cpste_line->line_length) && (cpste_line->next_line == NULL))
1959 		{
1960 
1961 			/*
1962 			 |	if there are multiple marked lines, find out
1963 			 |	how much vertical space they use
1964 			 */
1965 
1966 			if (cpste_line->prev_line != NULL)
1967 			{
1968 				i = scanline(curr_buff->curr_line, count) / COLS;
1969 				while ((i <= curr_buff->scr_vert) && (cpste_line->prev_line!= NULL))
1970 				{
1971 					curr_buff->curr_line = curr_buff->curr_line->prev_line;
1972 					cpste_line = cpste_line->prev_line;
1973 					i += curr_buff->curr_line->vert_len;
1974 				}
1975 			}
1976 			else
1977 				i = 0;
1978 
1979 			tp = curr_buff->curr_line->line;
1980 			ti = 1;
1981 
1982 			/*
1983 			 |	set up to highlight a partial line
1984 			 */
1985 
1986 			if (curr_buff->curr_line->line_length != cpste_line->line_length)
1987 			{
1988 				if (i != 0)
1989 				{
1990 					ti = curr_buff->curr_line->line_length -
1991 						cpste_line->line_length;
1992 					ti++;
1993 					for (ti1=1; ti1<ti; ti1++)
1994 						tp++;
1995 				}
1996 				else
1997 				{
1998 					for (ti = 1;
1999 					      ti <= (curr_buff->position -
2000 						cpste_line->line_length); ti++)
2001 					    tp++;
2002 				}
2003 			}
2004 
2005 			abs_column = curr_buff->scr_horz = scanline(curr_buff->curr_line, ti);
2006 			m = curr_buff->scr_horz / COLS;
2007 			curr_buff->scr_horz = curr_buff->scr_horz % COLS;
2008 			wmove(curr_buff->win, (m + curr_buff->scr_vert - 1), curr_buff->scr_horz);
2009 			wstandout(curr_buff->win);
2010 			curr_buff->pointer = tp;
2011 			pst_pos = 1;
2012 
2013 			if (i == 0)
2014 				i = scanline(curr_buff->curr_line, curr_buff->position) / COLS;
2015 
2016 			draw_line(m + curr_buff->scr_vert - i, abs_column, curr_buff->pointer, ti,
2017 						curr_buff->curr_line);
2018 
2019 			for (ti = i - curr_buff->curr_line->vert_len; ti >= 0;
2020 					ti -= curr_buff->curr_line->vert_len)
2021 			{
2022 				cpste_line = cpste_line->next_line;
2023 				curr_buff->curr_line = curr_buff->curr_line->next_line;
2024 				pst_pos = 1;
2025 				curr_buff->pointer = curr_buff->curr_line->line;
2026 				draw_line(curr_buff->scr_vert-ti, 0, curr_buff->curr_line->line, 1,
2027 						curr_buff->curr_line);
2028 			}
2029 		}
2030 		/*
2031 		 |	or the marked text is after the cursor...
2032 		 */
2033 		else
2034 		{
2035 			pst_pos = 1;
2036 			i = curr_buff->scr_vert;
2037 			draw_line(curr_buff->scr_vert, curr_buff->scr_pos, curr_buff->pointer, curr_buff->position, curr_buff->curr_line);
2038 			i += curr_buff->curr_line->vert_len - (scanline(curr_buff->curr_line, curr_buff->position) / COLS);
2039 			if (curr_buff->curr_line->next_line != NULL)
2040 			{
2041 				curr_buff->curr_line = curr_buff->curr_line->next_line;
2042 				cpste_line = cpste_line->next_line;
2043 				curr_buff->pointer = curr_buff->curr_line->line;
2044 				pst_pos = 1;
2045 				while ((i <= curr_buff->last_line) && (cpste_line != NULL))
2046 				{
2047 					draw_line(i, 0, curr_buff->pointer, 1, curr_buff->curr_line);
2048 					i += curr_buff->curr_line->vert_len;
2049 					if (curr_buff->curr_line->next_line != NULL)
2050 					{
2051 						curr_buff->curr_line = curr_buff->curr_line->next_line;
2052 						cpste_line = cpste_line->next_line;
2053 						curr_buff->pointer = curr_buff->curr_line->line;
2054 					}
2055 				}
2056 			}
2057 		}
2058 		pst_pos = tppos;
2059 		curr_buff->curr_line = a_line;
2060 		cpste_line = b_line;
2061 	}
2062 	curr_buff->pointer = curr_buff->curr_line->line;
2063 	for (value = 1; value < count; value++)
2064 		curr_buff->pointer ++;
2065 	curr_buff->abs_pos = curr_buff->scr_pos = scanline(curr_buff->curr_line, count);
2066 	curr_buff->scr_horz = curr_buff->scr_pos % COLS;
2067 	wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
2068 }
2069 
2070 #ifndef xae11
2071 void
get_options(numargs,arguments)2072 get_options(numargs, arguments)	/* get arguments from original command line	*/
2073 int numargs;
2074 char *arguments[];
2075 {
2076 	char *buff;
2077 	char *extens;
2078 	int count;
2079 	struct files *temp_names;
2080 
2081 	buff = ae_basename(arguments[0]);
2082 	if (!strcmp(buff, "rae"))
2083 	{
2084 		restricted = TRUE;
2085 		change_dir_allowed = FALSE;
2086 	}
2087 
2088 	count = 1;
2089 	while (count < numargs)
2090 	{
2091 		buff = arguments[count];
2092 		if (*buff == '-')	/* options	*/
2093 		{
2094 			++buff;
2095 			if (*buff == 'j')	/* turn off recover file */
2096 				journ_on = FALSE;
2097 			else if (*buff == 'r')	/* recover from bad exit */
2098 				recover = TRUE;
2099 			else if (*buff == 'e')	/* turn off echo in init file */
2100 				echo_flag = FALSE;
2101 			else if (*buff == 'i')	/* turn off info window	*/
2102 				info_window = FALSE;
2103 			else if (!strcmp(arguments[count], "-text"))
2104 			{
2105 				text_only = TRUE;
2106 			}
2107 			else if (!strcmp(arguments[count], "-binary"))
2108 			{
2109 				text_only = FALSE;
2110 			}
2111 			else if (!strcmp(arguments[count], "-tab"))
2112 						/* expand tabs to spaces */
2113 				expand = TRUE;
2114 			else if (*buff == 'n')	/* turn off highlighting on menus*/
2115 				nohighlight = TRUE;
2116 #ifdef XAE
2117 			else if (*buff == 'h')	/* get height of window	*/
2118 			{
2119 				buff++;
2120 				if (*buff == '\0')
2121 				{
2122 					count++;
2123 					buff = arguments[count];
2124 				}
2125 				win_height = atoi(buff);
2126 			}
2127 			else if (*buff == 'w')	/* get width of window	*/
2128 			{
2129 				buff++;
2130 				if (*buff == '\0')
2131 				{
2132 					count++;
2133 					buff = arguments[count];
2134 				}
2135 				win_width = atoi(buff);
2136 			}
2137 #endif
2138 		}
2139 		else if (*buff == '+')
2140 		{
2141 			buff++;
2142 			start_at_line = buff;
2143 		}
2144 		else	/* if the argument wasn't an option, must be a file name, right?	*/
2145 		{
2146 			if (top_of_stack == NULL)
2147 				temp_names = top_of_stack = name_alloc();
2148 			else
2149 			{
2150 				temp_names->next_name = name_alloc();
2151 				temp_names = temp_names->next_name;
2152 			}
2153 			temp_names->next_name = NULL;
2154 			extens = temp_names->name = xalloc(strlen(buff) + 1);
2155 			while (*buff != '\0')
2156 			{
2157 				*extens = *buff;
2158 				buff++;
2159 				extens++;
2160 			}
2161 			*extens = '\0';
2162 			input_file = TRUE;
2163 			recv_file = TRUE;
2164 		}
2165 		count++;
2166 	}
2167 }
2168 #endif /* xae11	*/
2169 
2170 void
finish(string)2171 finish(string)	/* prepare to EXIT edit session, write out file	*/
2172 char *string;
2173 {
2174 	char *query;
2175 	int leave;
2176 
2177 	leave = TRUE;
2178 	if (mark_text)
2179 	{
2180 		copy();
2181 	}
2182 
2183 	if ((num_of_bufs > 1) && (top_of_stack == NULL))
2184 	{
2185 		do
2186 			query = get_string(other_buffs_exist_msg, TRUE);
2187 		while ((toupper(*query) != toupper(*yes_char)) &&
2188 			(toupper(*query) != toupper(*no_char)));
2189 		if (toupper(*query) != toupper(*yes_char))
2190 			leave = FALSE;
2191 		else
2192 		{
2193 			leave = delete_all_buffers();
2194 		}
2195 	}
2196 
2197 	if (leave)
2198 	{
2199 		if (!curr_buff->main_buffer)
2200 			chng_buf(main_buffer_name);
2201 
2202 		if (file_op(SAVE_FILE) == 0)
2203 		{
2204 			change = FALSE;
2205 			quit(string);
2206 		}
2207 	}
2208 }
2209 
2210 int
delete_all_buffers()2211 delete_all_buffers()
2212 {
2213 	int success = TRUE;
2214 
2215 	t_buff = first_buff->next_buff;
2216 	while ((t_buff != NULL) && (success))
2217 	{
2218 		chng_buf(t_buff->name);
2219 		success = del_buf();
2220 		t_buff = first_buff->next_buff;
2221 	}
2222 	return(success);
2223 }
2224 
2225 void
quit(string)2226 quit(string)		/* leave editor, or if other files specified in invoking command line, edit next in sequence	*/
2227 char *string;
2228 {
2229 	char *query;
2230 	char *ans;
2231 	int editable_buffs = 0;
2232 
2233 	if (num_of_bufs > 1)
2234 	{
2235 		t_buff = first_buff;
2236 		while (t_buff != NULL)
2237 		{
2238 			if (t_buff->edit_buffer)
2239 				editable_buffs++;
2240 			t_buff = t_buff->next_buff;
2241 		}
2242 	}
2243 
2244 	if ((num_of_bufs > 1) && (top_of_stack == NULL))
2245 	{
2246 		do
2247 			query = get_string(other_buffs_exist_msg, TRUE);
2248 		while ((toupper(*query) != toupper(*yes_char)) &&
2249 			(toupper(*query) != toupper(*no_char)));
2250 		if (toupper(*query) != toupper(*yes_char))
2251 			return;
2252 		else
2253 		{
2254 			if (mark_text)
2255 				copy();
2256 			chng_buf(main_buffer_name);
2257 		}
2258 
2259 		if (!delete_all_buffers())
2260 			return;
2261 	}
2262 	if (first_buff->changed) /* if changes have been made in the file */
2263 	{
2264 		ans = get_string(changes_made_prompt, TRUE);
2265        		wmove(com_win, 0, 0);
2266         	werase(com_win);
2267 	        wrefresh(com_win);
2268 		if (toupper(*ans) != toupper(*yes_char))
2269 			return;
2270 	}
2271 	if (mark_text)
2272 	{
2273 		copy();
2274 	}
2275 	chng_buf(main_buffer_name);
2276 	if (curr_buff->journalling)
2277 			/* if recover file in use, delete it */
2278 	{
2279 		remove_journal_file(curr_buff);
2280 	}
2281 	while ((string != NULL) && (*string != '\0') && (*string != '!'))
2282 		string++;
2283 	if ((string != NULL) && (*string == '!'))
2284 		top_of_stack = NULL;
2285 	if (top_of_stack == NULL)	/* no other files to edit */
2286 	{
2287 		edit = FALSE;
2288 		wrefresh(com_win);
2289 		echo();
2290 		nl();
2291 		resetty();
2292 		resetterm();
2293 		noraw();
2294 		endwin();
2295 #ifndef XAE
2296 		putchar('\n');
2297 #endif	/* XAE */
2298 		exit(0);
2299 	}
2300 	else	/* prepare to edit next file	*/
2301 	{
2302 		change = FALSE;
2303 		curr_buff->curr_line = curr_buff->first_line;
2304 		while (curr_buff->curr_line->next_line != NULL)
2305 		{
2306 			free(curr_buff->curr_line->line);
2307 			curr_buff->curr_line = curr_buff->curr_line->next_line;
2308 			free(curr_buff->curr_line->prev_line);
2309 		}
2310 		curr_buff->num_of_lines = 1;
2311 		curr_buff->absolute_lin = 1;
2312 		free(curr_buff->curr_line->line);
2313 		free(curr_buff->curr_line);
2314 		curr_buff->scr_vert = curr_buff->scr_horz = 0;
2315 		curr_buff->curr_line = curr_buff->first_line = txtalloc();
2316 		curr_buff->curr_line->line = curr_buff->pointer = xalloc(10);
2317 		curr_buff->curr_line->line_length = 1;
2318 		curr_buff->curr_line->max_length = 10;
2319 		curr_buff->curr_line->prev_line = NULL;
2320 		curr_buff->curr_line->next_line = NULL;
2321 		curr_buff->curr_line->line_number = 1;
2322 		curr_buff->position = 1;
2323 		curr_buff->scr_pos = curr_buff->abs_pos = curr_buff->scr_horz = curr_buff->scr_vert = 0;
2324 		free(curr_buff->journal_file);
2325 		free(curr_buff->full_name);
2326 		curr_buff->journal_file = NULL;
2327 		curr_buff->file_name = NULL;
2328 		curr_buff->full_name = "";
2329 		werase(curr_buff->win);
2330 		recv_file = TRUE;
2331 		input_file = TRUE;
2332 		tmp_file = top_of_stack->name;
2333 		top_of_stack = top_of_stack->next_name;
2334 		value = check_fp();
2335 	}
2336 }
2337 
2338 void
abort_edit(foo)2339 abort_edit(foo)	/* handle interrupt signal (break key) gracefully	*/
2340 int foo;
2341 {
2342 	wrefresh(com_win);
2343 	echo();
2344 	nl();
2345 	resetty();
2346 	resetterm();
2347 	noraw();
2348 	endwin();
2349 	putchar('\n');
2350 	exit(0);
2351 }
2352 
2353 void
sh_command(string)2354 sh_command(string)	/* execute shell command			*/
2355 char *string;		/* string containing user command		*/
2356 {
2357 	char *temp_point;
2358 	char *last_slash;
2359 	char *path;		/* directory path to executable		*/
2360 	int parent;		/* zero if child, child's pid if parent	*/
2361 	struct text *line_holder;
2362 	struct bufr *tmp;	/* pointer to buffer structure		*/
2363 
2364 	if (restrict_mode())
2365 	{
2366 		return;
2367 	}
2368 
2369 	if (!(path = getenv("SHELL")))
2370 		path = "/bin/sh";
2371 	last_slash = temp_point = path;
2372 	while (*temp_point != '\0')
2373 	{
2374 		if (*temp_point == '/')
2375 			last_slash = ++temp_point;
2376 		else
2377 			temp_point++;
2378 	}
2379 	keypad(curr_buff->win, FALSE);
2380 	echo();
2381 	nl();
2382 	noraw();
2383 	resetty();
2384 	if (in_pipe)
2385 	{
2386 		pipe(pipe_in);		/* create a pipe	*/
2387 		parent = fork();
2388 		if (!parent)		/* if the child		*/
2389 		{
2390 /*
2391  |  child process which will fork and exec shell command (if shell output is
2392  |  to be read by editor)
2393  */
2394 			in_pipe = FALSE;
2395 /*
2396  |  redirect stdout to pipe
2397  */
2398 			temp_stdout = dup(1);
2399 			close(1);
2400 			dup(pipe_in[1]);
2401 /*
2402  |  redirect stderr to pipe
2403  */
2404 			temp_stderr = dup(2);
2405 			close(2);
2406 			dup(pipe_in[1]);
2407 			close(pipe_in[1]);
2408 		}
2409 		else  /* if the parent	*/
2410 		{
2411 /*
2412  |  prepare editor to read from the pipe
2413  */
2414 			signal(SIGCHLD, SIG_IGN);
2415 			chng_buf(in_buff_name);
2416 			line_holder = curr_buff->curr_line;
2417 			tmp_vert = curr_buff->scr_vert;
2418 			close(pipe_in[1]);
2419 			get_fd = pipe_in[0];
2420 			get_file("");
2421 			close(pipe_in[0]);
2422 			curr_buff->scr_vert = tmp_vert;
2423 			curr_buff->scr_horz = curr_buff->scr_pos = curr_buff->abs_pos = 0;
2424 			curr_buff->position = 1;
2425 			curr_buff->curr_line = line_holder;
2426 			curr_buff->pointer = curr_buff->curr_line->line;
2427 			midscreen(curr_buff->scr_vert, 1);
2428 			out_pipe = FALSE;
2429 			signal(SIGCHLD, SIG_DFL);
2430 /*
2431  |  since flag "in_pipe" is still TRUE, do not even wait for child to complete
2432  |  (the pipe is closed, no more output can be expected)
2433  */
2434 		}
2435 	}
2436 	if (!in_pipe)
2437 	{
2438 		signal(SIGINT, SIG_IGN);
2439 		if (out_pipe)
2440 		{
2441 			pipe(pipe_out);
2442 		}
2443 /*
2444  |  fork process which will exec command
2445  */
2446 		parent = fork();
2447 		if (!parent)		/* if the child	*/
2448 		{
2449 			if (shell_fork)
2450 				putchar('\n');
2451 			if (out_pipe)
2452 			{
2453 /*
2454  |  prepare the child process (soon to exec a shell command) to read from the
2455  |  pipe (which will be output from the editor's buffer)
2456  */
2457 				close(0);
2458 				dup(pipe_out[0]);
2459 				close(pipe_out[0]);
2460 				close(pipe_out[1]);
2461 			}
2462 			for (value = 1; value < 24; value++)
2463 				signal(value, SIG_DFL);
2464 			execl(path, last_slash, "-c", string, NULL);
2465 			printf("could not exec %s\n", path);
2466 			exit(-1);
2467 		}
2468 		else	/* if the parent	*/
2469 		{
2470 			if (out_pipe)
2471 			{
2472 /*
2473  |  output the contents of the buffer to the pipe (to be read by the
2474  |  process forked and exec'd above as stdin)
2475  */
2476 				close(pipe_out[0]);
2477 				tmp = first_buff;
2478 				while ((tmp != NULL) && (strcmp(out_buff_name, tmp->name)))
2479 					tmp = tmp->next_buff;
2480 				if (tmp != NULL)
2481 				{
2482 					line_holder = tmp->first_line;
2483 					while (line_holder != NULL)
2484 					{
2485 						write(pipe_out[1], line_holder->line, (line_holder->line_length-1));
2486                                                 if (tmp->dos_file)
2487                                                    write(pipe_out[1], "\r", 1);
2488 						write(pipe_out[1], "\n", 1);
2489 						line_holder = line_holder->next_line;
2490 					}
2491 				}
2492 				else
2493 					printf(no_buff_named_str, out_buff_name);
2494 				close(pipe_out[1]);
2495 				out_pipe = FALSE;
2496 			}
2497 			wait(&parent);
2498 			signal(SIGINT, abort_edit);
2499 /*
2500  |  if this process is actually the child of the editor, exit
2501  |  The editor forks a process.  If output must be sent to the command to be
2502  |  exec'd another process is forked, and that process (the child's child)
2503  |  will exec the command.  In this case, "shell_fork" will be FALSE.  If no
2504  |  output is to be performed to the shell command, "shell_fork" will be TRUE.
2505  */
2506 			if (!shell_fork)
2507 				exit(0);
2508 		}
2509 	}
2510 	if (shell_fork)
2511 	{
2512 		printf("%s", press_ret_to_cont_str);
2513 		fflush(stdout);
2514 		while (((in = getchar()) != '\n') && (in != '\r'))
2515 			;
2516 #ifdef XAE
2517 		raise_window();
2518 #endif
2519 	}
2520 	fixterm();
2521 	noecho();
2522 	nonl();
2523 	raw();
2524 	keypad(curr_buff->win, TRUE);
2525 	curr_buff->win = curr_buff->win;
2526 	clearok(curr_buff->win, TRUE);
2527 	redraw();
2528 }
2529 
2530 void
redraw()2531 redraw()		/* redraw screen			*/
2532 {
2533 	repaint_screen();
2534 }
2535 
2536 void
repaint_screen()2537 repaint_screen()
2538 {
2539 	struct bufr *t_buff;	/* temporary buffer	*/
2540 
2541 	for (t_buff = first_buff; t_buff != NULL; t_buff = t_buff->next_buff)
2542 	{
2543 		touchwin(t_buff->win);
2544 		wnoutrefresh(t_buff->win);
2545 		if (t_buff->footer != NULL)
2546 		{
2547 			touchwin(t_buff->footer);
2548 			wnoutrefresh(t_buff->footer);
2549 		}
2550 	}
2551 	if (info_window)
2552 	{
2553 		touchwin(info_win);
2554 		wnoutrefresh(info_win);
2555 	}
2556 }
2557 
2558 void
copy_str(str1,str2)2559 copy_str(str1, str2)	/* copy string1 to string2			*/
2560 char *str1, *str2;
2561 {
2562 	char *t1, *t2;
2563 
2564 	t1 = str1;
2565 	t2 = str2;
2566 	while (*t1 != '\0')
2567 	{
2568 		*t2 = *t1;
2569 		t2++;
2570 		t1++;
2571 	}
2572 	*t2 = *t1;
2573 }
2574 
2575 void
echo_string(string)2576 echo_string(string)	/* echo the given string	*/
2577 char *string;
2578 {
2579 	char *temp;
2580 	int Counter;
2581 
2582 	if (echo_flag)
2583 	{
2584 		temp = string;
2585 		while (*temp != '\0')
2586 		{
2587 			if (*temp == '\\')
2588 			{
2589 				temp++;
2590 				if (*temp == 'n')
2591 					putchar('\n');
2592 				else if (*temp == 't')
2593 					putchar('\t');
2594 				else if (*temp == 'b')
2595 					putchar('\b');
2596 				else if (*temp == 'r')
2597 					putchar('\r');
2598 				else if (*temp == 'f')
2599 					putchar('\f');
2600 				else if ((*temp == 'e') || (*temp == 'E'))
2601 					putchar('\033');		/* escape */
2602 				else if (*temp == '\\')
2603 					putchar('\\');
2604 				else if (*temp == '\'')
2605 					putchar('\'');
2606 				else if ((*temp >= '0') && (*temp <= '9'))
2607 				{
2608 					Counter = 0;
2609 					while ((*temp >= '0') && (*temp <= '9'))
2610 					{
2611 						Counter = (8 * Counter) + (*temp - '0');
2612 						temp++;
2613 					}
2614 					putchar(Counter);
2615 					temp--;
2616 				}
2617 				temp++;
2618 			}
2619 			else
2620 			{
2621 				putchar(*temp);
2622 				temp++;
2623 			}
2624 		}
2625 	}
2626 	fflush(stdout);
2627 }
2628 
2629 char *init_name[6] = {
2630 	"/usr/local/aee/init.ae",
2631 	"/usr/local/lib/init.ae",
2632 	NULL,                           /* to be ~/.init.ae */
2633 	".init.ae",
2634 	NULL,                           /* to be ~/.aeerc */
2635 	".aeerc"
2636 	};
2637 
2638 void
ae_init()2639 ae_init()	/* check for init file and read it if it exists	*/
2640 {
2641 	FILE *init_file;
2642 	char *string;
2643 	char *str1;
2644 	char *str2;
2645 	char *home;
2646 	char *tmp;
2647 	int c_int;
2648 	int lines;
2649 	int counter;
2650 
2651 	home = xalloc(11);
2652 	strcpy(home, "~/.init.ae");
2653 	init_name[2] = resolve_name(home);
2654 	free(home);
2655 
2656 	home = xalloc(11);
2657 	strcpy(home, "~/.aeerc");
2658 	init_name[4] = resolve_name(home);
2659 	free(home);
2660 
2661 
2662 
2663 	string = xalloc(512);
2664 	for (counter = 0; counter < 6; counter++)
2665 	{
2666 		lines = 1;
2667 		if (!(access(init_name[counter], 4)))
2668 		{
2669 			init_file = fopen(init_name[counter], "r");
2670 			while ((str2 = fgets(string, 512, init_file)) != NULL)
2671 			{
2672 				str1 = str2 = string;
2673 				while (*str2 != '\n')
2674 					str2++;
2675 				*str2 = '\0';
2676 
2677 				if (unique_test(string, init_strings) != 1)
2678 					continue;
2679 
2680 				if (compare(str1, DEFINE_str, FALSE))
2681 				{
2682 					str1 = next_word(str1);
2683 					def_key(str1);
2684 				}
2685 				else if (compare(str1, WINDOWS_str,  FALSE))
2686 					windows = TRUE;
2687 				else if (compare(str1, NOWINDOWS_str,  FALSE))
2688 					windows = FALSE;
2689 				else if (compare(str1, CASE_str,  FALSE))
2690 					case_sen = TRUE;
2691 				else if (compare(str1, NOCASE_str,  FALSE))
2692 					case_sen = FALSE;
2693 				else if (compare(str1, TABS_str,  FALSE))
2694 					tab_set(str1);
2695 				else if (compare(str1, UNTABS_str,  FALSE))
2696 					unset_tab(str1);
2697 				else if (compare(str1, EXPAND_str,  FALSE))
2698 					expand = TRUE;
2699 				else if (compare(str1, SPACING_str, FALSE))
2700 				{
2701 					str1 = next_word(str1);
2702 					if (*str1 != '\0')
2703 						tab_spacing = atoi(str1);
2704 				}
2705 				else if (compare(str1, NOEXPAND_str,  FALSE))
2706 					expand = FALSE;
2707 				else if (compare(str1, NOJUSTIFY_str,  FALSE))
2708 					right_justify = FALSE;
2709 				else if (compare(str1, JUSTIFY_str,  FALSE))
2710 					right_justify = TRUE;
2711 				else if (compare(str1, LITERAL_str,  FALSE))
2712 					literal = TRUE;
2713 				else if (compare(str1, NOLITERAL_str,  FALSE))
2714 					literal = FALSE;
2715 				else if (compare(str1, STATUS_str,  FALSE))
2716 					status_line = TRUE;
2717 				else if (compare(str1, NOSTATUS_str,  FALSE))
2718 					status_line = FALSE;
2719 				else if (compare(str1, INDENT_str,  FALSE))
2720 					indent = TRUE;
2721 				else if (compare(str1, NOINDENT_str,  FALSE))
2722 					indent = FALSE;
2723 				else if (compare(str1, OVERSTRIKE_str,  FALSE))
2724 					overstrike = TRUE;
2725 				else if (compare(str1, NOOVERSTRIKE_str,  FALSE))
2726 					overstrike = FALSE;
2727 				else if (compare(str1, AUTOFORMAT_str,  FALSE))
2728 				{
2729 					auto_format = TRUE;
2730 					observ_margins = TRUE;
2731 					indent = FALSE;
2732 				}
2733 				else if (compare(str1, NOAUTOFORMAT_str,  FALSE))
2734 					auto_format = FALSE;
2735 				else if (compare(str1, EIGHT_str,  FALSE))
2736 					eightbit = TRUE;
2737 				else if (compare(str1, NOEIGHT_str,  FALSE))
2738 					eightbit = FALSE;
2739 				else if (compare(str1, MARGINS_str,  FALSE))
2740 					observ_margins = TRUE;
2741 				else if (compare(str1, NOMARGINS_str,  FALSE))
2742 					observ_margins = FALSE;
2743 				else if (compare(str1, ee_mode_str,  FALSE))
2744 				{
2745 					ee_mode_menu = TRUE;
2746 					main_menu[0].item_string = ee_mode_main_menu_strings[0];
2747 					main_menu[1].item_string = ee_mode_main_menu_strings[1];
2748 					main_menu[2].item_string = ee_mode_main_menu_strings[2];
2749 					main_menu[3].item_string = ee_mode_main_menu_strings[3];
2750 					main_menu[4].item_string = ee_mode_main_menu_strings[4];
2751 					main_menu[5].item_string = ee_mode_main_menu_strings[5];
2752 					main_menu[6].item_string = ee_mode_main_menu_strings[6];
2753 					main_menu[7].item_string = ee_mode_main_menu_strings[7];
2754 					main_menu[8].item_string = ee_mode_main_menu_strings[8];
2755 					main_menu[3].procedure = menu_op;
2756 					main_menu[3].ptr_argument = file_menu;
2757 					main_menu[4].procedure = NULL;
2758 					main_menu[4].ptr_argument = NULL;
2759 					main_menu[4].iprocedure = NULL;
2760 					main_menu[4].nprocedure = redraw;
2761 					main_menu[5].procedure = NULL;
2762 					main_menu[5].ptr_argument = NULL;
2763 					main_menu[5].iprocedure = NULL;
2764 					main_menu[5].nprocedure = modes_op;
2765 					main_menu[6].procedure = menu_op;
2766 					main_menu[6].ptr_argument = search_menu;
2767 					main_menu[6].iprocedure = NULL;
2768 					main_menu[6].nprocedure = NULL;
2769 					main_menu[7].procedure = menu_op;
2770 					main_menu[7].ptr_argument = misc_menu;
2771 					main_menu[7].iprocedure = NULL;
2772 					main_menu[7].nprocedure = NULL;
2773 					main_menu[8].procedure = menu_op;
2774 					main_menu[8].ptr_argument = edit_menu;
2775 					main_menu[8].iprocedure = NULL;
2776 					main_menu[8].nprocedure = NULL;
2777 				}
2778 				else if ((compare(str1, LEFTMARGIN_str,  FALSE)) || (compare(str1, RIGHTMARGIN_str,  FALSE)))
2779 				{
2780 					tmp = next_word(str1);
2781 					if ((*tmp >= '0') && (*tmp <= '9'))
2782 					{
2783 						c_int = atoi(tmp);
2784 						if (compare(str1, LEFTMARGIN_str,  FALSE))
2785 							left_margin = c_int;
2786 						else if (compare(str1, RIGHTMARGIN_str,  FALSE))
2787 							right_margin = c_int;
2788 					}
2789 				}
2790 				else if (compare(str1, info_win_height_cmd_str,  FALSE))
2791 				{
2792 					tmp = next_word(str1);
2793 					if ((*tmp >= '0') && (*tmp <= '9'))
2794 					{
2795 						c_int = atoi(tmp);
2796 						if ((c_int > 0) && (c_int <= MAX_HELP_LINES))
2797 							info_win_height = c_int + 1;
2798 					}
2799 				}
2800 				else if (compare(str1, ECHO_str,  FALSE))
2801 				{
2802 #ifndef XAE
2803 					str1 = next_word(str1);
2804 					if (*str1 != '\0')
2805 						echo_string(str1);
2806 #endif
2807 				}
2808 				else if (compare(str1, PRINTCOMMAND_str, FALSE))
2809 				{
2810 					str1 = next_word(str1);
2811 					print_command = xalloc(strlen(str1)+1);
2812 					copy_str(str1, print_command);
2813 				}
2814 				else if (compare(str1, INFO_str,  FALSE))
2815 					info_window = TRUE;
2816 				else if (compare(str1, NOINFO_str,  FALSE))
2817 					info_window = FALSE;
2818 				else if (compare(str1, HIGHLIGHT_str,  FALSE))
2819 					nohighlight = FALSE;
2820 				else if (compare(str1, NOHIGHLIGHT_str,  FALSE))
2821 					nohighlight = TRUE;
2822 				else if (compare(str1, jrnl_dir,  FALSE))
2823 				{
2824 					str1 = next_word(str1);
2825 					tmp = str1;
2826 					while ((*tmp != ' ') &&
2827 					       (*tmp != '\t') &&
2828 					       (*tmp != '\0'))
2829 						tmp++;
2830 					*tmp = '\0';
2831 					journal_dir = resolve_name(str1);
2832 					if (str1 == journal_dir)
2833 					{
2834 						journal_dir =
2835 						   xalloc(strlen(str1) + 1);
2836 						strcpy(journal_dir, str1);
2837 					}
2838 					value = create_dir(journal_dir);
2839 					if (value == -1)
2840 					{
2841 						/*
2842 						 |  journal dir doesn't exist
2843 						 */
2844 						free(journal_dir);
2845 						journal_dir = NULL;
2846 					}
2847 				}
2848 				else if (compare(str1, text_cmd,  FALSE))
2849 					text_only = TRUE;
2850 				else if (compare(str1, binary_cmd,  FALSE))
2851 					text_only = FALSE;
2852 				else if (compare(str1, help_file_str,  FALSE))
2853 				{
2854 					str1 = next_word(str1);
2855 					tmp = str1;
2856 					while ((*tmp != ' ') &&
2857 					       (*tmp != '\t') &&
2858 					       (*tmp != '\0'))
2859 						tmp++;
2860 					*tmp = '\0';
2861 					ae_help_file = resolve_name(str1);
2862 					if (str1 == ae_help_file)
2863 					{
2864 						ae_help_file =
2865 						   xalloc(strlen(str1) + 1);
2866 						strcpy(ae_help_file, str1);
2867 					}
2868 				}
2869 				lines++;
2870 			}
2871 			fclose(init_file);
2872 			if (!compare(curr_buff->name, main_buffer_name, TRUE))
2873 				chng_buf(main_buffer_name);
2874 		}
2875 	}
2876 	free(string);
2877 }
2878 
2879