/* * $Id$ */ #include #include #include #if defined(__GNUC__) || defined(__DJGPP__) #include #include #include #include #include #include #include #include #if !defined(HAVE_POSIX_IO) #define HAVE_POSIX_IO #endif #if !defined(FA_RDONLY) #define FA_RDONLY 1 #define FA_HIDDEN 2 #define FA_SYSTEM 4 #define FA_LABEL 8 #define FA_DIREC 16 #define FA_ARCH 32 #endif #define PATH_SEPARATOR '/' #endif #if defined(__WATCOMC__) #include #include #include #include #include #include #if !defined(HAVE_POSIX_IO) #define HAVE_POSIX_IO #endif #define PATH_SEPARATOR '\\' #endif #if defined(__BORLANDC__) #include #include #include #include #include #include #include #include #if !defined(HAVE_POSIX_IO) #define HAVE_POSIX_IO #ifndef S_IEXEC #define S_IEXEC 0x0040 /* owner may execute */ #endif #ifndef S_IRWXU #define S_IRWXU 0x01c0 /* RWE permissions mask for owner */ #endif #ifndef S_IRUSR #define S_IRUSR 0x0100 /* owner may read */ #endif #ifndef S_IWUSR #define S_IWUSR 0x0080 /* owner may write */ #endif #ifndef S_IXUSR #define S_IXUSR 0x0040 /* owner may execute */ #endif #endif #define PATH_SEPARATOR '\\' #endif #ifdef __BORLANDC__ #undef DIRECTORY #endif HARBOUR DIRECTORY( void ) { #if defined(HAVE_POSIX_IO) PHB_ITEM arg1_it = _param(1,IT_STRING); PHB_ITEM arg2_it = _param(2,IT_STRING); extern STACK stack; struct stat statbuf; struct dirent *entry; struct tm *ft; char fullfile[_POSIX_PATH_MAX+1]; char pattern[_POSIX_PATH_MAX+1]; char dirname[_POSIX_PATH_MAX+1]; char filename[_POSIX_PATH_MAX+1]; char pfname[_POSIX_PATH_MAX+1]; char pfext[_POSIX_PATH_MAX+1]; char fname[_POSIX_PATH_MAX+1]; char fext[_POSIX_PATH_MAX+1]; char filesize[10]; char yyear[5]; char mmonth[3]; char dday[3]; char ddate[9]; char hh[3]; char mm[3]; char ss[3]; char ttime[9]; int attrib; char aatrib[7]; char string[_POSIX_PATH_MAX+1]; char * pos; long fsize; DIR * dir; time_t ftime; PHB_ITEM pdir; PHB_ITEM psubarray; PHB_ITEM pfilename; PHB_ITEM psize; PHB_ITEM pdate; PHB_ITEM ptime; PHB_ITEM pattr; dirname[0] = '\0'; pattern[0] = '\0'; if( arg1_it ) { strcpy(string, _parc(1)); pos = strrchr(string,PATH_SEPARATOR); if( pos ) { strcpy(pattern,(pos+1)); string[pos-string+1] = '\0'; strcpy(dirname,string); } else { strcpy(pattern,string); strcpy(dirname,".X"); dirname[1] = PATH_SEPARATOR; } } if (strlen(pattern) < 1) strcpy(pattern,"*.*"); if (strlen(dirname) < 1) { strcpy(dirname,".X"); dirname[1] = PATH_SEPARATOR; } if (strlen(pattern) > 0) { strcpy(string,pattern); pos = strrchr(string,'.'); if( pos ) { strcpy(pfext,(pos+1)); string[pos-string] = '\0'; strcpy(pfname,string); } else { strcpy(pfname,string); pfext[0] = '\0'; } } if (strlen(pfext) < 1) pfext[0] = '\0'; if (strlen(pfname) < 1) strcpy(pfname,"*"); /* debug code printf("\n dirname pattern %s %s ",dirname,pattern); printf("\n pfname pfext %s %s ",pfname,pfext); while(0==getchar()); */ /* should have drive,directory in dirname and filespec in pattern */ pdir = hb_itemArrayNew(0); dir = opendir( dirname ); if (NULL == dir) { printf("\n invalid dirname %s ",dirname); while(0==getchar()); } /* now put everything into an array */ while ((entry = readdir( dir )) != NULL) { strcpy(string,entry->d_name); pos = strrchr(string,'.'); if( pos ) { strcpy(fext,(pos+1)); string[pos-string] = '\0'; strcpy(fname,string); } else { strcpy(fname,string); fext[0] = '\0'; } if (strlen(fext) < 1) fext[0] = '\0'; if (strlen(fname) < 1) strcpy(fname,"*"); /* debug code printf("\n fname fext %s %s ",fname,fext); while(0==getchar()); */ if (hb_strMatchDOS( fname,pfname) && hb_strMatchDOS( fext,pfext)) { ddate[0] = '\0'; ttime[0] = '\0'; aatrib[0] = '\0'; filesize[0] = '\0'; filename[0] = '\0'; attrib = 0; fullfile[0] = '\0'; strcat(filename,entry->d_name); strcat(fullfile,dirname); strcat(fullfile,entry->d_name); if (-1 == stat(fullfile,&statbuf)) { printf("\n invalid file %s ",fullfile); while(0==getchar()); } fsize = statbuf.st_size; ltoa(fsize,filesize,10); ftime = statbuf.st_mtime; ft = localtime(&ftime); itoa(ft->tm_year+1900,yyear,10); strcat(ddate,yyear); itoa(ft->tm_mon,mmonth,10); if (strlen(mmonth) < 2) { strcat(mmonth,"0"); strrev(mmonth); } strcat(ddate,mmonth); itoa(ft->tm_mday,dday,10); if (strlen(dday) < 2) { strcat(dday,"0"); strrev(dday); } strcat(ddate,dday); itoa(ft->tm_hour,hh,10); if (strlen(hh) < 2) { strcat(hh,"0"); strrev(hh); } strcat(ttime,hh); strcat(ttime,":"); itoa(ft->tm_min,mm,10); if (strlen(mm) < 2) { strcat(mm,"0"); strrev(mm); } strcat(ttime,mm); strcat(ttime,":"); itoa(ft->tm_sec,ss,10); if (strlen(ss) < 2) { strcat(ss,"0"); strrev(ss); } strcat(ttime,ss); /* debug code printf("\n name date time %s %s %s ",entry,ddate,ttime); while(0==getchar()); */ /* TODO: seems to not clear on root entries ? */ attrib = _chmod(fullfile,0); if (attrib & FA_ARCH) strcat(aatrib,"A"); if (attrib & FA_DIREC) strcat(aatrib,"D"); if (attrib & FA_HIDDEN) strcat(aatrib,"H"); if (attrib & FA_LABEL) strcat(aatrib,"V"); if (attrib & FA_RDONLY) strcat(aatrib,"R"); if (attrib & FA_SYSTEM) strcat(aatrib,"S"); /* TODO: attribute match rtn */ pos = 0; if( arg2_it && _parclen(2) >= 1) { strcpy(string, _parc(2)); while (string[pos]) string[pos] = toupper(string[pos]); pos = strchr(string,*aatrib); } else pos = 1; if ( pos ) { /* array cname, csize, ddate, ctime, cattributes */ pfilename = hb_itemPutC(NULL,filename); psize = hb_itemPutC(NULL,filesize); pdate = hb_itemPutDS(NULL,ddate); ptime = hb_itemPutC(NULL,ttime); pattr = hb_itemPutC(NULL,aatrib); psubarray = hb_itemArrayNew(5); hb_itemArrayPut(psubarray,1,pfilename); hb_itemArrayPut(psubarray,2,psize); hb_itemArrayPut(psubarray,3,pdate); hb_itemArrayPut(psubarray,4,ptime); hb_itemArrayPut(psubarray,5,pattr); hb_arrayAdd(pdir,psubarray); hb_itemRelease(pfilename); hb_itemRelease(psize); hb_itemRelease(pdate); hb_itemRelease(ptime); hb_itemRelease(pattr); hb_itemRelease(psubarray); } } } closedir( dir ); ItemCopy( &stack.Return, pdir ); /* DIRECTORY() returns an array */ hb_itemRelease(pdir); #endif /* HAVE_POSIX_IO */ return; } static BOOL hb_strMatchDOS (char *pszString, char *pszMask) { while (*pszMask && *pszString) { if (*pszMask == '*') { while (*pszMask == '*') pszMask++; if (!(*pszMask)) return (TRUE); else if (*pszMask == '?') pszString++; else { while (toupper(*pszString) != toupper(*pszMask)) { if (!(*(++pszString))) return (FALSE); } while (toupper(*pszString) == toupper(*pszMask)) { if (!(*(++pszString))) break; } pszMask++; } } else if (toupper(*pszMask) != toupper(*pszString) && *pszMask != '?') return (FALSE); else { pszMask++; pszString++; } } return !((!(*pszString) && *pszMask && *pszMask != '*') || (!(*pszMask) && *pszString)); }