2009-09-02 Chris Allegretta <chrisa@asty.org>
* Attempt to check file writability and emit a warning on the status bar if nano doesn't think the file can be written to. Feature originally requested by Damien Jolders <madamien@skullsquad.com> et al. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4407 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
5687c3dfa6
commit
f8f9027295
|
@ -1,3 +1,8 @@
|
||||||
|
2009-09-02 Chris Allegretta <chrisa@asty.org>
|
||||||
|
* Attempt to check file writability and emit a warning on the status bar
|
||||||
|
if nano doesn't think the file can be written to. Feature originally
|
||||||
|
requested by Damien Jolders <madamien@skullsquad.com> et al.
|
||||||
|
|
||||||
2009-08-29 Chris Allegretta <chrisa@asty.org>
|
2009-08-29 Chris Allegretta <chrisa@asty.org>
|
||||||
* Fix more soft wrapping issues, particularly with scrolling,
|
* Fix more soft wrapping issues, particularly with scrolling,
|
||||||
discovered by Hannes <mr_creosote@mutantwatch.de>.
|
discovered by Hannes <mr_creosote@mutantwatch.de>.
|
||||||
|
|
96
src/files.c
96
src/files.c
|
@ -145,8 +145,8 @@ void open_buffer(const char *filename, bool undoable)
|
||||||
|
|
||||||
/* If we have a non-new file, read it in. Then, if the buffer has
|
/* If we have a non-new file, read it in. Then, if the buffer has
|
||||||
* no stat, update the stat, if applicable. */
|
* no stat, update the stat, if applicable. */
|
||||||
if (rc == 0) {
|
if (rc > 0) {
|
||||||
read_file(f, filename, undoable);
|
read_file(f, rc, filename, undoable);
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
if (openfile->current_stat == NULL) {
|
if (openfile->current_stat == NULL) {
|
||||||
openfile->current_stat =
|
openfile->current_stat =
|
||||||
|
@ -195,8 +195,8 @@ void replace_buffer(const char *filename)
|
||||||
initialize_buffer_text();
|
initialize_buffer_text();
|
||||||
|
|
||||||
/* If we have a non-new file, read it in. */
|
/* If we have a non-new file, read it in. */
|
||||||
if (rc == 0)
|
if (rc > 0)
|
||||||
read_file(f, filename, FALSE);
|
read_file(f, rc, filename, FALSE);
|
||||||
|
|
||||||
/* Move back to the beginning of the first line of the buffer. */
|
/* Move back to the beginning of the first line of the buffer. */
|
||||||
openfile->current = openfile->fileage;
|
openfile->current = openfile->fileage;
|
||||||
|
@ -348,8 +348,10 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||||
|
|
||||||
/* Read an open file into the current buffer. f should be set to the
|
/* Read an open file into the current buffer. f should be set to the
|
||||||
* open file, and filename should be set to the name of the file.
|
* open file, and filename should be set to the name of the file.
|
||||||
undoable means do we want to create undo records to try and undo this */
|
* undoable means do we want to create undo records to try and undo this.
|
||||||
void read_file(FILE *f, const char *filename, bool undoable)
|
* Will also attempt to check file writability if fd > 0
|
||||||
|
*/
|
||||||
|
void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
||||||
{
|
{
|
||||||
size_t num_lines = 0;
|
size_t num_lines = 0;
|
||||||
/* The number of lines in the file. */
|
/* The number of lines in the file. */
|
||||||
|
@ -370,6 +372,8 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||||
int input_int;
|
int input_int;
|
||||||
/* The current value we read from the file, whether an input
|
/* The current value we read from the file, whether an input
|
||||||
* character or EOF. */
|
* character or EOF. */
|
||||||
|
bool writable = TRUE;
|
||||||
|
/* Is the file writable (if we care) */
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
int format = 0;
|
int format = 0;
|
||||||
/* 0 = *nix, 1 = DOS, 2 = Mac, 3 = both DOS and Mac. */
|
/* 0 = *nix, 1 = DOS, 2 = Mac, 3 = both DOS and Mac. */
|
||||||
|
@ -469,6 +473,11 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||||
if (ferror(f))
|
if (ferror(f))
|
||||||
nperror(filename);
|
nperror(filename);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
if (fd > 0) {
|
||||||
|
int closecode = close(fd);
|
||||||
|
fprintf(stderr, "Closecode = %d\n", closecode);
|
||||||
|
writable = is_file_writable(filename);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
/* If file conversion isn't disabled and the last character in this
|
/* If file conversion isn't disabled and the last character in this
|
||||||
|
@ -578,34 +587,55 @@ void read_file(FILE *f, const char *filename, bool undoable)
|
||||||
if (undoable)
|
if (undoable)
|
||||||
update_undo(INSERT);
|
update_undo(INSERT);
|
||||||
|
|
||||||
if (format == 3)
|
if (format == 3) {
|
||||||
|
if (writable)
|
||||||
statusbar(
|
statusbar(
|
||||||
P_("Read %lu line (Converted from DOS and Mac format)",
|
P_("Read %lu line (Converted from DOS and Mac format)",
|
||||||
"Read %lu lines (Converted from DOS and Mac format)",
|
"Read %lu lines (Converted from DOS and Mac format)",
|
||||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
else if (format == 2) {
|
else
|
||||||
|
statusbar(
|
||||||
|
P_("Read %lu line (Converted from DOS and Mac format - Warning: No write permission)",
|
||||||
|
"Read %lu lines (Converted from DOS and Mac format - Warning: No write permission)",
|
||||||
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
|
} else if (format == 2) {
|
||||||
openfile->fmt = MAC_FILE;
|
openfile->fmt = MAC_FILE;
|
||||||
|
if (writable)
|
||||||
statusbar(P_("Read %lu line (Converted from Mac format)",
|
statusbar(P_("Read %lu line (Converted from Mac format)",
|
||||||
"Read %lu lines (Converted from Mac format)",
|
"Read %lu lines (Converted from Mac format)",
|
||||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
|
else
|
||||||
|
statusbar(P_("Read %lu line (Converted from Mac format - Warning: No write permission)",
|
||||||
|
"Read %lu lines (Converted from Mac format - Warning: No write permission)",
|
||||||
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
} else if (format == 1) {
|
} else if (format == 1) {
|
||||||
openfile->fmt = DOS_FILE;
|
openfile->fmt = DOS_FILE;
|
||||||
|
if (writable)
|
||||||
statusbar(P_("Read %lu line (Converted from DOS format)",
|
statusbar(P_("Read %lu line (Converted from DOS format)",
|
||||||
"Read %lu lines (Converted from DOS format)",
|
"Read %lu lines (Converted from DOS format)",
|
||||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
|
else
|
||||||
|
statusbar(P_("Read %lu line (Converted from DOS format - Warning: No write permission)",
|
||||||
|
"Read %lu lines (Converted from DOS format - Warning: No write permission)",
|
||||||
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
if (writable)
|
||||||
statusbar(P_("Read %lu line", "Read %lu lines",
|
statusbar(P_("Read %lu line", "Read %lu lines",
|
||||||
(unsigned long)num_lines), (unsigned long)num_lines);
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
|
else
|
||||||
|
statusbar(P_("Read %lu line ( Warning: No write permission)",
|
||||||
|
"Read %lu lines (Warning: No write permission)",
|
||||||
|
(unsigned long)num_lines), (unsigned long)num_lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the file (and decide if it exists). If newfie is TRUE, display
|
/* Open the file (and decide if it exists). If newfie is TRUE, display
|
||||||
* "New File" if the file is missing. Otherwise, say "[filename] not
|
* "New File" if the file is missing. Otherwise, say "[filename] not
|
||||||
* found".
|
* found".
|
||||||
*
|
*
|
||||||
* Return -2 if we say "New File", -1 if the file isn't opened, and 0
|
* Return -2 if we say "New File", -1 if the file isn't opened, and the
|
||||||
* otherwise. The file might still have an error while reading with a 0
|
* fd opened otherwise. The file might still have an error while reading
|
||||||
* return value. *f is set to the opened file. */
|
* with a 0 return value. *f is set to the opened file. */
|
||||||
int open_file(const char *filename, bool newfie, FILE **f)
|
int open_file(const char *filename, bool newfie, FILE **f)
|
||||||
{
|
{
|
||||||
struct stat fileinfo, fileinfo2;
|
struct stat fileinfo, fileinfo2;
|
||||||
|
@ -668,9 +698,51 @@ int open_file(const char *filename, bool newfie, FILE **f)
|
||||||
|
|
||||||
free(full_filename);
|
free(full_filename);
|
||||||
|
|
||||||
return 0;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A bit of a copy and paste from open_file(), is_file_writable()
|
||||||
|
* just checks whether the file is appendable as a quick
|
||||||
|
* permissions check, and we tend to err on the side of permissiveness
|
||||||
|
* (reporting TRUE when it might be wrong) to not fluster users
|
||||||
|
* editing on odd filesystems by printing incorrect warnings.
|
||||||
|
*/
|
||||||
|
int is_file_writable(const char *filename)
|
||||||
|
{
|
||||||
|
struct stat fileinfo, fileinfo2;
|
||||||
|
int fd;
|
||||||
|
FILE *f;
|
||||||
|
char *full_filename;
|
||||||
|
bool ans = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
if (ISSET(VIEW_MODE))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
assert(filename != NULL && f != NULL);
|
||||||
|
|
||||||
|
/* Get the specified file's full path. */
|
||||||
|
full_filename = get_full_path(filename);
|
||||||
|
|
||||||
|
/* Okay, if we can't stat the path due to a component's
|
||||||
|
permissions, just try the relative one */
|
||||||
|
if (full_filename == NULL
|
||||||
|
|| (stat(full_filename, &fileinfo) == -1 && stat(filename, &fileinfo2) != -1))
|
||||||
|
full_filename = mallocstrcpy(NULL, filename);
|
||||||
|
|
||||||
|
if ((fd = open(full_filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR |
|
||||||
|
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1
|
||||||
|
|| (f = fdopen(fd, "a")) == NULL)
|
||||||
|
ans = FALSE;
|
||||||
|
else
|
||||||
|
fclose(f);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
free(full_filename);
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function will return the name of the first available extension
|
/* This function will return the name of the first available extension
|
||||||
* of a filename (starting with [name][suffix], then [name][suffix].1,
|
* of a filename (starting with [name][suffix], then [name][suffix].1,
|
||||||
* etc.). Memory is allocated for the return value. If no writable
|
* etc.). Memory is allocated for the return value. If no writable
|
||||||
|
|
|
@ -1060,7 +1060,7 @@ void finish_stdin_pager(void)
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
nperror("fopen");
|
nperror("fopen");
|
||||||
|
|
||||||
read_file(f, "stdin", TRUE);
|
read_file(f, 0, "stdin", TRUE);
|
||||||
ttystdin = open("/dev/tty", O_RDONLY);
|
ttystdin = open("/dev/tty", O_RDONLY);
|
||||||
if (!ttystdin)
|
if (!ttystdin)
|
||||||
die(_("Couldn't reopen stdin from keyboard, sorry\n"));
|
die(_("Couldn't reopen stdin from keyboard, sorry\n"));
|
||||||
|
|
|
@ -270,7 +270,7 @@ bool close_buffer(void);
|
||||||
#endif
|
#endif
|
||||||
filestruct *read_line(char *buf, filestruct *prevnode, bool
|
filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||||
*first_line_ins, size_t buf_len);
|
*first_line_ins, size_t buf_len);
|
||||||
void read_file(FILE *f, const char *filename, bool undoable);
|
void read_file(FILE *f, int fd, const char *filename, bool undoable);
|
||||||
int open_file(const char *filename, bool newfie, FILE **f);
|
int open_file(const char *filename, bool newfie, FILE **f);
|
||||||
char *get_next_filename(const char *name, const char *suffix);
|
char *get_next_filename(const char *name, const char *suffix);
|
||||||
void do_insertfile(
|
void do_insertfile(
|
||||||
|
|
|
@ -812,7 +812,7 @@ bool execute_command(const char *command)
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
nperror("fdopen");
|
nperror("fdopen");
|
||||||
|
|
||||||
read_file(f, "stdin", TRUE);
|
read_file(f, 0, "stdin", TRUE);
|
||||||
|
|
||||||
if (wait(NULL) == -1)
|
if (wait(NULL) == -1)
|
||||||
nperror("wait");
|
nperror("wait");
|
||||||
|
|
Loading…
Reference in New Issue