David Benbennick's minor fixes, plus one of mine

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1275 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
David Lawrence Ramsey 2002-09-13 18:14:04 +00:00
parent 605165e292
commit e21adfa181
10 changed files with 330 additions and 386 deletions

View File

@ -15,6 +15,15 @@ CVS code -
some functions around to put similar functions closer some functions around to put similar functions closer
together (for this, rename clear_bottombars() to together (for this, rename clear_bottombars() to
blank_bottombars()). (DLR; suggested by David Benbennick) blank_bottombars()). (DLR; suggested by David Benbennick)
- More changes of char *'s to const char *'s when possible.
(David Benbennick)
- Fix various minor memory leaks in files.c. (David Benbennick)
- Fix minor problems with the operating directory code: set the
operating directory properly if it's specified only in a
nanorc file, and handle an operating directory of "/"
properly. New function init_operating_dir() to handle
setting it both on the command line and in the nanorc file.
(David Benbennick)
- configure.ac: - configure.ac:
- Added pt_BR to ALL_LINGUAS (Jordi). - Added pt_BR to ALL_LINGUAS (Jordi).
- Changed --enable-color warning to be slightly less severe. - Changed --enable-color warning to be slightly less severe.
@ -28,10 +37,9 @@ CVS code -
- Disallow multibuffer toggling at the "Insert File" prompt if - Disallow multibuffer toggling at the "Insert File" prompt if
we're in both view and multibuffer mode, so as to keep proper we're in both view and multibuffer mode, so as to keep proper
integration between the two, and make sure the toggle integration between the two, and make sure the toggle
actually works all the time otherwise. Also, use actually works all the time otherwise. Also, make sure
NANO_LOAD_KEY as an alias for TOGGLE_LOAD_KEY, so TOGGLE_LOAD_KEY isn't referenced when NANO_SMALL and
--enable-tiny and --enable-multibuffer can be used together ENABLE_MULTIBUFFER are both defined. (DLR)
again. (DLR)
open_prevfile_void(), open_nextfile_void() open_prevfile_void(), open_nextfile_void()
- Return the return values of open_prevfile() and - Return the return values of open_prevfile() and
open_nextfile(), respectively, instead of (incorrectly) open_nextfile(), respectively, instead of (incorrectly)
@ -45,9 +53,9 @@ CVS code -
username and the string already contains data. (DLR) username and the string already contains data. (DLR)
- global.c: - global.c:
shortcut_init() shortcut_init()
- Use NANO_LOAD_KEY as an alias for TOGGLE_LOAD_KEY, so - Disable the new multibuffer toggle at the file insertion
--enable-tiny and --enable-multibuffer can be used together prompt when NANO_SMALL and ENABLE_MULTIBUFFER are both
again. (DLR) defined. (DLR)
thanks_for_all_the_fish() thanks_for_all_the_fish()
- Make sure the reference to help_text is #ifdefed out when - Make sure the reference to help_text is #ifdefed out when
--disable-help is used. (DLR) --disable-help is used. (DLR)
@ -92,7 +100,9 @@ CVS code -
Benbennick) Benbennick)
do_justify() do_justify()
- Fix cosmetic problems caused when justifying on the - Fix cosmetic problems caused when justifying on the
magicline. (David Benbennick) magicline, and a minor problem where the cursor would
sometimes be moved to the wrong line after justification.
(David Benbennick)
main() main()
- When searching through the main shortcut list looking for a - When searching through the main shortcut list looking for a
shortcut key, stop searching after finding one; this avoids a shortcut key, stop searching after finding one; this avoids a
@ -104,6 +114,10 @@ CVS code -
- nanorc.sample: - nanorc.sample:
- Fix the c-file regex for all caps words to be extended regex - Fix the c-file regex for all caps words to be extended regex
format ({} instead of \{\}) (found by DLR). format ({} instead of \{\}) (found by DLR).
- utils.c:
charalloc()
- Switch from using calloc() to using malloc(). (David
Benbennick)
- faq.html: - faq.html:
- Typo fix. (DLR) - Typo fix. (DLR)
- TODO: - TODO:

501
files.c
View File

@ -489,16 +489,16 @@ int do_insertfile(int loading_file)
} }
#endif #endif
#ifndef NANO_SMALL
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (i == NANO_LOAD_KEY) { if (i == TOGGLE_LOAD_KEY) {
/* don't allow toggling if we're in both view mode and /* don't allow toggling if we're in both view mode and
multibuffer mode now */ multibuffer mode now */
if (!ISSET(VIEW_MODE) || !ISSET(MULTIBUFFER)) if (!ISSET(VIEW_MODE) || !ISSET(MULTIBUFFER))
TOGGLE(MULTIBUFFER); TOGGLE(MULTIBUFFER);
return do_insertfile(ISSET(MULTIBUFFER)); return do_insertfile(ISSET(MULTIBUFFER));
} }
#endif #endif /* ENABLE_MULTIBUFFER */
#ifndef NANO_SMALL
if (i == NANO_EXTCMD_KEY) { if (i == NANO_EXTCMD_KEY) {
int ts; int ts;
ts = statusq(1, extcmd_list, "", _("Command to execute ")); ts = statusq(1, extcmd_list, "", _("Command to execute "));
@ -509,7 +509,7 @@ int do_insertfile(int loading_file)
return 0; return 0;
} }
} }
#endif #endif /* !NANO_SMALL */
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
if (loading_file) { if (loading_file) {
@ -1000,7 +1000,7 @@ int close_open_file(void)
* yet on disk); it is not done if the relative path doesn't exist (since * yet on disk); it is not done if the relative path doesn't exist (since
* the first call to chdir() will fail then). * the first call to chdir() will fail then).
*/ */
char *get_full_path(char *origpath) char *get_full_path(const char *origpath)
{ {
char *newpath = NULL, *last_slash, *d_here, *d_there, *d_there_file, tmp; char *newpath = NULL, *last_slash, *d_here, *d_there, *d_there_file, tmp;
int path_only, last_slash_index; int path_only, last_slash_index;
@ -1136,7 +1136,7 @@ char *get_full_path(char *origpath)
* get_full_path()). On error, if the path doesn't reference a * get_full_path()). On error, if the path doesn't reference a
* directory, or if the directory isn't writable, it returns NULL. * directory, or if the directory isn't writable, it returns NULL.
*/ */
char *check_writable_directory(char *path) char *check_writable_directory(const char *path)
{ {
char *full_path = get_full_path(path); char *full_path = get_full_path(path);
int writable; int writable;
@ -1177,49 +1177,27 @@ char *check_writable_directory(char *path)
*/ */
char *safe_tempnam(const char *dirname, const char *filename_prefix) char *safe_tempnam(const char *dirname, const char *filename_prefix)
{ {
char *buf, *tempdir = NULL, *full_tempdir = NULL; char *full_tempdir = NULL;
const char *TMPDIR_env;
int filedesc; int filedesc;
/* if $TMPDIR is set and non-empty, set tempdir to it, run it through /* if $TMPDIR is set and non-empty, set tempdir to it, run it through
get_full_path(), and save the result in full_tempdir; otherwise, get_full_path(), and save the result in full_tempdir; otherwise,
leave full_tempdir set to to NULL */ leave full_tempdir set to to NULL */
if (getenv("TMPDIR") && strcmp(getenv("TMPDIR"),"")) { TMPDIR_env = getenv("TMPDIR");
if (TMPDIR_env && TMPDIR_env[0] != '\0')
/* store the value of $TMPDIR in tempdir, run its value through full_tempdir = check_writable_directory(TMPDIR_env);
get_full_path(), and save the result in full_tempdir */
tempdir = charalloc(strlen(getenv("TMPDIR")) + 1);
sprintf(tempdir, "%s", getenv("TMPDIR"));
full_tempdir = check_writable_directory(tempdir);
/* we don't need the value of tempdir anymore */
free(tempdir);
}
if (!full_tempdir) {
/* if $TMPDIR is blank or isn't set, or isn't a writable /* if $TMPDIR is blank or isn't set, or isn't a writable
directory, and dirname isn't NULL, try it; otherwise, leave directory, and dirname isn't NULL, try it; otherwise, leave
full_tempdir set to NULL */ full_tempdir set to NULL */
if (dirname) { if (!full_tempdir && dirname)
tempdir = charalloc(strlen(dirname) + 1); full_tempdir = check_writable_directory(dirname);
strcpy(tempdir, dirname);
full_tempdir = check_writable_directory(tempdir);
/* we don't need the value of tempdir anymore */
free(tempdir);
}
}
/* if $TMPDIR is blank or isn't set, or if it isn't a writable /* if $TMPDIR is blank or isn't set, or if it isn't a writable
directory, and dirname is NULL, try P_tmpdir instead */ directory, and dirname is NULL, try P_tmpdir instead */
if (!full_tempdir) { if (!full_tempdir)
tempdir = charalloc(strlen(P_tmpdir) + 1); full_tempdir = check_writable_directory(P_tmpdir);
strcpy(tempdir, P_tmpdir);
full_tempdir = check_writable_directory(tempdir);
/* we don't need the value of tempdir anymore */
free(tempdir);
}
/* if P_tmpdir didn't work, use /tmp instead */ /* if P_tmpdir didn't work, use /tmp instead */
if (!full_tempdir) { if (!full_tempdir) {
@ -1227,84 +1205,68 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix)
strcpy(full_tempdir, "/tmp/"); strcpy(full_tempdir, "/tmp/");
} }
buf = charalloc(strlen(full_tempdir) + 12); full_tempdir = nrealloc(full_tempdir, strlen(full_tempdir) + 12);
sprintf(buf, "%s", full_tempdir);
/* like tempnam(), use only the first 5 characters of the prefix */ /* like tempnam(), use only the first 5 characters of the prefix */
strncat(buf, filename_prefix, 5); strncat(full_tempdir, filename_prefix, 5);
strcat(full_tempdir, "XXXXXX");
filedesc = mkstemp(full_tempdir);
strcat(buf, "XXXXXX"); /* if mkstemp succeeded, close the resulting file; afterwards, it'll be
filedesc = mkstemp(buf); 0 bytes long, so delete it; finally, return the filename (all that's
left of it) */
/* if mkstemp() failed, get out */ if (filedesc != -1) {
if (filedesc == -1)
return NULL;
/* otherwise, close the resulting file; afterwards, it'll be 0 bytes
long, so delete it; finally, return the filename (all that's left
of it) */
else {
close(filedesc); close(filedesc);
unlink(buf); unlink(full_tempdir);
return buf; return full_tempdir;
} }
free(full_tempdir);
return NULL;
} }
#endif /* !DISABLE_SPELLER */ #endif /* !DISABLE_SPELLER */
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
/* Initialize full_operating_dir based on operating_dir. */
void init_operating_dir(void)
{
assert(full_operating_dir == NULL);
if (!operating_dir)
return;
full_operating_dir = get_full_path(operating_dir);
/* If get_full_path() failed or the operating directory is
inaccessible, unset operating_dir. */
if (!full_operating_dir || chdir(full_operating_dir) == -1) {
free(full_operating_dir);
full_operating_dir = NULL;
free(operating_dir);
operating_dir = NULL;
}
}
/* /*
* Check to see if we're inside the operating directory. Return 0 if we * Check to see if we're inside the operating directory. Return 0 if we
* are, or 1 otherwise. If allow_tabcomp is nonzero, allow incomplete * are, or 1 otherwise. If allow_tabcomp is nonzero, allow incomplete
* names that would be matches for the operating directory, so that tab * names that would be matches for the operating directory, so that tab
* completion will work. * completion will work.
*/ */
int check_operating_dir(char *currpath, int allow_tabcomp) int check_operating_dir(const char *currpath, int allow_tabcomp)
{ {
/* The char *full_operating_dir is global for mem cleanup, and /* The char *full_operating_dir is global for mem cleanup, and
therefore we only need to get it the first time this function therefore we only need to get it the first time this function
is called; also, a relative operating directory path will is called; also, a relative operating directory path will
only be handled properly if this is done */ only be handled properly if this is done */
char *fullpath, *whereami1, *whereami2 = NULL; char *fullpath;
int retval = 0;
const char *whereami1, *whereami2 = NULL;
/* if no operating directory is set, don't bother doing anything */ /* if no operating directory is set, don't bother doing anything */
if (!operating_dir) if (!operating_dir)
return 0; return 0;
/* if the operating directory is "/", that's the same as having no
operating directory, so discard it and get out */
if (!strcmp(operating_dir, "/")) {
free(operating_dir);
operating_dir = NULL;
return 0;
}
/* get the full operating (if we don't have it already) and current
directories, and then search the current for the operating (for
normal usage) and the operating for the current (for tab
completion, if we're allowing it); if the current directory's path
doesn't exist, assume we're outside the operating directory */
if (!full_operating_dir) {
full_operating_dir = get_full_path(operating_dir);
/* if get_full_path() failed, discard the operating directory */
if (!full_operating_dir) {
free(operating_dir);
operating_dir = NULL;
return 0;
}
/* if the full operating directory is "/", that's the same as
having no operating directory, so discard it and get out */
if (!strcmp(full_operating_dir, "/")) {
free(full_operating_dir);
full_operating_dir = NULL;
free(operating_dir);
operating_dir = NULL;
return 0;
}
}
fullpath = get_full_path(currpath); fullpath = get_full_path(currpath);
if (!fullpath) if (!fullpath)
return 1; return 1;
@ -1314,18 +1276,16 @@ int check_operating_dir(char *currpath, int allow_tabcomp)
whereami2 = strstr(full_operating_dir, fullpath); whereami2 = strstr(full_operating_dir, fullpath);
/* if both searches failed, we're outside the operating directory */ /* if both searches failed, we're outside the operating directory */
if (!whereami1 && !whereami2) /* otherwise */
return 1;
/* check the search results; if the full operating directory path is /* check the search results; if the full operating directory path is
not at the beginning of the full current path (for normal usage) not at the beginning of the full current path (for normal usage)
and vice versa (for tab completion, if we're allowing it), we're and vice versa (for tab completion, if we're allowing it), we're
outside the operating directory */ outside the operating directory */
if (whereami1 != fullpath && whereami2 != full_operating_dir) if (whereami1 != fullpath && whereami2 != full_operating_dir)
return 1; retval = 1;
free(fullpath);
/* otherwise, we're still inside it */ /* otherwise, we're still inside it */
return 0; return retval;
} }
#endif #endif
@ -1343,11 +1303,14 @@ int check_operating_dir(char *currpath, int allow_tabcomp)
* nonamechange means don't change the current filename, it is ignored * nonamechange means don't change the current filename, it is ignored
* if tmp == 1 or if we're appending/prepending. * if tmp == 1 or if we're appending/prepending.
*/ */
int write_file(char *name, int tmp, int append, int nonamechange) int write_file(const char *name, int tmp, int append, int nonamechange)
{ {
int retval = -1;
/* Instead of returning in this function, you should always
* merely set retval then goto cleanup_and_exit. */
long size, lineswritten = 0; long size, lineswritten = 0;
char *buf = NULL; char *buf = NULL;
filestruct *fileptr; const filestruct *fileptr;
FILE *f; FILE *f;
int fd; int fd;
int mask = 0, realexists, anyexists; int mask = 0, realexists, anyexists;
@ -1361,12 +1324,6 @@ int write_file(char *name, int tmp, int append, int nonamechange)
titlebar(NULL); titlebar(NULL);
fileptr = fileage; fileptr = fileage;
if (realname != NULL)
free(realname);
if (buf != NULL)
free(buf);
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
realname = real_dir_from_tilde(name); realname = real_dir_from_tilde(name);
#else #else
@ -1374,19 +1331,16 @@ int write_file(char *name, int tmp, int append, int nonamechange)
#endif #endif
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
if (!tmp && operating_dir) { /* If we're writing a temporary file, we're probably going outside
/* if we're writing a temporary file, we're probably going the operating directory, so skip the operating directory test. */
outside the operating directory, so skip the operating if (!tmp && operating_dir && check_operating_dir(realname, 0)) {
directory test */
if (check_operating_dir(realname, 0)) {
statusbar(_("Can't write outside of %s"), operating_dir); statusbar(_("Can't write outside of %s"), operating_dir);
goto cleanup_and_exit;
return -1;
}
} }
#endif #endif
/* Save the state of file at the end of the symlink (if there is one) */ /* Save the state of file at the end of the symlink (if there is
one). */
realexists = stat(realname, &st); realexists = stat(realname, &st);
#ifndef NANO_SMALL #ifndef NANO_SMALL
@ -1463,7 +1417,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
/* New case: if the file exists, just give up */ /* New case: if the file exists, just give up */
if (tmp && anyexists != -1) if (tmp && anyexists != -1)
return -1; goto cleanup_and_exit;
/* NOTE: If you change this statement, you MUST CHANGE the if /* NOTE: If you change this statement, you MUST CHANGE the if
statement below (that says: statement below (that says:
if (realexists == -1 || tmp || (!ISSET(FOLLOW_SYMLINKS) && if (realexists == -1 || tmp || (!ISSET(FOLLOW_SYMLINKS) &&
@ -1484,11 +1438,11 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if (fd == -1) { if (fd == -1) {
if (!tmp && ISSET(TEMP_OPT)) { if (!tmp && ISSET(TEMP_OPT)) {
UNSET(TEMP_OPT); UNSET(TEMP_OPT);
return do_writeout(filename, 1, 0); retval = do_writeout(filename, 1, 0);
} } else
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"),
strerror(errno)); strerror(errno));
return -1; goto cleanup_and_exit;
} }
} }
@ -1500,11 +1454,11 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if ((fd = mkstemp(buf)) == -1) { if ((fd = mkstemp(buf)) == -1) {
if (ISSET(TEMP_OPT)) { if (ISSET(TEMP_OPT)) {
UNSET(TEMP_OPT); UNSET(TEMP_OPT);
return do_writeout(filename, 1, 0); retval = do_writeout(filename, 1, 0);
} } else
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"),
strerror(errno)); strerror(errno));
return -1; goto cleanup_and_exit;
} }
} }
@ -1514,13 +1468,13 @@ int write_file(char *name, int tmp, int append, int nonamechange)
f = fdopen(fd, append == 1 ? "ab" : "wb"); f = fdopen(fd, append == 1 ? "ab" : "wb");
if (!f) { if (!f) {
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"), strerror(errno));
strerror(errno)); goto cleanup_and_exit;
return -1;
} }
while (fileptr != NULL && fileptr->next != NULL) { while (fileptr != NULL && fileptr->next != NULL) {
int data_len; int data_len;
/* Next line is so we discount the "magic line" */ /* Next line is so we discount the "magic line" */
if (filebot == fileptr && fileptr->data[0] == '\0') if (filebot == fileptr && fileptr->data[0] == '\0')
break; break;
@ -1539,7 +1493,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"),
strerror(errno)); strerror(errno));
fclose(f); fclose(f);
return -1; goto cleanup_and_exit;
} }
#ifdef DEBUG #ifdef DEBUG
else else
@ -1558,9 +1512,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
} }
if (fileptr != NULL) { if (fileptr != NULL) {
int data_len; int data_len = strlen(fileptr->data);
data_len = strlen(fileptr->data);
/* newlines to nulls, just before we write to disk */ /* newlines to nulls, just before we write to disk */
sunder(fileptr->data); sunder(fileptr->data);
@ -1573,7 +1525,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if (size < data_len) { if (size < data_len) {
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"),
strerror(errno)); strerror(errno));
return -1; goto cleanup_and_exit;
} else if (data_len > 0) { } else if (data_len > 0) {
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (ISSET(DOS_FILE) || ISSET(MAC_FILE)) { if (ISSET(DOS_FILE) || ISSET(MAC_FILE)) {
@ -1581,7 +1533,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"),
strerror(errno)); strerror(errno));
fclose(f); fclose(f);
return -1; goto cleanup_and_exit;
} }
lineswritten++; lineswritten++;
} }
@ -1593,7 +1545,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open file for writing: %s"), statusbar(_("Could not open file for writing: %s"),
strerror(errno)); strerror(errno));
fclose(f); fclose(f);
return -1; goto cleanup_and_exit;
} }
lineswritten++; lineswritten++;
} }
@ -1603,7 +1555,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if (fclose(f)) { if (fclose(f)) {
statusbar(_("Could not close %s: %s"), realname, strerror(errno)); statusbar(_("Could not close %s: %s"), realname, strerror(errno));
unlink(buf); unlink(buf);
return -1; goto cleanup_and_exit;
} }
/* if we're prepending, open the real file, and append it here */ /* if we're prepending, open the real file, and append it here */
@ -1614,25 +1566,25 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if ((fd_dest = open(buf, O_WRONLY | O_APPEND, (S_IRUSR|S_IWUSR))) == -1) { if ((fd_dest = open(buf, O_WRONLY | O_APPEND, (S_IRUSR|S_IWUSR))) == -1) {
statusbar(_("Could not reopen %s: %s"), buf, strerror(errno)); statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
return -1; goto cleanup_and_exit;
} }
f_dest = fdopen(fd_dest, "wb"); f_dest = fdopen(fd_dest, "wb");
if (!f_dest) { if (!f_dest) {
statusbar(_("Could not reopen %s: %s"), buf, strerror(errno)); statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
close(fd_dest); close(fd_dest);
return -1; goto cleanup_and_exit;
} }
if ((fd_source = open(realname, O_RDONLY | O_CREAT)) == -1) { if ((fd_source = open(realname, O_RDONLY | O_CREAT)) == -1) {
statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno)); statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
fclose(f_dest); fclose(f_dest);
return -1; goto cleanup_and_exit;
} }
f_source = fdopen(fd_source, "rb"); f_source = fdopen(fd_source, "rb");
if (!f_source) { if (!f_source) {
statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno)); statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
fclose(f_dest); fclose(f_dest);
close(fd_source); close(fd_source);
return -1; goto cleanup_and_exit;
} }
/* Doing this in blocks is an exercise left to some other reader. */ /* Doing this in blocks is an exercise left to some other reader. */
@ -1641,7 +1593,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno)); statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
fclose(f_source); fclose(f_source);
fclose(f_dest); fclose(f_dest);
return -1; goto cleanup_and_exit;
} }
} }
@ -1649,7 +1601,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not reopen %s: %s"), buf, strerror(errno)); statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
fclose(f_source); fclose(f_source);
fclose(f_dest); fclose(f_dest);
return -1; goto cleanup_and_exit;
} }
fclose(f_source); fclose(f_source);
@ -1678,7 +1630,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open %s for writing: %s"), statusbar(_("Could not open %s for writing: %s"),
realname, strerror(errno)); realname, strerror(errno));
unlink(buf); unlink(buf);
return -1; goto cleanup_and_exit;
} }
} }
if (link(buf, realname) != -1) if (link(buf, realname) != -1)
@ -1687,12 +1639,12 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open %s for writing: %s"), statusbar(_("Could not open %s for writing: %s"),
name, strerror(errno)); name, strerror(errno));
unlink(buf); unlink(buf);
return -1; goto cleanup_and_exit;
} else if (rename(buf, realname) == -1) { /* Try a rename?? */ } else if (rename(buf, realname) == -1) { /* Try a rename?? */
statusbar(_("Could not open %s for writing: %s"), statusbar(_("Could not open %s for writing: %s"),
realname, strerror(errno)); realname, strerror(errno));
unlink(buf); unlink(buf);
return -1; goto cleanup_and_exit;
} }
} }
if (chmod(realname, mask) == -1) if (chmod(realname, mask) == -1)
@ -1711,15 +1663,18 @@ int write_file(char *name, int tmp, int append, int nonamechange)
UNSET(MODIFIED); UNSET(MODIFIED);
titlebar(NULL); titlebar(NULL);
} }
return 1;
retval = 1;
cleanup_and_exit:
free(realname);
free(buf);
return retval;
} }
int do_writeout(char *path, int exiting, int append) int do_writeout(const char *path, int exiting, int append)
{ {
int i = 0; int i = 0;
#ifndef NANO_SMALL
const char *formatstr, *backupstr;
#endif
#ifdef NANO_EXTRA #ifdef NANO_EXTRA
static int did_cred = 0; static int did_cred = 0;
#endif #endif
@ -1730,7 +1685,7 @@ int do_writeout(char *path, int exiting, int append)
answer = mallocstrcpy(answer, path); answer = mallocstrcpy(answer, path);
if ((exiting) && (ISSET(TEMP_OPT))) { if (exiting && ISSET(TEMP_OPT)) {
if (filename[0]) { if (filename[0]) {
i = write_file(answer, 0, 0, 0); i = write_file(answer, 0, 0, 0);
display_main_list(); display_main_list();
@ -1745,8 +1700,9 @@ int do_writeout(char *path, int exiting, int append)
} }
while (1) { while (1) {
#ifndef NANO_SMALL #ifndef NANO_SMALL
const char *formatstr, *backupstr;
if (ISSET(MAC_FILE)) if (ISSET(MAC_FILE))
formatstr = _(" [Mac Format]"); formatstr = _(" [Mac Format]");
else if (ISSET(DOS_FILE)) else if (ISSET(DOS_FILE))
@ -1793,42 +1749,44 @@ int do_writeout(char *path, int exiting, int append)
"%s", _("File Name to Write")); "%s", _("File Name to Write"));
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
if (i != -1) { if (i == -1) {
statusbar(_("Cancelled"));
display_main_list();
return 0;
}
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
if (i == NANO_TOFILES_KEY) { if (i == NANO_TOFILES_KEY) {
char *tmp = do_browse_from(answer); char *tmp = do_browse_from(answer);
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE)
currshortcut = writefile_list; currshortcut = writefile_list;
#endif if (tmp == NULL)
continue;
if (tmp != NULL) { free(answer);
answer = mallocstrcpy(answer, tmp); answer = tmp;
} else } else
return do_writeout(answer, exiting, append); #endif /* !DISABLE_BROWSER */
} else
#endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (i == TOGGLE_DOS_KEY) { if (i == TOGGLE_DOS_KEY) {
UNSET(MAC_FILE); UNSET(MAC_FILE);
TOGGLE(DOS_FILE); TOGGLE(DOS_FILE);
return(do_writeout(answer, exiting, append)); continue;
} else if (i == TOGGLE_MAC_KEY) { } else if (i == TOGGLE_MAC_KEY) {
UNSET(DOS_FILE); UNSET(DOS_FILE);
TOGGLE(MAC_FILE); TOGGLE(MAC_FILE);
return(do_writeout(answer, exiting, append)); continue;
} else if (i == TOGGLE_BACKUP_KEY) { } else if (i == TOGGLE_BACKUP_KEY) {
TOGGLE(BACKUP_FILE); TOGGLE(BACKUP_FILE);
return(do_writeout(answer, exiting, append)); continue;
#else } else
if (0) { #endif /* ! NANO_SMALL */
#endif if (i == NANO_PREPEND_KEY) {
} else if (i == NANO_PREPEND_KEY) append = append == 2 ? 0 : 2;
return(do_writeout(answer, exiting, append == 2 ? 0 : 2)); continue;
else if (i == NANO_APPEND_KEY) } else if (i == NANO_APPEND_KEY) {
return(do_writeout(answer, exiting, append == 1 ? 0 : 1)); append = append == 1 ? 0 : 1;
continue;
}
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("filename is %s\n"), answer); fprintf(stderr, _("filename is %s\n"), answer);
@ -1844,10 +1802,11 @@ int do_writeout(char *path, int exiting, int append)
#endif #endif
if (!append && strcmp(answer, filename)) { if (!append && strcmp(answer, filename)) {
struct stat st; struct stat st;
if (!stat(answer, &st)) { if (!stat(answer, &st)) {
i = do_yesno(0, 0, _("File exists, OVERWRITE ?")); i = do_yesno(0, 0, _("File exists, OVERWRITE ?"));
if (!i || (i == -1)) if (i == 0 || i == -1)
continue; continue;
} }
} }
@ -1859,56 +1818,40 @@ int do_writeout(char *path, int exiting, int append)
filestruct *fileagebak = fileage; filestruct *fileagebak = fileage;
filestruct *filebotbak = filebot; filestruct *filebotbak = filebot;
filestruct *cutback = cutbuffer; filestruct *cutback = cutbuffer;
long totsizebak = totsize; int oldmod = ISSET(MODIFIED);
int oldmod = 0; /* write_file() unsets the MODIFIED flag. */
cutbuffer = NULL; cutbuffer = NULL;
/* Okay, since write_file changes the filename, back it up */ /* Put the marked text in the cutbuffer without changing
if (ISSET(MODIFIED)) the open file. */
oldmod = 1;
/* Now, non-destructively add the marked text to the
cutbuffer, and write the file out using the cutbuffer ;) */
if (current->lineno <= mark_beginbuf->lineno)
cut_marked_segment(current, current_x, mark_beginbuf, cut_marked_segment(current, current_x, mark_beginbuf,
mark_beginx, 0); mark_beginx, 0);
else
cut_marked_segment(mark_beginbuf, mark_beginx, current,
current_x, 0);
fileage = cutbuffer; fileage = cutbuffer;
for (filebot = cutbuffer; filebot->next != NULL; filebot = get_cutbottom();
filebot = filebot->next)
;
i = write_file(answer, 0, append, 1); i = write_file(answer, 0, append, 1);
/* Now restore everything */ /* Now restore everything */
free_filestruct(cutbuffer);
fileage = fileagebak; fileage = fileagebak;
filebot = filebotbak; filebot = filebotbak;
cutbuffer = cutback; cutbuffer = cutback;
totsize = totsizebak;
if (oldmod) if (oldmod)
set_modified(); set_modified();
} else } else
#endif /* !NANO_SMALL */ #endif /* !NANO_SMALL */
i = write_file(answer, 0, append, 0); i = write_file(answer, 0, append, 0);
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
/* if we're not about to exit, update the current entry in /* If we're not about to exit, update the current entry in
the open_files structure */ the open_files structure. */
if (!exiting) if (!exiting)
add_open_file(1); add_open_file(1);
#endif #endif
display_main_list(); display_main_list();
return i; return i;
} else { } /* while (1) */
statusbar(_("Cancelled"));
display_main_list();
return 0;
}
}
} }
int do_writeout_void(void) int do_writeout_void(void)
@ -1919,76 +1862,67 @@ int do_writeout_void(void)
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
/* Return a malloc()ed string containing the actual directory, used /* Return a malloc()ed string containing the actual directory, used
* to convert ~user and ~/ notation... * to convert ~user and ~/ notation... */
*/ char *real_dir_from_tilde(const char *buf)
char *real_dir_from_tilde(char *buf)
{ {
char *dirtmp = NULL; char *dirtmp = NULL;
int i = 1;
struct passwd *userdata;
/* set a default value for dirtmp, in the case user home dir not found */
dirtmp = mallocstrcpy(dirtmp, buf);
if (buf[0] == '~') { if (buf[0] == '~') {
if (buf[1] == 0 || buf[1] == '/') { size_t i;
const struct passwd *userdata;
/* Figure how how much of the str we need to compare */
for (i = 1; buf[i] != '/' && buf[i] != '\0'; i++)
;
if (i == 1) {
/* Determine home directory using getpwent(), don't rely on /* Determine home directory using getpwent(), don't rely on
$HOME */ $HOME */
uid_t euid = geteuid(); uid_t euid = geteuid();
do { do {
userdata = getpwent(); userdata = getpwent();
} while (userdata != NULL && userdata->pw_uid != euid); } while (userdata != NULL && userdata->pw_uid != euid);
} } else {
else { do {
char *find_user = NULL; userdata = getpwent();
} while (userdata != NULL &&
/* Figure how how much of the str we need to compare */ strncmp(userdata->pw_name, buf + 1, i - 1));
for (i = 1; buf[i] != '/' && buf[i] != 0; i++)
;
find_user = mallocstrcpy(find_user, &buf[1]);
find_user[i - 1] = '\0';
for (userdata = getpwent(); userdata != NULL &&
strcmp(userdata->pw_name, find_user);
userdata = getpwent());
free(find_user);
} }
endpwent(); endpwent();
if (userdata != NULL) { /* User found */ if (userdata != NULL) { /* User found */
free(dirtmp); dirtmp = charalloc(strlen(userdata->pw_dir) + strlen(buf + i) + 1);
dirtmp = charalloc(strlen(buf) + 2 + strlen(userdata->pw_dir));
sprintf(dirtmp, "%s%s", userdata->pw_dir, &buf[i]); sprintf(dirtmp, "%s%s", userdata->pw_dir, &buf[i]);
} }
} }
if (dirtmp == NULL)
dirtmp = mallocstrcpy(dirtmp, buf);
return dirtmp; return dirtmp;
} }
/* Tack a slash onto the string we're completing if it's a directory */ /* Tack a slash onto the string we're completing if it's a directory. We
* assume there is room for one more character on the end of buf. The
* return value says whether buf is a directory. */
int append_slash_if_dir(char *buf, int *lastwastab, int *place) int append_slash_if_dir(char *buf, int *lastwastab, int *place)
{ {
char *dirptr; char *dirptr = real_dir_from_tilde(buf);
struct stat fileinfo; struct stat fileinfo;
int ret = 0; int ret = 0;
dirptr = real_dir_from_tilde(buf); assert(dirptr != buf);
if (stat(dirptr, &fileinfo) == -1) if (stat(dirptr, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode)) {
ret = 0;
else if (S_ISDIR(fileinfo.st_mode)) {
strncat(buf, "/", 1); strncat(buf, "/", 1);
*place += 1; (*place)++;
/* now we start over again with # of tabs so far */ /* now we start over again with # of tabs so far */
*lastwastab = 0; *lastwastab = 0;
ret = 1; ret = 1;
} }
if (dirptr != buf)
free(dirptr); free(dirptr);
return ret; return ret;
} }
@ -2383,7 +2317,7 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
curs_set(1); curs_set(1);
return buf; return buf;
} }
#endif #endif /* !DISABLE_TABCOMP */
#ifndef DISABLE_BROWSER #ifndef DISABLE_BROWSER
@ -2397,57 +2331,53 @@ struct stat filestat(const char *path)
} }
/* Our sort routine for file listings - sort directories before /* Our sort routine for file listings - sort directories before
* files, and then alphabetically * files, and then alphabetically. */
*/
int diralphasort(const void *va, const void *vb) int diralphasort(const void *va, const void *vb)
{ {
struct stat file1info, file2info; struct stat fileinfo;
char *a = *(char **)va, *b = *(char **)vb; const char *a = *(char *const *)va, *b = *(char *const *)vb;
int aisdir, bisdir; int aisdir = stat(a, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode);
int bisdir = stat(b, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode);
aisdir = (stat(a, &file1info) != -1) && S_ISDIR(file1info.st_mode); if (aisdir && !bisdir)
bisdir = (stat(b, &file2info) != -1) && S_ISDIR(file2info.st_mode); return -1;
if (!aisdir && bisdir)
if (aisdir && !bisdir) return -1; return 1;
if (!aisdir && bisdir) return 1;
#ifdef HAVE_STRCASECMP #ifdef HAVE_STRCASECMP
return(strcasecmp(a,b)); return strcasecmp(a, b);
#else #else
return(strcmp(a,b)); return strcmp(a, b);
#endif #endif
} }
/* Free our malloc()ed memory */ /* Free our malloc()ed memory */
void free_charptrarray(char **array, int len) void free_charptrarray(char **array, int len)
{ {
int i; for (; len > 0; len--)
free(array[len - 1]);
for (i = 0; i < len; i++)
free(array[i]);
free(array); free(array);
} }
/* only print the last part of a path; isn't there a shell /* Only print the last part of a path; isn't there a shell
command for this? */ * command for this? */
char *tail(char *foo) const char *tail(const char *foo)
{ {
char *tmp = NULL; const char *tmp = foo + strlen(foo);
tmp = foo + strlen(foo);
while (*tmp != '/' && tmp != foo) while (*tmp != '/' && tmp != foo)
tmp--; tmp--;
if (*tmp == '/')
tmp++; tmp++;
return tmp; return tmp;
} }
/* Strip one dir from the end of a string */ /* Strip one dir from the end of a string. */
void striponedir(char *foo) void striponedir(char *foo)
{ {
char *tmp = NULL; char *tmp;
/* Don't strip the root dir */ /* Don't strip the root dir */
if (!strcmp(foo, "/")) if (!strcmp(foo, "/"))
@ -2461,23 +2391,22 @@ void striponedir(char *foo)
tmp--; tmp--;
if (tmp != foo) if (tmp != foo)
*tmp = 0; *tmp = '\0';
else else { /* SPK may need to make a 'default' path here */
{ /* SPK may need to make a 'default' path here */ if (*tmp != '/')
if (*tmp != '/') *(tmp) = '.'; *tmp = '.';
*(tmp+1) = 0; *(tmp + 1) = '\0';
} }
return;
} }
/* Initialize the browser code, including the list of files in *path */ /* Initialize the browser code, including the list of files in *path */
char **browser_init(char *path, int *longest, int *numents) char **browser_init(const char *path, int *longest, int *numents)
{ {
DIR *dir; DIR *dir;
struct dirent *next; struct dirent *next;
char **filelist = (char **) NULL; char **filelist;
int i = 0; int i = 0;
size_t path_len;
dir = opendir(path); dir = opendir(path);
if (!dir) if (!dir)
@ -2496,17 +2425,16 @@ char **browser_init(char *path, int *longest, int *numents)
filelist = nmalloc(*numents * sizeof (char *)); filelist = nmalloc(*numents * sizeof (char *));
if (!strcmp(path, "/"))
path = "";
path_len = strlen(path);
while ((next = readdir(dir)) != NULL) { while ((next = readdir(dir)) != NULL) {
if (!strcmp(next->d_name, ".")) if (!strcmp(next->d_name, "."))
continue; continue;
filelist[i] = charalloc(strlen(next->d_name) + strlen(path) + 2);
if (!strcmp(path, "/")) filelist[i] = charalloc(strlen(next->d_name) + path_len + 2);
snprintf(filelist[i], strlen(next->d_name) + strlen(path) + 1, sprintf(filelist[i], "%s/%s", path, next->d_name);
"%s%s", path, next->d_name);
else
snprintf(filelist[i], strlen(next->d_name) + strlen(path) + 2,
"%s/%s", path, next->d_name);
i++; i++;
} }
@ -2517,7 +2445,7 @@ char **browser_init(char *path, int *longest, int *numents)
} }
/* Our browser function. inpath is the path to start browsing from */ /* Our browser function. inpath is the path to start browsing from */
char *do_browser(char *inpath) char *do_browser(const char *inpath)
{ {
struct stat st; struct stat st;
char *foo, *retval = NULL; char *foo, *retval = NULL;
@ -2532,6 +2460,8 @@ char *do_browser(char *inpath)
#endif #endif
#endif #endif
assert(inpath != NULL);
/* If path isn't the same as inpath, we are being passed a new /* If path isn't the same as inpath, we are being passed a new
dir as an arg. We free it here so it will be copied from dir as an arg. We free it here so it will be copied from
inpath below */ inpath below */
@ -2542,7 +2472,7 @@ char *do_browser(char *inpath)
/* if path doesn't exist, make it so */ /* if path doesn't exist, make it so */
if (path == NULL) if (path == NULL)
path = mallocstrcpy(path, inpath); path = mallocstrcpy(NULL, inpath);
filelist = browser_init(path, &longest, &numents); filelist = browser_init(path, &longest, &numents);
foo = charalloc(longest + 8); foo = charalloc(longest + 8);
@ -2868,34 +2798,37 @@ char *do_browser(char *inpath)
/* Browser front end, checks to see if inpath has a dir in it and, if so, /* Browser front end, checks to see if inpath has a dir in it and, if so,
starts do_browser from there, else from the current dir */ starts do_browser from there, else from the current dir */
char *do_browse_from(char *inpath) char *do_browse_from(const char *inpath)
{ {
struct stat st; struct stat st;
char *tmp = NULL; char *tmp;
char *bob;
tmp = mallocstrcpy(tmp, inpath);
/* If there's no / in the string, we may as well start from . */ /* If there's no / in the string, we may as well start from . */
if (tmp == NULL || *tmp == '\0' || !strstr(tmp, "/")) { if (inpath == NULL || strchr(inpath, '/') == NULL) {
#ifdef PATH_MAX #ifdef PATH_MAX
char *from = getcwd(NULL, PATH_MAX + 1); char *from = getcwd(NULL, PATH_MAX + 1);
#else #else
char *from = getcwd(NULL, 0); char *from = getcwd(NULL, 0);
#endif /* PATH_MAX */ #endif
return do_browser(from ? from : "./");
bob = do_browser(from ? from : "./");
free(from);
return bob;
} }
/* If the string is a directory, pass do_browser that */ /* If the string is a directory, pass do_browser that */
st = filestat(tmp); st = filestat(inpath);
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
return do_browser(tmp); return do_browser(inpath);
tmp = mallocstrcpy(NULL, inpath);
/* Okay, there's a dir in there, but not at the end of the string... /* Okay, there's a dir in there, but not at the end of the string...
try stripping it off */ try stripping it off */
striponedir(tmp); striponedir(tmp);
align(&tmp); align(&tmp);
return do_browser(tmp); bob = do_browser(tmp);
free(tmp);
return bob;
} }
#endif /* !DISABLE_BROWSER */ #endif /* !DISABLE_BROWSER */

View File

@ -153,10 +153,10 @@ regex_t syntaxfile_regexp; /* Global to store compiled search regexp */
regmatch_t synfilematches[1]; /* Match positions for parenthetical */ regmatch_t synfilematches[1]; /* Match positions for parenthetical */
#endif /* ENABLE_COLOR */ #endif /* ENABLE_COLOR */
int length_of_list(const shortcut *s) int length_of_list(const shortcut *s)
{ {
int i = 0; int i = 0;
for (; s != NULL; s = s->next) for (; s != NULL; s = s->next)
i++; i++;
return i; return i;
@ -304,7 +304,7 @@ void free_shortcutage(shortcut **shortcutage)
void shortcut_init(int unjustify) void shortcut_init(int unjustify)
{ {
#ifndef DISABLE_HELP #ifndef DISABLE_HELP
char *nano_help_msg = "", *nano_writeout_msg = "", *nano_exit_msg = const char *nano_help_msg = "", *nano_writeout_msg = "", *nano_exit_msg =
"", *nano_goto_msg = "", *nano_justify_msg = "", *nano_goto_msg = "", *nano_justify_msg =
"", *nano_replace_msg = "", *nano_insert_msg = "", *nano_replace_msg = "", *nano_insert_msg =
"", *nano_whereis_msg = "", *nano_prevpage_msg = "", *nano_whereis_msg = "", *nano_prevpage_msg =
@ -325,11 +325,11 @@ void shortcut_init(int unjustify)
"", *nano_backup_msg = ""; "", *nano_backup_msg = "";
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
char *nano_openprev_msg = "", *nano_opennext_msg = const char *nano_openprev_msg = "", *nano_opennext_msg =
"", *nano_multibuffer_msg = ""; "", *nano_multibuffer_msg = "";
#endif #endif
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
char *nano_regexp_msg = "", *nano_bracket_msg = ""; const char *nano_regexp_msg = "", *nano_bracket_msg = "";
#endif #endif
nano_help_msg = _("Invoke the help menu"); nano_help_msg = _("Invoke the help menu");
@ -725,10 +725,10 @@ void shortcut_init(int unjustify)
#ifndef NANO_SMALL #ifndef NANO_SMALL
sc_init_one(&insertfile_list, NANO_EXTCMD_KEY, _("Execute Command"), sc_init_one(&insertfile_list, NANO_EXTCMD_KEY, _("Execute Command"),
IFHELP(nano_execute_msg, 0), 0, 0, NOVIEW, 0); IFHELP(nano_execute_msg, 0), 0, 0, NOVIEW, 0);
#endif
#ifdef ENABLE_MULTIBUFFER #ifdef ENABLE_MULTIBUFFER
sc_init_one(&insertfile_list, NANO_LOAD_KEY, _("New Buffer"), sc_init_one(&insertfile_list, TOGGLE_LOAD_KEY, _("New Buffer"),
IFHELP(nano_multibuffer_msg, 0), 0, 0, NOVIEW, 0); IFHELP(nano_multibuffer_msg, 0), 0, 0, NOVIEW, 0);
#endif
#endif #endif
free_shortcutage(&spell_list); free_shortcutage(&spell_list);

45
nano.c
View File

@ -2177,7 +2177,7 @@ int do_justify(void)
* 2) the line above it is not part of a paragraph, or * 2) the line above it is not part of a paragraph, or
* 3) the line above it does not have precisely the same quote * 3) the line above it does not have precisely the same quote
* part, or * part, or
* 4) the indentation of this line is not a subset of the * 4) the indentation of this line is not an initial substring of the
* indentation of the previous line, or * indentation of the previous line, or
* 5) this line has no quote part and some indentation, and * 5) this line has no quote part and some indentation, and
* AUTOINDENT is not set. * AUTOINDENT is not set.
@ -2250,30 +2250,29 @@ int do_justify(void)
current_x = 0; current_x = 0;
if (current->data[quote_len + indent_len] != '\0') { if (current->data[quote_len + indent_len] != '\0') {
/* This line is part of a paragraph. So we must search back to /* This line is part of a paragraph. So we must search back to
* the first line of this paragraph. */ * the first line of this paragraph. First we check items 1) and
if (quote_len > 0 || indent_len == 0 * 3) above. */
#ifndef NANO_SMALL
|| ISSET(AUTOINDENT)
#endif
) {
/* We don't justify indented paragraphs unless AUTOINDENT is
* turned on. See 5) above. */
while (current->prev && quotes_match(current->data, while (current->prev && quotes_match(current->data,
quote_len, IFREG(current->prev->data, &qreg))) { quote_len, IFREG(current->prev->data, &qreg))) {
/* indentation length of the previous line */
size_t temp_id_len = size_t temp_id_len =
indent_length(current->prev->data + quote_len); indent_length(current->prev->data + quote_len);
/* The indentation length of the previous line. */
if (!indents_match(current->prev->data + quote_len, /* Is this line the beginning of a paragraph, according to
temp_id_len, current->data + quote_len, items 2), 5), or 4) above? If so, stop. */
indent_len) || if (current->prev->data[quote_len + temp_id_len] == '\0' ||
current->prev->data[quote_len + temp_id_len] == '\0') (quote_len == 0 && indent_len > 0
#ifndef NANO_SMALL
&& !ISSET(AUTOINDENT)
#endif
) ||
!indents_match(current->prev->data + quote_len,
temp_id_len, current->data + quote_len, indent_len))
break; break;
indent_len = temp_id_len; indent_len = temp_id_len;
current = current->prev; current = current->prev;
current_y--; current_y--;
} }
}
} else { } else {
/* This line is not part of a paragraph. Move down until we get /* This line is not part of a paragraph. Move down until we get
* to a non "blank" line. */ * to a non "blank" line. */
@ -2646,15 +2645,13 @@ void signal_init(void)
#endif /* _POSIX_VDISABLE */ #endif /* _POSIX_VDISABLE */
if (!ISSET(SUSPEND)) { if (!ISSET(SUSPEND)) {
/* Insane! */
/* Insane! */
#ifdef _POSIX_VDISABLE #ifdef _POSIX_VDISABLE
term.c_cc[VSUSP] = _POSIX_VDISABLE; term.c_cc[VSUSP] = _POSIX_VDISABLE;
#else #else
act.sa_handler = SIG_IGN; act.sa_handler = SIG_IGN;
sigaction(SIGTSTP, &act, NULL); sigaction(SIGTSTP, &act, NULL);
#endif #endif
} else { } else {
/* If we don't do this, it seems other stuff interrupts the /* If we don't do this, it seems other stuff interrupts the
suspend handler! Try using nano with mutt without this suspend handler! Try using nano with mutt without this
@ -3091,12 +3088,6 @@ int main(int argc, char *argv[])
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
case 'o': case 'o':
operating_dir = mallocstrcpy(operating_dir, optarg); operating_dir = mallocstrcpy(operating_dir, optarg);
/* make sure we're inside the operating directory */
if (check_operating_dir(".", 0) && chdir(operating_dir) == -1) {
free(operating_dir);
operating_dir = NULL;
}
break; break;
#endif #endif
case 'p': case 'p':
@ -3150,6 +3141,12 @@ int main(int argc, char *argv[])
} }
} }
#ifndef DISABLE_OPERATINGDIR
/* Set up the operating directory. This entails chdir()ing there, so
that file reads and writes will be based there. */
init_operating_dir();
#endif
/* Clear the filename we'll be using */ /* Clear the filename we'll be using */
filename = charalloc(1); filename = charalloc(1);
filename[0] = '\0'; filename[0] = '\0';

3
nano.h
View File

@ -137,7 +137,7 @@ typedef struct toggle {
#ifdef ENABLE_NANORC #ifdef ENABLE_NANORC
typedef struct rcoption { typedef struct rcoption {
char *name; const char *name;
int flag; int flag;
} rcoption; } rcoption;
#endif /* ENABLE_NANORC */ #endif /* ENABLE_NANORC */
@ -326,7 +326,6 @@ know what you're doing */
#define NANO_TOFILES_KEY NANO_CONTROL_T #define NANO_TOFILES_KEY NANO_CONTROL_T
#define NANO_APPEND_KEY NANO_ALT_A #define NANO_APPEND_KEY NANO_ALT_A
#define NANO_PREPEND_KEY NANO_ALT_P #define NANO_PREPEND_KEY NANO_ALT_P
#define NANO_LOAD_KEY NANO_ALT_F
#define NANO_OPENPREV_KEY NANO_ALT_LCARAT #define NANO_OPENPREV_KEY NANO_ALT_LCARAT
#define NANO_OPENNEXT_KEY NANO_ALT_RCARAT #define NANO_OPENNEXT_KEY NANO_ALT_RCARAT
#define NANO_OPENPREV_ALTKEY NANO_ALT_COMMA #define NANO_OPENPREV_ALTKEY NANO_ALT_COMMA

22
proto.h
View File

@ -126,7 +126,6 @@ int do_uncut_text(void);
void load_file(int update); void load_file(int update);
void new_file(void); void new_file(void);
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, int len); filestruct *read_line(char *buf, filestruct *prev, int *line1ins, int len);
int write_file(char *name, int tmpfile, int append, int nonamechange);
int read_file(FILE *f, const char *filename, int quiet); int read_file(FILE *f, const char *filename, int quiet);
int open_file(const char *filename, int insert, int quiet); int open_file(const char *filename, int insert, int quiet);
char *get_next_filename(const char *name); char *get_next_filename(const char *name);
@ -147,20 +146,21 @@ int open_nextfile_void(void);
int close_open_file(void); int close_open_file(void);
#endif #endif
#if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR) #if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR)
char *get_full_path(char *origpath); char *get_full_path(const char *origpath);
#endif #endif
#ifndef DISABLE_SPELLER #ifndef DISABLE_SPELLER
char *check_writable_directory(char *path); char *check_writable_directory(const char *path);
char *safe_tempnam(const char *dirname, const char *filename_prefix); char *safe_tempnam(const char *dirname, const char *filename_prefix);
#endif #endif
#ifndef DISABLE_OPERATINGDIR #ifndef DISABLE_OPERATINGDIR
int check_operating_dir(char *currpath, int allow_tabcomp); void init_operating_dir(void);
int check_operating_dir(const char *currpath, int allow_tabcomp);
#endif #endif
int write_file(char *name, int tmp, int append, int nonamechange); int write_file(const char *name, int tmp, int append, int nonamechange);
int do_writeout(char *path, int exiting, int append); int do_writeout(const char *path, int exiting, int append);
int do_writeout_void(void); int do_writeout_void(void);
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
char *real_dir_from_tilde(char *buf); char *real_dir_from_tilde(const char *buf);
#endif #endif
int append_slash_if_dir(char *buf, int *lastwastab, int *place); int append_slash_if_dir(char *buf, int *lastwastab, int *place);
char **username_tab_completion(char *buf, int *num_matches); char **username_tab_completion(char *buf, int *num_matches);
@ -170,11 +170,11 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
struct stat filestat(const char *path); struct stat filestat(const char *path);
int diralphasort(const void *va, const void *vb); int diralphasort(const void *va, const void *vb);
void free_charptrarray(char **array, int len); void free_charptrarray(char **array, int len);
char *tail(char *foo); const char *tail(const char *foo);
void striponedir(char *foo); void striponedir(char *foo);
char **browser_init(char *path, int *longest, int *numents); char **browser_init(const char *path, int *longest, int *numents);
char *do_browser(char *inpath); char *do_browser(const char *inpath);
char *do_browse_from(char *inpath); char *do_browse_from(const char *inpath);
#endif #endif
/* Public functions in global.c */ /* Public functions in global.c */

View File

@ -19,6 +19,8 @@
* * * *
**************************************************************************/ **************************************************************************/
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
@ -30,7 +32,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <assert.h> #include <assert.h>
#include "config.h"
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
@ -43,7 +44,7 @@
#define _(string) (string) #define _(string) (string)
#endif #endif
static rcoption rcopts[] = { const static rcoption rcopts[] = {
#ifndef NANO_SMALL #ifndef NANO_SMALL
{"autoindent", AUTOINDENT}, {"autoindent", AUTOINDENT},
{"backup", BACKUP_FILE}, {"backup", BACKUP_FILE},
@ -90,7 +91,7 @@ static rcoption rcopts[] = {
{"tabsize", 0}, {"tabsize", 0},
{"tempfile", TEMP_OPT}, {"tempfile", TEMP_OPT},
{"view", VIEW_MODE}, {"view", VIEW_MODE},
{"", 0} {NULL, 0}
}; };
static int errors = 0; static int errors = 0;
@ -483,7 +484,7 @@ void parse_rcfile(FILE *rcstream)
/* We don't care if ptr == NULL, as it should if using proper syntax */ /* We don't care if ptr == NULL, as it should if using proper syntax */
if (set != 0) { if (set != 0) {
for (i = 0; rcopts[i].name != ""; i++) { for (i = 0; rcopts[i].name != NULL; i++) {
if (!strcasecmp(option, rcopts[i].name)) { if (!strcasecmp(option, rcopts[i].name)) {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, _("parse_rcfile: Parsing option %s\n"), fprintf(stderr, _("parse_rcfile: Parsing option %s\n"),

View File

@ -820,7 +820,7 @@ void do_gotopos(int line, int pos_x, int pos_y, int pos_placewewant)
int do_find_bracket(void) int do_find_bracket(void)
{ {
char ch_under_cursor, wanted_ch; char ch_under_cursor, wanted_ch;
char *pos, *brackets = "([{<>}])"; const char *pos, *brackets = "([{<>}])";
char regexp_pat[] = "[ ]"; char regexp_pat[] = "[ ]";
int offset, have_past_editbuff = 0, flagsave, current_x_save, count = 1; int offset, have_past_editbuff = 0, flagsave, current_x_save, count = 1;
filestruct *current_save; filestruct *current_save;

11
utils.c
View File

@ -19,13 +19,14 @@
* * * *
**************************************************************************/ **************************************************************************/
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <assert.h> #include <assert.h>
#include "config.h"
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
@ -221,12 +222,10 @@ void *nmalloc(size_t howmuch)
the transition cost of moving to the appropriate function. */ the transition cost of moving to the appropriate function. */
char *charalloc(size_t howmuch) char *charalloc(size_t howmuch)
{ {
char *r; char *r = (char *)malloc(howmuch * sizeof(char));
/* Panic save? */ if (r == NULL)
die(_("nano: malloc: out of memory!"));
if (!(r = (char *)calloc(howmuch, sizeof (char))))
die(_("nano: calloc: out of memory!"));
return r; return r;
} }

View File

@ -19,13 +19,14 @@
* * * *
**************************************************************************/ **************************************************************************/
#include "config.h"
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <assert.h> #include <assert.h>
#include "config.h"
#include "proto.h" #include "proto.h"
#include "nano.h" #include "nano.h"
@ -1804,10 +1805,10 @@ void do_credits(void)
{ {
int i, j = 0, k, place = 0, start_x; int i, j = 0, k, place = 0, start_x;
char *what; const char *what;
char *xlcredits[XLCREDIT_LEN]; const char *xlcredits[XLCREDIT_LEN];
char *credits[CREDIT_LEN] = { const char *credits[CREDIT_LEN] = {
"0", /* "The nano text editor" */ "0", /* "The nano text editor" */
"1", /* "version" */ "1", /* "version" */
VERSION, VERSION,