#include "ftptool.h"
#pragma ident "@(#)dircache.c 1.3 93/05/26"
#ifdef USE_PROTOTYPES
int dircache_add(struct dircache *dcache, char *name, struct dirlist *dlist)
#else
int dircache_add(dcache, name, dlist)
struct dircache *dcache;
char *name;
struct dirlist *dlist;
#endif
{
struct dirlist_header *new_header;
struct dirlist_header *last;
if (dircache_size != 0 && dircache_size == dcache->ndirs) {
last = dcache->last;
if (dcache->ndirs == 1) {
dcache->first = NULL;
dcache->last = NULL;
} else {
dcache->last = dcache->last->prev;
dcache->last->next = NULL;
}
free_dirlist_header(last);
dcache->ndirs--;
}
new_header = new_dirlist_header(name, dlist);
if (new_header == NULL)
return (ENOMEM);
if (dcache->ndirs == 0) {
dcache->first = new_header;
dcache->last = new_header;
new_header->next = NULL;
new_header->prev = NULL;
} else {
new_header->prev = NULL;
new_header->next = dcache->first;
dcache->first->prev = new_header;
dcache->first = new_header;
}
dcache->ndirs++;
return (0);
}
#ifdef USE_PROTOTYPES
void dircache_delete(struct dircache *dcache, char *name)
#else
void dircache_delete(dcache, name)
struct dircache *dcache;
char *name;
#endif
{
struct dirlist_header *first;
if (cache_lookup(dcache, name) == NULL)
return;
/* now at top of list */
first = dcache->first;
if (dcache->ndirs == 1) {
dcache->first = NULL;
dcache->last = NULL;
} else {
dcache->first = first->next;
dcache->first->prev = NULL;
}
free_dirlist_header(first);
dcache->ndirs--;
return;
}
#ifdef USE_PROTOTYPES
void dircache_shrink(struct dircache *dcache, int newsize)
#else
void dircache_shrink(dcache, newsize)
struct dircache *dcache;
int newsize;
#endif
{
struct dirlist_header *last;
if (newsize == 0)
return;
while (dcache->ndirs > newsize) {
last = dcache->last;
dcache->last = dcache->last->prev;
dcache->last->next = NULL;
free_dirlist_header(last);
dcache->ndirs--;
}
}
#ifdef USE_PROTOTYPES
void free_dircache(struct dircache *dcache)
#else
void free_dircache(dcache)
struct dircache *dcache;
#endif
{
struct dirlist_header *next;
struct dirlist_header *tmp;
for (tmp = dcache->first; tmp != NULL; /* null */) {
next = tmp->next;
free_dirlist_header(tmp);
tmp = next;
}
dcache->ndirs = 0;
dcache->first = NULL;
dcache->last = NULL;
}
#ifdef USE_PROTOTYPES
struct dirlist *cache_lookup(struct dircache *dcache, char *dirname)
#else
struct dirlist *cache_lookup(dcache, dirname)
struct dircache *dcache;
char *dirname;
#endif
{
struct dirlist_header *tmp;
for (tmp = dcache->first; tmp != NULL; tmp = tmp->next)
if (!strcmp(tmp->name, dirname)) {
/* match! move to top of cache */
if (tmp == dcache->first) {
/* nothing to do */
return (tmp->dlist);
} else if (tmp == dcache->last) {
/* at least 2 */
/* off list */
dcache->last = dcache->last->prev;
dcache->last->next = NULL;
} else {
/* in the middle */
/* off list */
tmp->prev->next = tmp->next;
tmp->next->prev = tmp->prev;
}
/* now add to front */
tmp->next = dcache->first;
tmp->prev = NULL;
dcache->first->prev = tmp;
dcache->first = tmp;
return (tmp->dlist);
}
/* no match */
return (NULL);
}
#ifdef USE_PROTOTYPES
struct dirlist_header *new_dirlist_header(char *name, struct dirlist *dlist)
#else
struct dirlist_header *new_dirlist_header(name, dlist)
char *name;
struct dirlist *dlist;
#endif
{
struct dirlist_header *tmp;
tmp = (struct dirlist_header *)malloc(sizeof (struct dirlist_header));
if (tmp == NULL)
return (NULL);
bzero((char *)tmp, sizeof (struct dirlist_header));
tmp->name = strdup(name);
if (tmp->name == NULL) {
free((char *)tmp);
return (NULL);
}
tmp->next = NULL;
tmp->prev = NULL;
tmp->dlist = dlist;
return (tmp);
}
#ifdef USE_PROTOTYPES
void free_dirlist_header(struct dirlist_header *head)
#else
void free_dirlist_header(head)
struct dirlist_header *head;
#endif
{
free_dirlist(head->dlist);
free(head->name);
free((char *)head);
}
#ifdef notdef
#ifdef USE_PROTOTYPES
void show_dircache(struct dircache *dcache)
#else
void show_dircache(dcache)
struct dircache *dcache;
#endif
{
struct dirlist_header *tmp;
printf("cache contains\n");
printf("--------------\n");
for (tmp = dcache->first; tmp != NULL; tmp = tmp->next) {
printf("%s\n", tmp->name);
}
printf("--------------\n");
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1