Check-in [79707b28c0]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Import jmglov toolkit Import Josh Glover's toolkit from the subversion vendor branch
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 79707b28c0a8af1d0882cb9b83c4735195ab1614
User & Date: cfuhrman 2015-01-09 18:25:56
Context
2015-08-18
19:34
Perltidy check-in: 689e787a2b user: cfuhrman tags: trunk
2015-01-09
18:25
Import jmglov toolkit Import Josh Glover's toolkit from the subversion vendor branch check-in: 79707b28c0 user: cfuhrman tags: trunk
2014-12-29
16:41
Tagging last and final SVN revision of trunk git-svn-id: https://svn.fuhrbear.com/r/cmf-toolkit/tags/svn-last-commit-trunk@98 03f70f0e-8934-0410-994f-e4f8be170ec1 check-in: af92f57d61 user: cfuhrman@pobox.com tags: svn-last-commit-trunk, svn-to-fossil-conversion-base, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added contrib/jmglov-toolkit/COPYING.



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Copyright (c) 2004, Josh Glover <jmglov@jmglov.net>
Copyright (c) 2003, Josh Glover <jmglov@jmglov.net>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of the <ORGANIZATION> nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Added contrib/jmglov-toolkit/Makefile.





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Change this to the desired target bin directory
BIN_DIR = $$HOME/bin

# Flags for the C compiler
CFLAGS = -Wall -O2

# C programs that must be compiled
C_PROGS = c-sizes

# Scripts that need no compiling
SCRIPTS = cvs-add cvs-lock cvs-status cvs-unlock find-emacs-unsaved.sh hwhich \
          jabber-passwd lpr-code lpr-core lpr-diff mkpkg-sol pkg_find pman \
	  pwhich screen-shot wc-code window-shot

usage :
	@echo 'Usage: make install'

build: ${C_PROGS}

clean:
	rm *.o ${C_PROGS} 2>/dev/null; true

install : build
	for i in ${SCRIPTS} ${C_PROGS}; do \
	  cp $$i ${BIN_DIR}; \
	  chmod a+x ${BIN_DIR}/$$i; \
	done

c-sizes: c-sizes.o
	${CC} ${CFLAGS} -o c-sizes c-sizes.o

Added contrib/jmglov-toolkit/automount.sh.













































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/sh
#
# =========================================================================
# File: automount.sh
#
# Copyright (c) 2005 and onwards, Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# DESCRIPTION:
#
#   Automatically mounts devices in its watch list when they exist. This
#   is useful for hotplug storage devices (like USB hard drives or digital
#   cameras).
#
# USAGE:
#
#   echo "ams:234:respawn:${HOME}/bin/automount.sh" >>/etc/inittab
#   init q
#
# EXAMPLES:
#
#   See USAGE.
#
# DEPENDENCIES:
#
#   Bourne shell (/bin/sh)
#   grep
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2005/01/19): Initial revision
# =========================================================================


# A list of devices that you want to automount (i.e. the device that appears
# when you plug your USB device in)
DEVS="/dev/ide/host0/bus0/target0/lun0/part1"

# Set this to the number of seconds that should elapse between polling
# attempts (the lower the number, the more responsive, but more CPU
# time will be consumed)
SLEEPTIME=15

# Loop forever
while [ 1 ]; do

  # Iterate through devices
  for i in ${DEVS}; do

    # Does this device exist?
    if [ -e $i ]; then

      # Do not mount devices that are already mounted
      mount | grep "^$i" >/dev/null 2>&1
      if [ $? != 0 ]; then mount $i; fi

    fi # if (found the device)

  done # for (traversing devices)

  sleep ${SLEEPTIME}

done # while (looping forever)

Added contrib/jmglov-toolkit/burn-cd-audio.



























































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/perl -w

use strict;

use File::Basename qw(fileparse dirname basename);

my $ME = File::Basename::basename $0;

# General options
my $WORKDIR = '/scratch/burncd';

# cdrecord options
#
# -audio                write an audio CD
# driveropts=burnfree   turn on BurnFree
# -dao                  write disc at once
# -eject                eject when done
# fs=6144k              use a 6M ring buffer
# gracetime=5           wait five seconds before writing
# -text                 write CD-Text
# -useinfo              use *.inf files to overwrite audio options
# -v                    be verbose

my $CDRECORD_OPTS = '-audio driveropts=burnfree -dao -eject fs=6144k '.
  'gracetime=5 -pad -text -useinfo -v';

# Device to use for cdrecord (dev=$CDRECORD_DEV)
my $CDRECORD_DEV = 'ATAPI:0,0,0';

# Speed to use for cdrecord (speed=$CDRECORD_SPD)
my $CDRECORD_SPD = '12';

# oggdec options
#
# -b 16         16 bits per sample
my $OGGDEC_OPTS = '-b 16';

# lame options
#
# --decode	decode MP3 file
my $LAME_OPTS = '--decode';


sub usage {

  print STDERR "Usage: $0 <playlist>\n";

  exit 1;

} # usage()


my $playlist = shift @ARGV;
usage
  unless defined $playlist;

# Determine artist and album title
my $playfl = basename $playlist, '.m3u';

$playfl =~ s/\'/\'\\\'\'/g;
$playfl =~ /^(.+)\s\-\s(.+)$/;
my $artist = $1;
my $album  = $2;

print STDERR "Artist: $artist\nAlbum:  $album\n";

# Create a directory for this album in the work directory
mkdir $WORKDIR unless -d $WORKDIR;
mkdir "$WORKDIR/$playfl";

# Determine the directory name for the playlist
my $playdir = dirname $playlist;
$playdir =~ s/\'/\'\\\'\'/g;

# Open the playlist file for reading
open IN, $playlist
  or die "Could not open playlist file '$playlist'\n";

my $cdrecord = "cdrecord $CDRECORD_OPTS dev=$CDRECORD_DEV ".
  "speed=$CDRECORD_SPD";
while (<IN>) {

  next if /^#/;

  chomp( my $ifn = $_ );

  die "$ME: unsupported file type: $1\n"
    unless $ifn =~ /(\.mp3|\.ogg)$/i;
  my $ext = $1;
  my $pfn = fileparse $ifn, $ext;
  $ifn =~ s/\'/\'\\\'\'/g;

  my ($bfn, $pth, $suf) = fileparse $ifn, $ext;

  $bfn =~ /^[^\-]+\s-\s(.+)$/;
  my $track = $1;

  $cdrecord .= " '$WORKDIR/$playfl/$bfn.wav'";
  next
    if -f "$WORKDIR/$playfl/$pfn.wav";

  if ($ext =~ /\.mp3/i) {

    die "Could not decode MP3 file '$playdir/$ifn'\n"
      unless system( "lame $LAME_OPTS '$playdir/$ifn' ".
                     "'$WORKDIR/$playfl/$bfn.wav'" ) == 0;
  
  } # if (MP3)

  elsif ($ext =~ /\.ogg/i) {

    die "Could not decode Ogg Vorbis file '$playdir/$ifn'\n"
      unless system( "oggdec $OGGDEC_OPTS -o '$WORKDIR/$playfl/$bfn.wav' ".
                     "'$playdir/$ifn'" ) == 0;

  } # elsif (Ogg Vorbis)

  # Sanity check
  else { die "$ME: unsupported file type: $ext\n" }

  open INF, ">$WORKDIR/$playfl/$pfn.inf"
    or die "Could not open INF file '$WORKDIR/$playfl/$pfn.inf'\n";

  print( INF
	 "Performer=      '$artist'\n".
	 "Albumtitle=     '$album'\n".
	 "Tracktitle=     '$track'\n".
	 "Albumperformer= '$artist'\n" );

  close INF;

} # while (reading playlist file)

# Close the playlist file
close IN;

die "Command failed:\n$cdrecord\n"
  unless system( $cdrecord ) == 0;

print "CD written successfully: $artist - $album\n";

Added contrib/jmglov-toolkit/c-sizes.c.































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* ========================================================================
 * Copyright 2003 Josh Glover <jmglov@jmglov.net>
 *
 * LICENCE:
 *
 *   This file is distributed under the terms of the BSD License (version
 *   2). See the COPYING file, which should have been distributed with
 *   this file, for details. If you did not receive the COPYING file, see:
 *
 *   http://www.jmglov.net/opensource/licenses/bsd.txt
 *
 * c-sizes.c
 *
 * DESCRIPTION:
 *
 *   Displays the size of all the normal C types on the current
 *   architecture, with the GCC compiler.
 *
 * USAGE:
 *
 *   c-sizes
 *
 * EXAMPLES:
 *
 *   c-sizes
 *
 * DEPENDENCIES:
 *
 *   GCC
 *
 * TODO:
 *
 *   - Nothing, this code is perfect
 *
 * MODIFICATIONS:
 *
 *   Josh Glover <jmglov@jmglov.net> (2003/10/17): Initial revision
 * ========================================================================
 */

#include <stdio.h>

int main( void ) {

  printf( "Sizes of common C types:\n\n"
          " void *                  %d bytes\n\n"
          " char                    %d bytes\n"
          " unsigned char           %d bytes\n"
          " short                   %d bytes\n"
          " unsigned short          %d bytes\n"
          " int                     %d bytes\n"
          " unsigned int            %d bytes\n"
          " float                   %d bytes\n"
          " long                    %d bytes\n"
          " unsigned long           %d bytes\n"
          " double                  %d bytes\n"
          " long long               %d bytes\n"
          " unsigned long long      %d bytes\n"
          " long double             %d bytes\n"
          "\n",
          sizeof( void * ),
          sizeof( char ),
          sizeof( unsigned char ),
          sizeof( short ),
          sizeof( unsigned short ),
          sizeof( int ),
          sizeof( unsigned int ),
          sizeof( float ),
          sizeof( long ),
          sizeof( unsigned long ),
          sizeof( double ),
          sizeof( long long ),
          sizeof( unsigned long long ),
          sizeof( long double ) );
  
  // We are done, return success
  return 0;

} // main()

Added contrib/jmglov-toolkit/cpan-modrm.









































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/bin/env perl
#
# =========================================================================
# File: cpan-modrm
#
# Copyright (c) 2005 and onwards, Josh Glover <cpan@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the Artistic License, being
#   entirely derived from Alan Burlison's "modrm" example script from the
#   ExtUtils::MakeMaker CPAN module's documentation:
#
#   http://search.cpan.org/~mschwern/ExtUtils-MakeMaker-6.27/lib/ExtUtils/Packlist.pm
#
# DESCRIPTION:
#
#   Uninstalls a CPAN module that was installed with a .packlist file.
#
# USAGE:
#
#   cpan-modrm <module> {<module>}
#
# EXAMPLES:
#
#   ***
#
# DEPENDENCIES:
#
#   ExtUtils::MakeMaker CPAN distribution
#   IO::Dir CPAN module
#
# MODIFICATIONS:
#
#   Alan Burlison <Alan.Burlison@uk.sun.com> (???): Initial revision
#   Josh Glover <cpan@jmglov.net> (2005/04/12): Accept modules as command-
#     line arguments, added comments
# =========================================================================

use strict;
use warnings;

use IO::Dir;
use ExtUtils::Packlist;
use ExtUtils::Installed;

use subs qw(emptydir);


# Subroutine: emptydir()
#
# Determines whether a directory is empty.
#
# Parameters:
#
#   dir - directory name
#
# Returns:
#
#   True if directory is empty, false otherwise

sub emptydir($) {

    my ($dir) = @_;
    my $dh = IO::Dir->new($dir) || return(0);
    my @count = $dh->read();
    $dh->close();
    return(@count == 2 ? 1 : 0);

} # emptydir()


my @uninstalled;

# Find all the installed packages
print("Finding all installed modules...\n");
my $installed = ExtUtils::Installed->new();

foreach my $module (grep(!/^Perl$/, $installed->modules())) {

  # Skip this module unless it was specified on the command-line
  next unless grep { $module eq $_ } @ARGV;

  my $version = $installed->version( $module ) || "???";

  # Prompt the user
  print( "Found module $module Version $version\n",
         "Do you want to delete $module? [n] " );
  my $r = <STDIN>; chomp $r;

  # Remove the module
  if ($r && $r =~ /^y/i) {

    # Remove all the files in the packlist
    foreach my $file (sort $installed->files( $module )) {

      print  "rm $file\n";
      unlink $file;

    } # foreach (removing each file in the packlist)

    # Remove the packlist file itself
    my $pf = $installed->packlist( $module )->packlist_file();
    print  "rm $pf\n";
    unlink $pf;

    # Remove all empty directories
    foreach my $dir (sort $installed->directory_tree( $module )) {

      if (emptydir $dir) {

        print "rmdir $dir\n";
        rmdir $dir;

      } # if (removing empty directory)

    } # foreach (removing empty directories)

    # Add this to the list of modules we have uninstalled
    push @uninstalled, "$module $version";

  } # if (removing a module)

} # foreach (traversing installed modules)

# Display the list of modules that we uninstalled
if (@uninstalled) {

  print "Uninstalled ".@uninstalled." CPAN modules:\n  ";
  print join( "\n  ", @uninstalled ), "\n";

} # if (displaying modules that were uninstalled)

Added contrib/jmglov-toolkit/cvs-add.

























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# cvs-add
#
# DESCRIPTION:
#
#   Performs a recursive 'cvs add' command on the specified directory.
#
# USAGE:
#
#   cvs-add {<dir>} {<file>}
#
#     where:
#
#       <dir>  directory to add
#
#     If no arguments are given, cvs-add will recursively add the current
#     working directory.
#
# EXAMPLES:
#
#   cvs-add foo bar/bar.pl
#
# DEPENDENCIES:
#
#   Bash
#   CVS
#   grep
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/27): Added -R in order to
#     include files (and directories) that exist in the repository but not
#     locally
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================

# If we have no arguments, assume '.'
if [ -z "$1" ]; then

  args="."

else

  args="$@"
    
fi # if (assuming '.')

find ${args} | xargs cvs add

Added contrib/jmglov-toolkit/cvs-lock.

























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
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
562
563
564
565
566
567
568
569
570
571
572
#!/bin/sh
#
# =========================================================================
# Copyright 2004 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# cvs-lock
#
# DESCRIPTION:
#
#   Recursively locks a directory and all below it in a CVS repository.
#
# USAGE:
#
#   See usage(), below
#
# EXAMPLES:
#
#   cvs-lock -d /var/cvsroot --dir foobar -t
#   
#   cvs-lock: invoked with the following settings:
#   
#   cvsroot:  /var/cvsroot
#   dir:      foobar
#   dryrun:   0
#   lock:     wfl
#   quiet:    0
#   trace:    1
#   
#   touch /var/cvsroot/.foobar
#   lock_directory /var/cvsroot/foobar
#   Lock: /var/cvsroot/foobar
#   mkdir /var/cvsroot/foobar/#cvslock
#   touch /var/cvsroot/foobar/#cvs.wfl.1978
#   rmdir /var/cvsroot/foobar/#cvslock
#   cvs-lock: CVS repository /var/cvsroot directory foobar locked
#   echo "1978" >> /var/cvsroot/.foobar
#
# TODO:
#
#   - Implement locking a remote repository using CVS_RSH 
#   - Nothing, this code is perfect
#
# DEPENDENCIES:
#
#   Bourne shell
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/05/28): Initial revision;
#     modified Jennifer Vesperman's cvs-freeze.sh script (from O'Reilly's
#     _Essential CVS_): http://examples.oreilly.com/cvs/freeze.sh
# =========================================================================

# Constant: KEYMAGIC
#
# Unique key to append to lockfiles

KEYMAGIC="$$"

# Constant: ME
#
# Basename of the script

ME=`basename $0`

# Constant: MAXTRIES
#
# Maximum number of times to try before giving up

MAXTRIES=5

# Constant: TMPFILE
#
# Temporary file for recording lockfiles

TMPFILE="/tmp/cvs-lock.${KEYMAGIC}"

# Variable: cvsroot
#
# Path to CVS repository (defaults to $CVSROOT environment variable)

cvsroot="${CVSROOT}"

# Variable: dir
#
# Top-level directory in CVS repository to lock

dir=""

# Variable: dryrun
#
# If non-zero, run in dryrun mode

dryrun=0

# Variable: locktype
#
# Type of lock (rfl == read lock, wfl == write lock)

locktype="rfl"

# Variable: quiet
#
# If non-zero, informational messages will be suppressed

quiet=0

# Variable: trace
#
# If non-zero, each command will be spewed to STDOUT before it is run

trace=0


# Function: bail_out()
#
# Exit abruptly with an error code after displaying an error message.
#
# Parameters:
#
#   1 - error message to display

bail_out () {

  echo "${ME}: $1"
  rm -f ${TMPFILE}
  exit 1

} # bail_out()


# Function: is_locktype_valid()
#
# Checks the specified locktype for validity.
#
# Parameters:
#
#   1 - locktype string to check
#
# Returns:
#
#   0 if locktype is valid, 1 otherwise

is_locktype_valid () {

  if [ -z "$1" ]; then return 1; fi

  # Read lock?
  if [ "$1" = "rfl" ]; then return 0; fi

  # Write lock?
  if [ "$1" = "wfl" ]; then return 0; fi

  # If control reaches here, locktype is invalid
  return 1

} # is_locktype_valid()


# Function: lock_directory()
#
# Locks the specified directory.
#
# Parameters:
#
#   1 - directory to lock
#
# Returns:
#
#   0 on success, 1 on failure

lock_directory () {

  if [ ${quiet} -eq 0 ]; then echo "${ME}: lock: $1"; fi

  # Make sure we have a valid locktype
  if ! is_locktype_valid ${locktype}; then

    echo "${ME}: invalid locktype: ${locktype}"
    return 1

  fi # if (invalid locktype)

  # Obtain the master lock
  if [ ${trace} -ne 0 ]; then

    echo mkdir "$1/#cvslock"

  fi # if (trace mode)

  if [ ${dryrun} -eq 0 ]; then

    mkdir "$1/#cvslock"

  fi # if (dryrun mode?)

  # If we could not get the master lock, return failure
  if [ $? != 0  ]; then return 1; fi

  # Create the lock
  if [ ${trace} -ne 0 ]; then

    echo touch "$1/#cvs.${locktype}.${KEYMAGIC}"

  fi # if (trace mode)

  if [ ${dryrun} -eq 0 ]; then

    touch "$1/#cvs.${locktype}.${KEYMAGIC}"

  fi # if (dryrun mode?)

  # Record it in case of trouble
  echo $1 >> $TMPFILE

  # Release the master lock
  if [ ${trace} -ne 0 ]; then

    echo rmdir "$1/#cvslock"

  fi # if (trace mode)

  if [ ${dryrun} -eq 0 ]; then

    rmdir "$1/#cvslock"

  fi # if (dryrun mode?)

  return 0

} # lock_directory()


# Function: unlock_all()
#
# Removes all the locks we've produced during the run so far, because
# if we encounter anyone else playing with the CVS locks, then there's a
# small risk of deadlock. In that event, we should undo everything we've
# done to the repository, wait and try again.
#
# Returns:
#
#   0 on success, 1 on failure

unlock_all () {

  # Make sure we have a valid locktype
  if ! is_locktype_valid; then return 1; fi

  for i in `cat ${TMPFILE}`; do

    if [ $trace -ne 0 ]; then echo "Unlock: $i"; fi

    # Obtain the master lock
    if [ ${trace} -ne 0 ]; then

      echo mkdir "$i/#cvslock"

    fi # if (trace mode)

    if [ ${dryrun} -eq 0 ]; then

      mkdir "$i/#cvslock"

    fi # if (dryrun mode?)

    # Obtain the master lock
    if [ $? -eq 0 ]; then

      # Remove lock
      if [ ${trace} -ne 0 ]; then

        echo rm -f "$i/#cvs.${locktype}.${KEYMAGIC}"

      fi # if (trace mode)

      if [ ${dryrun} -eq 0 ]; then

        rm -f "$i/#cvs.${locktype}.${KEYMAGIC}"

      fi # if (dryrun mode?)

      # Remove masterlock
      if [ ${trace} -ne 0 ]; then

        echo rmdir "$dir/#cvslock"

      fi # if (trace mode)

      if [ ${dryrun} -eq 0 ]; then

        rmdir "$dir/#cvslock"

      fi # if (dryrun mode?)

    fi # if (obtained the master lock)

  done # for (looping through locked directories in ${TMPFILE})

  return 0

} # unlock_all()


# Function: lock_all()
#
# Recursively calls <lock_dir()> to lock a whole directory tree.
#
# Returns:
#
#   0 on success, 1 on failure

lock_all () {

  for i in `find ${cvsroot}/${dir} -type d ! -iname CVS ! -iname Attic ! -iname "#cvslock"`; do

    if ! lock_directory $i; then

      # We couldn't get the master lock. Someone else must be working on
      # the repository, so let's back off and return failure.
      unlock_all
      return 1

    fi # if (could not lock this directory)

  done # for (recursively freezing directories)

  return 0

} # lock_all()


# Function: usage()
#
# Displays a usage message and exits with the specified code.
#
# Parameters:
#
#   1 - return code (defaults to 255)

usage () {

  retval=$1
  if [ -z "${retval}" ]; then retval=255; fi

  cat <<EOF

Usage: ${ME} {<option>}

  where valid <option>s are:

    -d <root>    CVS repository to use (defaults to ${CVSROOT})
    --dir <dir>  directory relative to CVS root to lock
    --dryrun     do nothing, just show what would be done
    -H,--help    displays this message
    -q           be quiet (suppress informational messages)
    -r           create read locks (default)
    -t           trace execution and spew trace debuggery
    -w           create write locks (defaults to read locks)

EOF

  exit ${retval}

} # usage()


# Main program
# -------------------------------------------------------------------------


# Parse args
while [ -n "$1" ]; do

  if [ "$1" = "-d" ]; then

    cvsroot="$2"
    shift; shift
    continue

  fi # if (-d)

  if [ "$1" = "--dir" ]; then

    dir="$2"
    shift; shift
    continue

  fi # if (--dir)

  if [ "$1" = "--dryrun" ]; then

    dryrun=1
    quiet=1
    trace=1
    shift
    continue

  fi # if (--dryrun)

  if [ "$1" = "-H" -o "$1" = "--help" ]; then

    usage 0

  fi # if (-H,--help)

  if [ "$1" = "-q" ]; then

    quiet=1
    shift
    continue

  fi # if (-q)

  if [ "$1" = "-r" ]; then

    locktype="rfl"
    shift
    continue

  fi # if (-r)

  if [ "$1" = "-t" ]; then

    trace=1
    shift
    continue

  fi # if (-t)

  if [ "$1" = "-w" ]; then

    locktype="wfl"
    shift
    continue

  fi # if (-w)

  # If control reaches here, our option is bogus
  echo "${ME}: invalid option: $1"
  usage

done # while (parsing args)

if [ -z "${cvsroot}" ]; then

  echo "${ME}: No CVSROOT specified in the environment! You must either set the CVSROOT environment variable or use the --cvsroot option."
  usage

fi # if (no ${cvsroot})

if [ -z "${dir}" ]; then

  echo "${ME}: no --dir option, defaulting to locking whole ${cvsroot} repository"

fi # if (no ${dir})

if [ ${quiet} -eq 0 ]; then

  cat <<EOF

${ME}: invoked with the following settings:

cvsroot:  ${cvsroot}
dir:      ${dir}
dryrun:   ${dryrun}
lock:     ${locktype}
quiet:    ${quiet}
trace:    ${trace}

EOF

fi # if (spewing debuggery)

if ! [ -d ${cvsroot} ]; then

  bail_out "not a directory: ${cvsroot}"

fi # if (${cvsroot} is not a directory)

keyfile=""
if [ -n "${dir}" ]; then

  keyfile=${cvsroot}/.${dir}

else

  keyfile=${cvsroot}/.cvsroot

fi # if (setting ${keyfile})

if [ ${trace} -ne 0 ]; then

  echo touch ${keyfile}

fi # if (trace mode)

if [ ${dryrun} -eq 0 ]; then

  touch ${keyfile}

fi # if (dryrun mode?)

if [ $? -ne 0 ]; then

  bail_out "cannot touch: ${keyfile}"

fi # if (cannot touch ${keyfile})

tries=0
while ! lock_all; do

  let tries=${tries}+1

  echo "${ME}: could not lock, repository in use? (Attempt ${tries})"

  if [ ${tries} -gt ${MAXTRIES} ]; then

    bail_out "maximum number of tries (${MAXTRIES}) reached, giving up"

  fi # if (surpassed maximum allowable tries)

  echo "${ME}: sleeping 1 second between tries"

  if [ ${trace} -ne 0 ]; then

    echo sleep 1
    echo rm -f ${TMPFILE}

  fi # if (trace mode)

  sleep 1
  rm -f ${TMPFILE}

  echo "${ME}: trying again..."

done # while (recursively freezing the repository)

if [ ${quiet} -eq 0 ]; then

  echo "${ME}: CVS repository ${cvsroot} directory ${dir} locked"

fi # if (spewing debuggery)

# Save the key and clean up
if [ ${trace} -ne 0 ]; then

  echo 'echo "'${KEYMAGIC}'" >> '${keyfile}

fi # if (trace mode)

if [ ${dryrun} -eq 0 ]; then

  echo "${KEYMAGIC}" >> ${keyfile}

fi # if (dryrun mode?)

rm -f ${TMPFILE}

# Victory!
exit 0


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

Added contrib/jmglov-toolkit/cvs-status.























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# cvs-status
#
# DESCRIPTION:
#
#   Filters a 'cvs status' command for files that are not up to date.
#
# USAGE:
#
#   cvs-status {<dir>} {<file>}
#
# EXAMPLES:
#
#   cvs-status foo bar foobar
#
# DEPENDENCIES:
#
#   Bash
#   CVS
#   grep
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/27): Added -R in order to
#     include files (and directories) that exist in the repository but not
#     locally
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


cvs status -R $@ | grep 'Status: [^U]'

Added contrib/jmglov-toolkit/cvs-unlock.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
#!/bin/sh
#
# =========================================================================
# Copyright 2004 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# cvs-unlock
#
# DESCRIPTION:
#
#   Recursively unlocks a directory and all below it in a CVS repository.
#   The directory must have previously been locked by cvs-lock.
#
#   *A single run of unlock unlocks multiple runs of lock.*
#
# USAGE:
#
#   See usage(), below
#
# EXAMPLES:
#
#   ***
#
# TODO:
#
#   - Why does unlock_dir() fail to detect that the lockfile exists?
#   - Implement unlocking a remote repository using CVS_RSH 
#   - Nothing, this code is perfect
#
# DEPENDENCIES:
#
#   Bourne shell
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/05/28): Initial revision;
#     modified Jennifer Vesperman's cvs-unfreeze.sh script (from O'Reilly's
#     _Essential CVS_): http://examples.oreilly.com/cvs/unfreeze.sh
# =========================================================================

# Constant: ME
#
# Basename of the script

ME=`basename $0`

# Variable: cvsroot
#
# Path to CVS repository (defaults to $CVSROOT environment variable)

cvsroot="${CVSROOT}"

# Variable: dir
#
# Top-level directory in CVS repository to lock

dir=""

# Variable: dryrun
#
# If non-zero, run in dryrun mode

dryrun=0

# Variable: keymagic
#
# Unique key to append to lockfiles

keymagic=""

# Variable: quiet
#
# If non-zero, informational messages will be spewed to STDOUT

quiet=0

# Variable: tmpfile
#
# Temporary file for recording lockfiles

tmpfile=""

# Variable: trace
#
# If non-zero, each command will be spewed to STDOUT before it is run

trace=0

# Variable: unlock_read
#
# Unlock read locks?

unlock_read="rfl"

# Variable: unlock_write
#
# Unlock write locks?

unlock_write="wfl"


# Function: bail_out()
#
# Exit abruptly with an error code after displaying an error message.
#
# Parameters:
#
#   1 - error message to display

bail_out () {

  echo "${ME}: $1"
  rm -f ${tmpfile}
  exit 1

} # bail_out()


# Function: unlock_directory()
#
# Unlocks the specified directory.
#
# Parameters:
#
#   1 - directory to unlock
#
# Returns:
#
#   0 on success, 1 on failure

unlock_directory () {

  if [ ${quiet} -eq 0 ]; then echo "${ME}: unlock: $1"; fi

  # Obtain the master lock
  if [ ${trace} -ne 0 ]; then

    echo mkdir "$1/#cvslock"

  fi # if (trace mode?)

  if [ ${dryrun} -eq 0 ]; then

    mkdir "$1/#cvslock"

  fi # if (dryrun mode?)

  # If we could not get the master lock, return failure
  if [ $? != 0  ]; then return 1; fi

  # Unlock read and or write locks?
  for i in ${unlock_read} ${unlock_write}; do

    # Check for a lockfile
    if [ ${trace} -ne 0 ]; then

      echo test -f "$1/#cvs.$i.${keymagic}"

    fi # if (trace mode?)

    if [ ${dryrun} -eq 0 ]; then

      test -f "$1/#cvs.$i.${keymagic}"

    fi # if (dryrun mode?)

    # If we did not find a lockfile, spew a warning. Otherwise, remove the
    # lockfile
    if [ $? -ne 0 ]; then

      echo "${ME}: unlock: expected to find a lockfile: $1/#cvs.$i.${keymagic}"

    else

      if [ ${trace} -ne 0 ]; then

        echo rm -f "$1/#cvs.$i.${keymagic}"

      fi # if (trace mode?)

      if [ ${dryrun} -eq 0 ]; then

        rm -f "$1/#cvs.$i.${keymagic}"

      fi # if (dryrun mode?)

    fi # if (did we find a lockfile?)

    if [ ${quiet} -eq 0 ]; then

      echo "${ME}: $1/#cvs.$i.${keymagic} unlocked"

    fi # if (spewing debuggery)

  done # for (unlocking read and/or write locks)

  # Release the master lock
  if [ ${trace} -ne 0 ]; then

    echo rmdir "$1/#cvslock"

  fi # if (trace mode?)

  if [ ${dryrun} -eq 0 ]; then

    rmdir "$1/#cvslock"

  fi # if (dryrun mode?)

  return 0

} # unlock_directory()


# Function: unlock_all()
#
# Recursively calls <unlock_dir()> to unlock a whole directory tree.
#
# Returns:
#
#   0 on success, 1 on failure

unlock_all () {

  tmpfile=/tmp/lock.${keymagic}

  for i in `find ${cvsroot}/${dir} -type d ! -iname CVS ! -iname Attic ! -iname "#cvslock"`; do

    # If we cannot unlock this directory, return failure
    if ! unlock_directory $i; then return 1; fi

  done # for (unlocking all directories below ${dir}

  return 0

} # unlock_all()


# Function: usage()
#
# Displays a usage message and exits with the specified code.
#
# Parameters:
#
#   1 - return code (defaults to 255)

usage () {

  retval=$1
  if [ -z "${retval}" ]; then retval=255; fi

  cat <<EOF

Usage: ${ME} {<option>}

  where valid <option>s are:

    -d <root>    CVS repository to use (defaults to ${CVSROOT})
    --dir <dir>  directory relative to CVS root to lock
    --dryrun     do nothing, just show what would be done
    -H,--help    displays this message
    -q           be quiet (suppress informational messages)
    -r           unlock only read locks (defaults to both)
    -t           trace execution and spew trace debuggery
    -w           unlock only write locks (defaults to both)

EOF

  exit ${retval}

} # usage()


# Main program
# -------------------------------------------------------------------------


# Parse args
while [ -n "$1" ]; do

  if [ "$1" = "-d" ]; then

    cvsroot="$2"
    shift; shift
    continue

  fi # if (-d)

  if [ "$1" = "--dir" ]; then

    dir="$2"
    shift; shift
    continue

  fi # if (--dir)

  if [ "$1" = "--dryrun" ]; then

    dryrun=1
    quiet=1
    trace=1
    shift
    continue

  fi # if (--dryrun)

  if [ "$1" = "-H" -o "$1" = "--help" ]; then

    usage 0

  fi # if (-H,--help)

  if [ "$1" = "-q" ]; then

    quiet=1
    shift
    continue

  fi # if (-q)

  if [ "$1" = "-r" ]; then

    unlock_write=""
    shift
    continue

  fi # if (-r)

  if [ "$1" = "-t" ]; then

    trace=1
    shift
    continue

  fi # if (-t)

  if [ "$1" = "-w" ]; then

    unlock_read=""
    shift
    continue

  fi # if (-w)

  # If control reaches here, our option is bogus
  echo "${ME}: invalid option: $1"
  usage

done # while (parsing args)

if [ -z "${cvsroot}" ]; then

  echo "${ME}: No CVSROOT specified in the environment! You must either set the CVSROOT environment variable or use the --cvsroot option."
  usage

fi # if (no ${cvsroot})

if [ -z "${dir}" ]; then

  echo "${ME}: no --dir option, defaulting to unlocking whole ${cvsroot} repository"

fi # if (no ${dir})

if [ ${quiet} -eq 0 ]; then

  cat <<EOF

${ME}: invoked with the following settings:

cvsroot:       ${cvsroot}
dir:           ${dir}
dryrun:        ${dryrun}
quiet:         ${quiet}
trace:         ${trace}
unlock_read:   ${unlock_read}
unlock_write:  ${unlock_write}

EOF

fi # if (spewing debuggery)

if ! [ -d ${cvsroot} ]; then

  bail_out "not a directory: ${cvsroot}"

fi # if (${cvsroot} is not a directory)

keyfile=""
if [ -n "${dir}" ]; then

  keyfile=${cvsroot}/.${dir}

else

  keyfile=${cvsroot}/.cvsroot

fi # if (setting ${keyfile})

if [ ${trace} -ne 0 ]; then

  echo test -f ${keyfile}

fi # if (trace mode?)

if ! test -f ${keyfile}; then

  bail_out "no such file: ${keyfile}; directory does not appear to be frozen"

fi # if (does ${keyfile} exist?)

# Walk through each of the keys that the directory has been locked with
# and unlock each one in turn. *A single run of unlock unlocks multiple
# runs of lock.*
tries=0
for keymagic in `cat ${keyfile}`; do

  if ! unlock_all; then

    echo "${ME}: unable to obtain master locks for all directories"

    let tries=${tries}+1

    if [ ${tries} -gt ${MAXTRIES} ]; then

      bail_out "maximum number of tries (${MAXTRIES}) reached, giving up"

    fi # if (surpassed maximum allowable tries)

    echo "${ME}: sleeping 1 second between tries"

    if [ ${trace} -ne 0 ]; then

      echo sleep 1

    fi # if (trace mode?)

    sleep 1

    echo "${ME}: trying again..."

  else

    if [ ${quiet} -eq 0 ]; then

      echo "${ME}: directory ${dir} unlocked from lock ${keymagic}"

    fi # if (spewing debuggery)

  fi # if (did unlocking succeed?)

done # for (unlocking all locks)

if [ ${quiet} -eq 0 ]; then

  echo "${ME}: CVS repository ${cvsroot} directory ${dir} unlocked"

fi # if (spewing debuggery)

if [ ${trace} -ne 0 ]; then

  echo rm -f ${keyfile}

fi # if (trace mode?)

if [ ${dryrun} -eq 0 ]; then

  rm -f ${keyfile}

fi # if (dryrun mode?)

# Victory!
exit 0


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

Added contrib/jmglov-toolkit/find-emacs-unsaved.sh.























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/sh
#
# =========================================================================
# File: find-emacs-unsaved.sh
#
# Copyright (c) 2005 and onwards, Josh Glover <josh.glover@tfcci.com>
#
# LICENCE:
#
#   This file is distributed under the terms of the New BSD License.
#   See the COPYING file, which should have been distributed with
#   this file, for details. If you did not receive the COPYING file,
#   see:
#
#   http://www.jmglov.net/opensource/licences/bsd.txt
#
# DESCRIPTION:
#
#   Prints pathnames of files which have unsaved [X]Emacs buffers.
#
# USAGE:
#
#   See usage(), below
#
# EXAMPLES:
#
#   find-emacs-unsaved.sh
#
# TODO:
#
#   - Nothing, this code is perfect
#
# DEPENDENCIES:
#
#   Bourne shell (e.g. /bin/sh or Bash)
#
# MODIFICATIONS:
#
#   Josh Glover <josh.glover@tfcci.com> (2005/03/07): Initial revision
# =========================================================================

find . -type f -name \#\* | sed -e 's|\#\([^\#/]\+\)\#$|\1|g' | sort

Added contrib/jmglov-toolkit/find-tabs.























































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/bin/bash
#
# =========================================================================
# Copyright 2004 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# find-tabs
#
# DESCRIPTION:
#
#   For files containing tab characters, prints out the filename, the
#   number of tabs, and the last author to commit to CVS with the log
#   message.
#
# USAGE:
#
#   find-tabs {<option>} {<filename>}
#
#     where valid <option>s are:
#
#       --cvs          run 'cvs log'
#       --strip <ext>  strip <ext> from filename before cvs log
#
#   find-tabs will also read filenames from standard input if called
#   with no arguments.
#
# EXAMPLES:
#
#   find-tabs sys/time.h string.h netinet/in.h libretto/chain.h
#
# DEPENDENCIES:
#
#   Awk
#   Bash
#   CVS (unless using --no-cvs option)
#   GNU Grep (or any flavour of grep that supports the -c option)
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/05/14): Initial revision
# =========================================================================

CVS=""
STRIP=""

echo "$1" | grep '^-' &>/dev/null
retval=$?
while [ ${retval} -eq 0 ]; do

  if [ "$1" == "-c" -o "$1" == "--cvs" ]; then

    CVS=yes
    shift
    echo "$1" | grep '^-' &>/dev/null
    retval=$?
    continue

  fi # if (-c,--cvs)

  if [ "$1" == "-s" -o "$1" == "--strip" ]; then

    STRIP="$2"
    shift; shift
    echo "$1" | grep '^-' &>/dev/null
    retval=$?
    continue

  fi # (-s,--strip)

  echo "$0: invalid option: $1"
  exit 1

done # while (parsing args)

FILES=""
if [ -n "$1" ]; then

  FILES="$@"

else

  FILES=`cat`

fi # if (reading files from args or STDIN?)

for i in ${FILES}; do

  grep '	' $i &>/dev/null
  if [ $? -eq 0 ]; then

    file="$i"
    if [ -n "${STRIP}" ]; then

      file=`echo "$i" | sed -e "s/${STRIP}$//"`

    fi # if (need to strip an extension)

    tabs=`grep -c '	' $i`

    if [ -n "${CVS}" ]; then

      author=`cvs log ${file} 2>/dev/null | sed -ne 14p | awk -F';' '{ print $2 }' | awk -F':' '{ print $2 }'`
      msg=`cvs log ${file} 2>/dev/null | sed -ne 15p`

      echo "$i: ${tabs} tabs, last commit by ${author}:"
      echo ${msg}

    else

      echo "$i: ${tabs} tabs"

    fi # if (doing cvs?)

  fi # if (found tabs)

done # do (loop through files, looking for tabs)

Added contrib/jmglov-toolkit/hwhich.











































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/perl -w
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# hwhich
#
# DESCRIPTION:
#
#   Searches the standard header paths for the specified header file[s].
#
# USAGE:
#
#   hwhich {header_files}
#
# EXAMPLES:
#
#   hwhich sys/time.h string.h netinet/in.h libretto/chain.h
#
# DEPENDENCIES:
#
#   Perl 5
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


my @SEARCH = qw(/usr/include /usr/local/include);

foreach my $hdr (@ARGV) {

    $hdr .= '.h'
      unless $hdr =~ /\.h$/;

    foreach (@SEARCH) {

	print "$_/$hdr\n"
	  if (-e "$_/$hdr");

    } # foreach (@SEARCH)

} # foreach my $mod (@ARGV)

Added contrib/jmglov-toolkit/jabber-passwd.

















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# jabber-passwd
#
# DESCRIPTION:
#
#   Prints Jabber password for the specified user.
#
# USAGE:
#
#   See usage()
#
# EXAMPLES:
#
#   jabber-passwd -h jabber -s /usr/local/jabber/spool/jabber.tfcc.com jmglov
#
# DEPENDENCIES:
#
#   Bash
#   SSH
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/04/15): Initial revision
# =========================================================================


# Use the full paths to programs that are not in your path
SSH=ssh

# Default Jabberd host
HOST=jabber

# Default spool directory
SPOOL=/usr/local/jabber/spool/jabber.tfcc.com


# Display usage message
function usage {

 echo "Usage: $0 [-h <hostname>] [-s <spooldir>] <username>"
 echo
 echo "  where options are:"
 echo
 echo "    -h <hostname>	host of the Jabber server"
 echo "    -s <spooldir>        spool directory on Jabber server"
 echo
 echo "  And <username> is the username of the Jabber user for whom to"
 echo "  display the password"
 echo

} # usage()


host=${HOST}
spool=${SPOOL}
username=""

# Deal with args
while [ -n "$1" ]; do

  # If the arg is '--', shift it off, then stop parsing args
  if [ "$1" == "--" ]; then

    shift
    break
    
  fi # if (--)

  # If the arg does not begin with '-', stop parsing args
  echo "$1" | grep '^-' &>/dev/null
  if [ $? -ne 0 ]; then

    break

  fi # if (arg is not an option)

done

# If we don't have at least one arg, spew usage and die
if [ -z "$1" ]; then

  echo "No <username> specified!"
  usage
  exit 1

fi # if (no username arg)

username="$1"
shift

${SSH} ${host} grep password ${SPOOL}/${username}.xml

Added contrib/jmglov-toolkit/lpr-code.

















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# lpr-code
#
# DESCRIPTION:
#
#   Uses Enscript to pretty-print source code.
#
# USAGE:
#
#   lpr-code {source_files} {enscript_options}
#
# EXAMPLES:
#
#   lpr-code foo.c foo.h
#
# DEPENDENCIES:
#
#   Bourne-compatible shell (if not Bash, change the #! line)
#   Enscript
#   lpr-core (from this distribution)
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


# Use the full paths to programs that are not in your path
GREP=grep
LPR_CORE=lpr-core

# Default flags for Enscript (you can specify extra flags after the
# filename)
#
# -C  print line numbers
# -E  highlight source code
ENFLAGS='-C -E'

files=""
enflags=""

# Eat filenames until we first encounter a flag
while [ $1 ]; do
  
  echo "$1" | $GREP '^-' >/dev/null 2>&1
  if [ $? -ne 0 -a -z "$enflags" ]; then
  
    files="$files $1"

  else

    enflags="$enflags $1"

  fi
  shift

done

echo $LPR_CORE $files $ENFLAGS $enflags
$LPR_CORE $files $ENFLAGS $enflags

Added contrib/jmglov-toolkit/lpr-core.













































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# lpr-core
#
# DESCRIPTION:
#
#   Uses Enscript to pretty-print files.
#
# USAGE:
#
#   lpr-core {files} {enscript_options}
#
# EXAMPLES:
#
#   lpr-core foo.txt bar.c -C
#
# DEPENDENCIES:
#
#   Bourne-compatible shell (if not Bash, change the #! line)
#   Enscript
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


# Use the full paths to programs that are not in your path
ENSCRIPT=enscript
GREP=grep

# Default flags for Enscript (you can specify extra flags after the
# filename)
#
# -G			     print fancy page headers
# -j			     print borders around columns
# -2r			     print 2up landscape mode
# --color		     use colors in the highlighting outputs
# --mark-wrapped-lines=plus  print a plus (+) character on wrapped lines
#
ENFLAGS='-G -j -2r --color --mark-wrapped-lines=plus'

files=""
enflags=""
copies="1"

# Eat filenames until we first encounter a flag
while [ $1 ]; do
  
  echo "$1" | $GREP '^-' >/dev/null 2>&1
  if [ $? -ne 0 -a -z "$enflags" ]; then
  
    files="$files $1"

  else

    if [ $1 == "-#" ]; then

      shift
      copies="$1"

    else

      enflags="$enflags $1"

    fi

  fi
  shift

done

if [ -n "${files}" ]; then

  for i in `seq 1 ${copies}`; do
  
    echo $ENSCRIPT $ENFLAGS $enflags $files
    $ENSCRIPT $ENFLAGS $enflags $files

  done

else

  text=`cat`
  for i in `seq 1 ${copies}`; do
  
    echo "${text}" | $ENSCRIPT $ENFLAGS $enflags

  done

fi

Added contrib/jmglov-toolkit/lpr-diff.











































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# lpr-code
#
# DESCRIPTION:
#
#   Uses Enscript to pretty-print unified diffs.
#
# USAGE:
#
#   lpr-diff {source_files} {enscript_options}
#
# EXAMPLES:
#
#   diff -U file1.c file2.c | lpr-diff
#
# DEPENDENCIES:
#
#   Bourne-compatible shell (if not Bash, change the #! line)
#   Enscript
#   lpr-core (from this distribution)
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


# Use the full paths to programs that are not in your path
LPR_CORE=lpr-core

# Default flags for Enscript (you can specify extra flags after the
# filename)
#
# -Ediff  highlight source code in diff mode
ENFLAGS='-Ediffu'

files=""
enflags=""

while [ $1 ]; do
  
  echo "$1" | $GREP '^[^-]' >/dev/null 2>&1
  if [ $? -eq 0 -a -z "$enflags" ]; then
  
    files="$files $1"

  else

    enflags="$enflags $1"

  fi
  shift

done

echo $LPR_CORE $files $ENFLAGS $enflags
$LPR_CORE $files $ENFLAGS $enflags

Added contrib/jmglov-toolkit/mkpkg-sol.

















































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# mkpkg.sol
#
# DESCRIPTION:
#
#   Builds a Solaris package from installed software.
#
# USAGE:
#
#   See usage(), below
#
# EXAMPLES:
#
#   ***
#
# DEPENDENCIES:
#
#   Bourne shell
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/03/11): Initial revision
# =========================================================================

# Constants
VENDOR='TFCCI'
EMAIL='swdev@tfcci.com'
PKGMK_LOG=/tmp/mkpkg-sol_err.log

# Defaults
base=`pwd`
packlist=''
dirlist=''
prototype=''
pkginfo_pkg=''
pkginfo_name=''
pkginfo_arch=''
pkginfo_version=''
pkginfo_category=''
pkginfo_vendor=''
pkginfo_email=''
pkginfo_pstamp=''
pkginfo_basedir=''
pkginfo_classes=''
filename=''

function usage {

  echo "Usage: $0 (-d <dir>|-p <packlist>|-t <prototype>) [<optional args>]"
  echo
  echo "  Where <optional args> include:"
  echo
  echo "    --pkg <value>	package name (e.g. TFCsomepkg)"
  echo "    --name <value>	package description (e.g. Some Package)"
  echo "    --arch <value>	architecture (e.g. intel)"
  echo "    --version <value>	version (e.g. 1.2.7)"
  echo "    --category <value>	category (e.g application)"
  echo "    --vendor <value>	vendor (e.g. TFCCI)"
  echo "    --email <value>	support email address (e.g. swdev@tfcci.com)"
  echo "    --pstamp <value>	package stamp (your name)"
  echo "    --basedir <value>	base directory (e.g. /usr/local)"
  echo "    --classes <value>	classes (none)"
  echo "    --filename <value>  package filename (e.g. digest-sha)"

} # usage()

# If we have no arguments, bail
if [ -z "$1" ]; then
  usage
  exit 1
fi # if (no args)

### Parse arguments here
while [ -n "$1" ]; do

  # Display usage and exit if we see: --help, -h, -?
  if [ "$1" == "--help" -o "$1" == "-h" -o "$1" == "-?" ]; then

    usage
    exit

  fi # if (--help, -h, -?)

  # -d <directory>
  if [ "$1" == "-d" ]; then

    dirlist="$dirlist $2"
    shift; shift; continue

  fi # if (-d)

  # -p <packlist>
  if [ "$1" == "-p" ]; then

    packlist="$packlist $2"
    shift; shift; continue

  fi # if (-p)

  # -t <prototype>
  if [ "$1" == "-t" ]; then

    prototype="$2"
    shift; shift; continue

  fi # if (-t)

  # --pkg <value>
  if [ "$1" == "--pkg" ]; then

    pkginfo_pkg="$2"
    shift; shift; continue

  fi # if (--pkg)

  # --name <value>
  if [ "$1" == "--name" ]; then

    pkginfo_name="$2"
    shift; shift; continue

  fi # if (--name)

  # --arch <value>
  if [ "$1" == "--arch" ]; then

    pkginfo_arch="$2"
    shift; shift; continue

  fi # if (--arch)

  # --version <value>
  if [ "$1" == "--version" ]; then

    pkginfo_version="$2"
    shift; shift; continue

  fi # if (--version)

  # --category <value>
  if [ "$1" == "--category" ]; then

    pkginfo_category="$2"
    shift; shift; continue

  fi # if (--category)

  # --vendor <value>
  if [ "$1" == "--vendor" ]; then

    pkginfo_vendor="$2"
    shift; shift; continue

  fi # if (--vendor)

  # --email <value>
  if [ "$1" == "--email" ]; then

    pkginfo_email="$2"
    shift; shift; continue

  fi # if (--email)

  # --pstamp <value>
  if [ "$1" == "--pstamp" ]; then

    pkginfo_pstamp="$2"
    shift; shift; continue

  fi # if (--pstamp)

  # --basedir <value>
  if [ "$1" == "--basedir" ]; then

    pkginfo_basedir="$2"
    shift; shift; continue

  fi # if (--basedir)

  # --classes <value>
  if [ "$1" == "--classes" ]; then

    pkginfo_classes="$2"
    shift; shift; continue

  fi # if (--classes)

  # --filename <value>
  if [ "$1" == "--filename" ]; then

    filename="$2"
    shift; shift; continue

  fi # if (--filename)

  # If control reaches here, this option is bogus
  echo "Unknown option $1, ignoring"
  shift

done # while (parsing arguments)

# If a prototype already exists, make a backup
if [ -e prototype ]; then

  ext=`date +%Y-%m-%d_%H-%M-%S`
  echo "$0: prototype: file exists, making backup copy prototype.$ext"
  mv prototype prototype.$ext || exit 1

fi # if (backing up prototype file)

# Build prototype
if [ -n "$prototype" ]; then

  cp $prototype ./prototype || exit 1

else

  echo 'i pkginfo=./pkginfo' >./prototype || exit 1

fi # if (copying or starting prototype)

# If we have directories, add them to the prototype
if [ -n "$dirlist" ]; then

  for i in $dirlist; do
  
    if [ ! -d $i ]; then

      echo "$0: $i: No such directory"
      exit 1
    
    fi # if (file does not exist)

    find $i -print | pkgproto >>./prototype || exit 1

  done # for (adding directories to prototype)

fi # if (adding packing lists to prototype)

# If we have packing lists, add them to the prototype
if [ -n "$packlist" ]; then

  for i in $packlist; do
  
    if [ ! -f $i ]; then

      echo "$0: $i: No such file"
      exit 1
    
    fi # if (file does not exist)

    sed -e "s|$base|.|" -e "s|\([^ ]\+\) .\+$|\1|g" $i \
      | pkgproto >>./prototype || exit 1

  done # for (adding packing lists to prototype)

fi # if (adding packing lists to prototype)

# If a pkginfo already exists, make a backup
if [ -e pkginfo ]; then

  ext=`date +%Y-%m-%d_%H-%M-%S`
  echo "$0: pkginfo: file exists, making backup copy pkginfo.$ext"
  mv pkginfo pkginfo.$ext || exit 1

fi # if (backing up pkginfo file)

# Build pkginfo
echo -n '' >./pkginfo

# PKG
if [ -z "$pkginfo_pkg" ]; then

  echo -n 'PKG (e.g. TFCsomepkg): '
  read pkginfo_pkg
  
fi # if (prompting for PKG)

echo PKG=\"$pkginfo_pkg\" >>./pkginfo || exit 1

# NAME
if [ -z "$pkginfo_name" ]; then

  echo -n 'NAME (e.g. Some Package): '
  read pkginfo_name
  
fi # if (prompting for NAME)

echo NAME=\"$pkginfo_name\" >>./pkginfo || exit 1

# ARCH
if [ -z "$pkginfo_arch" ]; then

  # Attempt to detect architecture
  arch=''
  if [ `uname -i` == "i86pc" ]; then
    arch='intel'
  else
    arch='sparc'
  fi

  echo -n "ARCH [$arch]: "
  read pkginfo_arch

  # Default to detected architecture
  if [ -z "$pkginfo_arch" ]; then
    pkginfo_arch="$arch"
  fi
  
fi # if (prompting for ARCH)

echo ARCH=\"$pkginfo_arch\" >>./pkginfo || exit 1

# VERSION
if [ -z "$pkginfo_version" ]; then

  echo -n 'VERSION (e.g. 1.2.7): '
  read pkginfo_version
  
fi # if (prompting for VERSION)

echo VERSION=\"$pkginfo_version\" >>./pkginfo || exit 1

# CATEGORY
if [ -z "$pkginfo_category" ]; then

  category='application'
  echo -n "CATEGORY [$category]: "
  read pkginfo_category

  # Default to detected category
  if [ -z "$pkginfo_category" ]; then
    pkginfo_category="$category"
  fi
  
fi # if (prompting for CATEGORY)

echo CATEGORY=\"$pkginfo_category\" >>./pkginfo || exit 1

# VENDOR
if [ -z "$pkginfo_vendor" ]; then

  echo -n "VENDOR [$VENDOR]: "
  read pkginfo_vendor

  # Default to detected vendor
  if [ -z "$pkginfo_vendor" ]; then
    pkginfo_vendor="$VENDOR"
  fi
  
fi # if (prompting for VENDOR)

echo VENDOR=\"$pkginfo_vendor\" >>./pkginfo || exit 1

# EMAIL
if [ -z "$pkginfo_email" ]; then

  echo -n "EMAIL [$EMAIL]: "
  read pkginfo_email

  # Default to detected email
  if [ -z "$pkginfo_email" ]; then
    pkginfo_email="$EMAIL"
  fi
  
fi # if (prompting for EMAIL)

echo EMAIL=\"$pkginfo_email\" >>./pkginfo || exit 1

# PSTAMP
if [ -z "$pkginfo_pstamp" ]; then

  echo -n "PSTAMP (your name): "
  read pkginfo_pstamp

fi # if (prompting for PSTAMP)

echo PSTAMP=\"$pkginfo_pstamp\" >>./pkginfo || exit 1

# BASEDIR
if [ -z "$pkginfo_basedir" ]; then

  basedir=`pwd`
  echo -n "BASEDIR [$basedir]: "
  read pkginfo_basedir

  # Default to detected basedir
  if [ -z "$pkginfo_basedir" ]; then
    pkginfo_basedir="$basedir"
  fi
  
fi # if (prompting for BASEDIR)

echo BASEDIR=\"$pkginfo_basedir\" >>./pkginfo || exit 1

# CLASSES
if [ -z "$pkginfo_classes" ]; then

  classes='none'
  echo -n "CLASSES [$classes]: "
  read pkginfo_classes

  # Default to detected classes
  if [ -z "$pkginfo_classes" ]; then
    pkginfo_classes="$classes"
  fi
  
fi # if (prompting for CLASSES)

echo CLASSES=\"$pkginfo_classes\" >>./pkginfo || exit 1

# Make the package
pkgmk -o -r $pkginfo_basedir 2>$PKGMK_LOG || exit 1

# See if we have missing directory entries and fix them
grep '^WARNING: missing directory entry for' $PKGMK_LOG &>/dev/null
if [ $? -eq 0 ]; then
  echo 'Adding missing directories'
  grep '^WARNING: missing directory entry for' $PKGMK_LOG |\
   awk -F'<' '{print $2}' | awk -F'>' '{print $1}' | pkgproto >>./prototype
  pkgmk -o -r $pkginfo_basedir
fi
rm $PKGMK_LOG

# Prompt for filename if it wasn't specified
if [ -z "$filename" ]; then

  echo -n "Enter package filename (e.g. some-package): "
  read filename

fi # if (prompting for filename)

rel=sol`uname -r | awk -F. '{ print $2 }'`
file=$filename-$pkginfo_version-$rel-$pkginfo_arch-local

# Create the package archive file
cd /var/spool/pkg
pkgtrans -s `pwd` /tmp/$file

# Zip the package archive file
cd /tmp
gzip $file

echo "$0: Package /tmp/$file.gz successfully created"

Added contrib/jmglov-toolkit/pkg_find.







































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# pkg_find
#
# DESCRIPTION:
#
#   Searches NetBSD's pkgsrc for the specified packages.
#
# USAGE:
#
#   pkg_find {packages}
#
# EXAMPLES:
#
#   pkg_find bash postfix sudo
#
# DEPENDENCIES:
#
#   Awk
#   Bourne-compatible shell (if not Bash, change the #! line)
#   Grep
#   NetBSD with pkgsrc
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/06): Initial CVS revision
# =========================================================================


PKGSRC=/usr/pkgsrc
INDEX=${PKGSRC}/README-all.html

while [ "$1" ]; do

  grep -i "^<!-- .*${1}.* -->" ${INDEX} | awk -F '<TD>' '{ print $2 }' | \
    awk -F '/README.html' '{ print $1 }' | awk -F 'href="' '{ print $2 }'
  shift

done

Added contrib/jmglov-toolkit/pman.

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# pman
#
# DESCRIPTION:
#
#   System programmer's front-end to Man, searches sections 2 and 3 of the
#   man pages first.
#
# USAGE:
#
#   pman {man_pages}
#
# EXAMPLES:
#
#   pman exit printf
#
# DEPENDENCIES:
#
#   Bourne-compatible shell (if not Bash, change the #! line)
#   GNU Man
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


man 2 "$@" 2>/dev/null
if [ $? -eq 0 ]; then exit; fi
man 3 "$@" 2>/dev/null
if [ $? -eq 0 ]; then exit; fi
man "$@" 2>/dev/null

Added contrib/jmglov-toolkit/pwhich.











































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/perl -w
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# pwhich
#
# DESCRIPTION:
#
#   Searches the standard Perl include paths for the specified modules.
#
# USAGE:
#
#   pwhich {perl_modules}
#
# EXAMPLES:
#
#   pwhich POSIX TFC::Base Tree::Nary FileHandle
#
# DEPENDENCIES:
#
#   Perl 5
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


foreach my $mod (@ARGV) {

    $mod =~ s/\:\:/\//g;
    $mod =~ s/\s+$//;
    $mod .= '.pm'
      unless $mod =~ /\.pm$/;

    foreach (@INC) {

	print "$_/$mod\n"
	  if (-e "$_/$mod");

    } # foreach (@INC)
    
} # foreach my $mod (@ARGV)

Added contrib/jmglov-toolkit/screen-shot.





















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# screen-shot
#
# DESCRIPTION:
#
#   Uses ImageMagick's import program to take a screen shot
#
# USAGE:
#
#   screen-shot
#
# EXAMPLES:
#
#   screen-shot
#
# DEPENDENCIES:
#
#   Bourne-compatible shell (if not Bash, change the #! line)
#   ImageMagick
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/02/26): Initial revision
# =========================================================================


# Use the full paths to programs that are not in your path
IMPORT=import

$IMPORT -window root screen-shot_`date +%s`.jpg

Added contrib/jmglov-toolkit/stopwatch.















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/perl -w
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licences/bsd.txt
#
# stopwatch
#
# DESCRIPTION:
#
#   Command-line interactive stopwatch.
#
# USAGE:
#
#   stopwatch {<ENTER>}
#
# EXAMPLES:
#
#   : jmglov@foo; stopwatch
#   Press <Enter> to start timing.
#   <Enter>
#   Timing...
#   <Enter>
#   2.84 sec<Enter>
#   1.82 sec<Enter>
#   2.07 sec<Enter>
#   1.32 sec<Enter>
#   1.29 sec<Enter>
#   1.24 sec<Enter>
#   1.36 sec<Enter>
#   1.56 sec<Ctrl-C>
#   : jmglov@foo;
#
# DEPENDENCIES:
#
#   Perl 5
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/12/29): Initial revision
# =========================================================================

use strict;

use Time::HiRes qw( gettimeofday tv_interval );

print "Press <Enter> to start timing.\n";

my $junk = <STDIN>;

print "Timing...\n";

# Loop forever (SIGINT to exit)
while (1) {

  my $start = [gettimeofday];

  $junk = <STDIN>;

  my $elapsed = tv_interval $start, [gettimeofday];

  printf "%.02f sec", $elapsed;

} # while (looping forever)

Added contrib/jmglov-toolkit/svn-changed.























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/sh
#
# =========================================================================
# File: svn-changed
#
# Copyright 2004 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# DESCRIPTION:
#
#   Shows the files that changed in a certain revision.
#
# USAGE:
#
#   svn-changed <rev>
#
# EXAMPLES:
#
#   ***
#
# DEPENDENCIES:
#
#   Awk
#   /bin/sh
#   grep
#   Subversion
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/12/01): Initial revision
# =========================================================================

rev=$1
let "prev = rev - 1"

svn diff -r $prev:$rev | grep '^Index:' | awk '{ print $2 }'

Added contrib/jmglov-toolkit/svn-gen-patch.

































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/sh
#
# =========================================================================
# File: svn-gen-patch
#
# Copyright (c) 2005 and onwards, Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# DESCRIPTION:
#
#   Generates a patch with all of the changes from a certain revision.
#
# USAGE:
#
#   svn-changed <rev> {<rev>}
#
# EXAMPLES:
#
#   ***
#
# DEPENDENCIES:
#
#   Awk
#   /bin/sh
#   grep
#   Subversion
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2005/03/29): Initial revision
# =========================================================================

while test -n "$1"; do

  rev=$1; shift
  let "prev = rev - 1"

  echo "Generating patch for revision ${rev}: ${rev}.patch"
  svn diff -r $prev:$rev >"${rev}.patch" || exit 1

done # while (generating patches)

Added contrib/jmglov-toolkit/svn-merge.



















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/bin/sh
#
# =========================================================================
# File: svn-merge
#
# Copyright (c) 2005 and onwards, Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# DESCRIPTION:
#
#   Merges all changes from one or more revisions from a branch to the
#   current working directory in the working copy.
#
# USAGE:
#
#   svn-merge <repos> <branch> <pre_msg> <rev> {<rev>}
#
# EXAMPLES:
#
#   ***
#
# DEPENDENCIES:
#
#   Awk
#   /bin/sh
#   grep
#   Subversion
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2005/03/29): Initial revision
# =========================================================================

repos="$1";   shift
branch="$1";  shift
pre_msg="$1"; shift

# Validate params
if test -z "$1"; then

  echo 'Usage: '"$0"' <repos> <branch> <pre_msg> <rev> {<rev>}' 1>&2
  exit 255

fi

# Iterate over revisions
while test -n "$1"; do

  rev=$1; shift
  let "prev = rev - 1"

  echo
  echo "Merging revision ${rev} from ${branch}"
  echo "svn merge -r $prev:$rev ${repos}/${branch}"

  svn merge -r $prev:$rev "${repos}/${branch}" || exit $?

  echo
  echo 'Current status:'
  svn stat -u
  echo "svn commit -m '${pre_msg} merged in from ${branch} (-r $prev:$rev)'"

  echo -n "Commit OK? (y/n) "
  read prompt
  echo "${prompt}" | grep -i '^y$' >/dev/null 2>&1
  retval=$?

  # Skip to the next iteration unless the user answered in the affirmative
  if test ${retval} -ne 0; then

    echo 1>&2
    echo 'Aborted! You will probably want to run "svn revert" to clean up' \
      1>&2
    exit 1

  fi

  # If control reaches here, go ahead with the commit
  svn commit -m "${pre_msg} merged in from ${branch} (-r $prev:$rev)" \
   || exit $?

done # while (generating patches)

Added contrib/jmglov-toolkit/svn-switch.











































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/bin/sh
#
# =========================================================================
# File: svn-switch
#
# Copyright (c) 2005 and onwards, Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# DESCRIPTION:
#
#   Switches one or more files in a working copy to a different location
#   in the repository.
#
# USAGE:
#
#   See USAGE, below.
#
# EXAMPLES:
#
#   ***
#
# DEPENDENCIES:
#
#   grep
#   Subversion
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2005/04/21): Initial revision
# =========================================================================


# Constants
# -------------------------------------------------------------------------

# Constant: ME
#
# Basename of script

ME=`basename $0`

# Constant: USAGE
#
# Usage message

USAGE="${ME}"': {<option>} <repos_loc> <files>
  where valid <option>s are:

    -r		reverse previous switch by switching all currently
      		switched files'


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


# Main program
# -------------------------------------------------------------------------


# Parse options
reverse=0
while test -n "$1"; do

  # Break out of the loop when we find a non-option argument
  echo "$1" | grep '^-' >/dev/null 2>&1
  if test $? -ne 0; then break; fi

  # -r
  if test "$1" = "-r"; then

    reverse=1
    shift
    continue

  fi # if (-r)

  # If control reaches here, we have an invalid option
  echo "${ME}: ignoring unrecognised option: $1" 1>&2
  shift

done # while (parsing options)

# Grab remaining command-line arguments
rloc="$1"; shift
files="";  shift

if test -z "${rloc}"; then

  echo "${USAGE}" 1>&2
  exit 255

fi # if (no <repos_loc>)

# For a reverse switch, find out which files are currently switched
if test ${reverse} -ne 0; then

  files=`svn stat -u | grep '^ \+S' | awk '{print $3}'`

fi # if (determining filenames for a reverse switch)

# Switch all of the files
for i in ${files}; do

  echo svn switch "${rloc}/${i}" "${i}"
  svn switch "${rloc}/${i}" "${i}"

done # for (switching files)


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

Added contrib/jmglov-toolkit/tempconv.

























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/perl -w
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# tempconv
#
# DESCRIPTION:
#
#   Converts one or more temperatures in Fahrenheit to Celsius, or vice-
#   versa.
#
# USAGE:
#
#   tempconv {options} <temp1>[:<temp2>|(<temp3> ... <tempN>)]
#
#     where valid options are:
#
#       -c  temperatures are in Celsius (default)
#       -f  temperatures are in Fahrenheit
#       -i  interval when a range is specified (default is 0.1)
#
#     to specify a range of temperatures, use the <start>:<stop> notation
#
# EXAMPLES:
#
#   tempconv -f -i .2 96.0-97.0
#
#
# DEPENDENCIES:
#
#   Perl 5
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/12/08): Initial revision
# =========================================================================

use strict;

use Getopt::Long;

# Parse arguments
my $celsius;
my $fahrenheit;
my $interval = 0.1;

GetOptions( 'c' => \$celsius, 'f' => \$fahrenheit, 'i=f' => \$interval )
  or die "GetOptions() failed\n";

$celsius = 1
  unless $fahrenheit;

# Grab all the temperatures
my @input;
foreach (@ARGV) {

  if (/^(\d+\.\d+):(\d+\.\d+)$/) {

    for (my $t = $1; $t <= $2; $t += $interval) {

      push @input, $t;

    } # for (filling @input with a range)

  } # if (we hit a range, put all of the range into @input)

  else {

    push @input, $_;

  } # else (single temperature)

} # foreach (grabbing input temperatures from @ARGV)

# Convert input temperatures to output ones
my @output;
foreach (@input) {

  # If input temperatures are Celsius, convert to Fahrenheit, and vice-versa
  if ($celsius) {

    push @output, (($_ * 1.8) + 32);

  } else {

    push @output, (($_ - 32) / 1.8);

  } # else

} # foreach (converting temperatures)

# Display converted temperatures
for (0 .. $#input) {

  printf( "%.02f %s => %.02f %s\n",
	  $input[$_], ($celsius ? "C" : "F"),
	  $output[$_], ($celsius ? "F" : "C") );

} # for (displaying converted temperatures)

Added contrib/jmglov-toolkit/wc-code.



















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/perl -w
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# wc-code
#
# DESCRIPTION:
#
#   For a list of C/C++ source code, displays the total number of lines,
#   lines of code, lines of comments, and blank lines.
#
# USAGE:
#
#   wc-code {source files}
#
# EXAMPLES:
#
#   wc-code *.c *.h
#
# DEPENDENCIES:
#
#   Perl 5
#
# TODO:
#
#   - Detect and handle Perl / shell scripts (to deal with comments)
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2003/10/05): Initial CVS revision
# =========================================================================


my $lines    = 0;
my $code     = 0;
my $comments = 0;
my $blank    = 0;


foreach (@ARGV) {

    my $in_comment = 0;

    die( "Could not open file '$_'\n" )
      unless open( IN, $_ );

    while (<IN>) {

	$lines++;

	if ($in_comment) {

	    $comments++;

	    $in_comment = 0
	      if (/\*\//);

	    next;

	} # if (we are in a comment)

	if (/^\s*$/) {

	    $blank++;
	    next;

	} # if (blank line)

	if (/^\s*\/\//) {

	    $comments++;
	    next;

	} # if (comment line)
	
	if (/^\s*\/\*/) {

	    $comments++;
	    $in_comment = 1;
	    next;

	} # if (start of multi-line comment)

	$code++;

    } # while (reading file)

    close( IN );

} # while (processing files)

printf( "Total lines: %d\n", $lines );
printf( " code:        %d (%.1f%%)\n", $code, ($code / $lines * 100) );
printf( " comments:    %d (%.1f%%)\n", $comments,
	($comments / $lines * 100) );
printf( " blank lines: %d (%.1f%%)\n", $blank, ($blank / $lines * 100) );

Added contrib/jmglov-toolkit/window-shot.























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
#
# =========================================================================
# Copyright 2003 Josh Glover <jmglov@jmglov.net>
#
# LICENCE:
#
#   This file is distributed under the terms of the BSD License (version
#   2). See the COPYING file, which should have been distributed with this
#   file, for details. If you did not receive the COPYING file, see:
#
#   http://www.jmglov.net/opensource/licenses/bsd.txt
#
# window-shot
#
# DESCRIPTION:
#
#   Uses ImageMagick's import program to take a screen shot of a window
#   (user-selectable with the mouse).
#
# USAGE:
#
#   window-shot
#
# EXAMPLES:
#
#   window-shot
#
# DEPENDENCIES:
#
#   Bourne-compatible shell (if not Bash, change the #! line)
#   ImageMagick
#
# MODIFICATIONS:
#
#   Josh Glover <jmglov@jmglov.net> (2004/02/26): Initial revision
# =========================================================================


# Use the full paths to programs that are not in your path
IMPORT=import

$IMPORT window-shot_`date +%s`.jpg