/* ** 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 */ #include #include #ifdef STDC_HEADERS # include # include #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); }