int glob(const char *_pattern, int _flags, int (*_errfunc)(const char *_epath, int _eerrno), glob_t *_pglob) { char path_buffer[2000]; int l_ofs, l_ptr; pathbuf = path_buffer+1; flags = _flags; errfunc = _errfunc; wildcard_nesting = 0; save_count = 0; save_list = 0; preserve_case = (char)_preserve_fncase(); slash = '/'; if (!(_flags & GLOB_APPEND)) { _pglob->gl_pathc = 0; _pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) _pglob->gl_offs = 0; } if (glob2(_pattern, pathbuf, preserve_case ? 0 : 1, /*preserve_case ? 0 :*/1) == GLOB_NOSPACE) { return GLOB_NOSPACE; } if (save_count == 0) { if (flags & GLOB_NOCHECK) { if (add(_pattern)) return GLOB_NOSPACE; } else return GLOB_NOMATCH; } if (flags & GLOB_DOOFFS) l_ofs = _pglob->gl_offs; else l_ofs = 0; if (flags & GLOB_APPEND) { _pglob->gl_pathv = (char **)realloc(_pglob->gl_pathv, (l_ofs + _pglob->gl_pathc + save_count + 1) * sizeof(char *)); if (_pglob->gl_pathv == 0) return GLOB_NOSPACE; l_ptr = l_ofs + _pglob->gl_pathc; } else { _pglob->gl_pathv = (char* *)malloc((l_ofs + save_count + 1) * sizeof(char *)); if (_pglob->gl_pathv == 0) return GLOB_NOSPACE; l_ptr = l_ofs; if (l_ofs) memset(_pglob->gl_pathv, 0, l_ofs * sizeof(char *)); } l_ptr += save_count; _pglob->gl_pathv[l_ptr] = 0; while (save_list) { Save *s = save_list; l_ptr --; _pglob->gl_pathv[l_ptr] = save_list->entry; save_list = save_list->prev; free(s); } if (!(flags & GLOB_NOSORT)) qsort(_pglob->gl_pathv + l_ptr, save_count, sizeof(char *), str_compare); _pglob->gl_pathc = l_ptr + save_count; return 0; }
/** * canonpath: make canonical path name. * * @param[in,out] path path * @return path * * @attention canonpath() rewrite argument buffer. */ char * canonpath(char *path) { #ifdef __DJGPP__ char *p; if (_USE_LFN) { char name[260], sfn[13]; char *base; /* * Ensure we're using a complete long name, not a mixture * of long and short. */ _truename(path, path); /* * _truename will successfully convert the path of a non- * existant file, but it's probably still a mixture of long and * short components - convert the path separately. */ if (access(path, F_OK) != 0) { base = basename(path); strcpy(name, base); *base = '\0'; _truename(path, path); strcat(path, name); } /* * Convert the case of 8.3 names, as other djgpp functions do. */ if (!_preserve_fncase()) { for (p = path+3, base = p-1; *base; p++) { if (*p == '\\' || *p == '\0') { memcpy(name, base+1, p-base-1); name[p-base-1] = '\0'; if (!strcmp(_lfn_gen_short_fname(name, sfn), name)) { while (++base < p) if (*base >= 'A' && *base <= 'Z') *base += 'a' - 'A'; } else base = p; } } } } /* * Lowercase the drive letter and convert to slashes. */ path[0] = tolower(path[0]); for (p = path+2; *p; ++p) if (*p == '\\') *p = '/'; #else #ifdef _WIN32 char *p, *s; p = path; /* * Change \ to / in a path (for DOS/Windows paths) */ while ((p = strchr(p, '\\')) != NULL) *p = '/'; #ifdef __CYGWIN__ /* * On NT with CYGWIN, getcwd can return something like * "//c/tmp", which isn't usable. We change that to "c:/tmp". */ p = path; if (p[0] == '/' && p[1] == '/' && isdrivechar(p[2]) && p[3] == '/') { s = &p[2]; /* point drive char */ *p++ = *s++; *p++ = ':'; while (*p++ = *s++) ; } #endif /* __CYGWIN__ */ #endif /* _WIN32 */ #endif /* __DJGPP__ */ return path; }