mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
163 lines
3.5 KiB
C
163 lines
3.5 KiB
C
/* Internal bookmarks support - default file format backend */
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "elinks.h"
|
|
|
|
#include "bfu/dialog.h"
|
|
#include "bookmarks/bookmarks.h"
|
|
#include "bookmarks/backend/common.h"
|
|
#include "bookmarks/backend/default.h"
|
|
#include "util/file.h"
|
|
#include "util/memory.h"
|
|
#include "util/string.h"
|
|
|
|
#define BOOKMARKS_FILENAME "bookmarks"
|
|
|
|
|
|
/* Loads the bookmarks from file */
|
|
static void
|
|
read_bookmarks_default(FILE *f)
|
|
{
|
|
/* INBUF_SIZE = max. title length + 1 byte for separator
|
|
* + max. url length + 1 byte for separator + 5 bytes for depth
|
|
* + 1 byte for end of line + 1 byte for null char + reserve */
|
|
#define INBUF_SIZE ((MAX_STR_LEN - 1) + 1 + (MAX_STR_LEN - 1) + 1 + 5 + 1 + 1 \
|
|
+ MAX_STR_LEN)
|
|
unsigned char in_buffer[INBUF_SIZE]; /* read buffer */
|
|
struct bookmark *last_bm = NULL;
|
|
int last_depth = 0;
|
|
|
|
/* TODO: Ignore lines with bad chars in title or url (?). -- Zas */
|
|
while (fgets(in_buffer, INBUF_SIZE, f)) {
|
|
unsigned char *title = in_buffer;
|
|
unsigned char *url;
|
|
unsigned char *depth_str;
|
|
int depth = 0;
|
|
unsigned char *flags = NULL;
|
|
unsigned char *line_end;
|
|
|
|
/* Load URL. */
|
|
|
|
url = strchr(in_buffer, '\t');
|
|
|
|
/* If separator is not found, or title is empty or too long,
|
|
* skip that line. */
|
|
if (!url || url == in_buffer
|
|
|| url - in_buffer > MAX_STR_LEN - 1)
|
|
continue;
|
|
*url = '\0';
|
|
url++;
|
|
|
|
/* Load depth. */
|
|
|
|
depth_str = strchr(url, '\t');
|
|
if (depth_str && depth_str - url > MAX_STR_LEN - 1)
|
|
continue;
|
|
|
|
if (depth_str) {
|
|
*depth_str = '\0';
|
|
depth_str++;
|
|
depth = atoi(depth_str);
|
|
int_bounds(&depth, 0, last_bm ? last_depth + 1 : 0);
|
|
|
|
/* Load flags. */
|
|
|
|
flags = strchr(depth_str, '\t');
|
|
if (flags) {
|
|
*flags = '\0';
|
|
flags++;
|
|
}
|
|
} else {
|
|
depth_str = url;
|
|
}
|
|
|
|
/* Load EOLN. */
|
|
|
|
line_end = strchr(flags ? flags : depth_str, '\n');
|
|
if (!line_end)
|
|
continue;
|
|
*line_end = '\0';
|
|
|
|
{
|
|
struct bookmark *root = NULL;
|
|
|
|
if (depth > 0) {
|
|
if (depth == last_depth) {
|
|
root = last_bm->root;
|
|
} else if (depth > last_depth) {
|
|
root = last_bm;
|
|
} else {
|
|
while (last_depth - depth) {
|
|
last_bm = last_bm->root;
|
|
last_depth--;
|
|
}
|
|
root = last_bm->root;
|
|
}
|
|
}
|
|
last_bm = add_bookmark(root, 1, title, url);
|
|
last_depth = depth;
|
|
|
|
if (!*url && title[0] == '-' && title[1] == '\0') {
|
|
last_bm->box_item->type = BI_SEPARATOR;
|
|
|
|
} else {
|
|
while (flags && *flags && last_bm) {
|
|
switch (*flags) {
|
|
case 'F':
|
|
last_bm->box_item->type = BI_FOLDER;
|
|
break;
|
|
case 'E':
|
|
last_bm->box_item->expanded = 1;
|
|
break;
|
|
}
|
|
flags++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#undef INBUF_SIZE
|
|
}
|
|
|
|
/* Saves the bookmarks to file */
|
|
static void
|
|
write_bookmarks_default(struct secure_save_info *ssi,
|
|
struct list_head *bookmarks_list)
|
|
{
|
|
int folder_state = get_opt_bool("bookmarks.folder_state");
|
|
struct bookmark *bm;
|
|
|
|
foreach (bm, *bookmarks_list) {
|
|
secure_fprintf(ssi, "%s\t%s\t%d\t", bm->title, bm->url, bm->box_item->depth);
|
|
if (bm->box_item->type == BI_FOLDER) {
|
|
secure_fputc(ssi, 'F');
|
|
if (folder_state && bm->box_item->expanded)
|
|
secure_fputc(ssi, 'E');
|
|
}
|
|
secure_fputc(ssi, '\n');
|
|
if (ssi->err) break;
|
|
|
|
if (!list_empty(bm->child))
|
|
write_bookmarks_default(ssi, &bm->child);
|
|
}
|
|
}
|
|
|
|
static unsigned char *
|
|
filename_bookmarks_default(int writing)
|
|
{
|
|
return BOOKMARKS_FILENAME;
|
|
}
|
|
|
|
|
|
struct bookmarks_backend default_bookmarks_backend = {
|
|
filename_bookmarks_default,
|
|
read_bookmarks_default,
|
|
write_bookmarks_default,
|
|
};
|