~ubuntu-branches/ubuntu/trusty/bash/trusty-security

« back to all changes in this revision

Viewing changes to builtins/shopt.def

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-03-03 22:52:05 UTC
  • mfrom: (1.3.5) (2.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20140303225205-87ltrt5kspeq0g1b
Tags: 4.3-1ubuntu1
* Merge with Debian; remaining changes:
  - skel.bashrc:
    - Run lesspipe.
    - Enable ls aliases.
    - Set options in ll alias to -alF.
    - Define an alert alias.
    - Enabled colored grep aliases.
  - etc.bash.bashrc:
    - Add sudo hint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
This file is shopt.def, from which is created shopt.c.
 
2
It implements the Bash `shopt' builtin.
 
3
 
 
4
Copyright (C) 1994-2012 Free Software Foundation, Inc.
 
5
 
 
6
This file is part of GNU Bash, the Bourne Again SHell.
 
7
 
 
8
Bash is free software: you can redistribute it and/or modify
 
9
it under the terms of the GNU General Public License as published by
 
10
the Free Software Foundation, either version 3 of the License, or
 
11
(at your option) any later version.
 
12
 
 
13
Bash is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 
20
 
 
21
$PRODUCES shopt.c
 
22
 
 
23
$BUILTIN shopt
 
24
$FUNCTION shopt_builtin
 
25
$SHORT_DOC shopt [-pqsu] [-o] [optname ...]
 
26
Set and unset shell options.
 
27
 
 
28
Change the setting of each shell option OPTNAME.  Without any option
 
29
arguments, list all shell options with an indication of whether or not each
 
30
is set. 
 
31
 
 
32
Options:
 
33
  -o    restrict OPTNAMEs to those defined for use with `set -o'
 
34
  -p    print each shell option with an indication of its status
 
35
  -q    suppress output
 
36
  -s    enable (set) each OPTNAME
 
37
  -u    disable (unset) each OPTNAME
 
38
 
 
39
Exit Status:
 
40
Returns success if OPTNAME is enabled; fails if an invalid option is
 
41
given or OPTNAME is disabled.
 
42
$END
 
43
 
 
44
#include <config.h>
 
45
 
 
46
#if defined (HAVE_UNISTD_H)
 
47
#  ifdef _MINIX
 
48
#    include <sys/types.h>
 
49
#  endif
 
50
#  include <unistd.h>
 
51
#endif
 
52
 
 
53
#include <stdio.h>
 
54
 
 
55
#include "version.h"
 
56
 
 
57
#include "../bashintl.h"
 
58
 
 
59
#include "../shell.h"
 
60
#include "../flags.h"
 
61
#include "common.h"
 
62
#include "bashgetopt.h"
 
63
 
 
64
#if defined (READLINE)
 
65
#  include "../bashline.h"
 
66
#endif
 
67
 
 
68
#if defined (HISTORY)
 
69
#  include "../bashhist.h"
 
70
#endif
 
71
 
 
72
#define UNSETOPT        0
 
73
#define SETOPT          1
 
74
 
 
75
#define OPTFMT          "%-15s\t%s\n"
 
76
 
 
77
extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
 
78
extern int cdable_vars, mail_warning, source_uses_path;
 
79
extern int no_exit_on_failed_exec, print_shift_error;
 
80
extern int check_hashed_filenames, promptvars;
 
81
extern int cdspelling, expand_aliases;
 
82
extern int extended_quote;
 
83
extern int check_window_size;
 
84
extern int glob_ignore_case, match_ignore_case;
 
85
extern int hup_on_exit;
 
86
extern int xpg_echo;
 
87
extern int gnu_error_format;
 
88
extern int check_jobs_at_exit;
 
89
extern int autocd;
 
90
extern int glob_star;
 
91
extern int glob_asciirange;
 
92
extern int lastpipe_opt;
 
93
 
 
94
#if defined (EXTENDED_GLOB)
 
95
extern int extended_glob;
 
96
#endif
 
97
 
 
98
#if defined (READLINE)
 
99
extern int hist_verify, history_reediting, perform_hostname_completion;
 
100
extern int no_empty_command_completion;
 
101
extern int force_fignore;
 
102
extern int dircomplete_spelling, dircomplete_expand;
 
103
extern int complete_fullquote;
 
104
 
 
105
extern int enable_hostname_completion __P((int));
 
106
#endif
 
107
 
 
108
#if defined (PROGRAMMABLE_COMPLETION)
 
109
extern int prog_completion_enabled;
 
110
#endif
 
111
 
 
112
#if defined (RESTRICTED_SHELL)
 
113
extern char *shell_name;
 
114
#endif
 
115
 
 
116
#if defined (DEBUGGER)
 
117
extern int debugging_mode;
 
118
#endif
 
119
 
 
120
static void shopt_error __P((char *));
 
121
 
 
122
static int set_shellopts_after_change __P((char *, int));
 
123
static int shopt_enable_hostname_completion __P((char *, int));
 
124
static int set_compatibility_level __P((char *, int));
 
125
 
 
126
#if defined (RESTRICTED_SHELL)
 
127
static int set_restricted_shell __P((char *, int));
 
128
#endif
 
129
 
 
130
#if defined (READLINE)
 
131
static int shopt_set_complete_direxpand __P((char *, int));
 
132
#endif
 
133
 
 
134
static int shopt_login_shell;
 
135
static int shopt_compat31;
 
136
static int shopt_compat32;
 
137
static int shopt_compat40;
 
138
static int shopt_compat41;
 
139
static int shopt_compat42;
 
140
 
 
141
typedef int shopt_set_func_t __P((char *, int));
 
142
 
 
143
static struct {
 
144
  char *name;
 
145
  int  *value;
 
146
  shopt_set_func_t *set_func;
 
147
} shopt_vars[] = {
 
148
  { "autocd", &autocd, (shopt_set_func_t *)NULL },
 
149
  { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
 
150
  { "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
 
151
  { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
 
152
#if defined (JOB_CONTROL)
 
153
  { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
 
154
#endif
 
155
  { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
 
156
#if defined (HISTORY)
 
157
  { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
 
158
#endif
 
159
  { "compat31", &shopt_compat31, set_compatibility_level },
 
160
  { "compat32", &shopt_compat32, set_compatibility_level },
 
161
  { "compat40", &shopt_compat40, set_compatibility_level },
 
162
  { "compat41", &shopt_compat41, set_compatibility_level },
 
163
  { "compat42", &shopt_compat41, set_compatibility_level },
 
164
#if defined (READLINE)
 
165
  { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
 
166
  { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
 
167
  { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
 
168
#endif
 
169
  { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
 
170
  { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
 
171
  { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
 
172
#if defined (DEBUGGER)
 
173
  { "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
 
174
#endif
 
175
#if defined (EXTENDED_GLOB)
 
176
  { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
 
177
#endif
 
178
  { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
 
179
  { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
 
180
#if defined (READLINE)
 
181
  { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
 
182
#endif
 
183
  { "globstar", &glob_star, (shopt_set_func_t *)NULL },
 
184
  { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
 
185
  { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
 
186
#if defined (HISTORY)
 
187
  { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
 
188
#endif
 
189
#if defined (READLINE)
 
190
  { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
 
191
  { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
 
192
  { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
 
193
#endif
 
194
  { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
 
195
  { "interactive_comments", &interactive_comments, set_shellopts_after_change },
 
196
  { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
 
197
#if defined (HISTORY)
 
198
  { "lithist", &literal_history, (shopt_set_func_t *)NULL },
 
199
#endif
 
200
  { "login_shell", &shopt_login_shell, set_login_shell },
 
201
  { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
 
202
#if defined (READLINE)
 
203
  { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
 
204
#endif
 
205
  { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
 
206
  { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
 
207
  { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
 
208
#if defined (PROGRAMMABLE_COMPLETION)
 
209
  { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
 
210
#endif
 
211
  { "promptvars", &promptvars, (shopt_set_func_t *)NULL },
 
212
#if defined (RESTRICTED_SHELL)
 
213
  { "restricted_shell", &restricted_shell, set_restricted_shell },
 
214
#endif
 
215
  { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
 
216
  { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
 
217
  { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
 
218
  { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
 
219
};
 
220
 
 
221
#define N_SHOPT_OPTIONS         (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
 
222
 
 
223
#define GET_SHOPT_OPTION_VALUE(i)       (*shopt_vars[i].value)
 
224
 
 
225
static const char * const on = "on";
 
226
static const char * const off = "off";
 
227
 
 
228
static int find_shopt __P((char *));
 
229
static int toggle_shopts __P((int, WORD_LIST *, int));
 
230
static void print_shopt __P((char *, int, int));
 
231
static int list_shopts __P((WORD_LIST *, int));
 
232
static int list_some_shopts __P((int, int));
 
233
static int list_shopt_o_options __P((WORD_LIST *, int));
 
234
static int list_some_o_options __P((int, int));
 
235
static int set_shopt_o_options __P((int, WORD_LIST *, int));
 
236
 
 
237
#define SFLAG   0x01
 
238
#define UFLAG   0x02
 
239
#define QFLAG   0x04
 
240
#define OFLAG   0x08
 
241
#define PFLAG   0x10
 
242
 
 
243
int
 
244
shopt_builtin (list)
 
245
     WORD_LIST *list;
 
246
{
 
247
  int opt, flags, rval;
 
248
 
 
249
  flags = 0;
 
250
  reset_internal_getopt ();
 
251
  while ((opt = internal_getopt (list, "psuoq")) != -1)
 
252
    {
 
253
      switch (opt)
 
254
        {
 
255
        case 's':
 
256
          flags |= SFLAG;
 
257
          break;
 
258
        case 'u':
 
259
          flags |= UFLAG;
 
260
          break;
 
261
        case 'q':
 
262
          flags |= QFLAG;
 
263
          break;
 
264
        case 'o':
 
265
          flags |= OFLAG;
 
266
          break;
 
267
        case 'p':
 
268
          flags |= PFLAG;
 
269
          break;
 
270
        default:
 
271
          builtin_usage ();
 
272
          return (EX_USAGE);
 
273
        }
 
274
    }
 
275
  list = loptend;
 
276
 
 
277
  if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
 
278
    {
 
279
      builtin_error (_("cannot set and unset shell options simultaneously"));
 
280
      return (EXECUTION_FAILURE);
 
281
    }
 
282
 
 
283
  rval = EXECUTION_SUCCESS;
 
284
  if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0))        /* shopt -o */
 
285
    rval = list_shopt_o_options (list, flags);
 
286
  else if (list && (flags & OFLAG))             /* shopt -so args */
 
287
    rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
 
288
  else if (flags & OFLAG)       /* shopt -so */
 
289
    rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
 
290
  else if (list && (flags & (SFLAG|UFLAG)))     /* shopt -su args */
 
291
    rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
 
292
  else if ((flags & (SFLAG|UFLAG)) == 0)        /* shopt [args] */
 
293
    rval = list_shopts (list, flags);
 
294
  else                                          /* shopt -su */
 
295
    rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
 
296
  return (rval);
 
297
}
 
298
 
 
299
/* Reset the options managed by `shopt' to the values they would have at
 
300
   shell startup. */
 
301
void
 
302
reset_shopt_options ()
 
303
{
 
304
  allow_null_glob_expansion = glob_dot_filenames = 0;
 
305
  cdable_vars = mail_warning = 0;
 
306
  no_exit_on_failed_exec = print_shift_error = 0;
 
307
  check_hashed_filenames = cdspelling = expand_aliases = 0;
 
308
 
 
309
  source_uses_path = promptvars = 1;
 
310
 
 
311
  check_window_size = CHECKWINSIZE_DEFAULT;
 
312
 
 
313
#if defined (EXTENDED_GLOB)
 
314
  extended_glob = 0;
 
315
#endif
 
316
 
 
317
#if defined (HISTORY)
 
318
  literal_history = force_append_history = 0;
 
319
  command_oriented_history = 1;
 
320
#endif
 
321
 
 
322
#if defined (READLINE)
 
323
  hist_verify = history_reediting = 0;
 
324
  perform_hostname_completion = 1;
 
325
#endif
 
326
 
 
327
  shopt_login_shell = login_shell;
 
328
}
 
329
 
 
330
static int
 
331
find_shopt (name)
 
332
     char *name;
 
333
{
 
334
  int i;
 
335
 
 
336
  for (i = 0; shopt_vars[i].name; i++)
 
337
    if (STREQ (name, shopt_vars[i].name))
 
338
      return i;
 
339
  return -1;
 
340
}
 
341
 
 
342
static void
 
343
shopt_error (s)
 
344
     char *s;
 
345
{
 
346
  builtin_error (_("%s: invalid shell option name"), s);
 
347
}
 
348
 
 
349
static int
 
350
toggle_shopts (mode, list, quiet)
 
351
     int mode;
 
352
     WORD_LIST *list;
 
353
     int quiet;
 
354
{
 
355
  WORD_LIST *l;
 
356
  int ind, rval;
 
357
 
 
358
  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
 
359
    {
 
360
      ind = find_shopt (l->word->word);
 
361
      if (ind < 0)
 
362
        {
 
363
          shopt_error (l->word->word);
 
364
          rval = EXECUTION_FAILURE;
 
365
        }
 
366
      else
 
367
        {
 
368
          *shopt_vars[ind].value = mode;        /* 1 for set, 0 for unset */
 
369
          if (shopt_vars[ind].set_func)
 
370
            (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
 
371
        }
 
372
    }
 
373
 
 
374
  set_bashopts ();
 
375
  return (rval);
 
376
}
 
377
 
 
378
static void
 
379
print_shopt (name, val, flags)
 
380
     char *name;
 
381
     int val, flags;
 
382
{
 
383
  if (flags & PFLAG)
 
384
    printf ("shopt %s %s\n", val ? "-s" : "-u", name);
 
385
  else
 
386
    printf (OPTFMT, name, val ? on : off);
 
387
}
 
388
 
 
389
/* List the values of all or any of the `shopt' options.  Returns 0 if
 
390
   all were listed or all variables queried were on; 1 otherwise. */
 
391
static int
 
392
list_shopts (list, flags)
 
393
     WORD_LIST *list;
 
394
     int flags;
 
395
{
 
396
  WORD_LIST *l;
 
397
  int i, val, rval;
 
398
 
 
399
  if (list == 0)
 
400
    {
 
401
      for (i = 0; shopt_vars[i].name; i++)
 
402
        {
 
403
          val = *shopt_vars[i].value;
 
404
          if ((flags & QFLAG) == 0)
 
405
            print_shopt (shopt_vars[i].name, val, flags);
 
406
        }
 
407
      return (sh_chkwrite (EXECUTION_SUCCESS));
 
408
    }
 
409
 
 
410
  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
 
411
    {
 
412
      i = find_shopt (l->word->word);
 
413
      if (i < 0)
 
414
        {
 
415
          shopt_error (l->word->word);
 
416
          rval = EXECUTION_FAILURE;
 
417
          continue;
 
418
        }
 
419
      val = *shopt_vars[i].value;
 
420
      if (val == 0)
 
421
        rval = EXECUTION_FAILURE;
 
422
      if ((flags & QFLAG) == 0)
 
423
        print_shopt (l->word->word, val, flags);
 
424
    }
 
425
 
 
426
  return (sh_chkwrite (rval));
 
427
}
 
428
 
 
429
static int
 
430
list_some_shopts (mode, flags)
 
431
     int mode, flags;
 
432
{
 
433
  int val, i;
 
434
 
 
435
  for (i = 0; shopt_vars[i].name; i++)
 
436
    {
 
437
      val = *shopt_vars[i].value;
 
438
      if (((flags & QFLAG) == 0) && mode == val)
 
439
        print_shopt (shopt_vars[i].name, val, flags);
 
440
    }
 
441
  return (sh_chkwrite (EXECUTION_SUCCESS));
 
442
}
 
443
 
 
444
static int
 
445
list_shopt_o_options (list, flags)
 
446
     WORD_LIST *list;
 
447
     int flags;
 
448
{
 
449
  WORD_LIST *l;
 
450
  int val, rval;
 
451
 
 
452
  if (list == 0)
 
453
    {
 
454
      if ((flags & QFLAG) == 0)
 
455
        list_minus_o_opts (-1, (flags & PFLAG));
 
456
      return (sh_chkwrite (EXECUTION_SUCCESS));
 
457
    }
 
458
 
 
459
  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
 
460
    {
 
461
      val = minus_o_option_value (l->word->word);
 
462
      if (val == -1)
 
463
        {
 
464
          sh_invalidoptname (l->word->word);
 
465
          rval = EXECUTION_FAILURE;
 
466
          continue;
 
467
        }
 
468
      if (val == 0)
 
469
        rval = EXECUTION_FAILURE;
 
470
      if ((flags & QFLAG) == 0)
 
471
        {
 
472
          if (flags & PFLAG)
 
473
            printf ("set %co %s\n", val ? '-' : '+', l->word->word);
 
474
          else
 
475
            printf (OPTFMT, l->word->word, val ? on : off);
 
476
        }
 
477
    }
 
478
  return (sh_chkwrite (rval));
 
479
}
 
480
 
 
481
static int
 
482
list_some_o_options (mode, flags)
 
483
     int mode, flags;
 
484
{
 
485
  if ((flags & QFLAG) == 0)
 
486
    list_minus_o_opts (mode, (flags & PFLAG));
 
487
  return (sh_chkwrite (EXECUTION_SUCCESS));
 
488
}
 
489
 
 
490
static int
 
491
set_shopt_o_options (mode, list, quiet)
 
492
     int mode;
 
493
     WORD_LIST *list;
 
494
     int quiet;
 
495
{
 
496
  WORD_LIST *l;
 
497
  int rval;
 
498
 
 
499
  for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
 
500
    {
 
501
      if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
 
502
        rval = EXECUTION_FAILURE;
 
503
    }
 
504
  set_shellopts ();
 
505
  return rval;
 
506
}
 
507
 
 
508
/* If we set or unset interactive_comments with shopt, make sure the
 
509
   change is reflected in $SHELLOPTS. */
 
510
static int
 
511
set_shellopts_after_change (option_name, mode)
 
512
     char *option_name;
 
513
     int mode;
 
514
{
 
515
  set_shellopts ();
 
516
  return (0);
 
517
}
 
518
 
 
519
static int
 
520
shopt_enable_hostname_completion (option_name, mode)
 
521
     char *option_name;
 
522
     int mode;
 
523
{
 
524
  return (enable_hostname_completion (mode));
 
525
}
 
526
 
 
527
static int
 
528
set_compatibility_level (option_name, mode)
 
529
     char *option_name;
 
530
     int mode;
 
531
{
 
532
  int ind;
 
533
 
 
534
  /* If we're setting something, redo some of the work we did above in
 
535
     toggle_shopt().  Unset everything and reset the appropriate option
 
536
     based on OPTION_NAME. */
 
537
  if (mode)
 
538
    {
 
539
      shopt_compat31 = shopt_compat32 = 0;
 
540
      shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
 
541
      ind = find_shopt (option_name);
 
542
      *shopt_vars[ind].value = mode;
 
543
    }
 
544
 
 
545
  /* Then set shell_compatibility_level based on what remains */
 
546
  if (shopt_compat31)
 
547
    shell_compatibility_level = 31;
 
548
  else if (shopt_compat32)
 
549
    shell_compatibility_level = 32;
 
550
  else if (shopt_compat40)
 
551
    shell_compatibility_level = 40;
 
552
  else if (shopt_compat41)
 
553
    shell_compatibility_level = 41;
 
554
  else if (shopt_compat42)
 
555
    shell_compatibility_level = 42;
 
556
  else
 
557
    shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
 
558
 
 
559
  return 0;
 
560
}
 
561
 
 
562
/* Set and unset the various compatibility options from the value of
 
563
   shell_compatibility_level; used by sv_shcompat */
 
564
void
 
565
set_compatibility_opts ()
 
566
{
 
567
  shopt_compat31 = shopt_compat32 = shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
 
568
  switch (shell_compatibility_level)
 
569
    {
 
570
      case DEFAULT_COMPAT_LEVEL:
 
571
        break;
 
572
      case 42:
 
573
        shopt_compat42 = 1; break;
 
574
      case 41:
 
575
        shopt_compat41 = 1; break;
 
576
      case 40:
 
577
        shopt_compat40 = 1; break;
 
578
      case 32:
 
579
        shopt_compat32 = 1; break;
 
580
      case 31:
 
581
        shopt_compat31 = 1; break;
 
582
    }
 
583
}
 
584
 
 
585
#if defined (READLINE)
 
586
static int
 
587
shopt_set_complete_direxpand (option_name, mode)
 
588
     char *option_name;
 
589
     int mode;
 
590
{
 
591
  set_directory_hook ();
 
592
  return 0;
 
593
}
 
594
#endif
 
595
 
 
596
#if defined (RESTRICTED_SHELL)
 
597
/* Don't allow the value of restricted_shell to be modified. */
 
598
 
 
599
static int
 
600
set_restricted_shell (option_name, mode)
 
601
     char *option_name;
 
602
     int mode;
 
603
{
 
604
  static int save_restricted = -1;
 
605
 
 
606
  if (save_restricted == -1)
 
607
    save_restricted = shell_is_restricted (shell_name);
 
608
 
 
609
  restricted_shell = save_restricted;
 
610
  return (0);
 
611
}
 
612
#endif /* RESTRICTED_SHELL */
 
613
 
 
614
/* Not static so shell.c can call it to initialize shopt_login_shell */
 
615
int
 
616
set_login_shell (option_name, mode)
 
617
     char *option_name;
 
618
     int mode;
 
619
{
 
620
  shopt_login_shell = login_shell != 0;
 
621
  return (0);
 
622
}
 
623
 
 
624
char **
 
625
get_shopt_options ()
 
626
{
 
627
  char **ret;
 
628
  int n, i;
 
629
 
 
630
  n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
 
631
  ret = strvec_create (n + 1);
 
632
  for (i = 0; shopt_vars[i].name; i++)
 
633
    ret[i] = savestring (shopt_vars[i].name);
 
634
  ret[i] = (char *)NULL;
 
635
  return ret;
 
636
}
 
637
 
 
638
/*
 
639
 * External interface for other parts of the shell.  NAME is a string option;
 
640
 * MODE is 0 if we want to unset an option; 1 if we want to set an option.
 
641
 * REUSABLE is 1 if we want to print output in a form that may be reused.
 
642
 */
 
643
int
 
644
shopt_setopt (name, mode)
 
645
     char *name;
 
646
     int mode;
 
647
{
 
648
  WORD_LIST *wl;
 
649
  int r;
 
650
 
 
651
  wl = add_string_to_list (name, (WORD_LIST *)NULL);
 
652
  r = toggle_shopts (mode, wl, 0);
 
653
  dispose_words (wl);
 
654
  return r;
 
655
}
 
656
 
 
657
int
 
658
shopt_listopt (name, reusable)
 
659
     char *name;
 
660
     int reusable;
 
661
{
 
662
  int i;
 
663
 
 
664
  if (name == 0)
 
665
    return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
 
666
 
 
667
  i = find_shopt (name);
 
668
  if (i < 0)
 
669
    {
 
670
      shopt_error (name);
 
671
      return (EXECUTION_FAILURE);
 
672
    }
 
673
 
 
674
  print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
 
675
  return (sh_chkwrite (EXECUTION_SUCCESS));
 
676
}
 
677
 
 
678
void
 
679
set_bashopts ()
 
680
{
 
681
  char *value;
 
682
  char tflag[N_SHOPT_OPTIONS];
 
683
  int vsize, i, vptr, *ip, exported;
 
684
  SHELL_VAR *v;
 
685
 
 
686
  for (vsize = i = 0; shopt_vars[i].name; i++)
 
687
    {
 
688
      tflag[i] = 0;
 
689
      if (GET_SHOPT_OPTION_VALUE (i))
 
690
        {
 
691
          vsize += strlen (shopt_vars[i].name) + 1;
 
692
          tflag[i] = 1;
 
693
        }
 
694
    }
 
695
 
 
696
  value = (char *)xmalloc (vsize + 1);
 
697
 
 
698
  for (i = vptr = 0; shopt_vars[i].name; i++)
 
699
    {
 
700
      if (tflag[i])
 
701
        {
 
702
          strcpy (value + vptr, shopt_vars[i].name);
 
703
          vptr += strlen (shopt_vars[i].name);
 
704
          value[vptr++] = ':';
 
705
        }
 
706
    }
 
707
 
 
708
  if (vptr)
 
709
    vptr--;                     /* cut off trailing colon */
 
710
  value[vptr] = '\0';
 
711
 
 
712
  v = find_variable ("BASHOPTS");
 
713
 
 
714
  /* Turn off the read-only attribute so we can bind the new value, and
 
715
     note whether or not the variable was exported. */
 
716
  if (v)
 
717
    {
 
718
      VUNSETATTR (v, att_readonly);
 
719
      exported = exported_p (v);
 
720
    }
 
721
  else
 
722
    exported = 0;
 
723
 
 
724
  v = bind_variable ("BASHOPTS", value, 0);
 
725
 
 
726
  /* Turn the read-only attribute back on, and turn off the export attribute
 
727
     if it was set implicitly by mark_modified_vars and SHELLOPTS was not
 
728
     exported before we bound the new value. */
 
729
  VSETATTR (v, att_readonly);
 
730
  if (mark_modified_vars && exported == 0 && exported_p (v))
 
731
    VUNSETATTR (v, att_exported);
 
732
 
 
733
  free (value);
 
734
}
 
735
 
 
736
void
 
737
parse_bashopts (value)
 
738
     char *value;
 
739
{
 
740
  char *vname;
 
741
  int vptr, ind;
 
742
 
 
743
  vptr = 0;
 
744
  while (vname = extract_colon_unit (value, &vptr))
 
745
    {
 
746
      ind = find_shopt (vname);
 
747
      if (ind >= 0)
 
748
        *shopt_vars[ind].value = 1;
 
749
      free (vname);
 
750
    }
 
751
}
 
752
 
 
753
void
 
754
initialize_bashopts (no_bashopts)
 
755
     int no_bashopts;
 
756
{
 
757
  char *temp;
 
758
  SHELL_VAR *var;
 
759
 
 
760
  if (no_bashopts == 0)
 
761
    {
 
762
      var = find_variable ("BASHOPTS");
 
763
      /* set up any shell options we may have inherited. */
 
764
      if (var && imported_p (var))
 
765
        {
 
766
          temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
 
767
          if (temp)
 
768
            {
 
769
              parse_bashopts (temp);
 
770
              free (temp);
 
771
            }
 
772
        }
 
773
    }
 
774
 
 
775
  /* Set up the $BASHOPTS variable. */
 
776
  set_bashopts ();
 
777
}