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
together (for this, rename clear_bottombars() to
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:
- Added pt_BR to ALL_LINGUAS (Jordi).
- Changed --enable-color warning to be slightly less severe.
@ -28,10 +37,9 @@ CVS code -
- Disallow multibuffer toggling at the "Insert File" prompt if
we're in both view and multibuffer mode, so as to keep proper
integration between the two, and make sure the toggle
actually works all the time otherwise. Also, use
NANO_LOAD_KEY as an alias for TOGGLE_LOAD_KEY, so
--enable-tiny and --enable-multibuffer can be used together
again. (DLR)
actually works all the time otherwise. Also, make sure
TOGGLE_LOAD_KEY isn't referenced when NANO_SMALL and
ENABLE_MULTIBUFFER are both defined. (DLR)
open_prevfile_void(), open_nextfile_void()
- Return the return values of open_prevfile() and
open_nextfile(), respectively, instead of (incorrectly)
@ -45,9 +53,9 @@ CVS code -
username and the string already contains data. (DLR)
- global.c:
shortcut_init()
- Use NANO_LOAD_KEY as an alias for TOGGLE_LOAD_KEY, so
--enable-tiny and --enable-multibuffer can be used together
again. (DLR)
- Disable the new multibuffer toggle at the file insertion
prompt when NANO_SMALL and ENABLE_MULTIBUFFER are both
defined. (DLR)
thanks_for_all_the_fish()
- Make sure the reference to help_text is #ifdefed out when
--disable-help is used. (DLR)
@ -92,7 +100,9 @@ CVS code -
Benbennick)
do_justify()
- 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()
- When searching through the main shortcut list looking for a
shortcut key, stop searching after finding one; this avoids a
@ -104,6 +114,10 @@ CVS code -
- nanorc.sample:
- Fix the c-file regex for all caps words to be extended regex
format ({} instead of \{\}) (found by DLR).
- utils.c:
charalloc()
- Switch from using calloc() to using malloc(). (David
Benbennick)
- faq.html:
- Typo fix. (DLR)
- TODO:

501
files.c
View File

@ -489,16 +489,16 @@ int do_insertfile(int loading_file)
}
#endif
#ifndef NANO_SMALL
#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
multibuffer mode now */
if (!ISSET(VIEW_MODE) || !ISSET(MULTIBUFFER))
TOGGLE(MULTIBUFFER);
return do_insertfile(ISSET(MULTIBUFFER));
}
#endif
#ifndef NANO_SMALL
#endif /* ENABLE_MULTIBUFFER */
if (i == NANO_EXTCMD_KEY) {
int ts;
ts = statusq(1, extcmd_list, "", _("Command to execute "));
@ -509,7 +509,7 @@ int do_insertfile(int loading_file)
return 0;
}
}
#endif
#endif /* !NANO_SMALL */
#ifdef ENABLE_MULTIBUFFER
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
* 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;
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
* 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);
int writable;
@ -1177,49 +1177,27 @@ char *check_writable_directory(char *path)
*/
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;
/* 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,
leave full_tempdir set to to NULL */
if (getenv("TMPDIR") && strcmp(getenv("TMPDIR"),"")) {
/* store the value of $TMPDIR in tempdir, run its value through
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) {
TMPDIR_env = getenv("TMPDIR");
if (TMPDIR_env && TMPDIR_env[0] != '\0')
full_tempdir = check_writable_directory(TMPDIR_env);
/* if $TMPDIR is blank or isn't set, or isn't a writable
directory, and dirname isn't NULL, try it; otherwise, leave
full_tempdir set to NULL */
if (dirname) {
tempdir = charalloc(strlen(dirname) + 1);
strcpy(tempdir, dirname);
full_tempdir = check_writable_directory(tempdir);
/* we don't need the value of tempdir anymore */
free(tempdir);
}
}
if (!full_tempdir && dirname)
full_tempdir = check_writable_directory(dirname);
/* if $TMPDIR is blank or isn't set, or if it isn't a writable
directory, and dirname is NULL, try P_tmpdir instead */
if (!full_tempdir) {
tempdir = charalloc(strlen(P_tmpdir) + 1);
strcpy(tempdir, P_tmpdir);
full_tempdir = check_writable_directory(tempdir);
/* we don't need the value of tempdir anymore */
free(tempdir);
}
if (!full_tempdir)
full_tempdir = check_writable_directory(P_tmpdir);
/* if P_tmpdir didn't work, use /tmp instead */
if (!full_tempdir) {
@ -1227,84 +1205,68 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix)
strcpy(full_tempdir, "/tmp/");
}
buf = charalloc(strlen(full_tempdir) + 12);
sprintf(buf, "%s", full_tempdir);
full_tempdir = nrealloc(full_tempdir, strlen(full_tempdir) + 12);
/* 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");
filedesc = mkstemp(buf);
/* if mkstemp() failed, get out */
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 {
/* if mkstemp succeeded, close the resulting file; afterwards, it'll be
0 bytes long, so delete it; finally, return the filename (all that's
left of it) */
if (filedesc != -1) {
close(filedesc);
unlink(buf);
return buf;
unlink(full_tempdir);
return full_tempdir;
}
free(full_tempdir);
return NULL;
}
#endif /* !DISABLE_SPELLER */
#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
* are, or 1 otherwise. If allow_tabcomp is nonzero, allow incomplete
* names that would be matches for the operating directory, so that tab
* 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
therefore we only need to get it the first time this function
is called; also, a relative operating directory path will
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 (!operating_dir)
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);
if (!fullpath)
return 1;
@ -1314,18 +1276,16 @@ int check_operating_dir(char *currpath, int allow_tabcomp)
whereami2 = strstr(full_operating_dir, fullpath);
/* if both searches failed, we're outside the operating directory */
if (!whereami1 && !whereami2)
return 1;
/* otherwise */
/* check the search results; if the full operating directory path is
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
outside the operating directory */
if (whereami1 != fullpath && whereami2 != full_operating_dir)
return 1;
retval = 1;
free(fullpath);
/* otherwise, we're still inside it */
return 0;
return retval;
}
#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
* 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;
char *buf = NULL;
filestruct *fileptr;
const filestruct *fileptr;
FILE *f;
int fd;
int mask = 0, realexists, anyexists;
@ -1361,12 +1324,6 @@ int write_file(char *name, int tmp, int append, int nonamechange)
titlebar(NULL);
fileptr = fileage;
if (realname != NULL)
free(realname);
if (buf != NULL)
free(buf);
#ifndef DISABLE_TABCOMP
realname = real_dir_from_tilde(name);
#else
@ -1374,19 +1331,16 @@ int write_file(char *name, int tmp, int append, int nonamechange)
#endif
#ifndef DISABLE_OPERATINGDIR
if (!tmp && operating_dir) {
/* if we're writing a temporary file, we're probably going
outside the operating directory, so skip the operating
directory test */
if (check_operating_dir(realname, 0)) {
/* If we're writing a temporary file, we're probably going outside
the operating directory, so skip the operating directory test. */
if (!tmp && operating_dir && check_operating_dir(realname, 0)) {
statusbar(_("Can't write outside of %s"), operating_dir);
return -1;
}
goto cleanup_and_exit;
}
#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);
#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 */
if (tmp && anyexists != -1)
return -1;
goto cleanup_and_exit;
/* NOTE: If you change this statement, you MUST CHANGE the if
statement below (that says:
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 (!tmp && ISSET(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"),
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 (ISSET(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"),
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");
if (!f) {
statusbar(_("Could not open file for writing: %s"),
strerror(errno));
return -1;
statusbar(_("Could not open file for writing: %s"), strerror(errno));
goto cleanup_and_exit;
}
while (fileptr != NULL && fileptr->next != NULL) {
int data_len;
/* Next line is so we discount the "magic line" */
if (filebot == fileptr && fileptr->data[0] == '\0')
break;
@ -1539,7 +1493,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open file for writing: %s"),
strerror(errno));
fclose(f);
return -1;
goto cleanup_and_exit;
}
#ifdef DEBUG
else
@ -1558,9 +1512,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
}
if (fileptr != NULL) {
int data_len;
data_len = strlen(fileptr->data);
int data_len = strlen(fileptr->data);
/* newlines to nulls, just before we write to disk */
sunder(fileptr->data);
@ -1573,7 +1525,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if (size < data_len) {
statusbar(_("Could not open file for writing: %s"),
strerror(errno));
return -1;
goto cleanup_and_exit;
} else if (data_len > 0) {
#ifndef NANO_SMALL
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"),
strerror(errno));
fclose(f);
return -1;
goto cleanup_and_exit;
}
lineswritten++;
}
@ -1593,7 +1545,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
statusbar(_("Could not open file for writing: %s"),
strerror(errno));
fclose(f);
return -1;
goto cleanup_and_exit;
}
lineswritten++;
}
@ -1603,7 +1555,7 @@ int write_file(char *name, int tmp, int append, int nonamechange)
if (fclose(f)) {
statusbar(_("Could not close %s: %s"), realname, strerror(errno));
unlink(buf);
return -1;
goto cleanup_and_exit;
}
/* 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) {
statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
return -1;
goto cleanup_and_exit;
}
f_dest = fdopen(fd_dest, "wb");
if (!f_dest) {
statusbar(_("Could not reopen %s: %s"), buf, strerror(errno));
close(fd_dest);
return -1;
goto cleanup_and_exit;
}
if ((fd_source = open(realname, O_RDONLY | O_CREAT)) == -1) {
statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
fclose(f_dest);
return -1;
goto cleanup_and_exit;
}
f_source = fdopen(fd_source, "rb");
if (!f_source) {
statusbar(_("Could not open %s for prepend: %s"), realname, strerror(errno));
fclose(f_dest);
close(fd_source);
return -1;
goto cleanup_and_exit;
}
/* 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));
fclose(f_source);
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));
fclose(f_source);
fclose(f_dest);
return -1;
goto cleanup_and_exit;
}
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"),
realname, strerror(errno));
unlink(buf);
return -1;
goto cleanup_and_exit;
}
}
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"),
name, strerror(errno));
unlink(buf);
return -1;
goto cleanup_and_exit;
} else if (rename(buf, realname) == -1) { /* Try a rename?? */
statusbar(_("Could not open %s for writing: %s"),
realname, strerror(errno));
unlink(buf);
return -1;
goto cleanup_and_exit;
}
}
if (chmod(realname, mask) == -1)
@ -1711,15 +1663,18 @@ int write_file(char *name, int tmp, int append, int nonamechange)
UNSET(MODIFIED);
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;
#ifndef NANO_SMALL
const char *formatstr, *backupstr;
#endif
#ifdef NANO_EXTRA
static int did_cred = 0;
#endif
@ -1730,7 +1685,7 @@ int do_writeout(char *path, int exiting, int append)
answer = mallocstrcpy(answer, path);
if ((exiting) && (ISSET(TEMP_OPT))) {
if (exiting && ISSET(TEMP_OPT)) {
if (filename[0]) {
i = write_file(answer, 0, 0, 0);
display_main_list();
@ -1745,8 +1700,9 @@ int do_writeout(char *path, int exiting, int append)
}
while (1) {
#ifndef NANO_SMALL
const char *formatstr, *backupstr;
if (ISSET(MAC_FILE))
formatstr = _(" [Mac Format]");
else if (ISSET(DOS_FILE))
@ -1793,42 +1749,44 @@ int do_writeout(char *path, int exiting, int append)
"%s", _("File Name to Write"));
#endif /* !NANO_SMALL */
if (i != -1) {
if (i == -1) {
statusbar(_("Cancelled"));
display_main_list();
return 0;
}
#ifndef DISABLE_BROWSER
if (i == NANO_TOFILES_KEY) {
char *tmp = do_browse_from(answer);
#if !defined(DISABLE_BROWSER) || !defined(DISABLE_MOUSE)
currshortcut = writefile_list;
#endif
if (tmp != NULL) {
answer = mallocstrcpy(answer, tmp);
if (tmp == NULL)
continue;
free(answer);
answer = tmp;
} else
return do_writeout(answer, exiting, append);
} else
#endif
#endif /* !DISABLE_BROWSER */
#ifndef NANO_SMALL
if (i == TOGGLE_DOS_KEY) {
UNSET(MAC_FILE);
TOGGLE(DOS_FILE);
return(do_writeout(answer, exiting, append));
continue;
} else if (i == TOGGLE_MAC_KEY) {
UNSET(DOS_FILE);
TOGGLE(MAC_FILE);
return(do_writeout(answer, exiting, append));
continue;
} else if (i == TOGGLE_BACKUP_KEY) {
TOGGLE(BACKUP_FILE);
return(do_writeout(answer, exiting, append));
#else
if (0) {
#endif
} else if (i == NANO_PREPEND_KEY)
return(do_writeout(answer, exiting, append == 2 ? 0 : 2));
else if (i == NANO_APPEND_KEY)
return(do_writeout(answer, exiting, append == 1 ? 0 : 1));
continue;
} else
#endif /* ! NANO_SMALL */
if (i == NANO_PREPEND_KEY) {
append = append == 2 ? 0 : 2;
continue;
} else if (i == NANO_APPEND_KEY) {
append = append == 1 ? 0 : 1;
continue;
}
#ifdef DEBUG
fprintf(stderr, _("filename is %s\n"), answer);
@ -1844,10 +1802,11 @@ int do_writeout(char *path, int exiting, int append)
#endif
if (!append && strcmp(answer, filename)) {
struct stat st;
if (!stat(answer, &st)) {
i = do_yesno(0, 0, _("File exists, OVERWRITE ?"));
if (!i || (i == -1))
if (i == 0 || i == -1)
continue;
}
}
@ -1859,56 +1818,40 @@ int do_writeout(char *path, int exiting, int append)
filestruct *fileagebak = fileage;
filestruct *filebotbak = filebot;
filestruct *cutback = cutbuffer;
long totsizebak = totsize;
int oldmod = 0;
int oldmod = ISSET(MODIFIED);
/* write_file() unsets the MODIFIED flag. */
cutbuffer = NULL;
/* Okay, since write_file changes the filename, back it up */
if (ISSET(MODIFIED))
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)
/* Put the marked text in the cutbuffer without changing
the open file. */
cut_marked_segment(current, current_x, mark_beginbuf,
mark_beginx, 0);
else
cut_marked_segment(mark_beginbuf, mark_beginx, current,
current_x, 0);
fileage = cutbuffer;
for (filebot = cutbuffer; filebot->next != NULL;
filebot = filebot->next)
;
filebot = get_cutbottom();
i = write_file(answer, 0, append, 1);
/* Now restore everything */
free_filestruct(cutbuffer);
fileage = fileagebak;
filebot = filebotbak;
cutbuffer = cutback;
totsize = totsizebak;
if (oldmod)
set_modified();
} else
#endif /* !NANO_SMALL */
i = write_file(answer, 0, append, 0);
#ifdef ENABLE_MULTIBUFFER
/* if we're not about to exit, update the current entry in
the open_files structure */
/* If we're not about to exit, update the current entry in
the open_files structure. */
if (!exiting)
add_open_file(1);
#endif
display_main_list();
return i;
} else {
statusbar(_("Cancelled"));
display_main_list();
return 0;
}
}
} /* while (1) */
}
int do_writeout_void(void)
@ -1919,76 +1862,67 @@ int do_writeout_void(void)
#ifndef DISABLE_TABCOMP
/* Return a malloc()ed string containing the actual directory, used
* to convert ~user and ~/ notation...
*/
char *real_dir_from_tilde(char *buf)
* to convert ~user and ~/ notation... */
char *real_dir_from_tilde(const char *buf)
{
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[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
$HOME */
uid_t euid = geteuid();
do {
userdata = getpwent();
} while (userdata != NULL && userdata->pw_uid != euid);
}
else {
char *find_user = NULL;
/* Figure how how much of the str we need to compare */
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);
} else {
do {
userdata = getpwent();
} while (userdata != NULL &&
strncmp(userdata->pw_name, buf + 1, i - 1));
}
endpwent();
if (userdata != NULL) { /* User found */
free(dirtmp);
dirtmp = charalloc(strlen(buf) + 2 + strlen(userdata->pw_dir));
dirtmp = charalloc(strlen(userdata->pw_dir) + strlen(buf + i) + 1);
sprintf(dirtmp, "%s%s", userdata->pw_dir, &buf[i]);
}
}
if (dirtmp == NULL)
dirtmp = mallocstrcpy(dirtmp, buf);
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)
{
char *dirptr;
char *dirptr = real_dir_from_tilde(buf);
struct stat fileinfo;
int ret = 0;
dirptr = real_dir_from_tilde(buf);
assert(dirptr != buf);
if (stat(dirptr, &fileinfo) == -1)
ret = 0;
else if (S_ISDIR(fileinfo.st_mode)) {
if (stat(dirptr, &fileinfo) != -1 && S_ISDIR(fileinfo.st_mode)) {
strncat(buf, "/", 1);
*place += 1;
(*place)++;
/* now we start over again with # of tabs so far */
*lastwastab = 0;
ret = 1;
}
if (dirptr != buf)
free(dirptr);
return ret;
}
@ -2383,7 +2317,7 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
curs_set(1);
return buf;
}
#endif
#endif /* !DISABLE_TABCOMP */
#ifndef DISABLE_BROWSER
@ -2397,57 +2331,53 @@ struct stat filestat(const char *path)
}
/* 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)
{
struct stat file1info, file2info;
char *a = *(char **)va, *b = *(char **)vb;
int aisdir, bisdir;
struct stat fileinfo;
const char *a = *(char *const *)va, *b = *(char *const *)vb;
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);
bisdir = (stat(b, &file2info) != -1) && S_ISDIR(file2info.st_mode);
if (aisdir && !bisdir) return -1;
if (!aisdir && bisdir) return 1;
if (aisdir && !bisdir)
return -1;
if (!aisdir && bisdir)
return 1;
#ifdef HAVE_STRCASECMP
return(strcasecmp(a,b));
return strcasecmp(a, b);
#else
return(strcmp(a,b));
return strcmp(a, b);
#endif
}
/* Free our malloc()ed memory */
void free_charptrarray(char **array, int len)
{
int i;
for (i = 0; i < len; i++)
free(array[i]);
for (; len > 0; len--)
free(array[len - 1]);
free(array);
}
/* only print the last part of a path; isn't there a shell
command for this? */
char *tail(char *foo)
/* Only print the last part of a path; isn't there a shell
* command for this? */
const char *tail(const char *foo)
{
char *tmp = NULL;
const char *tmp = foo + strlen(foo);
tmp = foo + strlen(foo);
while (*tmp != '/' && tmp != foo)
tmp--;
if (*tmp == '/')
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)
{
char *tmp = NULL;
char *tmp;
/* Don't strip the root dir */
if (!strcmp(foo, "/"))
@ -2461,23 +2391,22 @@ void striponedir(char *foo)
tmp--;
if (tmp != foo)
*tmp = 0;
else
{ /* SPK may need to make a 'default' path here */
if (*tmp != '/') *(tmp) = '.';
*(tmp+1) = 0;
*tmp = '\0';
else { /* SPK may need to make a 'default' path here */
if (*tmp != '/')
*tmp = '.';
*(tmp + 1) = '\0';
}
return;
}
/* 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;
struct dirent *next;
char **filelist = (char **) NULL;
char **filelist;
int i = 0;
size_t path_len;
dir = opendir(path);
if (!dir)
@ -2496,17 +2425,16 @@ char **browser_init(char *path, int *longest, int *numents)
filelist = nmalloc(*numents * sizeof (char *));
if (!strcmp(path, "/"))
path = "";
path_len = strlen(path);
while ((next = readdir(dir)) != NULL) {
if (!strcmp(next->d_name, "."))
continue;
filelist[i] = charalloc(strlen(next->d_name) + strlen(path) + 2);
if (!strcmp(path, "/"))
snprintf(filelist[i], strlen(next->d_name) + strlen(path) + 1,
"%s%s", path, next->d_name);
else
snprintf(filelist[i], strlen(next->d_name) + strlen(path) + 2,
"%s/%s", path, next->d_name);
filelist[i] = charalloc(strlen(next->d_name) + path_len + 2);
sprintf(filelist[i], "%s/%s", path, next->d_name);
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 */
char *do_browser(char *inpath)
char *do_browser(const char *inpath)
{
struct stat st;
char *foo, *retval = NULL;
@ -2532,6 +2460,8 @@ char *do_browser(char *inpath)
#endif
#endif
assert(inpath != NULL);
/* 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
inpath below */
@ -2542,7 +2472,7 @@ char *do_browser(char *inpath)
/* if path doesn't exist, make it so */
if (path == NULL)
path = mallocstrcpy(path, inpath);
path = mallocstrcpy(NULL, inpath);
filelist = browser_init(path, &longest, &numents);
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,
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;
char *tmp = NULL;
tmp = mallocstrcpy(tmp, inpath);
char *tmp;
char *bob;
/* 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
char *from = getcwd(NULL, PATH_MAX + 1);
#else
char *from = getcwd(NULL, 0);
#endif /* PATH_MAX */
return do_browser(from ? from : "./");
#endif
bob = do_browser(from ? from : "./");
free(from);
return bob;
}
/* If the string is a directory, pass do_browser that */
st = filestat(tmp);
st = filestat(inpath);
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...
try stripping it off */
striponedir(tmp);
align(&tmp);
return do_browser(tmp);
bob = do_browser(tmp);
free(tmp);
return bob;
}
#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 */
#endif /* ENABLE_COLOR */
int length_of_list(const shortcut *s)
{
int i = 0;
for (; s != NULL; s = s->next)
i++;
return i;
@ -304,7 +304,7 @@ void free_shortcutage(shortcut **shortcutage)
void shortcut_init(int unjustify)
{
#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_replace_msg = "", *nano_insert_msg =
"", *nano_whereis_msg = "", *nano_prevpage_msg =
@ -325,11 +325,11 @@ void shortcut_init(int unjustify)
"", *nano_backup_msg = "";
#ifdef ENABLE_MULTIBUFFER
char *nano_openprev_msg = "", *nano_opennext_msg =
const char *nano_openprev_msg = "", *nano_opennext_msg =
"", *nano_multibuffer_msg = "";
#endif
#ifdef HAVE_REGEX_H
char *nano_regexp_msg = "", *nano_bracket_msg = "";
const char *nano_regexp_msg = "", *nano_bracket_msg = "";
#endif
nano_help_msg = _("Invoke the help menu");
@ -725,10 +725,10 @@ void shortcut_init(int unjustify)
#ifndef NANO_SMALL
sc_init_one(&insertfile_list, NANO_EXTCMD_KEY, _("Execute Command"),
IFHELP(nano_execute_msg, 0), 0, 0, NOVIEW, 0);
#endif
#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);
#endif
#endif
free_shortcutage(&spell_list);

43
nano.c
View File

@ -2177,7 +2177,7 @@ int do_justify(void)
* 2) the line above it is not part of a paragraph, or
* 3) the line above it does not have precisely the same quote
* 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
* 5) this line has no quote part and some indentation, and
* AUTOINDENT is not set.
@ -2250,30 +2250,29 @@ int do_justify(void)
current_x = 0;
if (current->data[quote_len + indent_len] != '\0') {
/* This line is part of a paragraph. So we must search back to
* the first line of this paragraph. */
if (quote_len > 0 || indent_len == 0
#ifndef NANO_SMALL
|| ISSET(AUTOINDENT)
#endif
) {
/* We don't justify indented paragraphs unless AUTOINDENT is
* turned on. See 5) above. */
* the first line of this paragraph. First we check items 1) and
* 3) above. */
while (current->prev && quotes_match(current->data,
quote_len, IFREG(current->prev->data, &qreg))) {
/* indentation length of the previous line */
size_t temp_id_len =
indent_length(current->prev->data + quote_len);
/* The indentation length of the previous line. */
if (!indents_match(current->prev->data + quote_len,
temp_id_len, current->data + quote_len,
indent_len) ||
current->prev->data[quote_len + temp_id_len] == '\0')
/* Is this line the beginning of a paragraph, according to
items 2), 5), or 4) above? If so, stop. */
if (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;
indent_len = temp_id_len;
current = current->prev;
current_y--;
}
}
} else {
/* This line is not part of a paragraph. Move down until we get
* to a non "blank" line. */
@ -2646,7 +2645,6 @@ void signal_init(void)
#endif /* _POSIX_VDISABLE */
if (!ISSET(SUSPEND)) {
/* Insane! */
#ifdef _POSIX_VDISABLE
term.c_cc[VSUSP] = _POSIX_VDISABLE;
@ -2654,7 +2652,6 @@ void signal_init(void)
act.sa_handler = SIG_IGN;
sigaction(SIGTSTP, &act, NULL);
#endif
} else {
/* If we don't do this, it seems other stuff interrupts the
suspend handler! Try using nano with mutt without this
@ -3091,12 +3088,6 @@ int main(int argc, char *argv[])
#ifndef DISABLE_OPERATINGDIR
case 'o':
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;
#endif
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 */
filename = charalloc(1);
filename[0] = '\0';

3
nano.h
View File

@ -137,7 +137,7 @@ typedef struct toggle {
#ifdef ENABLE_NANORC
typedef struct rcoption {
char *name;
const char *name;
int flag;
} rcoption;
#endif /* ENABLE_NANORC */
@ -326,7 +326,6 @@ know what you're doing */
#define NANO_TOFILES_KEY NANO_CONTROL_T
#define NANO_APPEND_KEY NANO_ALT_A
#define NANO_PREPEND_KEY NANO_ALT_P
#define NANO_LOAD_KEY NANO_ALT_F
#define NANO_OPENPREV_KEY NANO_ALT_LCARAT
#define NANO_OPENNEXT_KEY NANO_ALT_RCARAT
#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 new_file(void);
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 open_file(const char *filename, int insert, int quiet);
char *get_next_filename(const char *name);
@ -147,20 +146,21 @@ int open_nextfile_void(void);
int close_open_file(void);
#endif
#if !defined(DISABLE_SPELLER) || !defined(DISABLE_OPERATINGDIR)
char *get_full_path(char *origpath);
char *get_full_path(const char *origpath);
#endif
#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);
#endif
#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
int write_file(char *name, int tmp, int append, int nonamechange);
int do_writeout(char *path, int exiting, int append);
int write_file(const char *name, int tmp, int append, int nonamechange);
int do_writeout(const char *path, int exiting, int append);
int do_writeout_void(void);
#ifndef DISABLE_TABCOMP
char *real_dir_from_tilde(char *buf);
char *real_dir_from_tilde(const char *buf);
#endif
int append_slash_if_dir(char *buf, int *lastwastab, int *place);
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);
int diralphasort(const void *va, const void *vb);
void free_charptrarray(char **array, int len);
char *tail(char *foo);
const char *tail(const char *foo);
void striponedir(char *foo);
char **browser_init(char *path, int *longest, int *numents);
char *do_browser(char *inpath);
char *do_browse_from(char *inpath);
char **browser_init(const char *path, int *longest, int *numents);
char *do_browser(const char *inpath);
char *do_browse_from(const char *inpath);
#endif
/* Public functions in global.c */

View File

@ -19,6 +19,8 @@
* *
**************************************************************************/
#include "config.h"
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
@ -30,7 +32,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include "config.h"
#include "proto.h"
#include "nano.h"
@ -43,7 +44,7 @@
#define _(string) (string)
#endif
static rcoption rcopts[] = {
const static rcoption rcopts[] = {
#ifndef NANO_SMALL
{"autoindent", AUTOINDENT},
{"backup", BACKUP_FILE},
@ -90,7 +91,7 @@ static rcoption rcopts[] = {
{"tabsize", 0},
{"tempfile", TEMP_OPT},
{"view", VIEW_MODE},
{"", 0}
{NULL, 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 */
if (set != 0) {
for (i = 0; rcopts[i].name != ""; i++) {
for (i = 0; rcopts[i].name != NULL; i++) {
if (!strcasecmp(option, rcopts[i].name)) {
#ifdef DEBUG
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)
{
char ch_under_cursor, wanted_ch;
char *pos, *brackets = "([{<>}])";
const char *pos, *brackets = "([{<>}])";
char regexp_pat[] = "[ ]";
int offset, have_past_editbuff = 0, flagsave, current_x_save, count = 1;
filestruct *current_save;

11
utils.c
View File

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

View File

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