per DB's patch, overhaul the rcfile and history file reading and writing

routines to fix a few fundamental problems and limitations; also add
getline() and getdelim() equivalents adapted from GNU mailutils 0.5 (and
tweaked to better integrate with nano), since the patch uses getline()


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1900 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
David Lawrence Ramsey
2004-08-17 05:23:38 +00:00
parent bb50b305d5
commit a27bd65057
9 changed files with 194 additions and 100 deletions

View File

@@ -2914,30 +2914,30 @@ char *do_browse_from(const char *inpath)
#endif /* !DISABLE_BROWSER */
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
/* Return $HOME/.nano_history, or NULL if we can't find the homedir.
* The string is dynamically allocated, and should be freed. */
char *histfilename(void)
{
char *nanohist = NULL;
if (homedir != NULL) {
size_t homelen = strlen(homedir);
nanohist = charalloc(homelen + 15);
strcpy(nanohist, homedir);
strcpy(nanohist + homelen, "/.nano_history");
}
return nanohist;
}
void load_history(void)
{
FILE *hist;
const struct passwd *userage = NULL;
static char *nanohist;
char *buf, *ptr;
char *homenv = getenv("HOME");
historyheadtype *history = &search_history;
if (homenv != NULL) {
nanohist = charealloc(nanohist, strlen(homenv) + 15);
sprintf(nanohist, "%s/.nano_history", homenv);
} else {
userage = getpwuid(geteuid());
endpwent();
nanohist = charealloc(nanohist, strlen(userage->pw_dir) + 15);
sprintf(nanohist, "%s/.nano_history", userage->pw_dir);
}
char *nanohist = histfilename();
/* assume do_rcfile() has reported missing home dir */
if (nanohist != NULL) {
FILE *hist = fopen(nanohist, "r");
if (homenv != NULL || userage != NULL) {
hist = fopen(nanohist, "r");
if (hist == NULL) {
if (errno != ENOENT) {
/* Don't save history when we quit. */
@@ -2947,80 +2947,72 @@ void load_history(void)
while (getchar() != '\n')
;
}
free(nanohist);
} else {
buf = charalloc(1024);
while (fgets(buf, 1023, hist) != 0) {
ptr = buf;
while (*ptr != '\n' && *ptr != '\0' && ptr < buf + 1023)
ptr++;
*ptr = '\0';
if (strlen(buf))
update_history(history, buf);
else
historyheadtype *history = &search_history;
char *line = NULL;
size_t buflen = 0;
ssize_t read;
while ((read = getline(&line, &buflen, hist)) >= 0) {
if (read > 0 && line[read - 1] == '\n') {
read--;
line[read] = '\0';
}
if (read > 0) {
unsunder(line, read);
update_history(history, line);
} else
history = &replace_history;
}
fclose(hist);
free(buf);
free(nanohist);
free(line);
UNSET(HISTORY_CHANGED);
}
free(nanohist);
}
}
bool writehist(FILE *hist, historyheadtype *histhead)
{
historytype *h;
/* write oldest first */
for (h = histhead->tail; h->prev != NULL; h = h->prev) {
size_t len = strlen(h->data);
sunder(h->data);
if (fwrite(h->data, sizeof(char), len, hist) < len ||
putc('\n', hist) == EOF)
return FALSE;
}
return TRUE;
}
/* save histories to ~/.nano_history */
void save_history(void)
{
FILE *hist;
const struct passwd *userage = NULL;
char *nanohist = NULL;
char *homenv = getenv("HOME");
historytype *h;
char *nanohist;
/* don't save unchanged or empty histories */
if ((search_history.count == 0 && replace_history.count == 0) ||
!ISSET(HISTORY_CHANGED) || ISSET(VIEW_MODE))
return;
if (homenv != NULL) {
nanohist = charealloc(nanohist, strlen(homenv) + 15);
sprintf(nanohist, "%s/.nano_history", homenv);
} else {
userage = getpwuid(geteuid());
endpwent();
nanohist = charealloc(nanohist, strlen(userage->pw_dir) + 15);
sprintf(nanohist, "%s/.nano_history", userage->pw_dir);
}
nanohist = histfilename();
if (nanohist != NULL) {
FILE *hist = fopen(nanohist, "wb");
if (homenv != NULL || userage != NULL) {
hist = fopen(nanohist, "wb");
if (hist == NULL)
rcfile_error(N_("Error writing %s: %s"), nanohist, strerror(errno));
else {
/* set rw only by owner for security ?? */
chmod(nanohist, S_IRUSR | S_IWUSR);
/* write oldest first */
for (h = search_history.tail; h->prev; h = h->prev) {
h->data = charealloc(h->data, strlen(h->data) + 2);
strcat(h->data, "\n");
if (fputs(h->data, hist) == EOF) {
rcfile_error(N_("Error writing %s: %s"), nanohist, strerror(errno));
goto come_from;
}
}
if (fputs("\n", hist) == EOF) {
if (!writehist(hist, &search_history) ||
putc('\n', hist) == EOF ||
!writehist(hist, &replace_history))
rcfile_error(N_("Error writing %s: %s"), nanohist, strerror(errno));
goto come_from;
}
for (h = replace_history.tail; h->prev; h = h->prev) {
h->data = charealloc(h->data, strlen(h->data) + 2);
strcat(h->data, "\n");
if (fputs(h->data, hist) == EOF) {
rcfile_error(N_("Error writing %s: %s"), nanohist, strerror(errno));
goto come_from;
}
}
come_from:
fclose(hist);
}
free(nanohist);