Subversion Repositories DevTools

Rev

Rev 227 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
/* MS-DOS GLOB (3C) FUNCTION
2
 *
3
 * MS-DOS GLOB FUNCTION - Copyright (c) 1990,4 Data Logic Limited.
4
 *
5
 * This code is subject to the following copyright restrictions:
6
 *
7
 * 1.  Redistribution and use in source and binary forms are permitted
8
 *     provided that the above copyright notice is duplicated in the
9
 *     source form.
10
 *
11
 *    $Header: /cvsroot/device/DEVL/UTILS/SH/GLOB.C,v 1.1 2002/08/02 06:49:31 adamy Exp $
12
 *
13
 *    $Log: GLOB.C,v $
14
 *    Revision 1.1  2002/08/02 06:49:31  adamy
15
 *    imported (reference only)
16
 *
17
 *    Revision 1.1  2001/07/20 05:55:41  ayoung
18
 *    WIN32 support
19
 *
20
 *    Revision 1.1.1.1  1999/12/02 01:11:12  gordonh
21
 *    UTIL
22
 *
23
 * Revision 2.3  1994/08/25  20:49:11  istewart
24
 * MS Shell 2.3 Release
25
 *
26
 * Revision 2.2  1994/02/01  10:25:20  istewart
27
 * Release 2.3 Beta 2, including first NT port
28
 *
29
 * Revision 2.1  1993/06/14  10:59:32  istewart
30
 * More changes for 223 beta
31
 *
32
 * Revision 2.0  1992/04/13  17:39:09  Ian_Stewartson
33
 * MS-Shell 2.0 Baseline release
34
 *
35
 */
36
 
5659 dpurdie 37
#include <sys/types.h>                  /* MS-DOS type definitions      */
38
#include <sys/stat.h>                   /* File status definitions      */
39
#include <stdio.h>                      /* Standard I/O delarations     */
40
#include <stdlib.h>                     /* Standard library functions   */
41
#include <string.h>                     /* String library functions     */
42
#include <limits.h>                     /* String library functions     */
43
#include <dirent.h>                     /* Direction I/O functions      */
44
#include <ctype.h>                      /* Character types function     */
45
#include <unistd.h>                     /* Other functions              */
227 dpurdie 46
 
47
#ifdef __TURBOC__
5659 dpurdie 48
#  include <alloc.h>                    /* Malloc functions             */
49
#  include <dir.h>                      /* Dos directory functions      */
227 dpurdie 50
#else
5659 dpurdie 51
#  include <malloc.h>                   /* Malloc functions             */
227 dpurdie 52
#endif
53
 
54
#include <glob.h>
55
 
56
#if defined (MSDOS) || defined (__OS2__) || defined (__TURBOC__) || defined (WIN32)
57
#  if defined (OS2) || defined (__OS2__)
58
 
59
#    define INCL_DOSDEVICES
60
#    define INCL_DOSMISC
5659 dpurdie 61
#    include <os2.h>                    /* OS2 functions declarations       */
227 dpurdie 62
 
63
#    if defined (__OS2__)
5659 dpurdie 64
#      define DISABLE_HARD_ERRORS       DosError (FERR_DISABLEHARDERR)
65
#      define ENABLE_HARD_ERRORS        DosError (FERR_ENABLEHARDERR)
227 dpurdie 66
#    else
5659 dpurdie 67
#      define DISABLE_HARD_ERRORS       DosError (HARDERROR_DISABLE)
68
#      define ENABLE_HARD_ERRORS        DosError (HARDERROR_ENABLE)
227 dpurdie 69
#    endif
70
 
71
#  elif defined (WIN32)
72
#  include <windows.h>
5659 dpurdie 73
#  define DISABLE_HARD_ERRORS   SetErrorMode (0)
74
#  define ENABLE_HARD_ERRORS    SetErrorMode (SEM_FAILCRITICALERRORS | \
75
                                              SEM_NOOPENFILEERRORBOX);
227 dpurdie 76
 
77
#  else
5659 dpurdie 78
#    include <bios.h>                   /* DOS BIOS functions           */
79
#    include <dos.h>                    /* DOS functions                */
227 dpurdie 80
#    define DISABLE_HARD_ERRORS
81
#    define ENABLE_HARD_ERRORS
82
#  endif
83
#endif
84
 
85
/*
86
 * OS/2 2.x has these missing
87
 */
88
 
89
#ifndef S_IFMT
5659 dpurdie 90
#  define       S_IFMT  0xf000  /* type of file                         */
227 dpurdie 91
#endif
92
 
93
#ifndef S_ISDIR
5659 dpurdie 94
#  define S_ISDIR(m)    ((((m) & S_IFMT) == S_IFDIR))
227 dpurdie 95
#endif
96
 
97
/*
98
 * Functions
99
 */
100
 
5659 dpurdie 101
static int      _GP_SortCompare         _PROTO ((char **, char **));
102
static int      _GP_ExpandField         _PROTO ((char *, char *, glob_t *));
103
static int      _GP_ExpandMetaCharacters _PROTO ((char *, glob_t *));
104
static int      _GP_AddArgument         _PROTO ((char *, glob_t *));
105
static bool     _GP_MatchPattern        _PROTO ((char *, char *));
106
static bool     _GP_access              _PROTO ((char *, int));
107
static bool     _GP_stat                _PROTO ((char *, struct stat *));
227 dpurdie 108
 
5659 dpurdie 109
static char     *_GP_MetaChars = "?*[\\";
110
static char     *_GP_NullString = "";
227 dpurdie 111
 
112
#if defined (MSDOS) || defined (__OS2__) || defined (__TURBOC__) || defined (WIN32)
5659 dpurdie 113
static  int     _GP_GetNumberofFloppyDrives (void);
227 dpurdie 114
 
115
#  if defined (OS2) || defined (__OS2__) || defined (__TURBOC__) || defined (WIN32)
5659 dpurdie 116
static void      _dos_setdrive (unsigned int, unsigned int *);
117
static void      _dos_getdrive (unsigned int *);
227 dpurdie 118
#  endif
119
 
5659 dpurdie 120
static char     *_GP_CheckForMultipleDrives     _PROTO ((char *));
227 dpurdie 121
#endif
122
 
123
/*
124
 * There appears to be no alloca in TurboC
125
 */
126
 
127
#if defined(__TURBOC__) || defined(WIN32)
5659 dpurdie 128
#  define alloca(x)             malloc (x)
129
#  define alloca_free(x)        free (x)
227 dpurdie 130
#else
131
#  define alloca_free(x)
132
#endif
133
 
134
/*
135
 * Free up space
136
 */
137
 
5659 dpurdie 138
void    globfree (gp)
139
glob_t  *gp;
227 dpurdie 140
{
5659 dpurdie 141
    int         i = (gp->gl_flags & GLOB_DOOFFS) ? gp->gl_offs : 0;
227 dpurdie 142
 
143
    while (i < gp->gl_pathc)
5659 dpurdie 144
        free (gp->gl_pathv[i++]);
227 dpurdie 145
 
146
    free (gp->gl_pathv);
147
}
148
 
149
/* Main search function */
150
 
5659 dpurdie 151
int     glob (Pattern, flags, ErrorFunction, gp)
152
char    *Pattern;
153
int     flags;
154
int     (*ErrorFunction) _PROTO ((char *, int));
155
glob_t  *gp;
227 dpurdie 156
{
5659 dpurdie 157
    int         ReturnValue;
158
    char        *PatternCopy;
159
    char        *cp;
227 dpurdie 160
 
161
/* If no append mode - initialise */
162
 
163
    if (!(flags & GLOB_APPEND))
164
    {
5659 dpurdie 165
        gp->gl_pathc = 0;
166
        gp->gl_pathv = (char **)NULL;
227 dpurdie 167
    }
168
 
169
    gp->gl_flags = flags;
170
    gp->gl_ef = ErrorFunction;
171
 
172
    if ((PatternCopy = alloca (strlen (Pattern) + 1)) == (char *)NULL)
5659 dpurdie 173
        return GLOB_NOSPACE;
227 dpurdie 174
 
175
/* Expand and kill environment */
176
 
177
    if (ReturnValue = _GP_ExpandMetaCharacters (strcpy (PatternCopy, Pattern),
5659 dpurdie 178
                                                gp))
227 dpurdie 179
    {
5659 dpurdie 180
        alloca_free (PatternCopy);
181
        return ReturnValue;
227 dpurdie 182
    }
183
 
184
/* Check for no finds.  If add value, strip out \ from the string */
185
 
186
    if ((gp->gl_pathc == 0) && (flags & GLOB_NOCHECK))
187
    {
5659 dpurdie 188
        cp = strcpy (PatternCopy, Pattern);
227 dpurdie 189
 
5659 dpurdie 190
        while ((cp = strpbrk (cp, "?*[")) != (char *)NULL)
191
        {
192
            if ((cp == PatternCopy) || (*(cp - 1) != '\\'))
193
                cp++;
227 dpurdie 194
 
5659 dpurdie 195
            else
196
                memmove (cp - 1, cp, strlen (cp) + 1);
197
        }
227 dpurdie 198
 
5659 dpurdie 199
        if (ReturnValue = _GP_AddArgument (PatternCopy, gp))
200
        {
201
            alloca_free (PatternCopy);
202
            return ReturnValue;
203
        }
227 dpurdie 204
    }
205
 
206
/* Terminate string */
207
 
208
    if ((gp->gl_pathc != 0) &&
5659 dpurdie 209
        (ReturnValue = _GP_AddArgument ((char *)NULL, gp)))
227 dpurdie 210
    {
5659 dpurdie 211
        alloca_free (PatternCopy);
212
        return ReturnValue;
227 dpurdie 213
    }
214
 
215
/* Get the sort length */
216
 
217
    ReturnValue = (gp->gl_flags & GLOB_DOOFFS) ? gp->gl_offs : 0;
218
 
219
    if ((!(flags & GLOB_NOSORT)) && (gp->gl_pathc > 1))
5659 dpurdie 220
        qsort (&gp->gl_pathv[ReturnValue], gp->gl_pathc, sizeof (char *),
221
               (int (*) (const void *, const void *)) _GP_SortCompare);
227 dpurdie 222
 
223
    alloca_free (PatternCopy);
224
    return 0;
225
}
226
 
227
/* Compare function for sort */
228
 
5659 dpurdie 229
static int      _GP_SortCompare (a1, a2)
230
char            **a1, **a2;
227 dpurdie 231
{
232
    return strcmp (*a1, *a2);
233
}
234
 
235
/* Expand a field if it has metacharacters in it */
236
 
5659 dpurdie 237
static int      _GP_ExpandField (CurrentDirectoryPattern, AppendString, gp)
238
char            *CurrentDirectoryPattern;       /* Prefix field         */
239
char            *AppendString;                  /* Postfix field        */
240
glob_t          *gp;
227 dpurdie 241
{
5659 dpurdie 242
    int                 i;
243
    int                 ReturnValue = 0;        /* Return Value         */
244
    char                *FullFileName;          /* Search file name     */
245
    char                *FileNameStart;
246
    char                *MatchString;           /* Match string         */
247
    DIR                 *DirHandler;
248
    struct dirent       *CurrentDirectoryEntry;
227 dpurdie 249
 
250
#if defined (MSDOS) || defined (__OS2__) || defined (__TURBOC__) || defined (WIN32)
5659 dpurdie 251
    unsigned int        CurrentDrive;           /* Current drive        */
252
    unsigned int        MaxDrives;              /* Max drive            */
253
    unsigned int        SelectedDrive;          /* Selected drive       */
254
    unsigned int        x_drive, y_drive;       /* Dummies              */
255
    char                *DriveCharacter;        /* Multi-drive flag     */
256
    char                SDriveString[2];
227 dpurdie 257
 
258
/* Convert file name to lower case */
259
 
260
#  if defined (OS2) || defined (__OS2__) || (WIN32)
261
    if (!IsHPFSFileSystem (CurrentDirectoryPattern))
5659 dpurdie 262
        strlwr (CurrentDirectoryPattern);
227 dpurdie 263
#  else
264
    strlwr (CurrentDirectoryPattern);
265
#  endif
266
 
267
/* Search all drives ? */
268
 
269
    if ((DriveCharacter = _GP_CheckForMultipleDrives (CurrentDirectoryPattern))
5659 dpurdie 270
                != (char *)NULL)
227 dpurdie 271
    {
5659 dpurdie 272
        _dos_getdrive (&CurrentDrive);  /* Get number of drives         */
273
        _dos_setdrive (CurrentDrive, &MaxDrives);
274
        SDriveString[1] = 0;
227 dpurdie 275
 
5659 dpurdie 276
        for (SelectedDrive = 1; SelectedDrive <= MaxDrives; ++SelectedDrive)
277
        {
278
            _dos_setdrive (SelectedDrive, &x_drive);
279
            _dos_getdrive (&y_drive);
280
            _dos_setdrive (CurrentDrive, &x_drive);
227 dpurdie 281
 
282
/* Check to see if the second diskette drive is really there */
283
 
5659 dpurdie 284
            if ((_GP_GetNumberofFloppyDrives () < 2) && (SelectedDrive == 2))
285
                continue;
227 dpurdie 286
 
287
/* If the drive exists and is in our list - process it */
288
 
5659 dpurdie 289
            *DriveCharacter = 0;
290
            *SDriveString = (char)(SelectedDrive + 'a' - 1);
291
            strlwr (CurrentDirectoryPattern);
227 dpurdie 292
 
5659 dpurdie 293
            if ((y_drive == SelectedDrive) &&
294
                _GP_MatchPattern (SDriveString, CurrentDirectoryPattern))
295
            {
296
                if ((FullFileName = alloca (strlen (DriveCharacter) + 3))
297
                                == (char *)NULL)
298
                    return GLOB_NOSPACE;
227 dpurdie 299
 
5659 dpurdie 300
                *DriveCharacter = ':';
301
                *FullFileName = *SDriveString;
302
                strcpy (FullFileName + 1, DriveCharacter);
227 dpurdie 303
 
5659 dpurdie 304
                i = _GP_ExpandField (FullFileName, AppendString, gp);
305
                alloca_free (FullFileName);
227 dpurdie 306
 
5659 dpurdie 307
                if (i)
308
                    return i;
309
            }
227 dpurdie 310
 
5659 dpurdie 311
            *DriveCharacter = ':';
312
        }
227 dpurdie 313
 
5659 dpurdie 314
        return 0;
227 dpurdie 315
    }
316
#endif
317
 
318
/* Get the path length */
319
 
320
    MatchString = strrchr (CurrentDirectoryPattern, '/');
321
 
322
#if defined (MSDOS) || defined (__OS2__) || defined (__TURBOC__) || defined (WIN32)
323
    if ((MatchString == (char *)NULL) &&
5659 dpurdie 324
        (*(CurrentDirectoryPattern + 1) == ':'))
325
        MatchString = CurrentDirectoryPattern + 1;
227 dpurdie 326
#endif
327
 
328
/* Set up file name for search */
329
 
330
    if ((MatchString == (char *)NULL) || (*MatchString == ':'))
331
    {
5659 dpurdie 332
        if ((FullFileName = alloca (NAME_MAX + 7 +
333
                                    strlen (AppendString))) == (char *)NULL)
334
            return GLOB_NOSPACE;
227 dpurdie 335
 
5659 dpurdie 336
        if (MatchString != (char *)NULL)
337
            *(strcpy (FullFileName, "x:.")) = *CurrentDirectoryPattern;
227 dpurdie 338
 
5659 dpurdie 339
        else
340
            strcpy (FullFileName, ".");
227 dpurdie 341
 
5659 dpurdie 342
        FileNameStart = FullFileName +
343
                        (int)((MatchString != (char *)NULL) ? 2 : 0);
227 dpurdie 344
    }
345
 
346
/* Case of /<directory>/... */
347
 
348
    else if ((FullFileName = alloca (NAME_MAX + 4 + strlen (AppendString) +
5659 dpurdie 349
                            (i = (int)(MatchString - CurrentDirectoryPattern))))
350
                        == (char *)NULL)
351
            return GLOB_NOSPACE;
227 dpurdie 352
 
353
    else
354
    {
5659 dpurdie 355
        strncpy (FullFileName, CurrentDirectoryPattern, i);
356
        *((FileNameStart = FullFileName + i)) = 0;
357
        strcpy (FileNameStart++, "/");
227 dpurdie 358
    }
359
 
360
    MatchString = (MatchString == (char *)NULL) ? CurrentDirectoryPattern
5659 dpurdie 361
                                                : MatchString + 1;
227 dpurdie 362
 
363
/* Search for file names */
364
 
365
    if ((DirHandler = opendir (FullFileName)) == (DIR *)NULL)
366
    {
5659 dpurdie 367
        i = 0;
227 dpurdie 368
 
5659 dpurdie 369
        if (((gp->gl_ef != NULL) && (*gp->gl_ef)(FullFileName, errno)) ||
370
            (gp->gl_flags & GLOB_ERR))
371
            i = GLOB_ABEND;
227 dpurdie 372
 
5659 dpurdie 373
        alloca_free (FullFileName);
374
        return i;
227 dpurdie 375
    }
376
 
377
/* Are there any matches */
378
 
379
    while ((CurrentDirectoryEntry = readdir (DirHandler)) !=
5659 dpurdie 380
            (struct dirent *)NULL)
227 dpurdie 381
    {
5659 dpurdie 382
        if ((*CurrentDirectoryEntry->d_name == '.') && (*MatchString != '.'))
383
            continue;
227 dpurdie 384
 
385
/* Check for match */
386
 
5659 dpurdie 387
        if (_GP_MatchPattern (CurrentDirectoryEntry->d_name, MatchString))
388
        {
389
            strcpy (FileNameStart, CurrentDirectoryEntry->d_name);
227 dpurdie 390
 
391
/* If the postfix is not null, this must be a directory */
392
 
5659 dpurdie 393
            if (strlen (AppendString))
394
            {
395
                struct stat             statb;
396
                char                    *p;
227 dpurdie 397
 
398
/* If not a directory - go to the next file */
399
 
5659 dpurdie 400
                if (!_GP_stat (FullFileName, &statb) ||
401
                    !S_ISDIR (statb.st_mode & S_IFMT))
402
                    continue;
227 dpurdie 403
 
404
/* Are there any metacharacters in the postfix? */
405
 
5659 dpurdie 406
                if ((p = strpbrk (AppendString, _GP_MetaChars)) == (char *)NULL)
407
                {
227 dpurdie 408
 
409
/* No - build the file name and check it exists */
410
 
5659 dpurdie 411
                    strcat (strcat (FileNameStart, "/"), AppendString);
227 dpurdie 412
 
5659 dpurdie 413
                    if (_GP_access (FullFileName, F_OK) &&
414
                        (ReturnValue = _GP_AddArgument (FullFileName, gp)))
415
                        break;
416
                }
227 dpurdie 417
 
418
/* Yes - build the filename upto the start of the meta characters */
419
 
5659 dpurdie 420
                else
421
                {
422
                    if ((p = strchr (p, '/')) != (char *)NULL)
423
                        *(p++) = 0;
227 dpurdie 424
 
5659 dpurdie 425
                    else
426
                        p = _GP_NullString;
227 dpurdie 427
 
428
/* Build the new directory name and check it out */
429
 
5659 dpurdie 430
                    strcat (strcat (FileNameStart, "/"), AppendString);
431
                    ReturnValue = _GP_ExpandField (FullFileName, p, gp);
227 dpurdie 432
 
5659 dpurdie 433
                    if (p != _GP_NullString)
434
                       *(--p) = '/';
227 dpurdie 435
 
436
/* Check for errors */
437
 
5659 dpurdie 438
                    if (ReturnValue)
439
                        break;
440
                }
441
            }
227 dpurdie 442
 
443
/* Process this file.  If error - terminate */
444
 
5659 dpurdie 445
            else if (_GP_access (FullFileName, F_OK) &&
446
                     (ReturnValue = _GP_AddArgument (FullFileName, gp)))
447
                break;
448
        }
227 dpurdie 449
    }
450
 
451
    closedir (DirHandler);
452
    alloca_free (FullFileName);
453
    return ReturnValue;
454
}
455
 
456
/* Find the location of meta-characters.  If no meta, add the argument and
457
 * return.  If meta characters, expand directory containing meta characters.
458
 */
459
 
5659 dpurdie 460
static int      _GP_ExpandMetaCharacters (file, gp)
461
char            *file;
462
glob_t          *gp;
227 dpurdie 463
{
5659 dpurdie 464
    char        *p;
465
    int         ReturnValue;
227 dpurdie 466
 
467
/* No metas - add to string */
468
 
469
    if ((p = strpbrk (file, _GP_MetaChars)) == (char *)NULL)
470
    {
5659 dpurdie 471
        if (!_GP_access (file, F_OK))
472
            return 0;
227 dpurdie 473
 
5659 dpurdie 474
        return _GP_AddArgument (file, gp);
227 dpurdie 475
    }
476
 
477
/* Ok - metas, find the end of the start of the directory */
478
 
479
    else if ((p = strchr (p, '/')) != (char *)NULL)
5659 dpurdie 480
        *(p++) = 0;
227 dpurdie 481
 
482
    else
5659 dpurdie 483
        p = _GP_NullString;
227 dpurdie 484
 
485
/* Continue recusive match */
486
 
487
    ReturnValue = _GP_ExpandField (file, p, gp);
488
 
489
/* Restore if necessary */
490
 
491
    if (p != _GP_NullString)
492
       *(--p) = '/';
493
 
494
    return ReturnValue;
495
}
496
 
497
/* Add an argument to the stack - file is assumed to be a array big enough
498
 * for the file name + 2
499
 */
500
 
5659 dpurdie 501
static int      _GP_AddArgument (file, gp)
502
char            *file;
503
glob_t          *gp;
227 dpurdie 504
{
5659 dpurdie 505
    int         Offset;
506
    char        **p1;
507
    struct stat FileStatus;
227 dpurdie 508
 
509
    Offset = gp->gl_pathc + ((gp->gl_flags & GLOB_DOOFFS) ? gp->gl_offs : 0);
510
    p1  = gp->gl_pathv;
511
 
512
/* Malloc space if necessary */
513
 
514
    if (gp->gl_pathc == 0)
5659 dpurdie 515
        p1 = (char **)calloc (sizeof (char *), (50 + Offset));
227 dpurdie 516
 
517
    else if ((gp->gl_pathc % 50) == 0)
5659 dpurdie 518
        p1 = (char **)localRealloc (p1, (Offset + 50) * (sizeof (char *)));
227 dpurdie 519
 
520
    if (p1 == (char **)NULL)
5659 dpurdie 521
        return GLOB_NOSPACE;
227 dpurdie 522
 
523
/* OK got space */
524
 
525
    gp->gl_pathv = p1;
526
 
527
/* End of list ? */
528
 
529
    if (file == (char *)NULL)
5659 dpurdie 530
        p1[Offset] = (char *)NULL;
227 dpurdie 531
 
532
    else
533
    {
5659 dpurdie 534
        if ((gp->gl_flags & GLOB_MARK) && (file[strlen (file) - 1] != '/') &&
535
            _GP_stat (file, &FileStatus) && (S_ISDIR (FileStatus.st_mode)))
536
            strcat (file, "/");
227 dpurdie 537
 
5659 dpurdie 538
        if ((p1[Offset] = strdup (file)) == (char *)NULL)
539
            return GLOB_NOSPACE;
227 dpurdie 540
 
5659 dpurdie 541
        strcpy (p1[Offset], file);
227 dpurdie 542
 
543
/* Increment counter */
544
 
5659 dpurdie 545
        ++(gp->gl_pathc);
227 dpurdie 546
    }
547
 
548
    return 0;
549
}
550
 
551
/* Check for multi_drive prefix */
552
 
553
#if defined (MSDOS) || defined (__OS2__) || defined (__TURBOC__) || defined (WIN32)
5659 dpurdie 554
static char     *_GP_CheckForMultipleDrives (prefix)
555
char            *prefix;
227 dpurdie 556
{
557
    if (strlen (prefix) < 2)
5659 dpurdie 558
        return (char *)NULL;
227 dpurdie 559
 
560
    if (((*prefix == '*') || (*prefix == '?')) && (prefix[1] == ':'))
5659 dpurdie 561
        return prefix + 1;
227 dpurdie 562
 
563
    if (*prefix != '[')
5659 dpurdie 564
        return (char *)NULL;
227 dpurdie 565
 
566
    while (*prefix && (*prefix != ']'))
567
    {
5659 dpurdie 568
        if ((*prefix == '\\') && (*(prefix + 1)))
569
            ++prefix;
227 dpurdie 570
 
5659 dpurdie 571
        ++prefix;
227 dpurdie 572
    }
573
 
574
    return (*prefix && (*(prefix + 1) == ':')) ? prefix + 1 : (char *)NULL;
575
}
576
 
577
/*
578
 * Some Turboc Functions to emulate MSC functions
579
 */
580
 
581
#  if defined (__TURBOC__)
5659 dpurdie 582
static void      _dos_getdrive (cdp)
583
unsigned int    *cdp;
227 dpurdie 584
{
585
    *cdp = (unsigned int)getdisk () + 1;
586
}
587
 
5659 dpurdie 588
static void      _dos_setdrive (cdr, ndp)
589
unsigned int    cdr;
590
unsigned int    *ndp;
227 dpurdie 591
{
592
   *ndp = (unsigned int)setdisk (cdr - 1);
593
}
594
#  endif
595
 
596
/*
597
 * Some OS/2 functions to emulate the DOS functions
598
 */
599
 
600
#  if defined (OS2) || defined (__OS2__)
5659 dpurdie 601
static void      _dos_getdrive (cdp)
602
unsigned int    *cdp;
227 dpurdie 603
{
5659 dpurdie 604
    USHORT      cdr;
605
    ULONG       ndr;
227 dpurdie 606
 
607
    DosQCurDisk((PUSHORT)&cdr, (PULONG) &ndr);
608
    *cdp = (unsigned int)cdr;
609
}
610
 
5659 dpurdie 611
static void      _dos_setdrive (cdr, ndp)
612
unsigned int    cdr;
613
unsigned int    *ndp;
227 dpurdie 614
{
5659 dpurdie 615
    ULONG               ulDrives;
616
    USHORT              usDisk;
617
    int                 i;
227 dpurdie 618
 
619
    DosSelectDisk ((USHORT)cdr);
620
 
621
/* Get the current disk and check that to see the number of drives */
622
 
623
    DosQCurDisk (&usDisk, &ulDrives);        /* gets current drive        */
624
 
625
    for (i = 25; (!(ulDrives & (1L << i))) && (i >= 0); --i)
5659 dpurdie 626
        continue;
227 dpurdie 627
 
628
    *ndp = i + 1;
629
}
630
 
631
#  elif defined (WIN32)
632
 
5659 dpurdie 633
static void      _dos_getdrive (cdp)
634
unsigned int    *cdp;
227 dpurdie 635
{
5659 dpurdie 636
    char        szCurDir [MAX_PATH];
227 dpurdie 637
 
638
    GetCurrentDirectory (MAX_PATH, szCurDir);
639
 
640
    *cdp = (unsigned int)(szCurDir[0] - 'A' + 1);
641
}
642
 
5659 dpurdie 643
static void      _dos_setdrive (cdr, ndp)
644
unsigned int    cdr;
645
unsigned int    *ndp;
227 dpurdie 646
{
5659 dpurdie 647
    char                szNewDrive[3];
648
    DWORD               dwLogicalDrives;
649
    unsigned int        i;
227 dpurdie 650
 
651
    szNewDrive[0] = cdr + 'A' - 1;
652
    szNewDrive[1] = ':';
653
    szNewDrive[2] = 0;
654
    *ndp = 0;
655
 
656
    if (!SetCurrentDirectory (szNewDrive))
5659 dpurdie 657
        return;
227 dpurdie 658
 
659
    dwLogicalDrives = GetLogicalDrives ();
660
 
661
    for (i = 25; (!(dwLogicalDrives & (1L << i))) && i >= 0; --i)
5659 dpurdie 662
        continue;
227 dpurdie 663
 
664
    *ndp = i + 1;
665
}
666
#  endif
667
 
668
/* Return the number of floppy disks */
669
 
670
#  if defined (OS2) || defined (__OS2__)
5659 dpurdie 671
static  int     _GP_GetNumberofFloppyDrives ()
227 dpurdie 672
{
5659 dpurdie 673
    BYTE        nflop = 1;
227 dpurdie 674
 
675
    DosDevConfig (&nflop, DEVINFO_FLOPPY, 0);
676
 
677
    return nflop;
678
}
679
 
680
#  elif defined (WIN32)
5659 dpurdie 681
static  int     _GP_GetNumberofFloppyDrives ()
227 dpurdie 682
{
5659 dpurdie 683
    char        szNewDrive[4];
684
    DWORD       dwLogicalDrives = GetLogicalDrives();
685
    int         LastTest = 0;
686
    int         i;
227 dpurdie 687
 
688
    strcpy (szNewDrive, "x:\\");
689
 
690
/* Look at each drive until we find a non-floppy which exists */
691
 
692
    for (i = 0; i < 25; i++)
693
    {
5659 dpurdie 694
        if (dwLogicalDrives & (1L << i))
695
        {
696
            szNewDrive[0] = i + 'A';
227 dpurdie 697
 
5659 dpurdie 698
            if (GetDriveType (szNewDrive) != DRIVE_REMOVABLE)
699
                break;
227 dpurdie 700
 
5659 dpurdie 701
            LastTest = i + 1;
702
        }
227 dpurdie 703
    }
704
 
705
    return LastTest;
706
}
707
 
708
#  elif defined (__TURBOC__)
5659 dpurdie 709
static  int     _GP_GetNumberofFloppyDrives ()
227 dpurdie 710
{
711
    return ((biosequip () & 0x00c0) >> 6) + 1;
712
}
713
 
714
#  else
5659 dpurdie 715
static  int     _GP_GetNumberofFloppyDrives ()
227 dpurdie 716
{
717
    return ((_bios_equiplist () & 0x00c0) >> 6) + 1;
718
}
719
#  endif
720
#endif
721
 
722
/*
723
 * Pattern Matching function
724
 */
725
 
5659 dpurdie 726
static bool     _GP_MatchPattern (string, pattern)
727
char            *string;                /* String to match                  */
728
char            *pattern;               /* Pattern to match against         */
227 dpurdie 729
{
5659 dpurdie 730
    register int        cur_s;          /* Current string character         */
731
    register int        cur_p;          /* Current pattern character        */
227 dpurdie 732
 
733
/* Match string */
734
 
735
    while (cur_p = *(pattern++))
736
    {
5659 dpurdie 737
        cur_s = *(string++);            /* Load current string character    */
227 dpurdie 738
 
5659 dpurdie 739
        switch (cur_p)                  /* Switch on pattern character      */
227 dpurdie 740
        {
5659 dpurdie 741
            case '[':                   /* Match class of characters        */
227 dpurdie 742
            {
743
                while(1)
744
                {
745
                    if (!(cur_p = *(pattern++)))
5659 dpurdie 746
                        return 0;
227 dpurdie 747
 
748
                    if (cur_p == ']')
5659 dpurdie 749
                        return FALSE;
227 dpurdie 750
 
751
                    if (cur_s != cur_p)
752
                    {
753
                        if (*pattern == '-')
754
                        {
755
                            if(cur_p > cur_s)
756
                                continue;
757
 
758
                            if (cur_s > *(++pattern))
759
                                continue;
760
                        }
761
                        else
762
                            continue;
763
                    }
764
 
765
                    break;
766
                }
767
 
768
                while (*pattern)
769
                {
770
                    if (*(pattern++) == ']')
771
                        break;
772
                }
773
 
5659 dpurdie 774
                break;
227 dpurdie 775
            }
776
 
5659 dpurdie 777
            case '?':                   /* Match any character              */
227 dpurdie 778
            {
779
                if (!cur_s)
5659 dpurdie 780
                    return FALSE;
227 dpurdie 781
 
782
                break;
783
            }
784
 
5659 dpurdie 785
            case '*':                   /* Match any number of any character*/
227 dpurdie 786
            {
787
                string--;
788
 
789
                do
790
                {
791
                    if (_GP_MatchPattern (string, pattern))
5659 dpurdie 792
                        return TRUE;
227 dpurdie 793
                }
794
                while (*(string++));
795
 
5659 dpurdie 796
                return FALSE;
227 dpurdie 797
            }
798
 
5659 dpurdie 799
            case '\\':                  /* Next character is non-meta       */
227 dpurdie 800
            {
801
                if (!(cur_p = *(pattern++)))
5659 dpurdie 802
                    return FALSE;
227 dpurdie 803
            }
804
 
5659 dpurdie 805
            default:                    /* Match against current pattern    */
227 dpurdie 806
            {
807
                if (cur_p != cur_s)
5659 dpurdie 808
                    return FALSE;
227 dpurdie 809
 
810
                break;
811
            }
812
        }
813
    }
814
 
815
    return (!*string) ? TRUE : FALSE;
816
}
817
 
818
/*
819
 * Local Stat function to do some additional checks
820
 */
821
 
822
static bool _GP_stat (char *FileName, struct stat *Status)
823
{
5659 dpurdie 824
    int         rc;
227 dpurdie 825
 
826
    DISABLE_HARD_ERRORS;
827
    rc = stat (FileName, Status);
828
    ENABLE_HARD_ERRORS;
829
 
830
    return rc ? FALSE : TRUE;
831
}
832
 
833
/*
834
 * Local access function to do some additional checks
835
 */
836
 
837
static bool _GP_access (char *FileName, int mode)
838
{
5659 dpurdie 839
    int         rc;
227 dpurdie 840
 
841
    DISABLE_HARD_ERRORS;
842
    rc = access (FileName, mode);
843
    ENABLE_HARD_ERRORS;
844
 
845
    return rc ? FALSE : TRUE;
846
}
847
 
848
/*
849
 * Test program
850
 */
851
 
852
#ifdef TEST
853
int main (int argc, char **argv)
854
{
5659 dpurdie 855
    int         i;
227 dpurdie 856
 
857
    for (i = 0; i < argc; i++)
5659 dpurdie 858
        printf ("Arg %d = <%s>\n", i, argv[i]);
227 dpurdie 859
 
860
    return 0;
861
}
862
#endif