www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/10/20/13:06:51

Sender: <solyom AT bmeik DOT eik DOT bme DOT hu>
Date: Thu, 20 Oct 1994 14:59:13 +0100
From: "DR. SOLYOM ANDRAS" <solyom AT bmeik DOT eik DOT bme DOT hu>
Reply-To: SOLYOM AT HUBME51 DOT bitnet
To: DJGPP AT SUN DOT soe DOT clarkson DOT edu
Cc: solyom AT bmeik DOT eik DOT bme DOT hu
Subject: LS for DOS

Dear Everyone,

It would really be good to have the unix utilities running on
MSDOS. Or it would even be better if had MSDOS utilities on
MSDOS that works like their UNIX counterpart, but which are
especially developed for MSDOS.

I personally was so in love with the UNIX style file
name globbing that I wrote an LS for DOS for myself, and I am
using it ever since. It is not a complete LS clone, so it has
only a tiny subset of its options ('l','a' and I created a 'd'
options to list only directori
es), and instead of the owner/
group/others set access modes it displays the MSDOS modes:
r/w/x/h/d/a, but you can say that 'ls -la [a-c]*doc' and it
works.

If anyone intrested, here is the code (I hope the comments
in it are good enough for documentation).
To compile it you need a C compiler, this file and the files
FNMATCH.C and FNMATCH.H from the GNU/DJGPP distribution.

(I also wrote a windows 'shell' for the most common DOS commands
 that let me use the UNIX style globbing, so e.g. while ru
nning
 WINDOWS I can type 'copy *a*doc b:' or 'del [^a]*exe' or simply
 'dir *c'. If anyone is interested please contact me! As it uses
 the WINIO Library from the book 'Undocumented Windows' I can only
 send you the EXE file and my source, not the libraries you need
 to compile it)

----------- CUT HERE ----------
/*==========================================================================*/
/* Name: LS.C                   (C) A. S˘lyom                               */
/* Task: LS a'la UNIX. 				
										*/
/*		 To compile as a full program define the macro						*/
/* 			_USE_FNMATCH													*/
/*			and compile it together with FNMATCH.C/FNMATCH.H from the GNU 	*/
/*															sources			*/
/*			Example with Borland C++:
 *			bcc -D_USE_FNMATCH -I(where  FNMATCH.H resides) ls.c fnmatch.c	*/
/* 		 To use it as a function in one of your program define 				*/
/*                      _FUNCTION_VERSION_                                  */
/* ------------- FREE PROGRAM USE AT YOUR OWN RI
SC ----------------			*/
/* Date: 1994  Jan. 27. 09:24:43pm                                          */
/* Changes: 07-29-94 11:08pm option -d to list only directories is added    */
/*==========================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>

#ifdef __TURBOC__
        #include <dos.h>
#endif

#ifdef _USE_FNMATCH
        static char wildcard[128];
        #include "fnmatch.h"
        extern int 
fnmatch(char *, char*, int);
#else
        extern int CreateRanges(char *);
#endif
extern int IsFileNameMatched(char *);

struct _tagFtime {
  unsigned ft_tsec:5;   /* 0-29, double to get real seconds */
  unsigned ft_min:6;    /* 0-59 */
  unsigned ft_hour:5;   /* 0-23 */
};
struct _tagFdate {
  unsigned ft_day:5;    /* 1-31 */
  unsigned ft_month:4;  /* 1-12 */
  unsigned ft_year:7;   /* since 1980 */
};
typedef struct {
        int attrib;
        union {
                struct _tagFti
me fTime;
                unsigned nTime;
                }ft;
        union {
                struct _tagFdate fDate;
                unsigned nDate;
                }fd;
    long lSize;
        char d_name[13];
}MYDIRENT;

static int isAll = 0;                   /* ls -a    hidden files too            */
static int isFull= 0;                   /* ls -l        full names with flags   */
static int onlyDirs= 0;                 /* ls -d        only directories        */
static int columns = 5;

static int numFiles = 0;


#define HIDFLAGS        (FA_HIDDEN | FA_SYSTEM)
/*======================================================================*/
void Usage(char *pszProg)
/* TASK:
 * EXPECTS:
 * GLOBALS:
 * RETURNS:
 */
/*----------------------------------------------------------------------*/
{
        char *p;

        p = strrchr(pszProg, '\\');
        if(!p)
                p = strrchr(pszProg, '/');

        if(!p)
                p = pszProg[1] == ':' ? pszProg+2 : pszProg;

        else
                ++p;
        if( strrchr(pszProg, '.') )
                *strrchr(pszProg, '.') = 0;

        printf("%s - UNIX like 'ls' with full regular expression filename match\n"
                   "(C) A. S˘lyom (1994)\n\n"
                   "Usage: %s [-flags] [path]\n"
                   "      flags:  a - list hidden files too\n"
                   "              l - long list format\n"
                   "              d - list only directories\n"
                   "   
                   ?     - help\n"
                   "      path: partial or full path to directory to be listed with optional\n"
                   "            regular expression template for file names in that directory\n"
                   "            The path must contain forward slashes (/) instead of the\n"
                   "            backslashes (\\) found in DOS names, as the backslash is\n"
                   "            reserved for regular expressions\n"
                   "Special
 characters in filename expressions:\n"
                   "            *     any number of any character\n"
                   "            ?     any character\n"
                   "            \\    escapes special meaning of * or ? or \\ \n"
                   "            []    character groups (e.g. [ax.] or [1-9a-zA-Z]\n"
                   "            [^]   any character that is NOT in group. The '^' character\n"
                   "                  must be the first one in the square bracke
t\n"
                   "Examples: \n"
                   "    %s -l *.[ch]  List all \".c\" and \".h\" files in long format\n"
                   "    %s -l *foo*   List all file names containing \"foo\" (e.g. \"123foo.c\")\n"
                   "    %s -a *       List all hidden and normal files\n"
#if !defined(_FUNCTION_VERSION_)
                   "This program is FREEWARE ! Use it at your own risk!\n"
#endif
                   ,p,p,p,p,p);
#if !defined(_FUNCTION_VERSION_)
        exit(1);
#e
ndif
}
/*======================================================================*/
char *StripFileName(char *ps)
/* separate file name from path
 * RETURNS: pointer to that file name of the path in 'ps'
 *              does not cut path
 */
/*----------------------------------------------------------------------*/
{
        char *p;

        p = strrchr(ps, '\\');
        if(!p)
                p = strrchr(ps, '/');
        if(!p)
                if(ps[1] == ':')
                        p = 
ps+1;
        if(p)
                ++p;
        else
                p = ps;

        return p;
}
/*======================================================================*/
char *_SetupPath(char *s)
/*----------------------------------------------------------------------*/
{
        char *p;
        static char path[80];
        int i;

        strcpy(path, s);

        for(p = s; *p; ++p)
                if(*p == '\\' && *(p+1)!= '\\' && *(p+1)!= '?')
                        *p++ = '/'
;

        p = StripFileName(s);

        path[ p - s] = 0;

        i = 0;
        if( *p == '.' )                         /* "dir .xx" */
        {
                i = 1;
                wildcard[0] = '*';
        }
        strcpy( &wildcard[i], p);
        if(!wildcard[0])
                strcpy(wildcard, "*");
#ifndef _USE_FNMATCH
        if(!CreateRanges(wildcard))
        {
                printf("Bad regular expression: '%s'\n", wildcard);
                return NULL;
        }
#
endif
        strcat(path, "*.*");
        return path;
}
#ifdef _USE_FNMATCH
/*======================================================================*/
int IsFileNameMatched(char *psz)
/*----------------------------------------------------------------------*/
{
//printf("DEBUG\n"
//         "  IsFileNameMatched-> string: '%s'. wildcard: '%s'\n", psz, wildcard);
        return fnmatch(wildcard, psz, FNM_CASEFOLD) ? 0 : 1;
}
#endif
/*=============================================================
=========*/
void BadArgs(char *pszProg)
/* TASK:
 * EXPECTS:
 * GLOBALS:
 * RETURNS:
 */
/*----------------------------------------------------------------------*/
{
        printf("Invalid arguments !\n");
        Usage(pszProg);
}
/*======================================================================*/
void GetOpts(char *pszProg, char *pszOpts)
/* TASK:
 * EXPECTS:
 * GLOBALS:
 * RETURNS:
 */
/*----------------------------------------------------------------------*/
{
        while(
*++pszOpts)       /* skip '-' or to next flag */
        {
                switch(*pszOpts)
                {
                        case 'a' :
                                isAll = 1;
                                break;
                        case 'l':
                                isFull = 1;
                                columns = 1;
                                break;
 /* MOD 07-29-94 11:12pm 3 lines added */
                        case 'd':
                                on
lyDirs = 1;
                                break;
                        default:
                                BadArgs(pszProg);
                                break;
                }
        }
}
/*======================================================================*/
int CompFunc(const void *p1, const void *p2)
/* TASK: Perform directory name compare
 * EXPECTS:
 * GLOBALS:
 * RETURNS:
 */
/*----------------------------------------------------------------------*/
{
        return 
strcmp( ( (MYDIRENT*)p1)->d_name, ( (MYDIRENT*)p2)->d_name);
}
/*======================================================================*/
#ifdef _FUNCTION_VERSION_
int ls(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
/* TASK: Perform directory listing
 * EXPECTS:
 * GLOBALS:
 * RETURNS: main() returns 1 if error, 0 otherwise, ls() returns 0 if error,
 *                      1 otherwise
 */
/*----------------------------------------------------------------------*/
{
    
    DIR *pdir;
        struct dirent *pd;
        MYDIRENT *pdeFiles=NULL, *pTmp;
        char szPath[128];
        char szName[64];
        char *p;
        int i = 1;
        long lSum = 0;
#ifdef _USE_FNMATCH
        extern char *_SetupPath(char *s);
#endif

#ifdef _FUNCTION_VERSION_
        isAll = 0;                                      /* ls -a    hidden files too            */
        isFull= 0;                                      /* ls -l        full names with flags   */
           
     /* MOD 07-29-94 11:23pm 1 line added */
        onlyDirs = 0;                           /* ls -d        list directories only   */
        columns = 5;
        numFiles = 0;
#endif
        if(argc == 1)
                strcpy(szPath,"*");
        else if(argc > 3)
                BadArgs(argv[0]);
        else if(argc == 3 && argv[1][0] != '-' && argv[1][0] != '/')
                BadArgs(argv[0]);
        else if (argc == 2 &&
                        (argv[1][0] == '?' || (argv[1][0] == '-
' && argv[1][0] == '?')) )
        {
                Usage(argv[0]);
#ifdef _FUNCTION_VERSION_
                return 1;
#endif
        }
        else
        {
                if(argc > 1 && argv[1][0] == '-')
                {
                        GetOpts(argv[0], argv[1]);
                        i = 2;
                }
                if(argc > i)
                        strcpy(szPath, argv[i]);
                else
                        strcpy(szPath,"*");
        }

        p
 = strrchr(szPath, '/');
        if(!p)
                p = strrchr(szPath, '\\');

        if(p)
                ++p;
        else if(szPath[1] == ':')
                p = &szPath[2];
        else
                p = szPath;

        strcpy(szName, p);
        *p = 0;
        for(p = szPath; *p; p++)
                if(*p == '/')
                        *p = '\\';

        if(!szName[0])
                strcpy(szName, "*");

#ifdef _USE_FNMATCH
        _SetupPath(szName);             /
* see SH.C */
#else
        if(!CreateRanges(szName))
        {
                printf("ls - Bad regular expression: '%s'\n", szName);
  #ifdef _FUNCTION_VERSION_
                return 0;
  #else
                exit(1);
  #endif
        }
#endif
                /* _USE_FNMATCH */
        if(!szPath[0])
                strcpy(szPath, ".\\");

        pdir = opendir(szPath);
        if(!pdir)
        {
                printf("Directory '%s' does not exist\n");
#ifdef _FUNCTION_VERSION_

                return 0;
#else
                exit(1);
#endif
        }

        while( (pd = readdir(pdir)) != NULL)
        {
#ifdef __TURBOC__
                if(  ( ( ((struct find_t *)pdir)->attrib & FA_LABEL) != 0)
                         ||
                         (
                                !isAll &&
                                 (
                                        ( (( (struct find_t *)pdir)->attrib & HIDFLAGS) != 0) ||
                                        pd->d
_name[0] == '.'
                                 )
                                        /* MOD 07-29-94 11:19pm 5 lines added */
                                   ||
                                (
                                        onlyDirs
                                                &&
                                         (( (struct find_t *)pdir)->attrib & FA_DIREC) == 0
                                )
                         )
                   )
                       
 continue;
#endif
                if( IsFileNameMatched(pd->d_name) )
                {
                        pTmp = pdeFiles;

                        if(!pdeFiles)
                                pTmp = malloc(sizeof(MYDIRENT));
                        else
                                pTmp = realloc(pdeFiles,
                                                                        (numFiles + 1) * sizeof(MYDIRENT));

                        if(pTmp)
                                pdeFil
es = pTmp;
                        else
                        {
                                printf("***** Out of memory...\n");
                                if(pdeFiles)
                                {
                                        printf("Files found so far:\n\n");
                                        break;          /* out of while */
                                }
                                else
                                {
                                 
       closedir(pdir);
#ifdef _FUNCTION_VERSION_
                                        return 0;
#else
                                        exit(1);
#endif
                                }
                        }
                        strcpy( (pdeFiles + numFiles)->d_name, pd->d_name);
                        (pdeFiles + numFiles)->attrib = ( (struct find_t *)pdir)->attrib;
                        (pdeFiles + numFiles)->fd.nDate =
                                                        
        ( (struct find_t *)pdir)->wr_date;
                        (pdeFiles + numFiles)->ft.nTime =
                                                                ( (struct find_t *)pdir)->wr_time;
                        /* MOD 08-02-94 07:43pm 1 line
                         *      (pdeFiles + numFiles++)->lSize = ( (struct find_t *)pdir)->size;
                         */
                        lSum += (pdeFiles + numFiles++)->lSize = ( (struct find_t *)pdir)->size;
                }
        }
 /* while */
        closedir(pdir);

        if(numFiles)
        {
                int i,j;
                char *p;

                qsort( (void *) pdeFiles, numFiles, sizeof(MYDIRENT), CompFunc);

                pTmp = pdeFiles;
                        /* MOD 08-02-94 07:45pm 2 lines added */
                if(lSum && isFull)
                        printf("total: %ld\n", lSum);

                for( i = 0; i < numFiles; i += columns)
                {
                        for(j =
 0; j < columns && (j+i) < numFiles; j++)
                        {
                                if( (pTmp->attrib & FA_DIREC) == 0 )
                                                strlwr(pTmp->d_name);

                                if(isFull)
                                {
                                        if(pTmp->attrib & FA_DIREC)
                                                fputchar('d');
                                        else
                                         
       fputchar('-');
                                        fputchar('r');  /* all DOS file can be read */
                                        if(pTmp->attrib & FA_RDONLY)
                                                fputchar('-');
                                        else
                                                fputchar('w');
                                        p = strchr(pTmp->d_name, '.');
                                        if(p)
                                      
  {
                                                ++p;
                                                if(strcmp(p, "com") == 0 || stricmp(p, "exe") == 0 ||
                                                                                                        stricmp(p, "bat") == 0)
                                                {
                                                        fputchar('x');
                                                }
                                               
 else
                                                        fputchar('-');
                                        }
                                        else if(pTmp->attrib & FA_DIREC)
                                                fputchar('x');
                                        else
                                                fputchar('-');

                                        if(pTmp->attrib & FA_HIDDEN)
                                                fputchar('h');
      
                                  else
                                                fputchar('-');
                                        if(pTmp->attrib & FA_SYSTEM)
                                                fputchar('s');
                                        else
                                                fputchar('-');
                                        if(pTmp->attrib & FA_ARCH)
                                                fputchar('a');
                                
        else
                                                fputchar('-');

                                        printf("\   %7lu   %02d-%02d-%02d   %02d:%02d \t%-15s",
                                                                        pTmp->lSize,
                                                                        pTmp->fd.fDate.ft_month,
                                                                        pTmp->fd.fDate.ft_day,
                                                       
                 pTmp->fd.fDate.ft_year+80,
                                                                        pTmp->ft.fTime.ft_hour,
                                                                        pTmp->ft.fTime.ft_min,
                                                                        pTmp->d_name);
                                }
                                else
                                {
                                        printf("%-15s", pTmp->d_name);
      
                          }
                                ++pTmp;
                        }
                        printf("\n");
                }
                free(pdeFiles);
        }
#ifdef _FUNCTION_VERSION_
        return 1;
#else
        return 0;
#endif
}
----------- CUT HERE ----------

			Adras Solyom


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019