📄 my_lib.c
字号:
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB This file is public domain and comes with NO WARRANTY of any kind *//* TODO: check for overun of memory for names. *//* Convert MSDOS-TIME to standar time_t */#define USES_TYPES /* sys/types is included */#include "mysys_priv.h"#include <m_string.h>#include <my_dir.h> /* Structs used by my_dir,includes sys/types */#include "mysys_err.h"#if defined(HAVE_DIRENT_H)# include <dirent.h># define NAMLEN(dirent) strlen((dirent)->d_name)#else#ifndef OS2# define dirent direct#endif# define NAMLEN(dirent) (dirent)->d_namlen# if defined(HAVE_SYS_NDIR_H)# include <sys/ndir.h># endif# if defined(HAVE_SYS_DIR_H)# include <sys/dir.h># endif# if defined(HAVE_NDIR_H)# include <ndir.h># endif# if defined(MSDOS) || defined(__WIN__)# include <dos.h># ifdef __BORLANDC__# include <dir.h># endif# endif#endif#ifdef VMS#include <rms.h>#include <iodef.h>#include <descrip.h>#endif#ifdef OS2#include "my_os2dirsrch.h"#endif#if defined(THREAD) && defined(HAVE_READDIR_R)#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)#else#define READDIR(A,B,C) (!(C=readdir(A)))#endif#define STARTSIZE ONCE_ALLOC_INIT*8 /* some mallocmargin */static int comp_names(struct fileinfo *a,struct fileinfo *b); /* We need this because program don't know with malloc we used */void my_dirend(MY_DIR *buffer){ DBUG_ENTER("my_dirend"); if (buffer) my_free((gptr) buffer,MYF(0)); DBUG_VOID_RETURN;} /* my_dirend */ /* Compare in sort of filenames */static int comp_names(struct fileinfo *a, struct fileinfo *b){ return (strcmp(a->name,b->name));} /* comp_names */#if !defined(MSDOS) && !defined(__WIN__)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 *//* * Convert from directory name to filename. * On VMS: * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1 * On UNIX, it's simple: just make sure there is a terminating / * Returns pointer to dst; */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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -