MY_DIR *my_dir(const char *path, myf MyFlags) { char *buffer; MY_DIR *result= 0; FILEINFO finfo; DYNAMIC_ARRAY *dir_entries_storage; MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; char tmp_path[FN_REFLEN+1],*tmp_file; #ifdef THREAD char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; #endif DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); #if defined(THREAD) && !defined(HAVE_READDIR_R) mysql_mutex_lock(&THR_LOCK_open); #endif dirp = opendir(directory_file_name(tmp_path,(char *) path)); #if defined(__amiga__) if ((dirp->dd_fd) < 0) /* Directory doesn't exists */ goto error; #endif if (dirp == NULL || ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + sizeof(MEM_ROOT), MyFlags))) goto error; dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { my_free(buffer); goto error; } init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; tmp_file=strend(tmp_path); #ifdef THREAD dp= (struct dirent*) dirent_tmp; #else dp=0; #endif while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { if (!(finfo.name= strdup_root(names_storage, dp->d_name))) goto error; if (MyFlags & MY_WANT_STAT) { if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, sizeof(MY_STAT)))) goto error; bzero(finfo.mystat, sizeof(MY_STAT)); (void) strmov(tmp_file,dp->d_name); (void) my_stat(tmp_path, finfo.mystat, MyFlags); if (!(finfo.mystat->st_mode & MY_S_IREAD)) continue; } else finfo.mystat= NULL; if (push_dynamic(dir_entries_storage, (uchar*)&finfo)) goto error; } (void) closedir(dirp); #if defined(THREAD) && !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; result->number_off_files= dir_entries_storage->elements; if (!(MyFlags & MY_DONT_SORT)) my_qsort((void *) result->dir_entry, result->number_off_files, sizeof(FILEINFO), (qsort_cmp) comp_names); DBUG_RETURN(result); error: #if defined(THREAD) && !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif my_errno=errno; if (dirp) (void) closedir(dirp); my_dirend(result); if (MyFlags & (MY_FAE | MY_WME)) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno); DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
MY_DIR *my_dir(const char *path, myf MyFlags) { char *buffer; MY_DIR *result= 0; FILEINFO finfo; DYNAMIC_ARRAY *dir_entries_storage; MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; char tmp_path[FN_REFLEN + 2], *tmp_file; char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); #if !defined(HAVE_READDIR_R) mysql_mutex_lock(&THR_LOCK_open); #endif dirp = opendir(directory_file_name(tmp_path,(char *) path)); if (dirp == NULL || ! (buffer= my_malloc(key_memory_MY_DIR, ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + sizeof(MEM_ROOT), MyFlags))) goto error; dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), NULL, /* init_buffer */ ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { my_free(buffer); goto error; } init_alloc_root(key_memory_MY_DIR, names_storage, NAMES_START_SIZE, NAMES_START_SIZE); /* MY_DIR structure is allocated and completly initialized at this point */ result= (MY_DIR*)buffer; tmp_file=strend(tmp_path); dp= (struct dirent*) dirent_tmp; while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { if (!(finfo.name= strdup_root(names_storage, dp->d_name))) goto error; if (MyFlags & MY_WANT_STAT) { if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, sizeof(MY_STAT)))) goto error; memset(finfo.mystat, 0, sizeof(MY_STAT)); (void) my_stpcpy(tmp_file,dp->d_name); (void) my_stat(tmp_path, finfo.mystat, MyFlags); if (!(finfo.mystat->st_mode & MY_S_IREAD)) continue; } else finfo.mystat= NULL; if (insert_dynamic(dir_entries_storage, (uchar*)&finfo)) goto error; } (void) closedir(dirp); #if !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; result->number_off_files= dir_entries_storage->elements; if (!(MyFlags & MY_DONT_SORT)) my_qsort((void *) result->dir_entry, result->number_off_files, sizeof(FILEINFO), (qsort_cmp) comp_names); DBUG_RETURN(result); error: #if !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif my_errno=errno; if (dirp) (void) closedir(dirp); my_dirend(result); if (MyFlags & (MY_FAE | MY_WME)) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_DIR, MYF(0), path, my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); } DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
my_string directory_file_name (my_string dst, const char *src) { #ifndef VMS /* Process as Unix format: just remove test the final slash. */ my_string end; if (src[0] == 0) src= (char*) "."; /* Use empty as current */ end=strmov(dst, src); if (end[-1] != FN_LIBCHAR) { end[0]=FN_LIBCHAR; /* Add last '/' */ end[1]='\0'; } return dst; #else /* VMS */ long slen; long rlen; my_string ptr, rptr; char bracket; struct FAB fab = cc$rms_fab; struct NAM nam = cc$rms_nam; char esa[NAM$C_MAXRSS]; if (! src[0]) src="[.]"; /* Empty is == current dir */ slen = strlen (src) - 1; if (src[slen] == FN_C_AFTER_DIR || src[slen] == FN_C_AFTER_DIR_2 || src[slen] == FN_DEVCHAR) { /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */ fab.fab$l_fna = src; fab.fab$b_fns = slen + 1; fab.fab$l_nam = &nam; fab.fab$l_fop = FAB$M_NAM; nam.nam$l_esa = esa; nam.nam$b_ess = sizeof esa; nam.nam$b_nop |= NAM$M_SYNCHK; /* We call SYS$PARSE to handle such things as [--] for us. */ if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL) { slen = nam.nam$b_esl - 1; if (esa[slen] == ';' && esa[slen - 1] == '.') slen -= 2; esa[slen + 1] = '\0'; src = esa; } if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2) { /* what about when we have logical_name:???? */ if (src[slen] == FN_DEVCHAR) { /* Xlate logical name and see what we get */ VOID(strmov(dst,src)); dst[slen] = 0; /* remove colon */ if (!(src = getenv (dst))) return dst; /* Can't translate */ /* should we jump to the beginning of this procedure? Good points: allows us to use logical names that xlate to Unix names, Bad points: can be a problem if we just translated to a device name... For now, I'll punt and always expect VMS names, and hope for the best! */ slen = strlen (src) - 1; if (src[slen] != FN_C_AFTER_DIR && src[slen] != FN_C_AFTER_DIR_2) { /* no recursion here! */ VOID(strmov(dst, src)); return(dst); } } else { /* not a directory spec */ VOID(strmov(dst, src)); return(dst); } } bracket = src[slen]; /* End char */ if (!(ptr = strchr (src, bracket - 2))) { /* no opening bracket */ VOID(strmov (dst, src)); return dst; } if (!(rptr = strrchr (src, '.'))) rptr = ptr; slen = rptr - src; VOID(strmake (dst, src, slen)); if (*rptr == '.') { /* Put bracket and add */ dst[slen++] = bracket; /* (rptr+1) after this */ } else { /* If we have the top-level of a rooted directory (i.e. xx:[000000]), then translate the device and recurse. */ if (dst[slen - 1] == ':' && dst[slen - 2] != ':' /* skip decnet nodes */ && strcmp(src + slen, "[000000]") == 0) { dst[slen - 1] = '\0'; if ((ptr = getenv (dst)) && (rlen = strlen (ptr) - 1) > 0 && (ptr[rlen] == FN_C_AFTER_DIR || ptr[rlen] == FN_C_AFTER_DIR_2) && ptr[rlen - 1] == '.') { VOID(strmov(esa,ptr)); esa[rlen - 1] = FN_C_AFTER_DIR; esa[rlen] = '\0'; return (directory_file_name (dst, esa)); } else dst[slen - 1] = ':'; } VOID(strmov(dst+slen,"[000000]")); slen += 8; } VOID(strmov(strmov(dst+slen,rptr+1)-1,".DIR.1")); return dst; } VOID(strmov(dst, src)); if (dst[slen] == '/' && slen > 1) dst[slen] = 0; return dst; #endif /* VMS */ } /* directory_file_name */
MY_DIR *my_dir(const char *path, myf MyFlags) { DIR *dirp; struct dirent *dp; struct fileinfo *fnames; char *buffer, *obuffer, *tempptr; uint fcnt,i,size,firstfcnt, maxfcnt,length; char tmp_path[FN_REFLEN+1],*tmp_file; my_ptrdiff_t diff; bool eof; #ifdef THREAD char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; #endif DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags)); #if defined(THREAD) && !defined(HAVE_READDIR_R) pthread_mutex_lock(&THR_LOCK_open); #endif dirp = opendir(directory_file_name(tmp_path,(my_string) path)); size = STARTSIZE; if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags))) goto error; fcnt = 0; tmp_file=strend(tmp_path); firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / (sizeof(struct fileinfo) + FN_LEN); fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); tempptr = (char *) (fnames + maxfcnt); #ifdef THREAD dp= (struct dirent*) dirent_tmp; #else dp=0; #endif eof=0; for (;;) { while (fcnt < maxfcnt && !(eof= READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { bzero((gptr) (fnames+fcnt),sizeof(fnames[0])); /* for purify */ fnames[fcnt].name = tempptr; tempptr = strmov(tempptr,dp->d_name) + 1; if (MyFlags & MY_WANT_STAT) { VOID(strmov(tmp_file,dp->d_name)); VOID(my_stat(tmp_path, &fnames[fcnt].mystat, MyFlags)); } ++fcnt; } if (eof) break; size += STARTSIZE; obuffer = buffer; if (!(buffer = (char *) my_realloc((gptr) buffer, size, MyFlags | MY_FREE_ON_ERROR))) goto error; /* No memory */ length= (uint) (sizeof(struct fileinfo ) * firstfcnt); diff= PTR_BYTE_DIFF(buffer , obuffer) + (int) length; fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); tempptr= ADD_TO_PTR(tempptr,diff,char*); for (i = 0; i < maxfcnt; i++) fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); /* move filenames upp a bit */ maxfcnt += firstfcnt; bmove_upp(tempptr,tempptr-length, (uint) (tempptr- (char*) (fnames+maxfcnt))); } (void) closedir(dirp); { MY_DIR * s = (MY_DIR *) buffer; s->number_off_files = (uint) fcnt; s->dir_entry = fnames; } if (!(MyFlags & MY_DONT_SORT)) qsort((void *) fnames, (size_s) fcnt, sizeof(struct fileinfo), (qsort_cmp) comp_names); #if defined(THREAD) && !defined(HAVE_READDIR_R) pthread_mutex_unlock(&THR_LOCK_open); #endif DBUG_RETURN((MY_DIR *) buffer); error: #if defined(THREAD) && !defined(HAVE_READDIR_R) pthread_mutex_unlock(&THR_LOCK_open); #endif my_errno=errno; if (dirp) (void) closedir(dirp); if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno); DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */