/*
** Copyright 2000-2004 University of Illinois Board of Trustees
** Copyright 2000-2004 Mark D. Roth
** All rights reserved.
**
** ftpdir.c - FTP directory access code
**
** Mark D. Roth <roth@feep.net>
*/
#include <internal.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <string.h>
# include <stdlib.h>
#endif
struct ftpdir
{
fget_list_t *fd_l; /* directory list */
fget_listptr_t fd_lp; /* internal pointer */
off_t fd_offset; /* number of entries scanned so far */
unsigned short fd_eof; /* boolean EOF indicator */
};
/* open directory */
int
ftp_opendir(FTPDIR **ftpdir, FTP *ftp, char *dir)
{
file_info_t *fip;
fget_hash_t *file_h;
fget_hashptr_t hp;
#ifdef DEBUG
printf("==> ftp_opendir(ftpdir=0x%lx, ftp=0x%lx, dir=\"%s\")\n",
ftpdir, ftp, dir);
#endif
if (dir == NULL || strlen(dir) == 0)
{
errno = EINVAL;
return -1;
}
if (_ftp_dircache_find_dir(ftp, dir, &file_h) == -1)
return -1;
if (file_h == NULL)
{
errno = EACCES;
return -1;
}
*ftpdir = (FTPDIR *)calloc(1, sizeof(FTPDIR));
if (*ftpdir == NULL)
return -1;
(*ftpdir)->fd_l = fget_list_new(LIST_QUEUE, NULL);
fget_listptr_reset(&(*ftpdir)->fd_lp);
fget_hashptr_reset(&hp);
while (fget_hash_next(file_h, &hp) != 0)
{
fip = (file_info_t *)fget_hashptr_data(&hp);
fget_list_add((*ftpdir)->fd_l, strdup(fip->fi_filename));
#ifdef DEBUG
printf(" ftp_opendir(): fip->fi_filename = \"%s\"\n",
fip->fi_filename);
#endif
}
#ifdef DEBUG
printf("<== ftp_opendir(): success\n");
#endif
return 0;
}
/* read directory */
int
ftp_readdir(FTPDIR *ftpdir, struct ftpdirent *ftpdirent)
{
int retval;
#ifdef DEBUG
printf("==> ftp_readdir(ftpdir=0x%lx, ftpdirent=0x%lx)\n",
ftpdir, ftpdirent);
#endif
if (ftpdir->fd_eof)
return 0;
ftpdir->fd_offset++;
retval = fget_list_next(ftpdir->fd_l, &ftpdir->fd_lp);
if (retval == 0)
ftpdir->fd_eof = 1;
else
ftpdirent->fd_name = (char *)fget_listptr_data(&ftpdir->fd_lp);
#ifdef DEBUG
printf("<== ftp_readdir(): returning %d (ftpdirent->fd_name=\"%s\")\n",
retval, ftpdirent->fd_name);
#endif
return retval;
}
/* rewind directory */
void
ftp_rewinddir(FTPDIR *ftpdir)
{
ftp_seekdir(ftpdir, 0);
}
/* tell where we are in the directory */
off_t
ftp_telldir(FTPDIR *ftpdir)
{
return ftpdir->fd_offset;
}
/* seek to a given point in the directory */
void
ftp_seekdir(FTPDIR *ftpdir, off_t loc)
{
struct ftpdirent fde;
if (loc < ftpdir->fd_offset)
{
fget_listptr_reset(&ftpdir->fd_lp);
ftpdir->fd_offset = 0;
}
while (ftpdir->fd_offset < loc && ftp_readdir(ftpdir, &fde) != 0);
}
/* close directory */
void
ftp_closedir(FTPDIR *ftpdir)
{
#ifdef DEBUG
printf("=== ftp_closedir(ftpdir=0x%lx)\n", ftpdir);
#endif
fget_list_free(ftpdir->fd_l, free);
free(ftpdir);
}
syntax highlighted by Code2HTML, v. 0.9.1