From 546ad9e70afde83f4df3eade950f560c49b3c88c Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Fri, 21 Apr 2006 23:50:36 +0000 Subject: [PATCH] Apparently I need to specify add/deletions too... svn path=/trunk/netsurf/; revision=2541 --- riscos/filename.h | 22 ---- {riscos => utils}/filename.c | 236 +++++++++++++++++------------------ utils/filename.h | 25 ++++ 3 files changed, 138 insertions(+), 145 deletions(-) delete mode 100644 riscos/filename.h rename {riscos => utils}/filename.c (61%) create mode 100644 utils/filename.h diff --git a/riscos/filename.h b/riscos/filename.h deleted file mode 100644 index f53025af8..000000000 --- a/riscos/filename.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of NetSurf, http://netsurf.sourceforge.net/ - * Licensed under the GNU General Public License, - * http://www.opensource.org/licenses/gpl-license - * Copyright 2005 Richard Wilson - */ - -#ifndef _NETSURF_RISCOS_FILENAME_H_ -#define _NETSURF_RISCOS_FILENAME_H_ - -#include - -#define CACHE_FILENAME_PREFIX ".WWW.NetSurf.Cache" - -char *ro_filename_request(void); -bool ro_filename_claim(const char *filename); -void ro_filename_release(const char *filename); -bool ro_filename_initialise(void); -void ro_filename_flush(void); - - -#endif diff --git a/riscos/filename.c b/utils/filename.c similarity index 61% rename from riscos/filename.c rename to utils/filename.c index f52d85a5e..88e1191c8 100644 --- a/riscos/filename.c +++ b/utils/filename.c @@ -2,7 +2,7 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2005 Richard Wilson + * Copyright 2006 Richard Wilson */ /** \file @@ -11,15 +11,15 @@ * A maximum of 2^24 files can be allocated at any point in time. */ +#include #include #include #include #include -#include "oslib/hourglass.h" -#include "oslib/osgbpb.h" -#include "oslib/osfile.h" -#include "netsurf/riscos/filename.h" +#include +#include "netsurf/utils/filename.h" #include "netsurf/utils/log.h" +#include #define FULL_WORD (unsigned int)4294967295 /* '0' + '0' * 10 */ @@ -27,7 +27,7 @@ struct directory { int numeric_prefix; /** numeric representation of prefix */ - char prefix[10]; /** directory prefix, eg '00.11.52.' */ + char prefix[10]; /** directory prefix, eg '00/11/52/' */ unsigned int low_used; /** first 32 files, 1 bit per file */ unsigned int high_used; /** last 32 files, 1 bit per file */ struct directory *next; /** next directory (sorted by prefix) */ @@ -35,19 +35,19 @@ struct directory { static struct directory *root = NULL; -static char ro_filename_buffer[12]; -static char ro_filename_directory[256]; +static char filename_buffer[12]; +static char filename_directory[256]; -static struct directory *ro_filename_create_directory(const char *prefix); -static bool ro_filename_flush_directory(const char *folder, int depth); -static bool ro_filename_delete_recursive(char *folder); +static struct directory *filename_create_directory(const char *prefix); +static bool filename_flush_directory(const char *folder, int depth); +static bool filename_delete_recursive(char *folder); /** * Request a new, unique, filename. * * \return a pointer to a shared buffer containing the new filename */ -char *ro_filename_request(void) { +char *filename_request(void) { struct directory *dir; int i = -1; @@ -63,7 +63,7 @@ char *ro_filename_request(void) { } if (i == -1) { /* no available slots - create a new directory */ - dir = ro_filename_create_directory(NULL); + dir = filename_create_directory(NULL); if (!dir) { LOG(("Failed to create a new directory.")); return NULL; @@ -74,8 +74,8 @@ char *ro_filename_request(void) { dir->low_used |= (1 << i); else dir->high_used |= (1 << (i - 32)); - sprintf(ro_filename_buffer, "%s%.2i", dir->prefix, i); - return ro_filename_buffer; + sprintf(filename_buffer, "%s%.2i", dir->prefix, i); + return filename_buffer; } @@ -85,18 +85,18 @@ char *ro_filename_request(void) { * \param filename the filename to claim * \return whether the claim was successful */ -bool ro_filename_claim(const char *filename) { +bool filename_claim(const char *filename) { char dir_prefix[9]; int file; struct directory *dir; - /* filename format is always '01.23.45.XX' */ + /* filename format is always '01/23/45/XX' */ strncpy(dir_prefix, filename, 9); dir_prefix[9] = '\0'; file = (filename[10] + filename[9] * 10 - START_PREFIX); /* create the directory */ - dir = ro_filename_create_directory(dir_prefix); + dir = filename_create_directory(dir_prefix); if (!dir) return false; @@ -119,11 +119,11 @@ bool ro_filename_claim(const char *filename) { * * \param filename the filename to release */ -void ro_filename_release(const char *filename) { +void filename_release(const char *filename) { struct directory *dir; int index, file; - /* filename format is always '01.23.45.XX' */ + /* filename format is always '01/23/45/XX' */ index = ((filename[7] + filename[6] * 10 - START_PREFIX) | ((filename[4] + filename[3] * 10 - START_PREFIX) << 6) | ((filename[1] + filename[0] * 10 - START_PREFIX) << 12)); @@ -144,11 +144,23 @@ void ro_filename_release(const char *filename) { /** * Initialise the filename provider. */ -bool ro_filename_initialise(void) { - /* create the 'CACHE_FILENAME_PREFIX' structure */ - xosfile_create_dir(".WWW", 0); - xosfile_create_dir(".WWW.NetSurf", 0); - xosfile_create_dir(".WWW.NetSurf.Cache", 0); +bool filename_initialise(void) { + char *directory, *start; + + directory = strdup(TEMP_FILENAME_PREFIX); + if (!directory) + return false; + + for (start = directory; *start != '\0'; *start++) { + if (*start == '/') { + *start = '\0'; + mkdir(directory, S_IRWXU); + *start = '/'; + } + } + LOG((directory)); + mkdir(directory, S_IRWXU); + free(directory); return true; } @@ -156,10 +168,8 @@ bool ro_filename_initialise(void) { /** * Deletes all files in the cache directory that are not accounted for. */ -void ro_filename_flush(void) { - xhourglass_on(); - while (ro_filename_flush_directory(CACHE_FILENAME_PREFIX, 0)); - xhourglass_off(); +void filename_flush(void) { + while (filename_flush_directory(TEMP_FILENAME_PREFIX, 0)); } @@ -173,16 +183,14 @@ void ro_filename_flush(void) { * \param depth the folder depth * \returns whether further calls may be needed */ -bool ro_filename_flush_directory(const char *folder, int depth) { +bool filename_flush_directory(const char *folder, int depth) { + DIR *parent; + struct dirent *entry; bool changed = false; bool del; int number, i; int prefix = 0; unsigned int prefix_mask = (63 << 12); - int context = 0; - int read_count; - osgbpb_INFO(100) info; - os_error *error; char child[256]; const char *prefix_start = NULL; struct directory *dir = NULL; @@ -191,7 +199,7 @@ bool ro_filename_flush_directory(const char *folder, int depth) { if (depth > 0) prefix_start = folder + strlen(folder) - depth * 3 + 1; for (i = 0; ((i < depth) && (i < 3)); i++) { - number = prefix_start[1] + prefix_start[0] * 10 - START_PREFIX; + number = prefix_start[1] + prefix_start[0] * 10 - START_PREFIX; prefix |= (number << (12 - i * 6)); prefix_mask |= (63 << (6 - i * 6)); prefix_start += 3; @@ -204,35 +212,26 @@ bool ro_filename_flush_directory(const char *folder, int depth) { return false; } - while (context != -1) { - /* read some directory info */ - error = xosgbpb_dir_entries_info(folder, - (osgbpb_info_list *) &info, 1, context, - sizeof(info), 0, &read_count, &context); - if (error) { - LOG(("xosgbpb_dir_entries_info: 0x%x: %s", - error->errnum, error->errmess)); - if (error->errnum == 0xd6) /* no such dir */ - return false; - break; - } - /* ensure we read some data */ - if (read_count == 0) + parent = opendir(folder); + + while ((entry = readdir(parent))) { + if ((entry->d_ino == 0) || (!strcmp(entry->d_name, ".")) || + (!strcmp(entry->d_name, ".."))) continue; + /* first 3 depths are directories only, then files only */ - del = false; - if (depth < 3) { - if (info.obj_type != fileswitch_IS_DIR) - del = true; - } else { - if (info.obj_type != fileswitch_IS_FILE) - del = true; - } + if (depth < 3) + del = (entry->d_type != DT_DIR); + else + del = (entry->d_type == DT_DIR); + /* check we are a file numbered '00' -> '63' */ - if ((!del) && (info.name[0] >= '0') && (info.name[0] <= '6') && - (info.name[1] >= '0') && (info.name[1] <= '9') && - (info.name[2] == '\0')) { - number = atoi(info.name); + if ((!del) && (entry->d_name[0] >= '0') && + (entry->d_name[0] <= '6') && + (entry->d_name[1] >= '0') && + (entry->d_name[1] <= '9') && + (entry->d_name[2] == '\0')) { + number = atoi(entry->d_name); if ((number >= 0) && (number <= 63)) { if (depth == 3) { if (number < 32) @@ -242,7 +241,7 @@ bool ro_filename_flush_directory(const char *folder, int depth) { del = !(dir->high_used & (1 << (number - 32))); } else { - del = true; + del = true; prefix &= ~(63 << (12 - depth * 6)); prefix |= (number << (12 - depth * 6)); for (dir = root; dir; dir = dir->next) { @@ -261,24 +260,24 @@ bool ro_filename_flush_directory(const char *folder, int depth) { del = true; } /* continue if we are a valid reference so far */ - if ((!del) && (info.obj_type != fileswitch_IS_DIR)) + if ((!del) && (entry->d_type != DT_DIR)) continue; /* delete or recurse */ - snprintf(child, 256, "%s.%s", folder, info.name); + snprintf(child, 256, "%s/%s", folder, entry->d_name); child[255] = '\0'; if (del) { - if (info.obj_type == fileswitch_IS_DIR) - ro_filename_delete_recursive(child); - error = xosfile_delete(child, 0, 0, 0, 0, 0); - if (error) - LOG(("xosfile_delete: 0x%x: %s", - error->errnum, error->errmess)); + if (entry->d_type == DT_DIR) + filename_delete_recursive(child); + if (remove(child)) + LOG(("Failed to remove '%s'", child)); else changed = true; } else { - while (ro_filename_flush_directory(child, depth + 1)); + while (filename_flush_directory(child, depth + 1)); } } + + closedir(parent); return changed; } @@ -289,42 +288,33 @@ bool ro_filename_flush_directory(const char *folder, int depth) { * \param directory the directory to delete * \return true on success, false otherwise */ -bool ro_filename_delete_recursive(char *folder) { - int context = 0; - int read_count; - osgbpb_INFO(100) info; - os_error *error; +bool filename_delete_recursive(char *folder) { + DIR *parent; + struct dirent *entry; char child[256]; - while (context != -1) { - /* read the first entry */ - error = xosgbpb_dir_entries_info(folder, - (osgbpb_info_list *) &info, 1, 0, - sizeof(info), 0, &read_count, &context); - if (error) { - LOG(("xosgbpb_dir_entries_info: 0x%x: %s", - error->errnum, error->errmess)); - if (error->errnum == 0xd6) /* no such dir */ - return false; - break; - } - /* ensure we read some data */ - if (read_count == 0) + parent = opendir(folder); + + while ((entry = readdir(parent))) { + if ((entry->d_ino == 0) || (!strcmp(entry->d_name, ".")) || + (!strcmp(entry->d_name, ".."))) continue; - snprintf(child, 256, "%s.%s", folder, info.name); - /* recurse for files */ - if (info.obj_type == fileswitch_IS_DIR) { - if (!ro_filename_delete_recursive(child)) - return false; + snprintf(child, 256, "%s/%s", folder, entry->d_name); + if (entry->d_type == DT_DIR) { + if (!filename_delete_recursive(child)) { + closedir(parent); + return false; + } } - error = xosfile_delete(child, 0, 0, 0, 0, 0); - if (error) { - LOG(("xosfile_delete: 0x%x: %s", - error->errnum, error->errmess)); + if (remove(child)) { + LOG(("Failed to remove '%s'", child)); + closedir(parent); return false; } - } - return true; + } + + closedir(parent); + return true; } @@ -335,14 +325,13 @@ bool ro_filename_delete_recursive(char *folder) { * \return a new directory structure, or NULL on memory exhaustion * * Empty directories are never deleted, except by an explicit call to - * ro_filename_flush(). + * filename_flush(). */ -static struct directory *ro_filename_create_directory(const char *prefix) { +static struct directory *filename_create_directory(const char *prefix) { char *last_1, *last_2; int index; struct directory *old_dir, *new_dir, *prev_dir = NULL; char dir_prefix[16]; - os_error *error; /* get the lowest unique prefix, or use the provided one */ if (!prefix) { @@ -350,13 +339,13 @@ static struct directory *ro_filename_create_directory(const char *prefix) { prev_dir = old_dir, old_dir = old_dir->next) if (old_dir->numeric_prefix != index) break; - sprintf(dir_prefix, "%.2i.%.2i.%.2i.", + sprintf(dir_prefix, "%.2i/%.2i/%.2i/", ((index >> 12) & 63), ((index >> 6) & 63), ((index >> 0) & 63)); prefix = dir_prefix; } else { - /* prefix format is always '01.23.45.' */ + /* prefix format is always '01/23/45/' */ index = ((prefix[7] + prefix[6] * 10 - START_PREFIX) | ((prefix[4] + prefix[3] * 10 - START_PREFIX) << 6) | ((prefix[1] + prefix[0] * 10 - START_PREFIX) << 12)); @@ -392,33 +381,34 @@ static struct directory *ro_filename_create_directory(const char *prefix) { * create the child. */ if ((prev_dir) && (!strncmp(prev_dir->prefix, new_dir->prefix, 6))) { new_dir->prefix[8] = '\0'; - sprintf(ro_filename_directory, "%s.%s", - CACHE_FILENAME_PREFIX, new_dir->prefix); - new_dir->prefix[8] = '.'; - error = xosfile_create_dir(ro_filename_directory, 0); - /* the user has probably deleted the parent directory whilst - * we are running if there is an error, so we don't report this - * yet and try to create the structure normally. */ - if (!error) + sprintf(filename_directory, "%s/%s", + TEMP_FILENAME_PREFIX, + new_dir->prefix); + new_dir->prefix[8] = '/'; + if (!mkdir(filename_directory, S_IRWXU)) return new_dir; - LOG(("xosfile_create_dir: 0x%x: %s", - error->errnum, error->errmess)); + + /* the user has probably deleted the parent directory whilst + * we are running if there is an error, so we don't report + * this yet and try to create the structure normally. */ + LOG(("Failed to create optimised structure '%s'", + filename_directory)); } /* create the directory structure */ - sprintf(ro_filename_directory, "%s.", CACHE_FILENAME_PREFIX); - last_1 = ro_filename_directory + strlen(CACHE_FILENAME_PREFIX) + 1; + sprintf(filename_directory, "%s/", + TEMP_FILENAME_PREFIX); + last_1 = filename_directory + strlen(TEMP_FILENAME_PREFIX) + 1; last_2 = new_dir->prefix; for (int i = 0; i < 3 && *last_2; i++) { *last_1++ = *last_2++; - while (*last_2 && *last_2 != '.') + while (*last_2 && *last_2 != '/') *last_1++ = *last_2++; if (*last_2) { last_1[0] = '\0'; - error = xosfile_create_dir(ro_filename_directory, 0); - if (error) { - LOG(("xosfile_create_dir: 0x%x: %s", - error->errnum, error->errmess)); + if (mkdir(filename_directory, S_IRWXU)) { + LOG(("Failed to create directory '%s'", + filename_directory)); return NULL; } } diff --git a/utils/filename.h b/utils/filename.h new file mode 100644 index 000000000..ef5b7090a --- /dev/null +++ b/utils/filename.h @@ -0,0 +1,25 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2006 Richard Wilson + */ + +#ifndef _NETSURF_UTILS_FILENAME_H_ +#define _NETSURF_UTILS_FILENAME_H_ + +#include + +#ifdef riscos +#define TEMP_FILENAME_PREFIX "/WWW/NetSurf/Cache" +#else +#define TEMP_FILENAME_PREFIX "/tmp/WWW/NetSurf/Cache" +#endif + +char *filename_request(void); +bool filename_claim(const char *filename); +void filename_release(const char *filename); +bool filename_initialise(void); +void filename_flush(void); + +#endif