--- import/iodump.c.old 2005-07-04 09:09:34.000000000 +0200 +++ import/iodump.c 2005-11-20 23:35:22.000000000 +0100 @@ -52,139 +52,217 @@ static int verbose_flag=TC_QUIET; -static DIR *dir=NULL; +typedef struct tcdirlist_ TCDirList; +struct tcdirlist_ { + DIR *dir; /* for internal use */ + + const char *dir_name; /* saved base path */ + const char *path_sep; /* optional *nix path separator */ + + char filename[PATH_MAX + 2]; + /* + * full path of file actually under focus + optional separator + + * final string terminator + */ + char **entries; + /* array of full PATHs of files in scanned dirlist */ + + int nfiles; /* (current) number of files in dirlist */ + int findex; /* index of file under focus */ + int buffered; + /* boolean flag: above array of file in directory is valid? */ +}; -static char filename[PATH_MAX+2]; -static char **rbuf_ptr; - -static int nfiles=0, findex=0, buffered=0; - -int open_directory(char *dir_name) +static int compare_name(const void *file1_ptr, const void *file2_ptr) { - if((dir = opendir(dir_name))==NULL) return(-1); - return(0); + return strcoll(*(const char **)file1_ptr, *(const char **)file2_ptr); } -static char *scan_directory(char *dir_name) -{ - struct dirent *dent; - char *end_of_dir; - int len; - - if (dir_name == 0) return NULL; - if (dir == 0) return NULL; - - len = strlen( dir_name ); - end_of_dir = &dir_name[ len - 1 ]; - - if ( *end_of_dir != '/' ) { - end_of_dir++; - *end_of_dir = '/'; - end_of_dir++; - *end_of_dir = 0; - } - - switch(buffered) { - - case 0: - - while((dent = readdir( dir ))!=NULL) { - - if((strncmp(dent->d_name, ".", 1)==0) || (strcmp(dent->d_name, "..")==0)) - continue; - - snprintf(filename, sizeof(filename), "%s%s", dir_name, dent->d_name); +static int tc_dirlist_next(TCDirList *tcdir) +{ + struct dirent *dent = NULL; + int have_file = 0; - //counter - ++nfiles; - - return(filename); - } - - break; - - case 1: - - if (findex < nfiles) { - return(rbuf_ptr[findex++]); - } else { - return(NULL); - } + if (tcdir == NULL) { + return -1; + } - break; - } - - return(NULL); + do { + dent = readdir(tcdir->dir); + if (dent == NULL) { + break; /* all entries in dirlist have been processed */ + } + + if ((strncmp(dent->d_name, ".", 1) != 0) + && (strcmp(dent->d_name, "..") != 0)) { + /* discard special files */ + have_file = 1; + } + + } while (!have_file); + + if (have_file) { + int res = snprintf(tcdir->filename, sizeof(tcdir->filename), + "%s%s%s", tcdir->dir_name, tcdir->path_sep, + dent->d_name); + /* enforce string terminator */ + tcdir->filename[sizeof(tcdir->filename)] = '\0'; + tc_test_string(__FILE__, __LINE__, + sizeof(tcdir->filename), res, errno); + return 0; + } + return 1; } - -static int compare_name(char **file1_ptr, char **file2_ptr) +static int tc_dirlist_sortbuf(TCDirList *tcdir) { - return strcoll(*file1_ptr, *file2_ptr); -} + int n = 0; + if (tcdir == NULL) { + return -1; + } -int sortbuf_directory(char *dir_name) -{ - struct dirent *dent; - char *end_of_dir; - int n, len; + tcdir->entries = malloc(tcdir->nfiles * sizeof(char *)); + if (tcdir->entries == NULL) { + fprintf(stderr, "(%s) can't allocate memory for " + "directory entries\n", __FILE__); + return -1; + } - int (*func) (); - - if (dir_name == 0) return(-1); - if (dir == 0) return(-1); - if(nfiles == 0) return(-1); - - len = strlen( dir_name ); - end_of_dir = &dir_name[ len - 1 ]; - - if ( *end_of_dir != '/' ) { - end_of_dir++; - *end_of_dir = '/'; - end_of_dir++; - *end_of_dir = 0; - } - - if((rbuf_ptr = (char **) calloc(nfiles, sizeof(char *)))==NULL) { - perror("out of memory"); - return(-1); - } - - n=0; + while (tc_dirlist_next(tcdir) == 0) { + tcdir->entries[n] = strdup(tcdir->filename); + if (tcdir->entries[n] == NULL) { + fprintf(stderr, "(%s) can't memorize dirlist entry " + "for '%s'\n", __FILE__, + tcdir->filename); + } + n++; + } - while((dent = readdir( dir ))!=NULL) { - - if((strncmp(dent->d_name, ".", 1)==0) || (strcmp(dent->d_name, "..")==0)) - continue; - - snprintf(filename, sizeof(filename), "%s%s", dir_name, dent->d_name); - rbuf_ptr[n++] = strdup(filename); - } - - // sorting + qsort(tcdir->entries, tcdir->nfiles, sizeof(char *), compare_name); - func = compare_name; + tcdir->buffered = 1; + tcdir->findex = 0; - qsort(rbuf_ptr, nfiles, sizeof(char *), func); + return 0; +} + +static int tc_dirlist_set_path_sep(TCDirList *tcdir) +{ + size_t len = 0; + char end_of_dir; - buffered=1; - findex=0; + len = strlen(tcdir->dir_name); + if (len == 0) { + return -1; + } - return(0); + end_of_dir = tcdir->dir_name[len - 1]; + if (end_of_dir == '/') { + tcdir->path_sep = ""; + } else { + tcdir->path_sep = "/"; + } + + return 0; +} + +static int tc_dirlist_file_count(TCDirList *tcdir) +{ + if (tcdir == NULL) { + return -1; + } + return tcdir->nfiles; } -void close_directory() +static int tc_dirlist_open(TCDirList *tcdir, const char *dirname) +{ + int ret; + + if (tcdir == NULL) { + return -1; + } + + tcdir->filename[0] = '\0'; + tcdir->entries = NULL; + tcdir->nfiles = 0; + tcdir->findex = 0; + tcdir->buffered = 0; + tcdir->dir_name = dirname; + + ret = tc_dirlist_set_path_sep(tcdir); + if (ret != 0) { + return ret; + } + + tcdir->dir = opendir(dirname); + if (tcdir->dir == NULL) { + return -1; + } + + rewinddir(tcdir->dir); + while (tc_dirlist_next(tcdir) == 0) { + tcdir->nfiles++; + } + rewinddir(tcdir->dir); + + return 0; +} + +static void tc_dirlist_close(TCDirList *tcdir) { - if(dir!=NULL) closedir(dir); - dir=NULL; + if (tcdir != NULL) { + if (tcdir->buffered == 1) { + int i = 0; + for (i = 0; i < tcdir->nfiles; i++) { + if (tcdir->entries[i] != NULL) { + /* should be always true */ + free(tcdir->entries[i]); + tcdir->nfiles--; + } + } + + if (tcdir->entries != NULL) { + /* should be always true */ + free(tcdir->entries); + } + + if (tcdir->nfiles > 0) { + /* should never happen */ + fprintf(stderr, "(%s) left out %i directory entries", + __FILE__, tcdir->nfiles); + } + } + + if (tcdir->dir != NULL) { + closedir(tcdir->dir); + tcdir->dir = NULL; + } + } } -void freebuf_directory() +static char *tc_dirlist_scan(TCDirList *tcdir) { - free(rbuf_ptr); + char *ret = NULL; + + if (tcdir == NULL) { + return NULL; + } + + if (tcdir->buffered == 0) { + if (tc_dirlist_next(tcdir) == 0) { + ret = tcdir->filename; + } + } else { /* tcdir->buffered == 0 */ + /* buffered */ + if (tcdir->findex < tcdir->nfiles) { + ret = tcdir->entries[tcdir->findex++]; + } + } + + return ret; } /* ------------------------------------------------------------ @@ -203,6 +281,7 @@ info_t ipipe_avi; + TCDirList tcdir; #ifdef NET_STREAM struct sockaddr_in sin; struct hostent *hp; @@ -326,13 +405,13 @@ //PASS 1: check file type - file order not important - if((open_directory(ipipe->name))<0) { + if(tc_dirlist_open(&tcdir, ipipe->name)<0) { fprintf(stderr, "(%s) unable to open directory \"%s\"\n", __FILE__, ipipe->name); exit(1); } else if(verbose_flag & TC_DEBUG) fprintf(stderr, "(%s) scanning directory \"%s\"\n", __FILE__, ipipe->name); - while((name=scan_directory(ipipe->name))!=NULL) { + while((name=tc_dirlist_scan(&tcdir))!=NULL) { if((ipipe->fd_in = open(name, O_RDONLY))<0) { perror("file open"); @@ -386,7 +465,7 @@ } // check itype } // process files - close_directory(); + tc_dirlist_close(&tcdir); if(!found) { fprintf(stderr,"\nerror: no valid files found in %s\n", name); @@ -398,17 +477,17 @@ //PASS 2: dump files in correct order - if((open_directory(ipipe->name))<0) { + if(tc_dirlist_open(&tcdir, ipipe->name)<0) { fprintf(stderr, "(%s) unable to sort directory entries\"%s\"\n", __FILE__, name); exit(1); } - if((sortbuf_directory(ipipe->name))<0) { + if(tc_dirlist_sortbuf(&tcdir)<0) { fprintf(stderr, "(%s) unable to sort directory entries\"%s\"\n", __FILE__, name); exit(1); } - while((name=scan_directory(ipipe->name))!=NULL) { + while((name=tc_dirlist_scan(&tcdir))!=NULL) { if((ipipe->fd_in = open(name, O_RDONLY))<0) { perror("file open"); @@ -480,9 +559,8 @@ close(ipipe->fd_in); }//process files - - close_directory(); - freebuf_directory(); + + tc_dirlist_close(&tcdir); break; } @@ -492,24 +570,25 @@ int fileinfo_dir(char *dname, int *fd, long *magic) { char *name=NULL; + TCDirList tcdir; //check file type - file order not important - if((open_directory(dname))<0) { + if(tc_dirlist_open(&tcdir, dname)<0) { fprintf(stderr, "(%s) unable to open directory \"%s\"\n", __FILE__, dname); exit(1); } else if(verbose_flag & TC_DEBUG) fprintf(stderr, "(%s) scanning directory \"%s\"\n", __FILE__, dname); - if((name=scan_directory(dname))==NULL) return(-1); + if((name=tc_dirlist_scan(&tcdir))==NULL) return(-1); if((*fd= open(name, O_RDONLY))<0) { perror("open file"); return(-1); } - close_directory(); + tc_dirlist_close(&tcdir); //first valid magic must be the same for all //files to follow, but is not checked here