version 1.11, 2014/05/10 16:45:23 |
version 1.12, 2015/11/05 22:08:44 |
|
|
* |
* |
* For more information, see the README file. |
* For more information, see the README file. |
*/ |
*/ |
|
/* |
|
* Modified for use with illumos. |
|
* Copyright 2014 Garrett D'Amore <garrett@damore.org> |
|
*/ |
|
|
|
|
#include "less.h" |
#include "less.h" |
#if HAVE_STAT |
|
#include <sys/stat.h> |
#include <sys/stat.h> |
#endif |
|
|
|
public int fd0 = 0; |
static int fd0 = 0; |
|
|
extern int new_file; |
extern int new_file; |
extern int errmsgs; |
extern int errmsgs; |
extern int cbufs; |
|
extern char *every_first_cmd; |
extern char *every_first_cmd; |
extern int any_display; |
extern int any_display; |
extern int force_open; |
extern int force_open; |
|
|
extern IFILE curr_ifile; |
extern IFILE curr_ifile; |
extern IFILE old_ifile; |
extern IFILE old_ifile; |
extern struct scrpos initial_scrpos; |
extern struct scrpos initial_scrpos; |
extern void constant *ml_examine; |
extern void *ml_examine; |
#if SPACES_IN_FILENAMES |
|
extern char openquote; |
extern char openquote; |
extern char closequote; |
extern char closequote; |
#endif |
extern int less_is_more; |
|
|
#if LOGFILE |
|
extern int logfile; |
extern int logfile; |
extern int force_logfile; |
extern int force_logfile; |
extern char *namelogfile; |
extern char *namelogfile; |
#endif |
|
|
|
#if HAVE_STAT_INO |
dev_t curr_dev; |
public dev_t curr_dev; |
ino_t curr_ino; |
public ino_t curr_ino; |
|
#endif |
|
|
|
char *curr_altfilename = NULL; |
char *curr_altfilename = NULL; |
static void *curr_altpipe; |
static void *curr_altpipe; |
|
|
#if EXAMINE || TAB_COMPLETE_FILENAME |
|
/* |
/* |
* Textlist functions deal with a list of words separated by spaces. |
* Textlist functions deal with a list of words separated by spaces. |
* init_textlist sets up a textlist structure. |
* init_textlist sets up a textlist structure. |
|
|
* words, returning each one as a standard null-terminated string. |
* words, returning each one as a standard null-terminated string. |
* back_textlist does the same, but runs thru the list backwards. |
* back_textlist does the same, but runs thru the list backwards. |
*/ |
*/ |
public void |
void |
init_textlist(tlist, str) |
init_textlist(struct textlist *tlist, char *str) |
struct textlist *tlist; |
|
char *str; |
|
{ |
{ |
char *s; |
char *s; |
#if SPACES_IN_FILENAMES |
|
int meta_quoted = 0; |
int meta_quoted = 0; |
int delim_quoted = 0; |
int delim_quoted = 0; |
char *esc = get_meta_escape(); |
char *esc = get_meta_escape(); |
int esclen = strlen(esc); |
int esclen = strlen(esc); |
#endif |
|
|
|
tlist->string = skipsp(str); |
tlist->string = skipsp(str); |
tlist->endstring = tlist->string + strlen(tlist->string); |
tlist->endstring = tlist->string + strlen(tlist->string); |
for (s = str; s < tlist->endstring; s++) |
for (s = str; s < tlist->endstring; s++) { |
{ |
if (meta_quoted) { |
#if SPACES_IN_FILENAMES |
|
if (meta_quoted) |
|
{ |
|
meta_quoted = 0; |
meta_quoted = 0; |
} else if (esclen > 0 && s + esclen < tlist->endstring && |
} else if (esclen > 0 && s + esclen < tlist->endstring && |
strncmp(s, esc, esclen) == 0) |
strncmp(s, esc, esclen) == 0) { |
{ |
|
meta_quoted = 1; |
meta_quoted = 1; |
s += esclen - 1; |
s += esclen - 1; |
} else if (delim_quoted) |
} else if (delim_quoted) { |
{ |
|
if (*s == closequote) |
if (*s == closequote) |
delim_quoted = 0; |
delim_quoted = 0; |
} else /* (!delim_quoted) */ |
} else /* (!delim_quoted) */ { |
{ |
|
if (*s == openquote) |
if (*s == openquote) |
delim_quoted = 1; |
delim_quoted = 1; |
else if (*s == ' ') |
else if (*s == ' ') |
*s = '\0'; |
*s = '\0'; |
} |
} |
#else |
|
if (*s == ' ') |
|
*s = '\0'; |
|
#endif |
|
} |
} |
} |
} |
|
|
public char * |
char * |
forw_textlist(tlist, prev) |
forw_textlist(struct textlist *tlist, char *prev) |
struct textlist *tlist; |
|
char *prev; |
|
{ |
{ |
char *s; |
char *s; |
|
|
/* |
/* |
* prev == NULL means return the first word in the list. |
* prev == NULL means return the first word in the list. |
* Otherwise, return the word after "prev". |
* Otherwise, return the word after "prev". |
|
|
return (s); |
return (s); |
} |
} |
|
|
public char * |
char * |
back_textlist(tlist, prev) |
back_textlist(struct textlist *tlist, char *prev) |
struct textlist *tlist; |
|
char *prev; |
|
{ |
{ |
char *s; |
char *s; |
|
|
/* |
/* |
* prev == NULL means return the last word in the list. |
* prev == NULL means return the last word in the list. |
* Otherwise, return the word before "prev". |
* Otherwise, return the word before "prev". |
|
|
s--; |
s--; |
return (s); |
return (s); |
} |
} |
#endif /* EXAMINE || TAB_COMPLETE_FILENAME */ |
|
|
|
/* |
/* |
* Close the current input file. |
* Close the current input file. |
*/ |
*/ |
static void |
static void |
close_file() |
close_file(void) |
{ |
{ |
struct scrpos scrpos; |
struct scrpos scrpos; |
|
|
if (curr_ifile == NULL_IFILE) |
if (curr_ifile == NULL_IFILE) |
return; |
return; |
|
|
|
|
* the same position if we edit this file again. |
* the same position if we edit this file again. |
*/ |
*/ |
get_scrpos(&scrpos); |
get_scrpos(&scrpos); |
if (scrpos.pos != NULL_POSITION) |
if (scrpos.pos != -1) { |
{ |
|
store_pos(curr_ifile, &scrpos); |
store_pos(curr_ifile, &scrpos); |
lastmark(); |
lastmark(); |
} |
} |
|
|
* If we opened a file using an alternate name, |
* If we opened a file using an alternate name, |
* do special stuff to close it. |
* do special stuff to close it. |
*/ |
*/ |
if (curr_altfilename != NULL) |
if (curr_altfilename != NULL) { |
{ |
|
close_altfile(curr_altfilename, get_filename(curr_ifile), |
close_altfile(curr_altfilename, get_filename(curr_ifile), |
curr_altpipe); |
curr_altpipe); |
free(curr_altfilename); |
free(curr_altfilename); |
curr_altfilename = NULL; |
curr_altfilename = NULL; |
} |
} |
curr_ifile = NULL_IFILE; |
curr_ifile = NULL_IFILE; |
#if HAVE_STAT_INO |
|
curr_ino = curr_dev = 0; |
curr_ino = curr_dev = 0; |
#endif |
|
} |
} |
|
|
/* |
/* |
|
|
* Filename == "-" means standard input. |
* Filename == "-" means standard input. |
* Filename == NULL means just close the current file. |
* Filename == NULL means just close the current file. |
*/ |
*/ |
public int |
int |
edit(filename) |
edit(char *filename) |
char *filename; |
|
{ |
{ |
if (filename == NULL) |
if (filename == NULL) |
return (edit_ifile(NULL_IFILE)); |
return (edit_ifile(NULL_IFILE)); |
return (edit_ifile(get_ifile(filename, curr_ifile))); |
return (edit_ifile(get_ifile(filename, curr_ifile))); |
} |
} |
|
|
/* |
/* |
* Edit a new file (given its IFILE). |
* Edit a new file (given its IFILE). |
* ifile == NULL means just close the current file. |
* ifile == NULL means just close the current file. |
*/ |
*/ |
public int |
int |
edit_ifile(ifile) |
edit_ifile(IFILE ifile) |
IFILE ifile; |
|
{ |
{ |
int f; |
int f; |
int answer; |
int answer; |
|
|
void *alt_pipe; |
void *alt_pipe; |
IFILE was_curr_ifile; |
IFILE was_curr_ifile; |
PARG parg; |
PARG parg; |
|
|
if (ifile == curr_ifile) |
if (ifile == curr_ifile) { |
{ |
|
/* |
/* |
* Already have the correct file open. |
* Already have the correct file open. |
*/ |
*/ |
|
|
* {{ Some stupid implementations of popen() mess up if you do: |
* {{ Some stupid implementations of popen() mess up if you do: |
* fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }} |
* fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }} |
*/ |
*/ |
#if LOGFILE |
|
end_logfile(); |
end_logfile(); |
#endif |
|
was_curr_ifile = save_curr_ifile(); |
was_curr_ifile = save_curr_ifile(); |
if (curr_ifile != NULL_IFILE) |
if (curr_ifile != NULL_IFILE) { |
{ |
|
chflags = ch_getflags(); |
chflags = ch_getflags(); |
close_file(); |
close_file(); |
#if !SMALL |
if ((chflags & CH_HELPFILE) && |
if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1) |
held_ifile(was_curr_ifile) <= 1) { |
{ |
|
/* |
/* |
* Don't keep the help file in the ifile list. |
* Don't keep the help file in the ifile list. |
*/ |
*/ |
del_ifile(was_curr_ifile); |
del_ifile(was_curr_ifile); |
was_curr_ifile = old_ifile; |
was_curr_ifile = old_ifile; |
} |
} |
#endif /* !SMALL */ |
|
} |
} |
|
|
if (ifile == NULL_IFILE) |
if (ifile == NULL_IFILE) { |
{ |
|
/* |
/* |
* No new file to open. |
* No new file to open. |
* (Don't set old_ifile, because if you call edit_ifile(NULL), |
* (Don't set old_ifile, because if you call edit_ifile(NULL), |
|
|
qopen_filename = shell_unquote(open_filename); |
qopen_filename = shell_unquote(open_filename); |
|
|
chflags = 0; |
chflags = 0; |
#if !SMALL |
|
if (strcmp(open_filename, helpfile()) == 0) |
if (strcmp(open_filename, helpfile()) == 0) |
chflags |= CH_HELPFILE; |
chflags |= CH_HELPFILE; |
#endif /* !SMALL */ |
if (alt_pipe != NULL) { |
if (alt_pipe != NULL) |
|
{ |
|
/* |
/* |
* The alternate "file" is actually a pipe. |
* The alternate "file" is actually a pipe. |
* f has already been set to the file descriptor of the pipe |
* f has already been set to the file descriptor of the pipe |
* in the call to open_altfile above. |
* in the call to open_altfile above. |
* Keep the file descriptor open because it was opened |
* Keep the file descriptor open because it was opened |
* via popen(), and pclose() wants to close it. |
* via popen(), and pclose() wants to close it. |
*/ |
*/ |
chflags |= CH_POPENED; |
chflags |= CH_POPENED; |
} else if (strcmp(open_filename, "-") == 0) |
} else if (strcmp(open_filename, "-") == 0) { |
{ |
/* |
/* |
|
* Use standard input. |
* Use standard input. |
* Keep the file descriptor open because we can't reopen it. |
* Keep the file descriptor open because we can't reopen it. |
*/ |
*/ |
f = fd0; |
f = fd0; |
chflags |= CH_KEEPOPEN; |
chflags |= CH_KEEPOPEN; |
/* |
} else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0) { |
* Must switch stdin to BINARY mode. |
|
*/ |
|
SET_BINARY(f); |
|
#if MSDOS_COMPILER==DJGPPC |
|
/* |
|
* Setting stdin to binary by default causes |
|
* Ctrl-C to not raise SIGINT. We must undo |
|
* that side-effect. |
|
*/ |
|
__djgpp_set_ctrl_c(1); |
|
#endif |
|
} else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0) |
|
{ |
|
f = -1; |
f = -1; |
chflags |= CH_NODATA; |
chflags |= CH_NODATA; |
} else if ((parg.p_string = bad_file(open_filename)) != NULL) |
} else if ((parg.p_string = bad_file(open_filename)) != NULL) { |
{ |
|
/* |
/* |
* It looks like a bad file. Don't try to open it. |
* It looks like a bad file. Don't try to open it. |
*/ |
*/ |
error("%s", &parg); |
error("%s", &parg); |
free(parg.p_string); |
free(parg.p_string); |
err1: |
err1: |
if (alt_filename != NULL) |
if (alt_filename != NULL) { |
{ |
|
close_altfile(alt_filename, filename, alt_pipe); |
close_altfile(alt_filename, filename, alt_pipe); |
free(alt_filename); |
free(alt_filename); |
} |
} |
|
|
/* |
/* |
* Re-open the current file. |
* Re-open the current file. |
*/ |
*/ |
if (was_curr_ifile == ifile) |
if (was_curr_ifile == ifile) { |
{ |
|
/* |
/* |
* Whoops. The "current" ifile is the one we just deleted. |
* Whoops. The "current" ifile is the one we just |
* Just give up. |
* deleted. Just give up. |
*/ |
*/ |
quit(QUIT_ERROR); |
quit(QUIT_ERROR); |
} |
} |
reedit_ifile(was_curr_ifile); |
reedit_ifile(was_curr_ifile); |
return (1); |
return (1); |
} else if ((f = open(qopen_filename, OPEN_READ)) < 0) |
} else if ((f = open(qopen_filename, O_RDONLY)) < 0) { |
{ |
|
/* |
/* |
* Got an error trying to open it. |
* Got an error trying to open it. |
*/ |
*/ |
parg.p_string = errno_message(filename); |
parg.p_string = errno_message(filename); |
error("%s", &parg); |
error("%s", &parg); |
free(parg.p_string); |
free(parg.p_string); |
goto err1; |
goto err1; |
} else |
} else { |
{ |
|
chflags |= CH_CANSEEK; |
chflags |= CH_CANSEEK; |
if (!force_open && !opened(ifile) && bin_file(f)) |
if (!force_open && !opened(ifile) && bin_file(f)) { |
{ |
|
/* |
/* |
* Looks like a binary file. |
* Looks like a binary file. |
* Ask user if we should proceed. |
* Ask user if we should proceed. |
*/ |
*/ |
parg.p_string = filename; |
parg.p_string = filename; |
answer = query("\"%s\" may be a binary file. See it anyway? ", |
answer = query("\"%s\" may be a binary file. " |
&parg); |
"See it anyway? ", &parg); |
if (answer != 'y' && answer != 'Y') |
if (answer != 'y' && answer != 'Y') { |
{ |
(void) close(f); |
close(f); |
|
goto err1; |
goto err1; |
} |
} |
} |
} |
|
|
* Get the new ifile. |
* Get the new ifile. |
* Get the saved position for the file. |
* Get the saved position for the file. |
*/ |
*/ |
if (was_curr_ifile != NULL_IFILE) |
if (was_curr_ifile != NULL_IFILE) { |
{ |
|
old_ifile = was_curr_ifile; |
old_ifile = was_curr_ifile; |
unsave_ifile(was_curr_ifile); |
unsave_ifile(was_curr_ifile); |
} |
} |
|
|
new_file = TRUE; |
new_file = TRUE; |
ch_init(f, chflags); |
ch_init(f, chflags); |
|
|
if (!(chflags & CH_HELPFILE)) |
if (!(chflags & CH_HELPFILE)) { |
{ |
struct stat statbuf; |
#if LOGFILE |
int r; |
|
|
if (namelogfile != NULL && is_tty) |
if (namelogfile != NULL && is_tty) |
use_logfile(namelogfile); |
use_logfile(namelogfile); |
#endif |
/* Remember the i-number and device of opened file. */ |
#if HAVE_STAT_INO |
r = stat(qopen_filename, &statbuf); |
/* Remember the i-number and device of the opened file. */ |
if (r == 0) { |
{ |
curr_ino = statbuf.st_ino; |
struct stat statbuf; |
curr_dev = statbuf.st_dev; |
int r = stat(qopen_filename, &statbuf); |
|
if (r == 0) |
|
{ |
|
curr_ino = statbuf.st_ino; |
|
curr_dev = statbuf.st_dev; |
|
} |
|
} |
} |
#endif |
|
if (every_first_cmd != NULL) |
if (every_first_cmd != NULL) |
ungetsc(every_first_cmd); |
ungetsc(every_first_cmd); |
} |
} |
|
|
free(qopen_filename); |
free(qopen_filename); |
no_display = !any_display; |
no_display = !any_display; |
flush(); |
flush(); |
any_display = TRUE; |
any_display = TRUE; |
|
|
if (is_tty) |
if (is_tty) { |
{ |
|
/* |
/* |
* Output is to a real tty. |
* Output is to a real tty. |
*/ |
*/ |
|
|
*/ |
*/ |
pos_clear(); |
pos_clear(); |
clr_linenum(); |
clr_linenum(); |
#if HILITE_SEARCH |
|
clr_hilite(); |
clr_hilite(); |
#endif |
|
cmd_addhist(ml_examine, filename); |
cmd_addhist(ml_examine, filename); |
if (no_display && errmsgs > 0) |
if (no_display && errmsgs > 0) { |
{ |
|
/* |
/* |
* We displayed some messages on error output |
* We displayed some messages on error output |
* (file descriptor 2; see error() function). |
* (file descriptor 2; see error() function). |
|
|
return (0); |
return (0); |
} |
} |
|
|
#if EXAMINE |
|
/* |
/* |
* Edit a space-separated list of files. |
* Edit a space-separated list of files. |
* For each filename in the list, enter it into the ifile list. |
* For each filename in the list, enter it into the ifile list. |
* Then edit the first one. |
* Then edit the first one. |
*/ |
*/ |
public int |
int |
edit_list(filelist) |
edit_list(char *filelist) |
char *filelist; |
|
{ |
{ |
IFILE save_ifile; |
IFILE save_ifile; |
char *good_filename; |
char *good_filename; |
|
|
|
|
save_ifile = save_curr_ifile(); |
save_ifile = save_curr_ifile(); |
good_filename = NULL; |
good_filename = NULL; |
|
|
/* |
/* |
* Run thru each filename in the list. |
* Run thru each filename in the list. |
* Try to glob the filename. |
* Try to glob the filename. |
* If it doesn't expand, just try to open the filename. |
* If it doesn't expand, just try to open the filename. |
* If it does expand, try to open each name in that list. |
* If it does expand, try to open each name in that list. |
*/ |
*/ |
init_textlist(&tl_files, filelist); |
init_textlist(&tl_files, filelist); |
filename = NULL; |
filename = NULL; |
while ((filename = forw_textlist(&tl_files, filename)) != NULL) |
while ((filename = forw_textlist(&tl_files, filename)) != NULL) { |
{ |
|
gfilelist = lglob(filename); |
gfilelist = lglob(filename); |
init_textlist(&tl_gfiles, gfilelist); |
init_textlist(&tl_gfiles, gfilelist); |
gfilename = NULL; |
gfilename = NULL; |
while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL) |
while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != |
{ |
NULL) { |
if (edit(gfilename) == 0 && good_filename == NULL) |
if (edit(gfilename) == 0 && good_filename == NULL) |
good_filename = get_filename(curr_ifile); |
good_filename = get_filename(curr_ifile); |
} |
} |
|
|
/* |
/* |
* Edit the first valid filename in the list. |
* Edit the first valid filename in the list. |
*/ |
*/ |
if (good_filename == NULL) |
if (good_filename == NULL) { |
{ |
|
unsave_ifile(save_ifile); |
unsave_ifile(save_ifile); |
return (1); |
return (1); |
} |
} |
if (get_ifile(good_filename, curr_ifile) == curr_ifile) |
if (get_ifile(good_filename, curr_ifile) == curr_ifile) { |
{ |
|
/* |
/* |
* Trying to edit the current file; don't reopen it. |
* Trying to edit the current file; don't reopen it. |
*/ |
*/ |
|
|
reedit_ifile(save_ifile); |
reedit_ifile(save_ifile); |
return (edit(good_filename)); |
return (edit(good_filename)); |
} |
} |
#endif /* EXAMINE */ |
|
|
|
/* |
/* |
* Edit the first file in the command line (ifile) list. |
* Edit the first file in the command line (ifile) list. |
*/ |
*/ |
public int |
int |
edit_first() |
edit_first(void) |
{ |
{ |
curr_ifile = NULL_IFILE; |
curr_ifile = NULL_IFILE; |
return (edit_next(1)); |
return (edit_next(1)); |
|
|
/* |
/* |
* Edit the last file in the command line (ifile) list. |
* Edit the last file in the command line (ifile) list. |
*/ |
*/ |
public int |
int |
edit_last() |
edit_last(void) |
{ |
{ |
curr_ifile = NULL_IFILE; |
curr_ifile = NULL_IFILE; |
return (edit_prev(1)); |
return (edit_prev(1)); |
|
|
/* |
/* |
* Edit the n-th next or previous file in the command line (ifile) list. |
* Edit the n-th next or previous file in the command line (ifile) list. |
*/ |
*/ |
static int |
static int |
edit_istep(h, n, dir) |
edit_istep(IFILE h, int n, int dir) |
IFILE h; |
|
int n; |
|
int dir; |
|
{ |
{ |
IFILE next; |
IFILE next; |
|
|
/* |
/* |
* Skip n filenames, then try to edit each filename. |
* Skip n filenames, then try to edit each filename. |
*/ |
*/ |
for (;;) |
for (;;) { |
{ |
|
next = (dir > 0) ? next_ifile(h) : prev_ifile(h); |
next = (dir > 0) ? next_ifile(h) : prev_ifile(h); |
if (--n < 0) |
if (--n < 0) { |
{ |
|
if (edit_ifile(h) == 0) |
if (edit_ifile(h) == 0) |
break; |
break; |
} |
} |
if (next == NULL_IFILE) |
if (next == NULL_IFILE) { |
{ |
|
/* |
/* |
* Reached end of the ifile list. |
* Reached end of the ifile list. |
*/ |
*/ |
return (1); |
return (1); |
} |
} |
if (ABORT_SIGS()) |
if (ABORT_SIGS()) { |
{ |
|
/* |
/* |
* Interrupt breaks out, if we're in a long |
* Interrupt breaks out, if we're in a long |
* list of files that can't be opened. |
* list of files that can't be opened. |
|
|
return (1); |
return (1); |
} |
} |
h = next; |
h = next; |
} |
} |
/* |
/* |
* Found a file that we can edit. |
* Found a file that we can edit. |
*/ |
*/ |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
edit_inext(h, n) |
edit_inext(IFILE h, int n) |
IFILE h; |
|
int n; |
|
{ |
{ |
return (edit_istep(h, n, +1)); |
return (edit_istep(h, n, +1)); |
} |
} |
|
|
public int |
int |
edit_next(n) |
edit_next(int n) |
int n; |
|
{ |
{ |
return edit_istep(curr_ifile, n, +1); |
return (edit_istep(curr_ifile, n, +1)); |
} |
} |
|
|
static int |
static int |
edit_iprev(h, n) |
edit_iprev(IFILE h, int n) |
IFILE h; |
|
int n; |
|
{ |
{ |
return (edit_istep(h, n, -1)); |
return (edit_istep(h, n, -1)); |
} |
} |
|
|
public int |
int |
edit_prev(n) |
edit_prev(int n) |
int n; |
|
{ |
{ |
return edit_istep(curr_ifile, n, -1); |
return (edit_istep(curr_ifile, n, -1)); |
} |
} |
|
|
/* |
/* |
* Edit a specific file in the command line (ifile) list. |
* Edit a specific file in the command line (ifile) list. |
*/ |
*/ |
public int |
int |
edit_index(n) |
edit_index(int n) |
int n; |
|
{ |
{ |
IFILE h; |
IFILE h; |
|
|
h = NULL_IFILE; |
h = NULL_IFILE; |
do |
do { |
{ |
if ((h = next_ifile(h)) == NULL_IFILE) { |
if ((h = next_ifile(h)) == NULL_IFILE) |
|
{ |
|
/* |
/* |
* Reached end of the list without finding it. |
* Reached end of the list without finding it. |
*/ |
*/ |
|
|
return (edit_ifile(h)); |
return (edit_ifile(h)); |
} |
} |
|
|
public IFILE |
IFILE |
save_curr_ifile() |
save_curr_ifile(void) |
{ |
{ |
if (curr_ifile != NULL_IFILE) |
if (curr_ifile != NULL_IFILE) |
hold_ifile(curr_ifile, 1); |
hold_ifile(curr_ifile, 1); |
return (curr_ifile); |
return (curr_ifile); |
} |
} |
|
|
public void |
void |
unsave_ifile(save_ifile) |
unsave_ifile(IFILE save_ifile) |
IFILE save_ifile; |
|
{ |
{ |
if (save_ifile != NULL_IFILE) |
if (save_ifile != NULL_IFILE) |
hold_ifile(save_ifile, -1); |
hold_ifile(save_ifile, -1); |
|
|
/* |
/* |
* Reedit the ifile which was previously open. |
* Reedit the ifile which was previously open. |
*/ |
*/ |
public void |
void |
reedit_ifile(save_ifile) |
reedit_ifile(IFILE save_ifile) |
IFILE save_ifile; |
|
{ |
{ |
IFILE next; |
IFILE next; |
IFILE prev; |
IFILE prev; |
|
|
quit(QUIT_ERROR); |
quit(QUIT_ERROR); |
} |
} |
|
|
public void |
void |
reopen_curr_ifile() |
reopen_curr_ifile(void) |
{ |
{ |
IFILE save_ifile = save_curr_ifile(); |
IFILE save_ifile = save_curr_ifile(); |
close_file(); |
close_file(); |
|
|
/* |
/* |
* Edit standard input. |
* Edit standard input. |
*/ |
*/ |
public int |
int |
edit_stdin() |
edit_stdin(void) |
{ |
{ |
if (isatty(fd0)) |
if (isatty(fd0)) { |
{ |
if (less_is_more) { |
error("Missing filename (\"less --help\" for help)", NULL_PARG); |
error("Missing filename (\"more -h\" for help)", |
|
NULL_PARG); |
|
} else { |
|
error("Missing filename (\"less --help\" for help)", |
|
NULL_PARG); |
|
} |
quit(QUIT_OK); |
quit(QUIT_OK); |
} |
} |
return (edit("-")); |
return (edit("-")); |
|
|
* Copy a file directly to standard output. |
* Copy a file directly to standard output. |
* Used if standard output is not a tty. |
* Used if standard output is not a tty. |
*/ |
*/ |
public void |
void |
cat_file() |
cat_file(void) |
{ |
{ |
register int c; |
int c; |
|
|
while ((c = ch_forw_get()) != EOI) |
while ((c = ch_forw_get()) != EOI) |
putchr(c); |
putchr(c); |
flush(); |
flush(); |
} |
} |
|
|
#if LOGFILE |
|
|
|
/* |
/* |
* If the user asked for a log file and our input file |
* If the user asked for a log file and our input file |
* is standard input, create the log file. |
* is standard input, create the log file. |
* We take care not to blindly overwrite an existing file. |
* We take care not to blindly overwrite an existing file. |
*/ |
*/ |
public void |
void |
use_logfile(filename) |
use_logfile(char *filename) |
char *filename; |
|
{ |
{ |
register int exists; |
int exists; |
register int answer; |
int answer; |
PARG parg; |
PARG parg; |
|
|
if (ch_getflags() & CH_CANSEEK) |
if (ch_getflags() & CH_CANSEEK) |
|
|
* Decide whether to overwrite the log file or append to it. |
* Decide whether to overwrite the log file or append to it. |
* If it doesn't exist we "overwrite" it. |
* If it doesn't exist we "overwrite" it. |
*/ |
*/ |
if (!exists || force_logfile) |
if (!exists || force_logfile) { |
{ |
|
/* |
/* |
* Overwrite (or create) the log file. |
* Overwrite (or create) the log file. |
*/ |
*/ |
answer = 'O'; |
answer = 'O'; |
} else |
} else { |
{ |
|
/* |
/* |
* Ask user what to do. |
* Ask user what to do. |
*/ |
*/ |
parg.p_string = filename; |
parg.p_string = filename; |
answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg); |
answer = query("Warning: \"%s\" exists; " |
|
"Overwrite, Append or Don't log? ", &parg); |
} |
} |
|
|
loop: |
loop: |
switch (answer) |
switch (answer) { |
{ |
|
case 'O': case 'o': |
case 'O': case 'o': |
/* |
/* |
* Overwrite: create the file. |
* Overwrite: create the file. |
|
|
* Append: open the file and seek to the end. |
* Append: open the file and seek to the end. |
*/ |
*/ |
logfile = open(filename, OPEN_APPEND); |
logfile = open(filename, OPEN_APPEND); |
if (lseek(logfile, (off_t)0, SEEK_END) == BAD_LSEEK) |
if (lseek(logfile, (off_t)0, SEEK_END) == BAD_LSEEK) { |
{ |
|
close(logfile); |
close(logfile); |
logfile = -1; |
logfile = -1; |
} |
} |
|
|
/* |
/* |
* Eh? |
* Eh? |
*/ |
*/ |
answer = query("Overwrite, Append, or Don't log? (Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG); |
answer = query("Overwrite, Append, or Don't log? " |
|
"(Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG); |
goto loop; |
goto loop; |
} |
} |
|
|
if (logfile < 0) |
if (logfile < 0) { |
{ |
|
/* |
/* |
* Error in opening logfile. |
* Error in opening logfile. |
*/ |
*/ |
|
|
return; |
return; |
} |
} |
free(filename); |
free(filename); |
SET_BINARY(logfile); |
|
} |
} |
|
|
#endif |
|