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 stdargv Function
2
 *
3
 * MS-DOS stdargv - 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/STDARGV.C,v 1.1 2002/08/02 06:49:33 adamy Exp $
12
 *
13
 *    $Log: STDARGV.C,v $
14
 *    Revision 1.1  2002/08/02 06:49:33  adamy
15
 *    imported (reference only)
16
 *
17
 *    Revision 1.1  2001/07/20 05:55:43  ayoung
18
 *    WIN32 support
19
 *
20
 *    Revision 1.1.1.1  1999/12/02 01:11:12  gordonh
21
 *    UTIL
22
 *
23
 *      Revision 2.9  1994/08/25  20:49:11  istewart
24
 *      MS Shell 2.3 Release
25
 *
26
 *      Revision 2.8  1994/02/01  10:25:20  istewart
27
 *      Release 2.3 Beta 2, including first NT port
28
 *
29
 *      Revision 2.7  1994/01/20  14:51:43  istewart
30
 *      Release 2.3 Beta 1
31
 *
32
 *      Revision 2.6  1994/01/11  17:55:25  istewart
33
 *      Release 2.3 Beta 0 patches
34
 *
35
 *      Revision 2.5  1993/08/25  16:04:22  istewart
36
 *      Add support for MSC 6 which requires osmajor and osminor to be set up
37
 *      for MSDOS.
38
 *
39
 *      Revision 2.4  1993/06/14  10:59:58  istewart
40
 *      More changes for 223 beta
41
 *
42
 *      Revision 2.3  1993/06/02  09:54:21  istewart
43
 *      Beta 223 Updates - see Notes file
44
 *
45
 *      Revision 2.2  1992/12/14  11:12:37  istewart
46
 *      BETA 215 Fixes and 2.1 Release
47
 *
48
 *      Revision 2.1  1992/11/06  10:03:44  istewart
49
 *      214 Beta test updates
50
 *
51
 *      Revision 2.0  1992/04/13  17:39:09  Ian_Stewartson
52
 *      MS-Shell 2.0 Baseline release
53
 *
54
 *
55
 *
56
 * MODULE DEFINITION:
57
 *
58
 * This function expandes the command line parameters in a UNIX like manner.
59
 * Wild character *?[] are allowed in file names. @filename causes command lines
60
 * to be read from filename.  Strings between " or ' are not expanded.  All
61
 * entries in the array are malloced.
62
 *
63
 * This function replaces the standard Microsoft C5.1 & C6.0 C Run-Time
64
 * start up line processing function (_setargv in stdargv.obj).
65
 *
66
 * For OS/2 2.x, this function replaces the standard IBM C Set/2 C Run-Time
67
 * start up line processing function (_setuparg in stdargv.obj).
68
 *
69
 * For Turbo C, this function replaces the standard Borland C Run-Time
70
 * start up line processing function (_setargv).
71
 *
72
 * For WatCom C, this function replaces the standard WatCom C Run-Time
73
 * start up line processing function (__Init_Argv).
74
 *
75
 * To get the OS2 16-bit version, compile with -DOS2
76
 * To get the OS2 32-bit version, compile with -D__OS2__
77
 * To get the NT 32-bit version, compile with -DWIN32
78
 *
79
 * Author:
80
 *      Ian Stewartson
81
 *      Data Logic, Queens House, Greenhill Way
82
 *      Harrow, Middlesex  HA1 1YR, UK.
83
 *      istewart@datlog.co.uk or ukc!datlog!istewart
84
 */
85
 
86
#include <sys/types.h>                  /* MS-DOS type definitions      */
87
#include <sys/stat.h>                   /* File status definitions      */
88
#include <stdio.h>                      /* Standard I/O delarations     */
89
#include <stdlib.h>                     /* Standard library functions   */
90
#include <errno.h>                      /* Error number declarations    */
91
 
92
#if defined (OS2) || defined (__OS2__)
93
#  define INCL_DOSSESMGR
94
#  define INCL_DOSMEMMGR
95
#  define INCL_DOSPROCESS
96
#  define INCL_DOSMODULEMGR
97
#  define INCL_WINSWITCHLIST
98
#  include <os2.h>                      /* OS2 functions declarations   */
99
#elif defined (WIN32)
100
#  include <windows.h>                  /* WIN NT functions declarations */
101
#else
102
#  include <dos.h>                      /* DOS functions declarations   */
103
#  include <bios.h>                     /* BIOS functions declarations  */
104
#endif
105
 
106
#include <ctype.h>                      /* Character type declarations  */
107
#include <string.h>                     /* String library functions     */
108
#include <limits.h>                     /* String library functions     */
109
#include <fcntl.h>                      /* File Control Declarations    */
110
#include <dirent.h>                     /* Direction I/O functions      */
111
#include <unistd.h>
112
#include <glob.h>                       /* Globbing functions           */
113
 
114
/*
115
 *  DATA DEFINITIONS:
116
 */
117
#define MAX_LINE        160             /* Max line length              */
118
#define S_ENTRY         sizeof (char *)
119
#ifndef TRUE
120
#define FALSE           0
121
#define TRUE            1
122
#endif
123
 
124
 
125
/*
126
 *  DATA DECLARATIONS:
127
 */
128
static void     _Ex_CommandLine (char *);       /* Expand file          */
129
static void     _Ex_ExpandIndirectFile (char *);
130
static char    *_Ex_GetSpace (int, char *);     /* Get space            */
131
static void     _Ex_AddArgument (char *);       /* Add argument         */
132
static char    *_Ex_SkipWhiteSpace (char *);    /* Skip spaces          */
133
static char    *_Ex_ConvertToUnixFormat (char *);
134
static void     _Ex_ExpandField (char *);       /* Split file name      */
135
static void     _Ex_FatalError (int, char *, char *);
136
static char    *_Ex_ConvertEnvVariables (char *);
137
static char    *_EX_OutOfMemory = "%s: %s\n";
138
 
139
#if defined (OS2) || defined (__OS2__)
140
static void     _Ex_ProcessEMXArguments (char *);
141
static void     _Ex_SetUpWindowName (void);
142
#elif defined (WIN32)
143
static void     _Ex_SetUpWindowName (void);
144
#endif
145
 
146
/*
147
 * Command Line pointers
148
 */
149
 
150
#if defined (__OS2__)
151
#  define ARG_ARRAY     _argv
152
#  define ARG_COUNT     _argc
153
#  define ENTRY_POINT   _setuparg
154
#elif defined (__TURBOC__)
155
#  define ARG_ARRAY     _C0argv
156
#  define ARG_COUNT     _C0argc
157
#  define ENTRY_POINT   _setargv
158
#elif defined (__WATCOMC__)
159
#  define ARG_ARRAY     ___Argv
160
#  define ARG_COUNT     ___Argc
161
#  define ENTRY_POINT   __Init_Argv
162
#else
163
#  define ARG_ARRAY     __argv
164
#  define ARG_COUNT     __argc
165
#  define ENTRY_POINT   _setargv
166
#endif
167
 
168
extern void     ENTRY_POINT (void);
169
extern char   **ARG_ARRAY;              /* Current argument address     */
170
extern int      ARG_COUNT;              /* Current argument count       */
171
extern bool     IsHPFSFileSystem (char *);
172
 
173
/*
174
 * General OS independent start of the command line and program name.
175
 */
176
 
177
#if defined (__OS2__) || defined(__WATCOMC__)
178
char            *_ACmdLine;
179
char            *_APgmName;             /* Program name                 */
180
#else
181
#  if defined (OS2)
182
extern ushort far _aenvseg;
183
extern ushort far _acmdln;
184
#  endif
185
char far        *_ACmdLine;
186
char far        *_APgmName;             /* Program name                 */
187
#endif
188
 
189
/*
190
 *  MODULE ABSTRACT: _setargv
191
 *
192
 *  UNIX like command line expansion
193
 */
194
 
195
/*
196
 * OS/2 2.x (32-bit) version
197
 */
198
#if defined (__OS2__)
199
void ENTRY_POINT (void)
200
{
201
    char        *argvp;
202
    APIRET      rc;
203
    PTIB        ptib;
204
    PPIB        ppib;
205
    char        *MName;
206
 
207
/* Get the command line and program name */
208
 
209
    if (rc = DosGetInfoBlocks (&ptib, &ppib))
210
    {
211
        fprintf (stderr, "DosGetInfoBlocks: Cannot find command line (%d)\n",
212
                 rc);
213
        exit (1);
214
    }
215
 
216
    if ((MName = malloc (PATH_MAX + NAME_MAX + 3)) == (char *)NULL)
217
        _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
218
 
219
    if (rc = DosQueryModuleName (ppib->pib_hmte, NAME_MAX + PATH_MAX + 2,
220
                                 MName))
221
    {
222
        fprintf (stderr, "DosQueryModuleName: Cannot get program name (%d)\n",
223
                 rc);
224
        exit (1);
225
    }
226
 
227
/* Save the program name and process the command line */
228
 
229
    _APgmName = MName;
230
    _Ex_ProcessEMXArguments (ppib->pib_pchcmd);
231
 
232
/* Set up the Window name.  Give up if it does not work.  */
233
 
234
    _Ex_SetUpWindowName ();
235
    _Ex_AddArgument ((char *)NULL);
236
    --ARG_COUNT;
237
}
238
 
239
#elif defined (OS2)
240
 
241
/*
242
 * OS/2 1.x (16-bit) version
243
 */
244
 
245
void    ENTRY_POINT (void)
246
{
247
#  if !defined (M_I86LM) && !defined (__LARGE__)
248
    char far            *s;             /* Temporary string pointer     */
249
    char                buf[MAX_LINE];  /* Temporary space              */
250
    char                *cp;
251
#  endif
252
    char far            *argvp = (char far *)((((long)_aenvseg) << 16));
253
    ushort              off = _acmdln;
254
 
255
    while (--off)
256
    {
257
        if (argvp[off - 1] == 0)
258
            break;
259
    }
260
 
261
/* Add program name */
262
 
263
    _APgmName =  &argvp[off];
264
 
265
    if (argvp[_acmdln] == 0)
266
    {
267
#  if !defined (M_I86LM) && !defined (__LARGE__)
268
        cp = buf;
269
        s = _APgmName;
270
        while (*(cp++) = *(s++))
271
            continue;
272
 
273
        _Ex_AddArgument (_Ex_ConvertToUnixFormat (buf));
274
#  else
275
        _Ex_AddArgument (_Ex_ConvertToUnixFormat (_APgmName));
276
#  endif
277
    }
278
 
279
    else
280
    {
281
        argvp += _acmdln;
282
 
283
#  if !defined (M_I86LM) && !defined (__LARGE__)
284
        cp = buf;
285
        s = argvp;
286
        while (*(cp++) = *(s++))
287
            continue;
288
 
289
        off = strlen (buf);
290
        _Ex_AddArgument (_Ex_ConvertToUnixFormat (buf));
291
        argvp += off + 1;
292
 
293
        cp = buf;
294
        s = argvp;
295
        while (*(cp++) = *(s++))
296
            continue;
297
 
298
        _Ex_CommandLine (buf);
299
#  else
300
        _Ex_ProcessEMXArguments (argvp);
301
#  endif
302
    }
303
 
304
/* Set up the Window name.  Give up if it does not work.  */
305
 
306
    _Ex_SetUpWindowName ();
307
    _Ex_AddArgument ((char *)NULL);
308
    --ARG_COUNT;
309
}
310
 
311
#elif defined (WIN32)
312
/*
313
 * Windows NT version
314
 */
315
void _cdecl ENTRY_POINT (void)
316
{
317
    char        *cline = GetCommandLine ();
318
    char        *MName;
319
 
320
#ifdef TEST
321
    printf ("Got Command line as |%s|\n", cline);
322
#endif
323
 
324
/* Get the command line and program name */
325
 
326
    if (!*cline)
327
    {
328
        if ((MName = malloc (MAX_PATH)) == (char *)NULL)
329
            _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
330
 
331
        if (!GetModuleFileName (0, MName, MAX_PATH))
332
        {
333
            fprintf (stderr, "GetModuleFileName: Cannot get program name (%ld)\n",
334
                     GetLastError ());
335
            exit (1);
336
        }
337
 
338
        cline = MName;
339
 
340
#ifdef TEST
341
        printf ("Got command program name |%s|\n", cline);
342
#endif
343
    }
344
 
345
/* Save the program name and process the command line */
346
 
347
    _Ex_CommandLine (_ACmdLine = cline);
348
    _Ex_AddArgument ((char *)NULL);
349
    _APgmName = _Ex_ConvertToUnixFormat (ARG_ARRAY[0]);
350
 
351
/* Set up the Window name.  Give up if it does not work.  */
352
 
353
    _Ex_SetUpWindowName ();
354
    --ARG_COUNT;
355
}
356
 
357
 
358
#elif defined (__WATCOMC__)
359
/*
360
 * WATCOMC version
361
 */
362
void ENTRY_POINT(void)
363
{
364
    extern void __setenvp(void);    /* A WATCOM thing which sets up environ */
365
    extern char *_LpPgmName;        /* the program name */
366
    extern char *_LpCmdLine;        /* the raw cmdline */
367
 
368
    __setenvp();    
369
    _APgmName = _LpCmdLine;      
370
    _ACmdLine = _LpPgmName;
371
 
372
/* Set up global parameters and expand */
373
 
374
    ARG_COUNT = 0;
375
    _Ex_AddArgument(_Ex_ConvertToUnixFormat(_APgmName));
376
    _Ex_CommandLine(_ACmdLine);
377
    _Ex_AddArgument((char *)NULL);
378
    --ARG_COUNT;
379
}
380
 
381
 
382
#else
383
/*
384
 * MSDOS version
385
 */
386
void ENTRY_POINT (void)
387
{
388
    char far            *s;             /* Temporary string pointer     */
389
    union REGS          r;
390
 
391
#  if !defined (M_I86LM) && !defined (__LARGE__)
392
    char                buf[MAX_LINE];  /* Temporary space              */
393
#  endif
394
                                        /* Set up pointer to command line */
395
    unsigned int        envs = *(int far *)((((long)_psp) << 16) + 0x02cL);
396
    unsigned int        Length;
397
 
398
/* For reasons that escape me, MSC 6.0 does sets up _osmajor and _osminor
399
 * in the command line parser!
400
 */
401
#if !defined(WIN32)
402
   r.h.ah = 0x30;
403
   intdos (&r, &r);
404
   _osminor = r.h.ah;
405
   _osmajor = r.h.al;
406
#endif
407
 
408
/* Check the length */
409
 
410
    _ACmdLine = (char far *)((((long)_psp) << 16) + 0x080L);
411
 
412
    if ((Length = (unsigned int)*(_ACmdLine++)) > 127)
413
        Length = 127;
414
 
415
    _ACmdLine[Length] = 0;
416
 
417
/* Command line can be null or 0x0d terminated - convert to null */
418
 
419
    if ((s = strchr (_ACmdLine, 0x0d)) != (char *)NULL)
420
        *s = 0;
421
 
422
#ifdef TEST
423
    printf ("_psp line = <%s>\n", _ACmdLine);
424
#endif
425
 
426
/* Set up global parameters and expand */
427
 
428
    ARG_COUNT = 0;
429
 
430
/* Get the program name */
431
 
432
    if ((_osmajor <= 2) || (envs == 0))
433
        s = "unknown";
434
 
435
/* In the case of DOS 3+, we look in the environment space */
436
 
437
    else
438
    {
439
        s = (char far *)(((long)envs) << 16);
440
 
441
        while (*s)
442
        {
443
            while (*(s++) != 0)
444
                continue;
445
        }
446
 
447
        s += 3;
448
    }
449
 
450
/* Add the program name         */
451
 
452
    _APgmName = s;
453
 
454
#  if !defined (M_I86LM) && !defined (__LARGE__)
455
    cp = buf;
456
    while (*(cp++) = *(s++))
457
        continue;
458
 
459
    _Ex_AddArgument (_Ex_ConvertToUnixFormat (buf));
460
 
461
    s  = _ACmdLine;
462
    cp = buf;
463
    while (*(cp++) = *(s++))
464
        continue;
465
 
466
    _Ex_CommandLine (buf);
467
#  else
468
    _Ex_AddArgument (_Ex_ConvertToUnixFormat (s));
469
    _Ex_CommandLine (_ACmdLine);
470
#  endif
471
 
472
    _Ex_AddArgument ((char *)NULL);
473
    --ARG_COUNT;
474
}
475
#endif
476
 
477
/*
478
 * Expand the DOS Command line
479
 */
480
 
481
static void     _Ex_CommandLine (argvp)
482
char            *argvp;                 /* Line to expand               */
483
{
484
    char        *spos;                  /* End of string pointer        */
485
    char        *cpos;                  /* Start of string pointer      */
486
    char        *tpos;
487
    char        *fn;                    /* Extracted file name string   */
488
 
489
/* Search for next separator */
490
 
491
    spos = argvp;
492
 
493
    while (*(cpos = _Ex_SkipWhiteSpace (spos)))
494
    {
495
 
496
/* Extract string argument */
497
 
498
        if ((*cpos == '"') || (*cpos == '\''))
499
        {
500
            spos = cpos + 1;
501
 
502
            do
503
            {
504
                if ((spos = strchr (spos, *cpos)) != (char *)NULL)
505
                {
506
                    spos++;
507
                    if (spos[-2] != '\\')
508
                        break;
509
                }
510
 
511
                else
512
                    spos = &spos[strlen (cpos)];
513
 
514
            } while (*spos);
515
 
516
            fn  = _Ex_GetSpace (spos - cpos - 2, cpos + 1);
517
 
518
/* Remove escaped characters */
519
 
520
           tpos = fn;
521
 
522
           while ((tpos = strchr (tpos, *cpos)) != (char *)NULL)
523
               strcpy (tpos - 1, tpos);
524
        }
525
 
526
/* Extract normal argument */
527
 
528
        else
529
        {
530
            spos = cpos;
531
            while (!isspace (*spos) && *spos)
532
                spos++;
533
 
534
            fn = _Ex_GetSpace (spos - cpos, cpos);
535
        }
536
 
537
/* Process argument */
538
 
539
        if (*cpos != '\'')
540
            fn = _Ex_ConvertEnvVariables (fn);
541
 
542
        switch (*cpos)
543
        {
544
            case '@':           /* Expand file                          */
545
                _Ex_ExpandIndirectFile (fn);
546
                break;
547
 
548
            case '"':           /* Expand string                        */
549
            case '\'':
550
                _Ex_AddArgument (fn);
551
                break;
552
 
553
            default:            /* Expand field                         */
554
                _Ex_ExpandField (fn);
555
        }
556
 
557
        free (fn);
558
    }
559
}
560
 
561
/* Expand an indirect file Argument */
562
 
563
static void     _Ex_ExpandIndirectFile (file)
564
char            *file;          /* Expand file name                     */
565
{
566
    FILE        *fp;            /* File descriptor                      */
567
    char        *EoLFound;      /* Pointer                              */
568
    int         c_maxlen = MAX_LINE;
569
    char        *line;          /* Line buffer                          */
570
    char        *eolp;
571
 
572
/* If file open fails, expand as a field */
573
 
574
#ifdef __OS2__
575
    if ((fp = fopen (file + 1, "r")) == NULL)
576
#else
577
    if ((fp = fopen (file + 1, "rt")) == NULL)
578
#endif
579
        _Ex_FatalError (errno, "%s: Cannot open re-direct file - %s (%s)\n",
580
                        file + 1);
581
 
582
/* Grab some memory for the line */
583
 
584
    if ((line = malloc (c_maxlen)) == (char *)NULL)
585
        _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
586
 
587
/* For each line in the file, remove EOF characters and add argument */
588
 
589
    while (fgets (line, c_maxlen, fp) != (char *)NULL)
590
    {
591
        EoLFound = strchr (line, '\n');
592
        eolp = line;
593
 
594
/* Handle continuation characters */
595
 
596
        while (TRUE)
597
        {
598
 
599
/* Check for a continuation character */
600
 
601
            if (((EoLFound = strchr (eolp, '\n')) != (char *)NULL) &&
602
                (*(EoLFound - 1) == '\\'))
603
            {
604
                *(EoLFound - 1) = '\n';
605
                *EoLFound = 0;
606
                EoLFound = (char *)NULL;
607
            }
608
 
609
            else if (EoLFound == (char *)NULL)
610
                EoLFound = strchr (line, 0x1a);
611
 
612
            if (EoLFound != (char *)NULL)
613
                break;
614
 
615
/* Find the end of the line */
616
 
617
            c_maxlen = strlen (line);
618
 
619
/* Get some more space */
620
 
621
            if ((line = realloc (line, c_maxlen + MAX_LINE)) == (char *)NULL)
622
                _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
623
 
624
            eolp = &line[c_maxlen];
625
 
626
            if (fgets (eolp, MAX_LINE, fp) == (char *)NULL)
627
                break;
628
        }
629
 
630
/* Terminate the line and add it to the argument list */
631
 
632
        if (EoLFound != (char *)NULL)
633
            *EoLFound = 0;
634
 
635
        _Ex_AddArgument (line);
636
    }
637
 
638
    if (ferror(fp))
639
        _Ex_FatalError (errno, "%s: %s (%s)\n", file + 1);
640
 
641
    free (line);
642
    fclose (fp);
643
 
644
/* Delete tempoary files */
645
 
646
    if (((line = strrchr (file + 1, '.')) != (char *)NULL) &&
647
        (stricmp (line, ".tmp") == 0))
648
        unlink (file + 1);                      /* Delete it            */
649
}
650
 
651
/* Get space for an argument name */
652
 
653
static char     *_Ex_GetSpace (length, in_s)
654
int             length;                 /* String length                */
655
char            *in_s;                  /* String address               */
656
{
657
    char        *out_s;                 /* Malloced space address       */
658
 
659
    if ((out_s = malloc (length + 1)) == (char *)NULL)
660
        _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
661
 
662
/* Copy string for specified length */
663
 
664
    strncpy (out_s, in_s, length);
665
    out_s[length] = 0;
666
 
667
    return (out_s);
668
}
669
 
670
/* Append an argument to the array */
671
 
672
static void     _Ex_AddArgument (Argument)
673
char            *Argument;                      /* Argument to add              */
674
{
675
    if (ARG_COUNT == 0)
676
        ARG_ARRAY = (char **)malloc (50 * S_ENTRY);
677
 
678
    else if ((ARG_COUNT % 50) == 0)
5659 dpurdie 679
        ARG_ARRAY = (char **)localRealloc (ARG_ARRAY, (ARG_COUNT + 50) * S_ENTRY);
227 dpurdie 680
 
681
    if (ARG_ARRAY == (char **)NULL)
682
        _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
683
 
684
    if (Argument == (char *)NULL)
685
        ARG_ARRAY[ARG_COUNT++] = (char *)NULL;
686
 
687
    else
688
        ARG_ARRAY[ARG_COUNT++] = _Ex_GetSpace (strlen (Argument), Argument);
689
}
690
 
691
/*  Skip over spaces */
692
 
693
static char     *_Ex_SkipWhiteSpace (a)
694
char            *a;                     /* String start address         */
695
{
696
    while (isspace(*a))
697
        a++;
698
 
699
    return (a);
700
}
701
 
702
/* Convert name to Unix format */
703
 
704
static char     *_Ex_ConvertToUnixFormat (a)
705
char            *a;
706
{
707
    char        *sp = a;
708
 
709
    while ((a = strchr (a, '\\')) != (char *)NULL)
710
        *(a++) = '/';
711
 
712
#if !defined (OS2) && !defined (__OS2__) && !defined (WIN32)
713
    return strlwr (sp);
714
#else
715
    if (!IsHPFSFileSystem (sp))
716
        strlwr (sp);
717
 
718
    return sp;
719
#endif
720
 
721
}
722
 
723
/* Find the location of meta-characters.  If no meta, add the argument and
724
 * return NULL.  If meta characters, return position of end of directory
725
 * name.  If not multiple directories, return -1
726
 */
727
 
728
static void     _Ex_ExpandField (file)
729
char            *file;
730
{
731
    int         i = 0;
732
    glob_t      gp;
733
 
734
    if (strpbrk (file, "?*[]\\") == (char *)NULL)
735
    {
736
        _Ex_AddArgument (file);
737
        return;
738
    }
739
 
740
    if (glob (file, GLOB_NOCHECK, (int (_CDECL *)(char *, int))NULL , &gp))
741
        _Ex_FatalError (ENOMEM, _EX_OutOfMemory, (char *)NULL);
742
 
743
    i = 0;
744
 
745
    while (i < gp.gl_pathc)
746
        _Ex_AddArgument (gp.gl_pathv[i++]);
747
 
748
    globfree (&gp);
749
}
750
 
751
/* Fatal errors */
752
 
753
static void     _Ex_FatalError (ecode, format, para)
754
int             ecode;
755
char            *format;
756
char            *para;
757
{
758
    fprintf (stderr, format, "stdargv", strerror (ecode), para);
759
    exit (1);
760
}
761
 
762
/* Process Environment - note that field is a malloc'ed field */
763
 
764
static char     *_Ex_ConvertEnvVariables (field)
765
char            *field;
766
{
767
    char        *sp, *cp, *np, *ep;
768
    char        save;
769
    int         b_flag;
770
 
771
    sp = field;
772
 
773
/* Replace any $ strings */
774
 
775
    while ((sp = strchr (sp, '$')) != (char *)NULL)
776
    {
777
 
778
/* If ${...}, find the terminating } */
779
 
780
        if (*(cp = ++sp) == '{')
781
        {
782
            b_flag = 1;
783
            ++cp;
784
 
785
            while (*cp && (*cp != '}'))
786
                cp++;
787
        }
788
 
789
/* Else must be $..., find the terminating non-alphanumeric */
790
 
791
        else
792
        {
793
            b_flag = 0;
794
 
795
            while (isalnum (*cp))
796
                cp++;
797
        }
798
 
799
/* Grab the environment variable */
800
 
801
        if (cp == sp)
802
            continue;
803
 
804
/* Get its value */
805
 
806
        save = *cp;
807
        *cp = 0;
808
        ep = getenv (sp + b_flag);
809
        *cp = save;
810
 
811
        if (ep != (char *)NULL)
812
        {
813
            np = _Ex_GetSpace (strlen(field) - (cp - sp) + strlen (ep) - 1, field);
814
            strcpy (&np[sp - field - 1], ep);
815
            free (field);
816
            strcpy ((sp = &np[strlen(np)]), cp + b_flag);
817
            field = np;
818
        }
819
    }
820
 
821
    return field;
822
}
823
 
824
/*
825
 * Handle EMX style arguments
826
 */
827
 
828
#if defined (OS2) || defined (__OS2__)
829
static void     _Ex_ProcessEMXArguments (char *argvp)
830
{
831
    char        *cp;
832
    char        *s = argvp;
833
 
834
    _Ex_AddArgument (_Ex_ConvertToUnixFormat (argvp));
835
    argvp += strlen (argvp) + 1;
836
    _ACmdLine = argvp;
837
#ifdef TEST
838
    printf ("argvp line = <%s>\n", _ACmdLine);
839
#endif
840
 
841
/*
842
 * Add support in OS2 version for Eberhard Mattes EMX interface to commands.
843
 */
844
 
845
    if ((*argvp) && (*(cp = argvp + strlen (argvp) + 1) == '~') &&
846
        (strcmp (s, _Ex_ConvertToUnixFormat (cp + 1)) == 0))
847
    {
848
 
849
/* Skip over the program name at string 2 to the start of the first
850
 * argument at string 3
851
 */
852
 
853
        argvp += strlen (argvp) + 1;
854
        argvp += strlen (argvp) + 1;
855
 
856
        while (*argvp)
857
        {
858
            cp = (*argvp == '~') ? argvp + 1 : argvp;
859
 
860
            if (*cp == '@')
861
                _Ex_ExpandIndirectFile (cp);
862
 
863
            else
864
                _Ex_AddArgument (cp);
865
 
866
            argvp += strlen (argvp) + 1;
867
        }
868
    }
869
 
870
    else
871
        _Ex_CommandLine (argvp);
872
}
873
 
874
/*
875
 * Set up the Window Name
876
 */
877
 
878
static void     _Ex_SetUpWindowName (void)
879
{
880
    HSWITCH             hswitch;
881
    SWCNTRL             swctl;
882
    char                *cp;
883
 
884
    if (((hswitch = WinQuerySwitchHandle (0, getpid ()))) &&
885
        (!WinQuerySwitchEntry (hswitch, &swctl)))
886
    {
887
        if ((cp = strrchr (ARG_ARRAY[0], '/')) == (char *)NULL)
888
            cp = ARG_ARRAY[0];
889
 
890
        else
891
            ++cp;
892
 
893
        strncpy (swctl.szSwtitle, cp, MAXNAMEL);
894
        swctl.szSwtitle[MAXNAMEL] = 0;
895
 
896
        if ((cp = strrchr (swctl.szSwtitle, '.')) != (char *)NULL)
897
            *cp = 0;
898
 
899
        WinChangeSwitchEntry (hswitch, &swctl);
900
    }
901
}
902
#endif
903
 
904
/*
905
 * Windows NT version
906
 */
907
 
908
#ifdef WIN32
909
static void     _Ex_SetUpWindowName (void)
910
{
911
    char                *cp;
912
 
913
    if ((cp = strrchr (ARG_ARRAY[0], '/')) == (char *)NULL)
914
        cp = ARG_ARRAY[0];
915
 
916
    else
917
        ++cp;
918
 
919
    SetConsoleTitle (cp);
920
}
921
#endif
922
 
923
 
924
/*
925
 * Test main program
926
 */
927
#ifdef TEST
928
int     main (int argc, char **argv)
929
{
930
    int         i;
931
 
932
    printf ("_ACmdLine = <%s>\n", _ACmdLine);
933
 
934
    for (i = 0; i < argc; i++)
935
        printf ("Arg %d = |%s|\n", i, argv[i]);
936
 
937
    return 0;
938
}
939
#endif