static Char filetype(Char *dir, Char *file) { Char path[PATH_MAX]; struct stat statb; Strlcpy(path, dir, sizeof path/sizeof(Char)); catn(path, file, sizeof(path) / sizeof(Char)); if (lstat(short2str(path), &statb) == 0) { switch (statb.st_mode & S_IFMT) { case S_IFDIR: return ('/'); case S_IFLNK: if (stat(short2str(path), &statb) == 0 && /* follow it out */ S_ISDIR(statb.st_mode)) return ('>'); else return ('@'); case S_IFSOCK: return ('='); default: if (statb.st_mode & 0111) return ('*'); } } return (' '); }
int executable(const Char *dir, const Char *name, int dir_ok) { struct stat stbuf; Char path[MAXPATHLEN + 1]; char *strname; char extension[MAXPATHLEN]; char *ptr, *p2 ; int has_ext = 0; extern void copyn(Char *, const Char *, size_t); extern void catn(Char *, const Char *, int); (void) memset(path, 0, sizeof(path)); if (dir && *dir) { copyn(path, dir, MAXPATHLEN); catn(path, name, MAXPATHLEN); p2 = ptr = short2str(path); while (*ptr++) continue; --ptr; while(ptr > p2) { if (*ptr == '/') break; if (*ptr == '.') { has_ext = 1; StringCbCopy(extension,MAXPATHLEN,ptr+1); break; } ptr--; } if (!has_ext && (nt_stat(p2, &stbuf) == -1)) catn(path, STRdotEXE, MAXPATHLEN); strname = short2str(path); } else strname = short2str(name); return (stat(strname, &stbuf) != -1 && ((dir_ok && S_ISDIR(stbuf.st_mode)) || (S_ISREG(stbuf.st_mode) && (is_nt_executable(strname,extension) || (stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR))) ))); }