openfoam-selector.in 27.3 KB
Newer Older
1
#!/usr/bin/perl
2 3
#
# Copyright (c) 2007 Cisco Systems, Inc.  All rights reserved.
4
# Copyright (C) 2018 OpenCFD Ltd.
5 6
#
# Simple perl script to effect system-wide and per-user default
7
# selections of which OPENFOAM to use.
8 9 10 11 12 13 14 15 16 17 18
#

use strict;
use Getopt::Long;
use Text::Wrap;
use File::Copy;

#===========================================================================

=head1 NAME

19
openfoam-selector - A simple site-wide/per-user OPENFOAM versions selection tool
20 21 22 23 24

=head1 SYNOPSIS

=head2 Commands for end users

25
openfoam-selector [options] --list
26

27
openfoam-selector [options] --set <name>
28

29
openfoam-selector [options] --unset
30

31
openfoam-selector [options] --query
32

33
openfoam-selector [options] --version
34

35
=head2 Commands for OPENFOAM versions
36

37
openfoam-selector [options] --register <name> --source-dir <dir>
38

39
openfoam-selector [options] --unregister <name>
40 41 42

=head1 DESCRIPTION

43 44 45 46
The openfoam-selector command is a simplistic tool to select one of
multiple OPENFOAM versions.  openfoam-selector allows system
administrators to set a site-wide default OPENFOAM version while
also allowing users to set their own default OPENFOAM version
47 48 49 50 51 52 53 54
(thereby overriding the system-wide default).

Note that both the site-wide and per-user defaults are independent
from each other; a system administrator may choose not to have a
site-wide default while a user may choose to have a personal default
-- and vice versa.

The system is effected by having system-wide shell startup files that
55 56
looks first at the user's OPENFOAM preferences.  If found, the OPENFOAM
version indicated by the user's preferences is setup in the
57
current environment.  If not found, look for a site-wide default.  If
58
found, the OPENFOAM version indicated in by the site-wide default is
59 60 61 62
setup in the current environment.  If not found, exit silently.

=head2 End Users / System Administrators

63
The openfoam-selector command provides four main actions:
64 65 66

=over

67
=item * List which OPENFOAM versions are available
68 69 70 71 72 73 74 75 76 77

=item * Set a default (either on a per-user or site-wide basis)

=item * Unset a default (either on a per-user or site-wide basis)

=item * Query what the current default is

=back

A common scenario is that a system administrator sets a site-wide
78 79 80
default for a supported OPENFOAM version that most users will use.
Power users then change their per-user defaults to use a different OPENFOAM
version.
81 82

Another common scenario is for power users to frequently use
83 84
openfoam-selector to swap back and forth between multiple different OPENFOAM
version.
85

86 87 88
B<NOTE:> The openfoam-selector command only changes the defaults for I<new>
shells.  Specifically, after you invoke the openfoam-selector command to
change the default OPENFOAM version, this change does not take
89 90 91
effect until you start a new shell.  This is intentional.  See the
"KNOWN LIMITATIONS" section, below.

92
=head2 OPENFOAM Versions
93

94
OPENFOAM versions register themselves with openfoam-selector when they
95
are installed and unregister themselves when they are uninstalled.
96
Each OPENFOAM installation provides two files that setup the environment
97 98 99 100
for itself:

=over

101
=item * etc/bashrc: File sourceable by Bourne-like shells (sh, bash,
102 103
etc.)

104
=item * etc/cshrc: File sourceable by C-like shells (csh, tcsh,
105 106 107 108 109
etc.)

=back

These files are expected to be in a single directory and "registered"
110 111 112
with openfoam-selector using the I<--register> and I<--source-dir> options.
openfoam-selector will copy these files to its own internal store; it is
safe to remove the originals after the openfoam-selector registration
113 114 115 116 117 118 119
completes successfully.

The <name> argument to I<--register> must be simplistic -- it cannot
contain any shell special characters (not even if they are escaped),
nor can it contain spaces.  The intent is to provide simple names that
users can type without escaping or quoting.  Names not conforming to
these rules will be rejected and the registration will fail.
120 121
Additionally, names with a leading prefix I<__internal> are reserved
for internal use.
122

123 124
When an OPENFOAM version is uninstalled, it should unregister with
openfoam-selector via the I<--unregister> option.
125 126 127

=head1 OPTIONS

128
--list: List which OPENFOAM versions are available
129 130 131 132 133 134 135 136 137

--no: Assume "no" to any interactive questions asked.

--query: See what the current default is.  If specified with no
options, whichevery default has precedence -- if any -- will be
shown.  If specified with I<--user>, only show the per-user default
(if there is one).  If specified with I<--system>, only show the
site-wide default (if there is one).

138
--register: Register a new OPENFOAM version.  Must be
139 140
combined with the I<--source-dir> option.

141
--set <name>: Set the default OPENFOAM version.  May be combined
142 143 144
with I<--system> or I<--user> (I<--user> is the default and does not
need to be specified).

145 146
--source-dir: Specify the location where F<etc/bashrc, etc/cshrc> files
can be found.  Only meaningful when used with the
147 148 149 150 151 152
I<--register> option.

--system: When used with I<--set> or I<--unset>, specifies to work
with the site-wide default (vs. the per-user default).  When used with
I<--query>, it specifies to specifically query the site-wide default.

153
--unregister: Unregister an OPENFOAM version.
154 155 156 157 158

--user: When used with I<--set> or I<--unset>, specifies to work with
the per-user default (vs. the site-wide default).  When used with
I<--query>, it specifies to specifically query the per-user default.

159
--unset: Unset the default OPENFOAM version.  May be combined with
160 161 162 163 164
I<--system> or I<--user> (I<--user> is the default and does not need
to be explicitly specified).

--verbose: Be verbose.

165
--version: Return the version of openfoam-selector.
166 167 168 169 170 171 172 173

--yes: Assume "yes" to any interactive questions asked.

=head1 EXAMPLES

=head2 Examples for End Users / System Administrators

The four main actions that system administrators and end users invoke
174
are: listing which OPENFOAM versions are available, setting a
175 176 177
default, unsetting a default, and querying what the current default
is.

178
=head3 Listing which OPENFOAM versions are available
179

180 181
The I<--list> option to the openfoam-selector command shows a simple list
of which OPENFOAM versions are available:
182

183 184 185 186 187
  shell$ openfoam-selector --list
  openfoam-1.5
  openfoam-2.2
  openfoam-1712
  openfoam-1806
188 189 190 191
  shell$

=head3 Setting a default

192 193 194
By default, OPENFOAM selections are performed on a per-user basis with the
I<--set> option, using a name from the list of available OPENFOAM
versions (which can be obtained via the I<--list> command):
195

196
  shell$ openfoam-selector --set openfoam-1712
197 198 199 200 201
  shell$

Note that the default takes effect in the I<next> shell that is
started; it does B<NOT> take effect in the current shell!

202
If a default OPENFOAM is already set, setting a new default will cause an
203 204 205 206
interactive confirmation prompt.  This interactive prompt can be
avoided by using the I<--yes> option, which assumes a "yes" answer to
all questions:

207 208
  shell$ openfoam-selector --set openfoam-1806
  shell$ openfoam-selector --set openfoam-1806 --yes
209 210 211 212 213 214
  shell$

If the I<--system> option is used, the site-wide default is modified
instead of the per-user default.  Since this option typically reqires
writing files into protected areas, root access may be required.

215
  shell# openfoam-selector --set openfoam-1806 --system
216 217 218 219 220 221
  shell#

=head3 Unsetting a default

Unset the current default with the I<--unset> option:

222
  shell$ openfoam-selector --unset
223 224 225 226 227
  shell$

Similar to I<--set>, the I<--system> option can be used to unset the
site-wide default

228
  shell# openfoam-selector --unset --system
229 230 231 232
  shell#

=head3 Querying what the current default is

233 234
The I<--query> option can be used to see what the current OPENFOAM
version is (more specifically, what the OPENFOAM version
235
I<will be> for the next shell that is started).  It indicates both
236
which OPENFOAM is the default and at what level the default was set
237 238
(per-user vs. site-wide):

239 240 241
  shell$ openfoam-selector --set openfoam-1.2.3
  shell$ openfoam-selector --query
  default:openfoam-1.2.3
242 243 244 245 246 247
  level:user
  shell$

Note that if there is no per-user default, the system default will be
shown:

248
  shell# openfoam-selector --set openfoam-1.2.3 --system
249

250 251 252
  shell$ openfoam-selector --unset
  shell$ openfoam-selector --query
  default:otherfoam-4.5.6
253
  level:system
254 255 256
  shell$ openfoam-selector --set openfoam-1.2.3
  shell$ openfoam-selector --query
  default:openfoam-1.2.3
257 258 259 260 261 262
  level:user
  shell$

If there is no per-user default and no site-wide default, I<--query>
will return silently:

263
  shell$ openfoam-selector --query
264 265
  shell$

266
=head2 Examples for OPENFOAM versions
267 268 269 270

Registering and unregistering typically writes files into protected
areas, and therefore usually requires root access.

271
If there are no OPENFOAM versions registered, I<--list> will return
272 273
silently:

274
  shell# openfoam-selector --list
275 276
  shell#

277
An OPENFOAM with etc/bashrc in /opt/somefoam can be
278 279
registered as follows:

280 281 282 283
  shell# openfoam-selector --register myfavourite \
         --source-dir /opt/somefoam
  shell# openfoam-selector --list
  myfavourite
284 285 286 287 288 289
  shell#

Note that re-registering the same <name> will cause an interactive
confirmation prompt; the I<--yes> option can be supplied to assume
"yes" to all questions asked:

290 291 292 293 294
  shell# openfoam-selector --list
  openfoam-1806
  shell# openfoam-selector --register myfavourite \
         --source-dir /usr/local/openfoam-1806 --yes
  myfavourite is already registered.
295
  Overwriting previously registered files.
296 297
  shell# openfoam-selector --list
  myfavourite
298 299 300 301
  shell#

Unregistering is also simple:

302 303 304 305
  shell# openfoam-selector --list
  myfavourite
  shell# openfoam-selector --unregister myfavourite
  shell# openfoam-selector --list
306 307 308 309 310 311 312 313 314
  shell#

=head2 Registering and Unregistering in RPMs

Registering and unregistering via RPM is unfortunately more
complicated than it needs to be because of the following issues:

1. Although RPM obeys dependency ordering of "rpm -i a b c".  That is,
   F<c> will be installed before F<a> if F<a> requires F<c>.
315
   Regardless, RPM's must know a) that the openfoam-selector command is
316 317 318 319
   installed, and b) be able to find it in its path.

2. RPM does not obey dependency ordering of "rpm -e a b c".  That is,
   F<c> may be uninstalled before F<a>, even if F<a> requires F<c>.
320 321
   Hence, the openfoam-selector command may disappear before an RPM using the
   openfoam-selector command in a scriptlet is uninstalled.
322 323 324 325 326

3. "Updating" RPMs will first uninstall the old RPM and then
   re-install the new one.

Additionally, the staged installations (such as the OFED installer)
327
require telling the openfoam-selector command additional information so
328 329
that various internal data files can be found.

330
In general, OPENFOAM installations via RPMs should register during the
331 332 333
%post scriptlet and unregister during the %preun scriptlet (I<not>
during the %postun scriptlet!).

334 335 336 337
If RPMs "require" the openfoam-selector RPM, they can be assured that the
openfoam-selector command will exist and be installed properly, but they
still need to be able to find openfoam-selector in their PATH.  Hence, if
openfoam-selector is not installed into a default PATH location, the %post
338 339
scriptlet won't be able to find it, and the registration call will
fail.  The simplest workaround (at least for the moment) is to set the
340
PATH to where openfoam-selector is installed before installing any RPMs
341 342 343 344 345
that use it.

With that in mind, here is a possible %post scriptlet for
OFED-installed RPMS:

346
  openfoam-selector --register <name> --source-dir <source_dir> \
347 348 349 350 351
      --yes --silent

Note the following:

1. The I<--yes> option forces an overwrite if, for some reason, a
352
   previous OPENFOAM of the name is already registered.
353

354
2. The I<--silent> option makes openfoam-selector run silently, since RPMs
355 356 357 358
   are supposed to install with no output.

Here is a possible %preun scriptlet for OFED-installed RPMs:

359
  openfoam-selector --unregister <name> --yes || \
360 361 362 363 364 365 366
      /bin/true > /dev/null 2> /dev/null

Note the following:

1. We use %preun instead of %postun because of RPM's upgrade behavior.

2. Since RPM does not honor dependencies when uninstalling, it is
367 368
   possible that openfoam-selector is no longer installed, and therefore
   the command may fail.  However, since openfoam-selector is no longer
369 370 371 372 373 374 375
   installed, we don't care that it failed (i.e., there's nothing to
   unregister from), so just redirect all output to F</dev/null> and
   ensure that the return code from the overall command is "true" (RPM
   will abort if any individual scriptlet command fails).

=head1 KNOWN LIMITATIONS

376
The main known limitation of openfoam-selector is that it only affects
377
I<future> shells -- running it does not affect the I<current> shell.
378
After you run openfoam-selector to set a new default OPENFOAM (regardless of
379 380 381 382
whether it is a system-level or user-specific default), that default
will not take effect until you start a new shell -- even though
I<--query> will report the new default.

383 384
This behavior is because openfoam-selector defaults are I<only> read during
shell startup.  It was an intentional design decision -- openfoam-selector
385 386 387 388 389 390
is intended to be a simplistic tool, and an all-encompassing solution.

Other solutions for modifying the current environment exist, such as
the Environment Modules package (L<http://modules.sourceforge.net/>)
and SoftEnv from Argonne National Laboratory (and probably others).
Using these tools, you can immediately change the environment of the
391 392 393
current shell (to include switching to use a different OPENFOAM
version).  As such, these already-existing, mature tools are
better suited for such usage patterns; openfoam-selector is not intended to
394 395 396 397 398
replace them.

For rsh/ssh-based parallel environments, switching defaults frequently
should be done with care.  Specifically, rsh/ssh-based launchers may
depends on a common environment across all nodes (e.g., to find helper
399
executables and/or libraries for a specific OPENFOAM).  Consider the
400 401
following example:

402 403
  shell$ openfoam-selector --set openfoam-1.2.3
  shell$ mpirun -np 32 --hostfile myhosts openfoam_app -parallel
404

405 406
While F<openfoam_app> is starting, it may be dangerous to switch the
openfoam-selector default (perhaps in a different window) because the rsh
407
and/or ssh commands currently executing may be relying on finding the
408 409
same OPENFOAM version on all nodes.  Changing the default I<while>
the application is launching may cause a different OPENFOAM version
410 411 412 413
to be found on some nodes, thereby causing undefined behavior.

=head1 FILES

414
$HOME/@OPENFOAM_SELECTOR_HOME_FILE@ Location of per-user default selection
415

416
@OPENFOAM_SELECTOR_SYSCONFDIR@/@OPENFOAM_SELECTOR_SYSCONFIG_FILE@ Location of
417 418
site-wide default selection.

419
@OPENFOAM_SELECTOR_DATADIR@/data Directory containing registered OPENFOAM
420 421 422 423 424 425 426 427 428 429
shell startup files.

=head1 AUTHOR

Written by Jeff Squyres.

=head1 REPORTING BUGS

Send bug reports to the OpenFabrics general mailing list (see
L<http://www.openfabrics.org/>).  This is a high-volume mailing list,
430
so be sure to put "openfoam-selector" in the subject to ensure that it is
431 432 433 434 435 436 437 438 439 440
not missed.

=head1 COPYRIGHT

Copyright (c) 2007 Cisco Systems, Inc.  All rights reserved.

This is free software; see the source for copying conditions.  There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

441
Copyright (C) 2018 OpenCFD Ltd.
442

443 444 445 446 447 448
=cut

#===========================================================================

# Global variables

449 450
my $data_dir = "@OPENFOAM_SELECTOR_DATADIR@";
my $sysconfig_dir = "@OPENFOAM_SELECTOR_SYSCONFDIR@";
451

452 453
my $sysconfig_file = "@OPENFOAM_SELECTOR_SYSCONFIG_FILE@";
my $home_file = "@OPENFOAM_SELECTOR_HOME_FILE@";
454 455 456 457 458 459 460 461 462

#===========================================================================

sub show_help {
    our $silent;
    my $ret = shift;

    print "$0 options:

463
Options for OPENFOAM versions:
464

465 466
--register <name>     Register an OPENFOAM version with the central
                      openfoam-selector database.  Requires use of the
467 468
                      --source-dir option.
--source-dir <dir>    Used with --register, indicating that <dir> is
469 470 471
                      where the etc/bashrc file can be found.
--unregister <name>   Remove an OPENFOAM version list from the
                      central openfoam-selector database.
472 473 474 475 476

Options for system administrators:

--system              When used with the --set and --unset options,
                      act on the system-wide defaults (vs. the
477
                      per-user defaults).  When used with --query, only
478 479 480
                      show the site-wide default (if there is one).
--user                When used with the --set and --unset options,
                      act on the per-user defaults (vs. the
481
                      site-wide defaults).  When used with --query, only
482 483 484 485
                      show the per-user default (if there is one).

Options for users:

486 487 488 489 490
--list                Show a list of the currently registered OPENFOAM
                      versions.
--set <name>          Set <name> to be the default OPENFOAM selection.
--unset               Remove the default OPENFOAM selection.
--query               Shows the current default OPENFOAM selection.
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
--yes                 Assume the answer is \"yes\" to any question.
--no                  Assume the answer is \"no\" to any question.
--verbose             Be verbose about actions.
--silent              Print nothing (not even warnings or errors;
                      overrides --verbose)
--version             Display the version of $0.
"
      if (!$silent);
    exit($ret);
}

#===========================================================================

sub make_safe_filename {
    my $name = shift;
    $name =~ s/[ :\/\\\*\&\$\#\@\!\t\n\[\]\{\}\(\)]/_/g;
507
    $name =~ s/^__internal//;  # Disallow reserved names
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
    return $name;
}

#===========================================================================

sub error {
    our $silent;
    print STDERR wrap("ERROR: ", "       ", @_) . "\n"
      if (!$silent);
    exit(1);
}


sub warning {
    our $silent;
    print STDERR wrap("WARNING: ", "         ", @_) . "\n"
      if (!$silent);
}


sub verbose {
    our $silent;
    our $verbose_flag;
    print wrap("", "", @_) . "\n"
      if ($verbose_flag && !$silent);
}

#===========================================================================

sub get_yn {
    my $prompt = shift;
    my $default = shift;

    if (defined($default)) {
        if ($default) {
            $default = 1;
            $prompt .= " (Y/n) ";
        } else {
            $default = 0;
            $prompt .= " (y/N) ";
        }
    } else {
        $prompt .= " (y/n/) ";
    }

    while (1) {
        print $prompt;
        my $ans = <STDIN>;
        chomp($ans);
        if ($ans =~ /y/i) {
            return 1;
        } elsif ($ans =~ /n/i) {
            return 0;
        } elsif ("" eq $ans) {
562
            return $default
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
              if (defined($default));
        }
        print "\nPlease choose Y or N\n";
    }
}

#===========================================================================

sub do_query {
    my $file = shift;
    my $level = shift;

    if (-f $file) {
        open(FILE, $file);
        my $name = <FILE>;
        close(FILE);
579

580 581 582 583 584 585 586 587 588 589 590 591 592 593
        chomp($name);
        print "default:$name\nlevel:$level\n";
        exit(0);
    }
}

#===========================================================================

# Set autoflush
select STDOUT;
$| = 1;

# Module options
$Text::Wrap::columns = 76;
594
# No option bundling
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640

my $help = 0;
my $register;
my $source_dir;
my $unregister;
my $system = 0;
my $user = 0;
my $list = 0;
my $set;
my $unset;
my $yes;
my $query = 0;
our $verbose_flag = 0;
my $version = 0;
my $no;
our $silent = 0;

my $ok = Getopt::Long::GetOptions("help|h" => \$help,
                                  "register=s" => \$register,
                                  "source-dir=s" => \$source_dir,
                                  "unregister=s" => \$unregister,
                                  "system" => \$system,
                                  "user" => \$user,
                                  "list" => \$list,
                                  "set=s" => \$set,
                                  "unset" => \$unset,
                                  "query" => \$query,
                                  "yes|y" => \$yes,
                                  "verbose" => \$verbose_flag,
                                  "version" => \$version,
                                  "no" => \$no,
                                  "silent" => \$silent,
                                  );

show_help(1) if (!$ok);
show_help(0) if ($help);
$yes = 0
  if (defined($no));
error("Can only specify one of --user or --system; not both")
    if ($user + $system > 1);

#---------------------------------------------------------------------------

# Check for bozo case -- this is a simple script, so let's limit to
# one action at a time

641
my $val = defined($register) + defined($unregister) + $list +
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
  defined($set) + defined($unset) + $query + $version;
if (0 == $val) {
    print("Nothing to do!\n")
      if (!$silent);
    show_help(0);
}
if (1 != $val) {
    print("ERROR: Please only specify one action\n")
      if (!$silent);
    show_help(1);
}

#---------------------------------------------------------------------------

# Version informtion

if ($version) {
    print "$0 version @PACKAGE_VERSION@

Copyright (c) 2007 Cisco Systems, Inc.  All rights reserved.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

665 666 667
Written by Jeff Squyres.

Changes Copyright (C) 2018 OpenCFD Ltd.\n"
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
      if (!$silent);
    exit(0);
}

#---------------------------------------------------------------------------

# Registration

elsif ($register) {
    # Check to be sure that they also specified a --source-dir
    error("--register must be used in conjunction with --source-dir")
      if (!defined($source_dir));

    # Make sure that the source dir exists
    error("Cannot read from source directory ($source_dir)")
      if (! -d $source_dir);

    # Look for the target files in the source dir
686 687
    error("Cannot find both etc/bashrc in source directory ($source_dir)")
      if (! (-f "$source_dir/etc/bashrc"));
688 689

    # Only allow simple names, just for simplicity
690
    my $foam_name = make_safe_filename($register);
691
    error("Please use a simple registration name that is also valid as a filename; avoid shell meta characters that would need to be escaped (\"$register\" is not suitable)")
692
      if ($foam_name ne $register);
693 694 695 696

    # Ensure data directory exists
    if (! -d $data_dir) {
        system("mkdir -p $data_dir");
697
        error("Cannot make openfoam-selector data directory ($data_dir)")
698 699 700
          if (! -d $data_dir);
    }

701 702 703
    # See if there's already registered files for this OPENFOAM version
    if (-f "$data_dir/$foam_name") {
        verbose("$foam_name is already registered.");
704 705 706 707 708
        if (defined($yes)) {
            if (!$yes) {
                verbose("NOT overwriting previously registered files");
                exit(0);
            }
709
        } else {
710 711 712 713 714 715 716 717 718 719
            my $ans = get_yn("Overwrite the previously registered files?", 0);
            if (!$ans) {
                verbose("Did NOT overwrite previous files");
                exit(0);
            }
            verbose("Overwriting previously registered files");
        }
    }

    # Copy the files over
720 721 722 723 724 725 726 727 728 729
    verbose("Registering $source_dir");

    if (open my $fh, '>', "$data_dir/$foam_name")
    {
        print $fh "$source_dir\n";
    }
    else
    {
        error("Unable to register $source_dir to $data_dir -- aborting");
    }
730 731 732 733 734 735 736 737
}

#---------------------------------------------------------------------------

# Unregistration

elsif ($unregister) {
    # Only allow simple names, just for simplicity
738 739
    my $foam_name = make_safe_filename($unregister);
    if ($foam_name ne $unregister) {
740 741 742 743
        error("Please use a simple registration name that is also valid as a filename; avoid shell meta characters that would need to be escaped (\"$register\" is not suitable)");
    }

    # If the data directory does not exist, there's nothing to do
744
    error("Could not find $foam_name files registered")
745 746 747
      if (! -d $data_dir);

    # Look for the files in the data directory
748 749 750
    if (-f "$data_dir/$foam_name") {
        verbose("Unregistering $foam_name");
        unlink("$data_dir/$foam_name");
751

752 753
        warning("Unable to unregister $foam_name -- file not removed!")
          if (-f "$data_dir/$foam_name");
754
    } else {
755
        warning("No files found to unregister for $foam_name -- aborting");
756 757 758 759 760 761 762 763 764 765 766 767 768
    }
}

#---------------------------------------------------------------------------

# Listing

elsif ($list) {
    exit(0)
      if ($silent);

    if (-d $data_dir) {
        opendir(DIR, "$data_dir") ||
769
          error("Cannot open openfoam-selector data directory ($data_dir)");
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
        my @names = grep { -f "$data_dir/$_" } readdir(DIR);
        closedir(DIR);

        # Strip off the .sh/.csh endings
        my $index;
        foreach my $n (@names) {
            $n =~ s/\.sh$//;
            $n =~ s/\.csh$//;
            $index->{$n} = 1;
        }
        # Sort and print out what's left
        foreach my $n (sort(keys(%$index))) {
            print "$n\n";
        }
    }
}

#---------------------------------------------------------------------------

# Setting

elsif ($set) {
    my $file;

    # Check to see if the specified files exist
795 796
    error("OPENFOAM \"$set\" does not seem to be registered -- aborting")
      if (! -f "$data_dir/$set");
797 798 799 800 801 802 803 804

    # Which default are we changing?
    if ($system) {
        verbose("Setting system-wide default: $set");
        $file = "$sysconfig_dir/$sysconfig_file";
        # Ensure that the directory exists
        system("mkdir -p $sysconfig_dir")
          if (! -d $sysconfig_dir);
805
        error("Could not make openfoam-selector defaults directory ($sysconfig_dir)")
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
          if (! -d $sysconfig_dir);
    } else {
        verbose("Setting user-specific default: $set");
        $file = "$ENV{HOME}/$home_file";
    }

    # If the file already exist, prompt if they want to overwrite it
    if (-f $file) {
        if (defined($yes)) {
            if (!$yes) {
                verbose("NOT overwriting pre-existing default");
                exit(0);
            }
        } else {
            my $ans = get_yn("Defaults already exist; overwrite them?", 0);
            if (!$ans) {
                verbose("Defaults NOT overwritten");
                exit(0);
            }
        }
        verbose("Overwriting pre-existing default");
    }

    # Write it
    open(FILE, ">$file") ||
      error("Could not write to defaults file ($file) -- aborting");
    print FILE "$set\n";
    close(FILE);
}

#---------------------------------------------------------------------------

# Unsetting

elsif ($unset) {
    # If system, unlink the sysconfig file
    if ($system) {
        verbose("Removing system-wide default");
        unlink("$sysconfig_dir/$sysconfig_file") ||
845
          error("Unable to remove the openfoam-selector defaults file! ($sysconfig_dir/$sysconfig_file)");
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
        exit(0);
    }

    # Otherwise, we're unsetting user-level defaults.  So unlink the
    # file under $HOME
    my $file;
    $file = "$ENV{HOME}/$home_file";
    if (-f $file) {
        verbose("Removing user-specific default");
        unlink($file) ||
          error("Unable to remove user-level default file! ($file)");
    }
}

#---------------------------------------------------------------------------

# Querying

elsif ($query) {
    exit(0)
      if ($silent);

    my $files = {
        user => "$ENV{HOME}/$home_file",
        system => "$sysconfig_dir/$sysconfig_file",
    };

    do_query($files->{user}, "user")
        if ($user || !$system);
    do_query($files->{system}, "system")
        if ($system || !$user);
}

# Should never get here
exit(0);