With this patch applied the user can configure a directory to store temporary/cache files. The history and cookies remain in RC_DIR. I suppose the intent of writing the history to a temp file first is to make the actual write an atomic operation. As rename() does not work across mount points, we need to handle the temp file for the history different to keep this behaviour. Add a new type for the temp history file and handle this case different when creating a temp file.
232 lines
5.0 KiB
C
232 lines
5.0 KiB
C
/* $Id: history.c,v 1.11 2003/09/26 17:59:51 ukai Exp $ */
|
|
#include "fm.h"
|
|
|
|
#ifdef USE_HISTORY
|
|
Buffer *
|
|
historyBuffer(Hist *hist)
|
|
{
|
|
Str src = Strnew();
|
|
HistItem *item;
|
|
char *p, *q;
|
|
|
|
/* FIXME: gettextize? */
|
|
Strcat_charp(src, "<html>\n<head><title>History Page</title></head>\n");
|
|
Strcat_charp(src, "<body>\n<h1>History Page</h1>\n<hr>\n");
|
|
Strcat_charp(src, "<ol>\n");
|
|
if (hist && hist->list) {
|
|
for (item = hist->list->last; item; item = item->prev) {
|
|
q = html_quote((char *)item->ptr);
|
|
if (DecodeURL)
|
|
p = html_quote(url_decode2((char *)item->ptr, NULL));
|
|
else
|
|
p = q;
|
|
Strcat_charp(src, "<li><a href=\"");
|
|
Strcat_charp(src, q);
|
|
Strcat_charp(src, "\">");
|
|
Strcat_charp(src, p);
|
|
Strcat_charp(src, "</a>\n");
|
|
}
|
|
}
|
|
Strcat_charp(src, "</ol>\n</body>\n</html>");
|
|
return loadHTMLString(src);
|
|
}
|
|
|
|
void
|
|
loadHistory(Hist *hist)
|
|
{
|
|
FILE *f;
|
|
Str line;
|
|
|
|
if (hist == NULL)
|
|
return;
|
|
if ((f = fopen(rcFile(HISTORY_FILE), "rt")) == NULL)
|
|
return;
|
|
|
|
while (!feof(f)) {
|
|
line = Strfgets(f);
|
|
Strchop(line);
|
|
Strremovefirstspaces(line);
|
|
Strremovetrailingspaces(line);
|
|
if (line->length == 0)
|
|
continue;
|
|
pushHist(hist, url_quote(line->ptr));
|
|
}
|
|
fclose(f);
|
|
}
|
|
|
|
void
|
|
saveHistory(Hist *hist, size_t size)
|
|
{
|
|
FILE *f;
|
|
HistItem *item;
|
|
char *tmpf;
|
|
int rename_ret;
|
|
|
|
if (hist == NULL || hist->list == NULL)
|
|
return;
|
|
tmpf = tmpfname(TMPF_HIST, NULL)->ptr;
|
|
if ((f = fopen(tmpf, "w")) == NULL) {
|
|
/* FIXME: gettextize? */
|
|
disp_err_message("Can't open history", FALSE);
|
|
return;
|
|
}
|
|
for (item = hist->list->first; item && hist->list->nitem > size;
|
|
item = item->next)
|
|
size++;
|
|
for (; item; item = item->next)
|
|
fprintf(f, "%s\n", (char *)item->ptr);
|
|
if (fclose(f) == EOF) {
|
|
/* FIXME: gettextize? */
|
|
disp_err_message("Can't save history", FALSE);
|
|
return;
|
|
}
|
|
rename_ret = rename(tmpf, rcFile(HISTORY_FILE));
|
|
if (rename_ret != 0) {
|
|
disp_err_message("Can't save history", FALSE);
|
|
return;
|
|
}
|
|
}
|
|
#endif /* USE_HISTORY */
|
|
|
|
Hist *
|
|
newHist()
|
|
{
|
|
Hist *hist;
|
|
|
|
hist = New(Hist);
|
|
hist->list = (HistList *)newGeneralList();
|
|
hist->current = NULL;
|
|
hist->hash = NULL;
|
|
return hist;
|
|
}
|
|
|
|
Hist *
|
|
copyHist(Hist *hist)
|
|
{
|
|
Hist *new;
|
|
HistItem *item;
|
|
|
|
if (hist == NULL)
|
|
return NULL;
|
|
new = newHist();
|
|
for (item = hist->list->first; item; item = item->next)
|
|
pushHist(new, (char *)item->ptr);
|
|
return new;
|
|
}
|
|
|
|
HistItem *
|
|
unshiftHist(Hist *hist, char *ptr)
|
|
{
|
|
HistItem *item;
|
|
|
|
if (hist == NULL || hist->list == NULL ||
|
|
hist->list->nitem >= HIST_LIST_MAX)
|
|
return NULL;
|
|
item = (HistItem *)newListItem((void *)allocStr(ptr, -1),
|
|
(ListItem *)hist->list->first, NULL);
|
|
if (hist->list->first)
|
|
hist->list->first->prev = item;
|
|
else
|
|
hist->list->last = item;
|
|
hist->list->first = item;
|
|
hist->list->nitem++;
|
|
return item;
|
|
}
|
|
|
|
HistItem *
|
|
pushHist(Hist *hist, char *ptr)
|
|
{
|
|
HistItem *item;
|
|
|
|
if (hist == NULL || hist->list == NULL ||
|
|
hist->list->nitem >= HIST_LIST_MAX)
|
|
return NULL;
|
|
item = (HistItem *)newListItem((void *)allocStr(ptr, -1),
|
|
NULL, (ListItem *)hist->list->last);
|
|
if (hist->list->last)
|
|
hist->list->last->next = item;
|
|
else
|
|
hist->list->first = item;
|
|
hist->list->last = item;
|
|
hist->list->nitem++;
|
|
return item;
|
|
}
|
|
|
|
/* Don't mix pushHashHist() and pushHist()/unshiftHist(). */
|
|
|
|
HistItem *
|
|
pushHashHist(Hist *hist, char *ptr)
|
|
{
|
|
HistItem *item;
|
|
|
|
if (hist == NULL || hist->list == NULL ||
|
|
hist->list->nitem >= HIST_LIST_MAX)
|
|
return NULL;
|
|
item = getHashHist(hist, ptr);
|
|
if (item) {
|
|
if (item->next)
|
|
item->next->prev = item->prev;
|
|
else /* item == hist->list->last */
|
|
hist->list->last = item->prev;
|
|
if (item->prev)
|
|
item->prev->next = item->next;
|
|
else /* item == hist->list->first */
|
|
hist->list->first = item->next;
|
|
hist->list->nitem--;
|
|
}
|
|
item = pushHist(hist, ptr);
|
|
putHash_sv(hist->hash, ptr, (void *)item);
|
|
return item;
|
|
}
|
|
|
|
HistItem *
|
|
getHashHist(Hist *hist, char *ptr)
|
|
{
|
|
HistItem *item;
|
|
|
|
if (hist == NULL || hist->list == NULL)
|
|
return NULL;
|
|
if (hist->hash == NULL) {
|
|
hist->hash = newHash_sv(HIST_HASH_SIZE);
|
|
for (item = hist->list->first; item; item = item->next)
|
|
putHash_sv(hist->hash, (char *)item->ptr, (void *)item);
|
|
}
|
|
return (HistItem *)getHash_sv(hist->hash, ptr, NULL);
|
|
}
|
|
|
|
char *
|
|
lastHist(Hist *hist)
|
|
{
|
|
if (hist == NULL || hist->list == NULL)
|
|
return NULL;
|
|
if (hist->list->last) {
|
|
hist->current = hist->list->last;
|
|
return (char *)hist->current->ptr;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *
|
|
nextHist(Hist *hist)
|
|
{
|
|
if (hist == NULL || hist->list == NULL)
|
|
return NULL;
|
|
if (hist->current && hist->current->next) {
|
|
hist->current = hist->current->next;
|
|
return (char *)hist->current->ptr;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *
|
|
prevHist(Hist *hist)
|
|
{
|
|
if (hist == NULL || hist->list == NULL)
|
|
return NULL;
|
|
if (hist->current && hist->current->prev) {
|
|
hist->current = hist->current->prev;
|
|
return (char *)hist->current->ptr;
|
|
}
|
|
return NULL;
|
|
}
|