/* * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef _WEBDAV_CACHE_H_INCLUDE #define _WEBDAV_CACHE_H_INCLUDE #include #include /*****************************************************************************/ /* define node_head structure */ LIST_HEAD(node_head, node_entry); struct node_entry { LIST_ENTRY(node_entry) entries; /* the other nodes on the parent's children list */ struct node_entry *parent; /* the parent node_entry, or NULL if this is the root node */ LIST_HEAD(, node_entry) children; /* this node's children (if any) */ /* * Node identification fields */ size_t name_length; /* length of name */ char *name; /* the utf8 name */ ino_t fileid; /* file ID number */ webdav_filetype_t node_type; /* (int) either WEBDAV_FILE_TYPE or WEBDAV_DIR_TYPE */ u_int32_t flags; /* * Attribute fields * * Set attr_time to 0 and free the memory used by attr_ref (if any) to invalidate attributes. */ uid_t attr_uid; /* user authorized to use attribute data */ time_t attr_time; /* local time - when attribute data was received from server */ struct stat attr_stat; /* stat attributes */ /* file system specific attribute data */ char *attr_appledoubleheader; /* NULL if no appledoubleheader data */ /* * File cache fields * * Clear the nodeInFileList flag bit and insert into the from the file_list make it a valid cache file. * * Clear the nodeInFileList flag bit and remove from the file_list to invalidate a cache file. Don't forget to free the * file_ref before you free the node. * * A valid cache file can be either active (the file or directory it is a * cache for is open) or inactive (the file or directory it is a cache for * is closed). Active cache files have a file_inactive_time of zero; * inactive cache files have the time the cache file was made inactive so * that they can be aged out of the cache. */ LIST_ENTRY(node_entry) file_list; /* the g_file_list */ int file_fd; /* the cache file's file descriptor or -1 if none */ u_int32_t file_status; /* the status of the cache file download: * WEBDAV_DOWNLOAD_NEVER (never downloaded) * WEBDAV_DOWNLOAD_IN_PROGRESS (download still in progress) * WEBDAV_DOWNLOAD_FINISHED (download complete) * WEBDAV_DOWNLOAD_ABORTED (download was stopped before complete because of close or error) * If WEBDAV_DOWNLOAD_TERMINATED is set, an in-progress download should be stopped. * Note: the download_status field should be word aligned. */ time_t file_validated_time; /* local time - when cache file was last validated by server */ time_t file_inactive_time; /* local time - when cache file was made inactive (the file this cache is for was closed) - 0 if active */ /* file system specific file cache data */ time_t file_last_modified; /* the HTTP-date converted to time_t from the Last-Modified entity-header or from the getlastmodified property, or -1 if no valid Last-Modified date */ char *file_entity_tag; /* The entity-tag from the ETag response-header or from the getetag property */ uid_t file_locktoken_uid; /* the uid associated with the locktoken (filesystem_close and filesystem_lock need it to renew locks and to unlock). */ char *file_locktoken; /* the lock token, or NULL */ }; #define WEBDAV_DOWNLOAD_NEVER 0 #define WEBDAV_DOWNLOAD_IN_PROGRESS 1 #define WEBDAV_DOWNLOAD_FINISHED 2 #define WEBDAV_DOWNLOAD_ABORTED 3 #define WEBDAV_DOWNLOAD_STATUS_MASK 0x7fffffff #define WEBDAV_DOWNLOAD_TERMINATED 0x80000000 /* node_entry flags */ enum { nodeDeletedBit = 0, /* the node is deleted and is on the deleted list */ nodeDeletedMask = 0x00000001, nodeInFileListBit = 1, /* the node is cached and is on the file list */ nodeInFileListMask = 0x00000002 }; /*****************************************************************************/ #define ATTRIBUTES_TIMEOUT_MIN 2 /* Minimum number of seconds attributes are valid */ #define ATTRIBUTES_TIMEOUT_MAX 60 /* Maximum number of seconds attributes are valid */ #define FILE_VALIDATION_TIMEOUT 60 /* Number of seconds file is valid from file_validated_time */ #define FILE_CACHE_TIMEOUT 3600 /* 1 hour */ #define NODE_IS_DELETED(node) (((node)->flags & nodeDeletedMask) != 0) int node_attributes_valid(struct node_entry *node, uid_t uid); #define NODE_FILE_IS_CACHED(node) ( ((node)->flags & nodeInFileListMask) != 0 ) #define NODE_FILE_IS_OPEN(node) ( (node)->file_inactive_time == 0 ) #define NODE_FILE_CACHE_INVALID(node) ( ((node)->file_inactive_time != 0) && \ (time(NULL) >= ((node)->file_inactive_time + FILE_CACHE_TIMEOUT)) ) #define NODE_FILE_INVALID(node) ( ((node)->file_validated_time == 0) || \ (time(NULL) >= ((node)->file_validated_time + FILE_VALIDATION_TIMEOUT)) ) /*****************************************************************************/ int nodecache_init( size_t name_length, /* length of root node name */ char *name, /* the utf8 name of root node */ struct node_entry **root_node); /* the root node */ int nodecache_get_node( struct node_entry *parent, /* the parent node_entry */ size_t name_length, /* length of name */ const char *name, /* the utf8 name of the node */ int make_entry, /* TRUE if a new node_entry should be created if needed*/ webdav_filetype_t node_type, /* if make_entry is TRUE, the type of node to create */ struct node_entry **node); /* the found (or new) node_entry */ void nodecache_free_nodes(void); int nodecache_move_node( struct node_entry *node, /* the node_entry to move */ struct node_entry *new_parent, /* the new parent node_entry */ size_t new_name_length, /* length of new_name or 0 if not renaming */ char *new_name); /* the utf8 new name of the node or NULL */ int nodecache_delete_node( struct node_entry *node); /* the node_entry to delete (and possibly remove) */ int nodecache_add_attributes( struct node_entry *node, /* the node_entry to update or add attributes_entry to */ uid_t uid, /* the uid these attributes are valid for */ struct stat *statp, /* the stat buffer */ char *appledoubleheader); /* pointer appledoubleheader or NULL */ int nodecache_remove_attributes( struct node_entry *node); /* the node_entry to remove attributes from */ void nodecache_invalidate_caches(void); int nodecache_add_file_cache( struct node_entry *node, /* the node_entry to add a file_cache_entry to */ int fd); /* the file descriptor of the cache file */ void nodecache_remove_file_cache( struct node_entry *node); /* the node_entry to remove file_cache_entry from */ struct node_entry *nodecache_get_next_file_cache_node( int get_first); /* if true, return first file cache node; otherwise, the next one */ int nodecache_get_path_from_node( struct node_entry *target_node, /* -> node */ char **path); /* <- relative path to root node */ /*****************************************************************************/ #ifdef DEBUG void nodecache_display_node_tree(void); void nodecache_display_file_cache(void); #endif /*****************************************************************************/ #endif