project: cmd comerr
+tests: all
+ ${COMPILE_PART1} tests ${COMPILE_PART2}
+
config:
${COMPILE_PART1} config ${COMPILE_PART2}
src/sia/Makefile \
src/sys/Makefile \
src/tbutc/Makefile \
+src/tests/Makefile \
+src/tests/Dirpath.pm \
src/tools/Makefile \
src/tsm41/Makefile \
src/tviced/Makefile \
--- /dev/null
+# This is -*- perl -*-
+
+package OpenAFS::Auth;
+use OpenAFS::Dirpath;
+
+use strict;
+#use vars qw( @ISA @EXPORT );
+#@ISA = qw(Exporter);
+#require Exporter;
+#@EXPORT = qw($openafs-authadmin $openafs-authuser);
+
+sub getcell {
+ my($cell);
+ open(CELL, "$openafsdirpath->{'afsconfdir'}/ThisCell")
+ or die "Cannot open $openafsdirpath->{'afsconfdir'}/ThisCell: $!\n";
+ $cell = <CELL>;
+ chomp $cell;
+ close CELL;
+ return $cell;
+}
+
+sub getrealm {
+ my($cell);
+ open(CELL, "$openafsdirpath->{'afsconfdir'}/ThisCell")
+ or die "Cannot open $openafsdirpath->{'afsconfdir'}/ThisCell: $!\n";
+ $cell = <CELL>;
+ chomp $cell;
+ close CELL;
+ $cell =~ tr/a-z/A-Z/;
+ return $cell;
+}
+
+sub authadmin {
+ my $cell = &getrealm;
+ my $cmd = "kinit -k -t /usr/afs/etc/krb5.keytab admin\@${cell} ; afslog";
+ system($cmd);
+}
+sub authuser {
+ my $cell = &getrealm;
+ my $cmd = "kinit -k -t /usr/afs/etc/krb5.keytab user\@${cell} ; afslog";
+ system($cmd);
+}
+
+1;
--- /dev/null
+## CMUCS AFStools
+## Copyright (c) 1996, 2001 Carnegie Mellon University
+## All Rights Reserved.
+#
+# Permission to use, copy, modify and distribute this software and its
+# documentation is hereby granted, provided that both the copyright
+# notice and this permission notice appear in all copies of the
+# software, derivative works or modified versions, and any portions
+# thereof, and that both notices appear in supporting documentation.
+#
+# CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+# CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+# ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+#
+# Carnegie Mellon requests users of this software to return to
+#
+# Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
+# School of Computer Science
+# Carnegie Mellon University
+# Pittsburgh PA 15213-3890
+#
+# any improvements or extensions that they make and grant Carnegie Mellon
+# the rights to redistribute these changes.
+#
+# CMU_copyright.pm - CMU copyright
+# This isn't a real package; it merely provides a central location to keep
+# information regarding redistribution of this set of modules, and to make
+# sure that no one can use the modules (at least, as shipped) without also
+# having a copy of these terms.
+
+package AFS::CMU_copyright;
+
+1;
--- /dev/null
+# This is -*- perl -*-
+
+package OpenAFS::ConfigUtils;
+
+use strict;
+use vars qw( @ISA @EXPORT @unwinds);
+@ISA = qw(Exporter);
+require Exporter;
+@EXPORT = qw(@unwinds run unwind);
+
+sub run ($) {
+ print join(' ', @_);
+ print "\n";
+ system (@_) == 0
+ or die "Failed: $?\n";
+}
+
+# This subroutine takes a command to run in case of failure. After
+# each succesful step, this routine should be run with a command to
+# undo the successful step.
+
+ sub unwind($) {
+ push @unwinds, $_[0];
+ }
+
+1;
--- /dev/null
+# This is -*- perl -*-
+
+package OpenAFS::Dirpath;
+
+use strict;
+use vars qw( @ISA @EXPORT $openafsdirpath);
+@ISA = qw(Exporter);
+require Exporter;
+@EXPORT = qw($openafsdirpath);
+
+# Dirpath configuration
+$openafsdirpath = {
+ 'afsconfdir' => '@afsconfdir@',
+ 'viceetcdir' => '@viceetcdir@',
+ 'afssrvbindir' => '@afssrvbindir@',
+ 'afssrvsbindir' => '@afssrvsbindir@',
+ 'afssrvlibexecdir' => '@afssrvlibexecdir@',
+ 'afsdbdir' => '@afsdbdir@',
+ 'afslogsdir' => '@afslogsdir@',
+ 'afslocaldir' => '@afslocaldir@',
+ 'afsbackupdir' => '@afsbackupdir@',
+ 'afsbosconfigdir' => '@afsbosconfigdir@'
+};
+
+1;
--- /dev/null
+# Generated automatically from Makefile.in by configure.
+srcdir = .
+include /usr/src/openafs/openafs/src/config/Makefile.config
+
+SHELL = /bin/sh
+
+CFLAGS = -I. -I${srcdir} ${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
+LDFLAGS=${DBG} ${OPTMZ} ${XLDFLAGS}
+
+SYS_LIBS = ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a
+
+AUTH_LIBS = ${TOP_LIBDIR}/libauth.a ${SYS_LIBS}
+
+INT_LIBS = ${TOP_LIBDIR}/libafsint.a ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a
+
+TEST_PROGRAMS = write-ro-file hello-world read-vs-mmap read-vs-mmap2 \
+ mmap-and-read large-dir large-dir2 large-dir3 mountpoint \
+ test-setgroups test-setpag hardlink1 hardlink2 mkdir2 \
+ create-files create-symlinks create-dirs dup2-and-unlog \
+ readdir-vs-lstat read-write create-remove mkdir3 \
+ symlink echo-n test-parallel1 test-parallel2 create-stat \
+ kill-softly kill-softer rm-rf exit-wo-close \
+ mmap-vs-read mmap-vs-read2 strange-characters-c pine \
+ append-over-page write-ucc utime-dir mmap-shared-write \
+ rename5 rename-under-feet write-closed write-closed2 \
+ truncate fchmod make-page utime-file rename6 \
+ write3 still-there-p write-large afscp hardlink4 \
+ intr-read asu truncate-files mmap-cat blocks-new-file \
+ fsx write-rand
+
+TEST_OBJS = write-ro-file.o read-vs-mmap.o read-vs-mmap2.o \
+ mmap-and-read.o large-dir.o large-dir2.o large-dir3.o \
+ test-setgroups.o test-setpag.o hardlink1.o hardlink2.o \
+ mkdir2.o create-files.o create-symlinks.o create-dirs.o \
+ dup2-and-unlog.o readdir-vs-lstat.o read-write.o \
+ create-remove.o symlink.o echo-n.o test-parallel1.o \
+ test-parallel1.o mkdir3.o rename6.o \
+ create-stat.o kill-softly.o kill-softer.o rm-rf.o \
+ exit-wo-close.o mmap-vs-read.o mmap-vs-read2.o \
+ strange-characters-c.o pine.o append-over-page.o \
+ write-ucc.o utime-dir.o mmap-shared-write.o rename5.o \
+ rename-under-feet.o write-closed.o write-closed2.o \
+ truncate.o fchmod.o make-page.o utime-file.o \
+ write3.o still-there-p.o write-large.o hardlink4.o \
+ intr-read.o asu.o truncate-files.o mmap-cat.o \
+ blocks-new-file.o fsx.o afscp.o afscp_callback.o \
+ write-rand.o
+
+TEST_SRCS = write-ro-file.c read-vs-mmap.c read-vs-mmap2.c \
+ mmap-and-read.c large-dir.c large-dir2.c large-dir3.c \
+ test-setgroups.c test-setpag.c hardlink1.c hardlink2.c \
+ mkdir2.c create-files.c create-symlinks.c create-dirs.c \
+ dup2-and-unlog.c readdir-vs-lstat.c read-write.c \
+ create-remove.c symlink.c echo-n.c test-parallel1.c \
+ test-parallel2.c mkdir3.c rename6.c \
+ create-stat.c kill-softly.c kill-softer.c rm-rf.c \
+ exit-wo-close.c mmap-vs-read.c mmap-vs-read2.c \
+ strange-characters-c.c pine.c append-over-page.c \
+ write-ucc.c utime-dir.c mmap-shared-write.c rename5.c \
+ rename-under-feet.c write-closed.c write-closed2.c \
+ truncate.c fchmod.c make-page.c utime-file.c \
+ write3.c still-there-p.c write-large.c hardlink4.c \
+ intr-read.c asu.c truncate-files.c mmap-cat.c \
+ blocks-new-file.c fsx.c afscp.c afscp_callback.c \
+ write-rand.c
+
+EXTRA_OBJS = err.o errx.o warn.o warnx.o
+
+all: run-tests $(TEST_PROGRAMS) OS.pm
+
+OS.pm: OS-$(MKAFS_OSTYPE).pm
+ $(CP) OS-$(MKAFS_OSTYPE).pm OS.pm
+
+write-rand: write-rand.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-rand.o $(EXTRA_OBJS) $(LIBS)
+
+write-ro-file: write-ro-file.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-ro-file.o $(EXTRA_OBJS) $(LIBS)
+
+write-large: write-large.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-large.o $(EXTRA_OBJS) $(LIBS)
+
+read-vs-mmap: read-vs-mmap.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ read-vs-mmap.o $(EXTRA_OBJS) $(LIBS)
+
+read-vs-mmap2: read-vs-mmap2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ read-vs-mmap2.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-vs-read: mmap-vs-read.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-vs-read.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-vs-read2: mmap-vs-read2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-vs-read2.o $(EXTRA_OBJS) $(LIBS)
+
+read-write: read-write.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ read-write.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-and-read: mmap-and-read.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-and-read.o $(EXTRA_OBJS) $(LIBS)
+
+large-dir: large-dir.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ large-dir.o $(EXTRA_OBJS) $(LIBS)
+
+large-dir2: large-dir2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ large-dir2.o $(EXTRA_OBJS) $(LIBS)
+
+large-dir3: large-dir3.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ large-dir3.o $(EXTRA_OBJS) $(LIBS)
+
+fchmod: fchmod.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ fchmod.o $(EXTRA_OBJS) $(LIBS)
+
+truncate: truncate.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ truncate.o $(EXTRA_OBJS) $(LIBS)
+
+make-page: make-page.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ make-page.o $(EXTRA_OBJS) $(LIBS)
+
+still-there-p: still-there-p.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ still-there-p.o $(EXTRA_OBJS) $(LIBS)
+
+intr-read: intr-read.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ intr-read.o $(EXTRA_OBJS) $(LIBS)
+
+blocks-new-file: blocks-new-file.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ blocks-new-file.o $(EXTRA_OBJS) $(LIBS)
+
+asu: asu.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ asu.o $(EXTRA_OBJS) $(LIBS)
+
+test-setgroups: test-setgroups.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-setgroups.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+test-setpag: test-setpag.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-setpag.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+hardlink1: hardlink1.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ hardlink1.o $(EXTRA_OBJS) $(LIBS)
+
+hardlink2: hardlink2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ hardlink2.o $(EXTRA_OBJS) $(LIBS)
+
+hardlink4: hardlink4.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ hardlink4.o $(EXTRA_OBJS) $(LIBS)
+
+mkdir2: mkdir2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mkdir2.o $(EXTRA_OBJS) $(LIBS)
+
+mkdir3: mkdir3.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mkdir3.o $(EXTRA_OBJS) $(LIBS)
+
+create-files: create-files.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-files.o $(EXTRA_OBJS) $(LIBS)
+
+create-symlinks: create-symlinks.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-symlinks.o $(EXTRA_OBJS) $(LIBS)
+
+create-dirs: create-dirs.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-dirs.o $(EXTRA_OBJS) $(LIBS)
+
+create-remove: create-remove.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-remove.o $(EXTRA_OBJS) $(LIBS)
+
+dup2-and-unlog: dup2-and-unlog.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ dup2-and-unlog.o $(EXTRA_OBJS) $(AUTH_LIBS) $(LIBS)
+
+readdir-vs-lstat: readdir-vs-lstat.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ readdir-vs-lstat.o $(EXTRA_OBJS) $(LIBS)
+
+symlink: symlink.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ symlink.o $(EXTRA_OBJS) $(LIBS)
+
+echo-n: echo-n.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ echo-n.o $(EXTRA_OBJS)
+
+test-parallel1: test-parallel1.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-parallel1.o $(EXTRA_OBJS) $(LIBS)
+
+test-parallel2: test-parallel2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-parallel2.o $(EXTRA_OBJS) $(LIBS)
+
+create-stat: create-stat.o fs_lib.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-stat.o fs_lib.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+kill-softly: kill-softly.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ kill-softly.o $(EXTRA_OBJS) $(LIBS)
+
+kill-softer: kill-softer.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ kill-softer.o $(EXTRA_OBJS) $(LIBS)
+
+rm-rf: rm-rf.o fs_lib.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rm-rf.o fs_lib.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+exit-wo-close: exit-wo-close.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ exit-wo-close.o $(EXTRA_OBJS) $(LIBS)
+
+strange-characters-c: strange-characters-c.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ strange-characters-c.o $(EXTRA_OBJS) $(LIBS)
+
+pine: pine.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ pine.o $(EXTRA_OBJS) $(LIBS)
+
+append-over-page: append-over-page.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ append-over-page.o $(EXTRA_OBJS) $(LIBS)
+
+write-ucc: write-ucc.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-ucc.o $(EXTRA_OBJS) $(LIBS)
+
+utime-dir: utime-dir.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ utime-dir.o $(EXTRA_OBJS) $(LIBS)
+
+utime-file: utime-file.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ utime-file.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-shared-write: mmap-shared-write.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-shared-write.o $(EXTRA_OBJS) $(LIBS)
+
+rename5: rename5.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rename5.o $(EXTRA_OBJS) $(LIBS)
+
+rename6: rename6.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rename6.o $(EXTRA_OBJS) $(LIBS)
+
+write3: write3.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write3.o $(EXTRA_OBJS) $(LIBS)
+
+rename-under-feet: rename-under-feet.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rename-under-feet.o $(EXTRA_OBJS) $(LIBS)
+
+write-closed: write-closed.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-closed.o $(EXTRA_OBJS) $(LIBS)
+
+write-closed2: write-closed2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-closed2.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+truncate-files: truncate-files.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ truncate-files.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-cat: mmap-cat.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-cat.o $(EXTRA_OBJS) $(LIBS)
+
+run-tests: run-tests.in
+ (cd ..; CONFIG_FILES=tests/run-tests CONFIG_HEADERS= $(SHELL) /usr/src/openafs/openafs/config.status)
+ @chmod +x run-tests
+
+#.c.o:
+# $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+afscp: afscp.o afscp_callback.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ afscp.o afscp_callback.o $(EXTRA_OBJS) $(INT_LIBS)
+
+hello-world: hello-world.in
+ sed -e "s!%CC%!$(CC)!" $(srcdir)/hello-world.in > $@
+ chmod +x hello-world
+
+mountpoint: mountpoint.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/mountpoint.in > $@
+ chmod +x mountpoint
+
+clean:
+ rm -f run-tests $(TEST_PROGRAMS) *.o *~
+
+realclean:
+
+distclean: clean
+ rm -f Makefile
+
+mostlyclean:
+
+install:
+
+uninstall:
+
+
+TAGS: $(TEST_SRCS)
+ etags $(TEST_SRCS)
+
+check: run-tests $(TEST_PROGRAMS)
+ ./run-tests -all
+
+check-fast: run-tests $(TEST_PROGRAMS)
+ ./run-tests -all -fast
+
+.PHONY: all install clean realclean distclean mostlyclean install uninstall check
--- /dev/null
+srcdir = @srcdir@
+include @TOP_OBJDIR@/src/config/Makefile.config
+
+SHELL = /bin/sh
+
+CFLAGS = -I. -I${srcdir} ${DBG} ${OPTMZ} -I${TOP_OBJDIR}/src/config -I${TOP_INCDIR} ${XCFLAGS}
+LDFLAGS=${DBG} ${OPTMZ} ${XLDFLAGS}
+
+SYS_LIBS = ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a
+
+AUTH_LIBS = ${TOP_LIBDIR}/libauth.a ${SYS_LIBS}
+
+INT_LIBS = ${TOP_LIBDIR}/libafsint.a ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a
+
+TEST_PROGRAMS = write-ro-file hello-world read-vs-mmap read-vs-mmap2 \
+ mmap-and-read large-dir large-dir2 large-dir3 mountpoint \
+ test-setgroups test-setpag hardlink1 hardlink2 mkdir2 \
+ create-files create-symlinks create-dirs dup2-and-unlog \
+ readdir-vs-lstat read-write create-remove mkdir3 \
+ symlink echo-n test-parallel1 test-parallel2 create-stat \
+ kill-softly kill-softer rm-rf exit-wo-close \
+ mmap-vs-read mmap-vs-read2 strange-characters-c pine \
+ append-over-page write-ucc utime-dir mmap-shared-write \
+ rename5 rename-under-feet write-closed write-closed2 \
+ truncate fchmod make-page utime-file rename6 \
+ write3 still-there-p write-large afscp hardlink4 \
+ intr-read asu truncate-files mmap-cat blocks-new-file \
+ fsx write-rand
+
+TEST_OBJS = write-ro-file.o read-vs-mmap.o read-vs-mmap2.o \
+ mmap-and-read.o large-dir.o large-dir2.o large-dir3.o \
+ test-setgroups.o test-setpag.o hardlink1.o hardlink2.o \
+ mkdir2.o create-files.o create-symlinks.o create-dirs.o \
+ dup2-and-unlog.o readdir-vs-lstat.o read-write.o \
+ create-remove.o symlink.o echo-n.o test-parallel1.o \
+ test-parallel1.o mkdir3.o rename6.o \
+ create-stat.o kill-softly.o kill-softer.o rm-rf.o \
+ exit-wo-close.o mmap-vs-read.o mmap-vs-read2.o \
+ strange-characters-c.o pine.o append-over-page.o \
+ write-ucc.o utime-dir.o mmap-shared-write.o rename5.o \
+ rename-under-feet.o write-closed.o write-closed2.o \
+ truncate.o fchmod.o make-page.o utime-file.o \
+ write3.o still-there-p.o write-large.o hardlink4.o \
+ intr-read.o asu.o truncate-files.o mmap-cat.o \
+ blocks-new-file.o fsx.o afscp.o afscp_callback.o \
+ write-rand.o
+
+TEST_SRCS = write-ro-file.c read-vs-mmap.c read-vs-mmap2.c \
+ mmap-and-read.c large-dir.c large-dir2.c large-dir3.c \
+ test-setgroups.c test-setpag.c hardlink1.c hardlink2.c \
+ mkdir2.c create-files.c create-symlinks.c create-dirs.c \
+ dup2-and-unlog.c readdir-vs-lstat.c read-write.c \
+ create-remove.c symlink.c echo-n.c test-parallel1.c \
+ test-parallel2.c mkdir3.c rename6.c \
+ create-stat.c kill-softly.c kill-softer.c rm-rf.c \
+ exit-wo-close.c mmap-vs-read.c mmap-vs-read2.c \
+ strange-characters-c.c pine.c append-over-page.c \
+ write-ucc.c utime-dir.c mmap-shared-write.c rename5.c \
+ rename-under-feet.c write-closed.c write-closed2.c \
+ truncate.c fchmod.c make-page.c utime-file.c \
+ write3.c still-there-p.c write-large.c hardlink4.c \
+ intr-read.c asu.c truncate-files.c mmap-cat.c \
+ blocks-new-file.c fsx.c afscp.c afscp_callback.c \
+ write-rand.c
+
+EXTRA_OBJS = err.o errx.o warn.o warnx.o
+
+all: run-tests $(TEST_PROGRAMS) OS.pm
+
+OS.pm: OS-$(MKAFS_OSTYPE).pm
+ $(CP) OS-$(MKAFS_OSTYPE).pm OS.pm
+
+write-rand: write-rand.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-rand.o $(EXTRA_OBJS) $(LIBS)
+
+write-ro-file: write-ro-file.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-ro-file.o $(EXTRA_OBJS) $(LIBS)
+
+write-large: write-large.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-large.o $(EXTRA_OBJS) $(LIBS)
+
+read-vs-mmap: read-vs-mmap.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ read-vs-mmap.o $(EXTRA_OBJS) $(LIBS)
+
+read-vs-mmap2: read-vs-mmap2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ read-vs-mmap2.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-vs-read: mmap-vs-read.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-vs-read.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-vs-read2: mmap-vs-read2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-vs-read2.o $(EXTRA_OBJS) $(LIBS)
+
+read-write: read-write.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ read-write.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-and-read: mmap-and-read.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-and-read.o $(EXTRA_OBJS) $(LIBS)
+
+large-dir: large-dir.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ large-dir.o $(EXTRA_OBJS) $(LIBS)
+
+large-dir2: large-dir2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ large-dir2.o $(EXTRA_OBJS) $(LIBS)
+
+large-dir3: large-dir3.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ large-dir3.o $(EXTRA_OBJS) $(LIBS)
+
+fchmod: fchmod.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ fchmod.o $(EXTRA_OBJS) $(LIBS)
+
+truncate: truncate.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ truncate.o $(EXTRA_OBJS) $(LIBS)
+
+make-page: make-page.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ make-page.o $(EXTRA_OBJS) $(LIBS)
+
+still-there-p: still-there-p.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ still-there-p.o $(EXTRA_OBJS) $(LIBS)
+
+intr-read: intr-read.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ intr-read.o $(EXTRA_OBJS) $(LIBS)
+
+blocks-new-file: blocks-new-file.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ blocks-new-file.o $(EXTRA_OBJS) $(LIBS)
+
+asu: asu.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ asu.o $(EXTRA_OBJS) $(LIBS)
+
+test-setgroups: test-setgroups.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-setgroups.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+test-setpag: test-setpag.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-setpag.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+hardlink1: hardlink1.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ hardlink1.o $(EXTRA_OBJS) $(LIBS)
+
+hardlink2: hardlink2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ hardlink2.o $(EXTRA_OBJS) $(LIBS)
+
+hardlink4: hardlink4.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ hardlink4.o $(EXTRA_OBJS) $(LIBS)
+
+mkdir2: mkdir2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mkdir2.o $(EXTRA_OBJS) $(LIBS)
+
+mkdir3: mkdir3.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mkdir3.o $(EXTRA_OBJS) $(LIBS)
+
+create-files: create-files.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-files.o $(EXTRA_OBJS) $(LIBS)
+
+create-symlinks: create-symlinks.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-symlinks.o $(EXTRA_OBJS) $(LIBS)
+
+create-dirs: create-dirs.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-dirs.o $(EXTRA_OBJS) $(LIBS)
+
+create-remove: create-remove.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-remove.o $(EXTRA_OBJS) $(LIBS)
+
+dup2-and-unlog: dup2-and-unlog.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ dup2-and-unlog.o $(EXTRA_OBJS) $(AUTH_LIBS) $(LIBS)
+
+readdir-vs-lstat: readdir-vs-lstat.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ readdir-vs-lstat.o $(EXTRA_OBJS) $(LIBS)
+
+symlink: symlink.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ symlink.o $(EXTRA_OBJS) $(LIBS)
+
+echo-n: echo-n.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ echo-n.o $(EXTRA_OBJS)
+
+test-parallel1: test-parallel1.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-parallel1.o $(EXTRA_OBJS) $(LIBS)
+
+test-parallel2: test-parallel2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ test-parallel2.o $(EXTRA_OBJS) $(LIBS)
+
+create-stat: create-stat.o fs_lib.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ create-stat.o fs_lib.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+kill-softly: kill-softly.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ kill-softly.o $(EXTRA_OBJS) $(LIBS)
+
+kill-softer: kill-softer.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ kill-softer.o $(EXTRA_OBJS) $(LIBS)
+
+rm-rf: rm-rf.o fs_lib.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rm-rf.o fs_lib.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+exit-wo-close: exit-wo-close.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ exit-wo-close.o $(EXTRA_OBJS) $(LIBS)
+
+strange-characters-c: strange-characters-c.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ strange-characters-c.o $(EXTRA_OBJS) $(LIBS)
+
+pine: pine.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ pine.o $(EXTRA_OBJS) $(LIBS)
+
+append-over-page: append-over-page.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ append-over-page.o $(EXTRA_OBJS) $(LIBS)
+
+write-ucc: write-ucc.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-ucc.o $(EXTRA_OBJS) $(LIBS)
+
+utime-dir: utime-dir.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ utime-dir.o $(EXTRA_OBJS) $(LIBS)
+
+utime-file: utime-file.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ utime-file.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-shared-write: mmap-shared-write.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-shared-write.o $(EXTRA_OBJS) $(LIBS)
+
+rename5: rename5.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rename5.o $(EXTRA_OBJS) $(LIBS)
+
+rename6: rename6.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rename6.o $(EXTRA_OBJS) $(LIBS)
+
+write3: write3.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write3.o $(EXTRA_OBJS) $(LIBS)
+
+rename-under-feet: rename-under-feet.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ rename-under-feet.o $(EXTRA_OBJS) $(LIBS)
+
+write-closed: write-closed.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-closed.o $(EXTRA_OBJS) $(LIBS)
+
+write-closed2: write-closed2.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ write-closed2.o $(EXTRA_OBJS) $(SYS_LIBS) $(LIBS)
+
+truncate-files: truncate-files.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ truncate-files.o $(EXTRA_OBJS) $(LIBS)
+
+mmap-cat: mmap-cat.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ mmap-cat.o $(EXTRA_OBJS) $(LIBS)
+
+run-tests: run-tests.in
+ (cd ..; CONFIG_FILES=tests/run-tests CONFIG_HEADERS= $(SHELL) @TOP_OBJDIR@/config.status)
+ @chmod +x run-tests
+
+#.c.o:
+# $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+afscp: afscp.o afscp_callback.o $(EXTRA_OBJS)
+ $(CC) $(LDFLAGS) -o $@ afscp.o afscp_callback.o $(EXTRA_OBJS) $(INT_LIBS)
+
+hello-world: hello-world.in
+ sed -e "s!%CC%!$(CC)!" $(srcdir)/hello-world.in > $@
+ chmod +x hello-world
+
+mountpoint: mountpoint.in
+ sed -e "s!%bindir%!$(bindir)!" $(srcdir)/mountpoint.in > $@
+ chmod +x mountpoint
+
+clean:
+ rm -f run-tests $(TEST_PROGRAMS) *.o *~ OS.pm
+
+install:
+
+uninstall:
+
+
+TAGS: $(TEST_SRCS)
+ etags $(TEST_SRCS)
+
+check: run-tests $(TEST_PROGRAMS)
+ ./run-tests -all
+
+check-fast: run-tests $(TEST_PROGRAMS)
+ ./run-tests -all -fast
+
+.PHONY: all install clean realclean distclean mostlyclean install uninstall check
--- /dev/null
+# This is -*- perl -*-
+
+package OpenAFS::OS;
+
+use strict;
+use vars qw( @ISA @EXPORT $openafsinitcmd);
+@ISA = qw(Exporter);
+require Exporter;
+@EXPORT = qw($openafsinitcmd);
+
+# OS-specific configuration
+$openafsinitcmd = {
+ 'client-start' => '/etc/init.d/openafs-client start',
+ 'client-stop' => '/etc/init.d/openafs-client stop',
+ 'client-forcestart' => '/etc/init.d/openafs-client force-start',
+ 'client-restart' => '/etc/init.d/openafs-client restart',
+ 'filesrv-start' => '/etc/init.d/openafs-fileserver start',
+ 'filesrv-stop' => '/etc/init.d/openafs-fileserver stop',
+ 'filesrv-forcestart'=> '/etc/init.d/openafs-fileserver force-start',
+ 'filesrv-restart' => '/etc/init.d/openafs-fileserver restart',
+};
+
+1;
--- /dev/null
+# This is -*- perl -*-
+
+package OpenAFS::OS;
+
+use strict;
+use vars qw( @ISA @EXPORT $openafsinitcmd);
+@ISA = qw(Exporter);
+require Exporter;
+@EXPORT = qw($openafsinitcmd);
+
+# OS-specific configuration
+$openafsinitcmd = {
+ 'client-start' => 'modload /usr/vice/etc/modload/libafs.nonfs.o; /usr/vice/etc/afsd -nosettime',
+ 'client-stop' => 'echo Solaris client cannot be stopped',
+ 'client-forcestart' => 'modload /usr/vice/etc/modload/libafs.nonfs.o; /usr/vice/etc/afsd -nosettime',
+ 'client-restart' => 'echo Solaris client cannot be restarted',
+ 'filesrv-start' => '/usr/afs/bin/bosserver',
+ 'filesrv-stop' => '/usr/afs/bin/bos shutdown localhost -local -wait; pkill /usr/afs/bin/bosserver',
+ 'filesrv-forcestart'=> '/usr/afs/bin/bosserver',
+ 'filesrv-restart' => '/usr/afs/bin/bos shutdown localhost -local -wait; pkill /usr/afs/bin/bosserver; sleep 1; /usr/afs/bin/bosserver',
+};
+
+1;
--- /dev/null
+AFS verification suite
+14 Jan 2002
+
+Prerequisites
+
+1) A Kerberos KDC should already be configured
+2) An afs key should be in the KeyFile the AFS binaries will use
+ (/usr/afs/etc/KeyFile in an IBM-style installation; bos_util can be used
+ to set it up)
+3) 2 srvtabs or keytabs with user keys, one for the user "admin"
+ and one for the user "user" that can be used for authenticated testing
+ of the AFS installation
+4) The necessary tools for getting an AFS token from the installed Kerberos
+ (typically aklog) should be available.
+5) Ability to run as root on the "test" node.
+6) If the AFS to be tested is not OpenAFS, pt_util from OpenAFS should be
+ built and installed.
+7) Volume dump test tools included in new versions of OpenAFS.
+8) The "test" node should have partitions mounted as /vicepa and /vicepb
+9) perl5
+10) wget (should be configurable to use curl; what else?)
+
+(*) This is not yet true but will be by the time the suite is delivered.
+
+Setup
+1) Scripts provided bootstrap and populate a "test cell". (afs-newcell)
+
+Tests
+
+A) Simple tests
+10) Create a file. (creat1)
+20) Create a directory. (mkdir1/mkdir2)
+30) Create a symlink. (symlink)
+40) Create a in-same-directory hardlink. (hardlink1)
+50) Create a hardlink to a different-directory-same-volume file. (hardlink4)
+60) Create a hardlink to a directory. (hardlink2)
+70) Create a cross-volume hardlink. (hardlink5)
+80) Touch a file. (touch1)
+90) Write a simple file. (write1)
+100) Rewrite a file. (write3)
+110) Rename a file. (rename1)
+
+B) Basic functionality
+10) Stat multiple hardlinked files. (hardlink3)
+20) Write, truncate, rewrite a file. (write2)
+30) Append to a file. (append1)
+40) Rename a file over another file. (rename2)
+50) Rename a file into a same-volume directory. (rename4)
+60) Rename a file into another-volume directory. (rename6)
+70) Rename an open directory. (rename-under-feet)
+80) Create a file with a large filename. (large-filename)
+90) Chmod a file by descriptor. (fchmod)
+100) Utimes a file. (utime-file)
+110) Utimes a directory. (utime-dir)
+120) Test directory "link count" increasing/decreasing appropriately. (mkdir3)
+
+C) Mountpoint tests
+10) Create and remove a good mountpoint. (mkm-rmm)
+20) Create a mountpoint to a nonexistant volume. (mountpoint)
+
+D) ACL tests
+10) Add a valid PTS user to an ACL. (acladduser)
+20) Add a valid PTS group to an ACL. (acladdgroup)
+30) Add ACL rights for a PTS user. (acladdrights)
+40) Add negative ACL rights for a PTS user. (acladdnegrights)
+50) Clear negative ACL rights for a PTS user. (aclclearnegrights)
+60) Remove a valid PTS user from an ACL. (aclremoveuser)
+70) Remove a valid PTS group from an ACL. (aclremovegroup)
+80) Copy an ACL. (aclcopy)
+
+E) Executable tests
+10) Write and execute a script in a directory. (exec)
+20) Download and build http://www.openafs.org/dl/openafs/1.2.2/openafs-1.2.2-src.tar.gz, then run something from it. (build-openafs)
+
+F) mmap tests
+10) Append over a mapped page. (append-over-page)
+20) Write via mmap to a shared-mapped file. (mmap-shared-write)
+30) Compare a file being read via mmap private and read (mmap-vs-read2)
+40) Compare a file being read via mmap shared and read (mmap-vs-read)
+50) Compare a file being read via read and mmap shared (read-vs-mmap2)
+60) Compare a file being read via read and mmap private (read-vs-mmap)
+
+G) Filesystem Semantics tests
+10) Create a file with 8 bit characters in its name. (strange-characters)
+20) Test pine lockfile semantics. (pine)
+30) Create and remove a single file in parallel. (parallel1)
+40) Create a >2gb file (write-large)
+
+H) AFS behavior tests
+10) Write a file in a readonly volume. (write-ro)
+20) Create 31707 entries in a directory. (too-many-files)
+30) Test setpag(). (setpag)
+40) Test setgroups(). (setgroups)
+
+I) Remote operation tests
+10) Write a file locally and read it in a foreign cache manager. (extcopyin)
+20) Write a file in a foreign cache manager and read it locally. (extcopyout)
+
+K) Client abuse tests
+10) Write a file, read, rewrite and reread a file with the same open descriptor. (read-write)
+20) Populate and clean up a directory tree. (create-remove-files)
+30) FSX file system stresser (fsx)
+
+L) Fileserver tests
+
+M) Ptserver tests
+10) Create a user (ptscreateuser)
+20) Create a group (ptscreategroup)
+30) Add a user to a group (ptsadduser)
+40) Chown a group (ptschown)
+50) Get user membership (ptsmembersuser)
+60) Get group membership (ptsmembersgroup)
+70) Examine a user (ptsexamineuser)
+80) Examine a group (ptsexaminegroup)
+90) Remove a user from a group (ptsremove)
+100) List groups a user owns (ptslistown)
+100) Set maxuser (ptssetmax)
+110) List maxuser (ptslistmax)
+130) Set fields on a user (ptssetf)
+140) Delete a group (ptsdeletegroup)
+150) Delete a user (ptsdeleteuser)
+160) pt_util exercising (?)
+
+N) Volserver/vlserver tests
+10) Create a volume (voscreate)
+20) Move a volume (vosmove)
+30) Add a replication site (vosaddsite)
+40) Release a volume (vosrelease)
+50) Remove a replication site (vosremsite)
+70) Remove a volume (vosremove)
+80) Delete a VLDB entry (vosdelentry)
+90) Synchronize vldb to volumes (vossyncvldb)
+100) Zap a volume (voszap)
+110) Synchronize volumes to vldb (vossyncserv)
+120) Lock a VLDB entry (voslock)
+130) Unlock a VLDB entry (vosunlock)
+140) Unlock all VLDB entries after locking one or more (vosunlockall)
+150) Rename a volume. (vosrename)
+160) List all volumes on a partition. (voslistvol)
+170) List vldb (voslistvldb)
+180) Get partition info. (vospartinfo)
+190) List partitions (voslistpart)
+200) Backup a volume (vosbackup)
+210) Examine a volume (vosexamine)
+220) Dump a volume (vosdump)
+230) Restore a volume (vosrestore)
+240) Verify a volume dump (?)
+
+O) Bosserver tests
+10) Add a bosserver host (bosaddhost)
+20) List server hosts (bostlisthosts)
+30) Remove a server host (bosremovehost)
+40) Add a superuser (bosadduser)
+50) List superusers (boslistusers)
+60) Remove a superuser (bosremoveuser)
+70) Install an executable shell script (bosinstall)
+80) Execute something via the bosserver (bosexec)
+80) Create a bos bnode (boscreate)
+90) Delete a running bnode (bosdeleterunning)
+100) Get a bnode status (bosstatus)
+110) Stop a bos bnode (bosstop)
+120) Restart a bos bnode (bosrestartstopped)
+130) Start a bos bnode (bosstart)
+140) Shutdown a bnode (bosshutdown)
+150) Delete a stopped bnode (bosdelete)
+160) Add a key (bosaddkey)
+170) List keys (boslistkeys)
+180) Remove a key (bosremovekey)
+180) Salvage a volume (bossalvagevolume)
+190) Salvage a partition (bossalvagepart)
+200) Salvage a server (bossalvageserver)
+
+P) Regression
+10) Restore volume with a bad uniquifier in it, salvage, check. (?)
+20) Check for bad dentry caching on Linux taking advantage of last test. (?)
+30) Write a file larger than the cache. (fcachesize-write-file)
+40) Read a file larger than the cache. (fcachesize-read-file)
+
+---
+Copyright information
+
+The AFStools perl modules are:
+
+## Copyright (c) 1996, 2001 Carnegie Mellon University
+## All Rights Reserved.
+#
+# Permission to use, copy, modify and distribute this software and its
+# documentation is hereby granted, provided that both the copyright
+# notice and this permission notice appear in all copies of the
+# software, derivative works or modified versions, and any portions
+# thereof, and that both notices appear in supporting documentation.
+#
+# CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+# CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+# ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+#
+# Carnegie Mellon requests users of this software to return to
+#
+# Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
+# School of Computer Science
+# Carnegie Mellon University
+# Pittsburgh PA 15213-3890
+#
+# any improvements or extensions that they make and grant Carnegie Mellon
+# the rights to redistribute these changes.
+
+Some tests as noted are:
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
--- /dev/null
+This is a (potentially) modified verion of the AFSTools perl suite.
+You should visit grand.central.org for the official version.
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+
+eval { &AFS_pts_creategroup(group1,,,); };
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$ret = &AFS_fs_setacl([$path],[["group1", "rl"]],,);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+while ($ret = pop(@$pos2)) {
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "group1") {
+ $found++;
+ } else {
+ unshift @tmp, @$ret;
+ }
+}
+
+@tmp2=();
+while ($ret = pop(@$pos1)) {
+ unshift @tmp2, @$ret;
+}
+
+if ($found != 1) {
+ exit(1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+
+eval { &AFS_pts_createuser(user1,,); };
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$ret = &AFS_fs_setacl([$path],[],[["user1", "rl"]],);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+while ($ret = pop(@$neg2)) {
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "user1") {
+ $found++;
+ } else {
+ unshift @tmp, @$ret;
+ }
+}
+
+if ($found != 1) {
+ exit(1);
+}
+
+@tmp2=();
+while ($ret = pop(@$neg1)) {
+ unshift @tmp2, @$ret;
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+
+eval { &AFS_pts_createuser(user1,,); };
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$ret = &AFS_fs_setacl([$path],[["user1", "rlidw"]],,);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+while ($ret = pop(@$pos2)) {
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "user1") {
+ if ($tmp2[1] ne "rlidw") {
+ exit (1);
+ }
+ $tmp2[1] = "rl";
+ unshift @tmp, @tmp2;
+ } else {
+ unshift @tmp, @$ret;
+ }
+}
+
+@tmp2=();
+while ($ret = pop(@$pos1)) {
+ unshift @tmp2, @$ret;
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+
+eval { &AFS_pts_createuser(user1,,); };
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$ret = &AFS_fs_setacl([$path],[["user1", "rl"]],,);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+while ($ret = pop(@$pos2)) {
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "user1") {
+ $found++;
+ } else {
+ unshift @tmp, @$ret;
+ }
+}
+
+@tmp2=();
+while ($ret = pop(@$pos1)) {
+ unshift @tmp2, @$ret;
+}
+
+if ($found != 1) {
+ exit(1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+
+eval { &AFS_pts_createuser(user1,,); };
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$ret = &AFS_fs_setacl([$path],[],[["user1", "r"]],);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+while ($ret = pop(@$neg2)) {
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "user1") {
+ if ($tmp2[1] ne "r") {
+ exit 1;
+ }
+ $tmp2[1] = "rl";
+ unshift @tmp, @tmp2;
+ } else {
+ unshift @tmp, @$ret;
+ }
+}
+
+@tmp2=();
+while ($ret = pop(@$neg1)) {
+ unshift @tmp2, @$ret;
+}
+
+if (@tmp != @tmp2) {
+ exit(1);
+}
+if (@pos1 != @pos2) {
+ exit(1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found, $path2);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+
+eval { &AFS_pts_createuser(user1,,); };
+$path = "/afs/${wscell}/service/acltest";
+$path2 = "/afs/${wscell}/service/acltest2";
+mkdir $path, 0777;
+mkdir $path2, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$ret = &AFS_fs_copyacl($path,[$path2],1);
+($pos2, $neg2) = &AFS_fs_getacl($path2);
+if (@pos1 != @pos2) {
+ exit(1);
+}
+if (@neg1 != @neg2) {
+ exit(1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found, $listref, $first);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+$first = 0;
+
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$listref = "[ ";
+while ($ret = pop(@$pos1)) {
+ $first++;
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "group1") {
+ $found++;
+ } else {
+ unshift @tmp, @$ret;
+ if ($first == 0 ) {
+ $listref = $listref . "[ @tmp2 ]";
+ } else {
+ $listref = $listref . ", [ @tmp2 ]";
+ }
+ }
+}
+$listref = $listref . " ]";
+
+if ($found != 1) {
+ print "WARNING: Can't remove user not on ACL. This shouldn't happen.\n";
+ exit(1);
+}
+
+$ret = &AFS_fs_setacl([$path],$listref,,);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+
+@tmp2=();
+while ($ret = pop(@$pos1)) {
+ unshift @tmp2, @$ret;
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($wscell, $path, @pos1, @pos2, @neg1, @neg2, $ret, @tmp, @tmp2, @tmp3, $found, $listref, $first);
+&AFS_Init();
+$wscell = &AFS_fs_wscell();
+$found = 0;
+$first = 0;
+
+$path = "/afs/${wscell}/service/acltest";
+mkdir $path, 0777;
+($pos1, $neg1) = &AFS_fs_getacl($path);
+$listref = "[ ";
+while ($ret = pop(@$pos1)) {
+ $first++;
+ @tmp2=@$ret;
+ if ($tmp2[0] eq "user1") {
+ $found++;
+ } else {
+ unshift @tmp, @$ret;
+ if ($first == 0 ) {
+ $listref = $listref . "[ @tmp2 ]";
+ } else {
+ $listref = $listref . ", [ @tmp2 ]";
+ }
+ }
+}
+$listref = $listref . " ]";
+
+if ($found != 1) {
+ print "WARNING: Can't remove user not on ACL. This shouldn't happen.\n";
+ exit(1);
+}
+
+$ret = &AFS_fs_setacl([$path],$listref,,);
+($pos2, $neg2) = &AFS_fs_getacl($path);
+
+@tmp2=();
+while ($ret = pop(@$pos1)) {
+ unshift @tmp2, @$ret;
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl -w
+# Copyright (C) 2000 by Sam Hartman
+# This file may be copied either under the terms of the GNU GPL or the IBM Public License
+# either version 2 or later of the GPL or version 1.0 or later of the IPL.
+
+use Term::ReadLine;
+use strict;
+use OpenAFS::ConfigUtils;
+use OpenAFS::Dirpath;
+use OpenAFS::OS;
+use OpenAFS::Auth;
+use Getopt::Long;
+use vars qw($admin $server $cellname $cachesize $part
+ $requirements_met $shutdown_needed $csdb);
+my $rl = new Term::ReadLine('afs-newcell');
+
+=head1 NAME
+
+ afs-newcell - Set up initial database server for AFS cell.
+
+=head1 SYNOPSIS
+
+B<afs-newcell> [B<--requirements-met>] [B<--admin> admin_user] [B<--cellname> cellname] [B<--cachesize> size] [B<--partition> partition-letter]
+
+=head1 DESCRIPTION
+
+
+This script sets up the initial AFS database and configures the first
+database/file server. It also sets up an AFS cell's root volumes. It
+assumes that you already have a fileserver and database servers. The
+fileserver should have an empty root.afs. This script creates root.cell,
+user, service and populates root.afs.
+
+The B<requirements-met> option specifies that the initial requirements
+have been met and that the script can proceed without displaying the
+initial banner or asking for confirmation.
+
+The B<admin> option specifies the name of the administrative user.
+This user will be given system:administrators and susers permission in
+the cell.
+
+The B<cellname> option specifies the name of the cell.
+
+The B<cachesize> option specifies the size of the AFS cache.
+
+=head1 AUTHOR
+
+Sam Hartman <hartmans@debian.org>
+
+=cut
+
+# main script
+
+# mkvol(volume, mount)
+sub mkvol($$) {
+ my ($vol, $mnt) = @_;
+ run("$openafsdirpath->{'afssrvsbindir'}/vos create $server $part $vol -localauth");
+ unwind("$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part $vol -localauth");
+ run("$openafsdirpath->{'afssrvbindir'}/fs mkm $mnt $vol ");
+ run("$openafsdirpath->{'afssrvbindir'}/fs sa $mnt system:anyuser rl");
+}
+
+GetOptions (
+ "requirements-met" => \$requirements_met,
+ "cellname=s" => \$cellname,
+ "cachesize=s" => \$cachesize,
+ "partition=s" => \$part,
+ "admin=s" => \$admin);
+
+unless ($requirements_met) {
+ print <<eoreqs;
+ Prerequisites
+
+In order to set up a new AFS cell, you must meet the following:
+
+1) You need a working Kerberos realm with Kerberos4 support. You
+ should install Heimdal with Kth-kerberos compatibility or MIT
+ Kerberos5.
+
+2) You need to create the single-DES AFS key and load it into
+ $openafsdirpath->{'afsconfdir'}/KeyFile. If your cell's name is the same as
+ your Kerberos realm then create a principal called afs. Otherwise,
+ create a principal called afs/cellname in your realm. The cell
+ name should be all lower case, unlike Kerberos realms which are all
+ upper case. You can use asetkey from the openafs-krb5 package, or
+ if you used AFS3 salt to create the key, the bos addkey command.
+
+3) This machine should have a filesystem mounted on /vicepa. If you
+ do not have a free partition, on Linux you can create a large file by using
+ dd to extract bytes from /dev/zero. Create a filesystem on this file
+ and mount it using -oloop.
+
+4) You will need an administrative principal created in a Kerberos
+ realm. This principal will be added to susers and
+ system:administrators and thus will be able to run administrative
+ commands. Generally the user is a root instance of some administravie
+ user. For example if jruser is an administrator then it would be
+ reasonable to create jruser/root and specify jruser/root as the user
+ to be added in this script.
+
+5) The AFS client must not be running on this workstation. It will be
+ at the end of this script.
+
+eoreqs
+
+ $_ = $rl->readline("Do you meet these requirements? [y/n] ");
+ unless (/^y/i ) {
+ print "Run this script again when you meet the requirements\n";
+ exit(1);
+ }
+
+ if ($> != 0) {
+ die "This script should almost always be run as root. Use the --requirements-met option to run as non-root.\n";
+ }
+}
+open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+while(<MOUNT>) {
+ if(m:^AFS:) {
+ print "The AFS client is currently running on this workstation.\n";
+ print "Please restart this script after running $openafsinitcmd->{'client-stop'}\n";
+ exit(1);
+ }
+ if(m:^/afs on AFS:) {
+ print "The AFS client is currently running on this workstation.\n";
+ print "Please restart this script after running $openafsinitcmd->{'client-stop'}\n";
+ exit(1);
+ }
+}
+close MOUNT;
+
+unless ( -f "$openafsdirpath->{'afsconfdir'}/KeyFile") {
+ print "You do not have an AFS keyfile. Please create this using asetkey from openafs-krb5 or
+the bos addkey command";
+ exit(1);
+}
+
+print "If the fileserver is not running, this may hang for 30 seconds.\n";
+run("$openafsinitcmd->{'filesrv-stop'}");
+$server = `hostname`;
+chomp $server;
+$admin = $rl->readline("What administrative principal should be used? ") unless $admin;
+ die "Please specify an administrative user\n" unless $admin;
+$admin =~ s:/:.:g;
+if($admin =~ /@/) {
+die "The administrative user must be in the same realm as the cell and no realm may be specified.\n";
+}
+
+$cellname = $rl->readline("What cellname should be used? ") unless $cellname;
+die "Please specify a cellname\n" unless $cellname;
+
+if (! -f "$openafsdirpath->{'afsconfdir'}/ThisCell") {
+ open(CELL, "> $openafsdirpath->{'afsconfdir'}/ThisCell");
+ print CELL "${cellname}";
+ close CELL;
+}
+
+open(CELL, "$openafsdirpath->{'afsconfdir'}/ThisCell") or
+ die "Cannot open $openafsdirpath->{'afsconfdir'}/ThisCell: $!\n";
+
+my $lcell = <CELL>;
+chomp $lcell;
+close CELL;
+
+run( "echo \\>$lcell >$openafsdirpath->{'afsconfdir'}/CellServDB");
+$csdb = `host $server|awk '{print $4 " #" $1}'`;
+run( "echo $csdb >>$openafsdirpath->{'afsconfdir'}/CellServDB");
+run("$openafsinitcmd->{'filesrv-start'}");
+unwind("$openafsinitcmd->{'filesrv-stop'}");
+$shutdown_needed = 1;
+run ("$openafsdirpath->{'afssrvbindir'}/bos addhost $server $server -localauth ||true");
+run("$openafsdirpath->{'afssrvbindir'}/bos adduser $server $admin -localauth");
+unwind("$openafsdirpath->{'afssrvbindir'}/bos removeuser $server $admin -localauth");
+if ( -f "$openafsdirpath->{'afsdbdir'}/prdb.DB0" ) {
+ die "Protection database already exists; cell already partially created\n";
+ }
+open(PRDB, "|$openafsdirpath->{'afssrvsbindir'}/pt_util -p $openafsdirpath->{'afsdbdir'}/prdb.DB0 -w ")
+or die "Unable to start pt_util: $!\n";
+print PRDB "$admin 128/20 1 -204 -204\n";
+print PRDB "system:administrators 130/20 -204 -204 -204\n";
+print PRDB" $admin 1\n";
+close PRDB;
+unwind( "rm $openafsdirpath->{'afsdbdir'}/prdb* ");
+# Start up ptserver and vlserver
+run("$openafsdirpath->{'afssrvbindir'}/bos create $server ptserver simple $openafsdirpath->{'afssrvlibexecdir'}/ptserver -localauth");
+unwind("$openafsdirpath->{'afssrvbindir'}/bos delete $server ptserver -localauth");
+
+run("$openafsdirpath->{'afssrvbindir'}/bos create $server vlserver simple $openafsdirpath->{'afssrvlibexecdir'}/vlserver -localauth");
+unwind("$openafsdirpath->{'afssrvbindir'}/bos delete $server vlserver -localauth");
+
+run( "$openafsdirpath->{'afssrvbindir'}/bos create $server fs fs ".
+ "-cmd $openafsdirpath->{'afssrvlibexecdir'}/fileserver ".
+ "-cmd $openafsdirpath->{'afssrvlibexecdir'}/volserver ".
+ "-cmd $openafsdirpath->{'afssrvlibexecdir'}/salvager -localauth");
+unwind( "$openafsdirpath->{'afssrvbindir'}/bos delete $server fs -localauth ");
+
+print "Waiting for database elections: ";
+sleep(30);
+print "done.\n";
+# Past this point we want to control when bos shutdown happens
+$shutdown_needed = 0;
+unwind( "$openafsdirpath->{'afssrvbindir'}/bos shutdown $server -localauth ");
+run("$openafsdirpath->{'afssrvsbindir'}/vos create $server a root.afs -localauth");
+# bring up client
+
+$cachesize = $rl->readline("What size cache (in 1k blocks)? ") unless $cachesize;
+die "Please specify a cache size\n" unless $cachesize;
+
+run("echo $lcell >$openafsdirpath->{'viceetcdir'}/ThisCell");
+run("cp $openafsdirpath->{'afsconfdir'}/CellServDB $openafsdirpath->{'viceetcdir'}/CellServDB");
+run("echo /afs:/usr/vice/cache:${cachesize} >$openafsdirpath->{'viceetcdir'}/cacheinfo");
+run("$openafsinitcmd->{'client-forcestart'}");
+my $afs_running = 0;
+open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+while(<MOUNT>) {
+if(m:^AFS:) {
+ $afs_running = 1;
+}
+ }
+unless ($afs_running) {
+print "*** The AFS client failed to start.\n";
+print "Please fix whatever problem kept it from running.\n";
+ exit(1);
+}
+unwind("$openafsinitcmd->{'client-stop'}");
+
+unless ($part) {
+ $part = $rl ->readline("What partition? [a] ");
+ $part = "a" unless $part;
+}
+
+&OpenAFS::Auth::authadmin();
+
+run("$openafsdirpath->{'afssrvbindir'}/fs sa /afs system:anyuser rl");
+
+run("$openafsdirpath->{'afssrvsbindir'}/vos create $server $part root.cell -localauth");
+unwind("$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.cell -localauth");
+# We make root.cell s:anyuser readable after we mount in the next
+# loop.
+open(CELLSERVDB, "$openafsdirpath->{'viceetcdir'}/CellServDB")
+ or die "Unable to open $openafsdirpath->{'viceetcdir'}/CellServDB: $!\n";
+while(<CELLSERVDB>) {
+ chomp;
+ if (/^>\s*([a-z0-9_\-.]+)/ ) {
+ run("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/$1 root.cell -cell $1 -fast");
+ unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/$1");
+ }
+}
+
+run("$openafsdirpath->{'afssrvbindir'}/fs sa /afs/$lcell system:anyuser rl");
+run ("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/.$lcell root.cell -cell $lcell -rw");
+unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/.$lcell");
+run("$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/.root.afs root.afs -rw");
+unwind ("$openafsdirpath->{'afssrvbindir'}/fs rmm /afs/.root.afs");
+
+mkvol( "user", "/afs/$lcell/user" );
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part user -localauth ");
+
+mkvol( "service", "/afs/$lcell/service" );
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part service -localauth ");
+
+mkvol( "rep", "/afs/$lcell/.replicated" );
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part rep -localauth ");
+run( "$openafsdirpath->{'afssrvbindir'}/fs mkm /afs/$lcell/replicated rep.readonly " );
+
+run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part rep -localauth" );
+run( "$openafsdirpath->{'afssrvsbindir'}/vos release rep -localauth" );
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part rep.readonly -localauth ");
+
+mkvol( "unrep", "/afs/$lcell/unreplicated" );
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part unrep -localauth ");
+
+$lcell =~ /^([^.]*)/;
+my $cellpart = $1;
+run("ln -s /afs/$lcell /afs/$cellpart");
+unwind ("rm /afs/$cellpart");
+run( "ln -s /afs/.$lcell /afs/.$cellpart" );
+unwind ("rm /afs/.$cellpart");
+
+run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part root.afs -localauth" );
+run( "$openafsdirpath->{'afssrvsbindir'}/vos addsite $server $part root.cell -localauth" );
+run( "$openafsdirpath->{'afssrvsbindir'}/vos release root.afs -localauth" );
+run( "$openafsdirpath->{'afssrvsbindir'}/vos release root.cell -localauth" );
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.cell.readonly -localauth ");
+unwind( "$openafsdirpath->{'afssrvsbindir'}/vos remove $server $part root.afs.readonly -localauth ");
+
+
+
+@unwinds = ();
+END {
+# If we fail before all the instances are created, we need to perform
+# our own bos shutdown
+ system("$openafsdirpath->{'afssrvbindir'}/bos shutdown $server -localauth") if $shutdown_needed;
+ run(pop @unwinds) while @unwinds;
+ }
--- /dev/null
+#!/bin/sh
+/bin/rm -rf /usr/afs/db/prdb.DB0 /usr/afs/db/prdb.DBSYS1 /usr/afs/db/vldb.DB0 /usr/afs/db/vldb.DBSYS1 /usr/afs/local/BosConfig /usr/afs/etc/UserList /usr/afs/etc/ThisCell /usr/afs/etc/CellServDB
+/bin/rm -rf /vicepa/AFSIDat
+/bin/rm -rf /vicepb/AFSIDat
+/bin/rm -rf /vicepa/V*.vol
+/bin/rm -rf /vicepb/V*.vol
+exit 0
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMUCS/CMU_copyright.pm for use and distribution information
+
+package OpenAFS::afsconf;
+
+=head1 NAME
+
+OpenAFS::afsconf - Access to AFS config info
+
+=head1 SYNOPSIS
+
+ use OpenAFS::afsconf;
+
+ $cell = AFS_conf_localcell();
+ $cell = AFS_conf_canoncell($cellname);
+ @servers = AFS_conf_cellservers($cellname);
+ @cells = AFS_conf_listcells();
+ %info = AFS_conf_cacheinfo();
+
+=head1 DESCRIPTION
+
+This module provides access to information about the local workstation's
+AFS configuration. This includes information like the name of the
+local cell, where AFS is mounted, and access to information in the
+F<CellServDB>. All information returned by this module is based on the
+configuration files, and does not necessarily reflect changes made
+on the afsd command line or using B<fs> commands.
+
+=cut
+
+use OpenAFS::CMU_copyright;
+use OpenAFS::config;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_conf_localcell
+ &AFS_conf_canoncell
+ &AFS_conf_listcells
+ &AFS_conf_cellservers
+ &AFS_conf_cacheinfo);
+
+
+# _confpath($file) - Return path to a configuration file
+sub _confpath {
+ my($file) = @_;
+
+ if ($conf_paths{$file}) {
+ $conf_paths{$file};
+ } elsif ($AFS_Parms{confdir} && -r "$AFS_Parms{confdir}/$file") {
+ $conf_paths{$file} = "$AFS_Parms{confdir}/$file";
+ } elsif (-r "$def_ConfDir/$file") {
+ $conf_paths{$file} = "$def_ConfDir/$file";
+ } else {
+ die "Unable to locate $file\n";
+ }
+}
+
+=head2 AFS_conf_localcell()
+
+Return the canonical name of the local cell. This depends on the contents
+of the F<ThisCell> file in the AFS configuration directory.
+
+=cut
+
+$AFS_Help{conf_localcell} = '=> $lclcell';
+sub AFS_conf_localcell {
+ my($path) = _confpath(ThisCell);
+ my($result);
+
+ return '' if (!$path);
+ if (open(THISCELL, $path)) {
+ chomp($result = <THISCELL>);
+ close(THISCELL);
+ $result;
+ } else {
+ die "Unable to open $path: $!\n";
+ }
+}
+
+=head2 AFS_conf_canoncell($cellname)
+
+Return the canonical name of the specified cell, as found in F<CellServDB>.
+I<$cellname> may be any unique prefix of a cell name, as with various AFS
+commands that take cell names as arguments.
+
+=head2 AFS_conf_cellservers($cellname)
+
+Return a list of servers in the specified cell. As with B<AFS_conf_canoncell>,
+I<$cellname> may be any unique prefix of a cell name. The resulting list
+contains server hostnames, as found in F<CellServDB>.
+
+=cut
+
+$AFS_Help{conf_canoncell} = '$cellname => $canon';
+$AFS_Help{conf_cellservers} = '$cellname => @servers';
+
+sub AFS_conf_canoncell { &_findcell($_[0], 0); }
+sub AFS_conf_cellservers { &_findcell($_[0], 1); }
+
+sub _findcell {
+ my($cellname, $doservers) = @_;
+ my($path, $found, @servers, $looking);
+
+ return $canon_name{$cellname} if (!$doservers && $canon_name{$cellname});
+ $path = _confpath(CellServDB) || die "Unable to locate CellServDB\n";
+
+ if (open(CELLSERVDB, $path)) {
+ my($cellpat) = $cellname;
+ $cellpat =~ s/(\W)/\\$1/g;
+ while (<CELLSERVDB>) {
+ $looking = 0 if (/^\>/);
+ if (/^\>$cellpat/) {
+ if ($found) {
+ close(CELLSERVDB);
+ die "Cell name $cellname is not unique\n";
+ } else {
+ chop($found = $_);
+ $found =~ s/^\>(\S+).*/$1/;
+ $looking = 1 if ($doservers);
+ }
+ } elsif ($looking && (/^[\.\d]+\s*\#\s*(.*\S+)/ || /^([\.\d]+)/)) {
+ push(@servers, $1);
+ }
+ }
+ close(CELLSERVDB);
+ if ($found) {
+ $canon_name{$cellname} = $found;
+ $doservers ? @servers : ($found);
+ } else {
+ die "Cell $cellname not in CellServDB\n";
+ }
+ } else {
+ die "Unable to open $path: $!\n";
+ }
+}
+
+=head2 AFS_conf_listcells()
+
+Return a list of canonical names (as found in F<CellServDB>) of all
+known AFS cells.
+
+=cut
+
+$AFS_Help{conf_listcells} = '=> @cells';
+sub AFS_conf_listcells {
+ my($path, @cells);
+
+ $path = _confpath(CellServDB) || die "Unable to locate CellServDB!\n";
+
+ if (open(CELLSERVDB, $path)) {
+ while (<CELLSERVDB>) {
+ if (/^\>(\S+)/) {
+ push(@cells, $1);
+ }
+ }
+ close(CELLSERVDB);
+ @cells;
+ } else {
+ die "Unable to open $path: $!\n";
+ }
+}
+
+=head2 AFS_conf_cacheinfo()
+
+Return a table of information about the local workstation's cache
+configuration. This table may contain any or all of the following elements:
+
+=over 14
+
+=item afsroot
+
+Mount point for the AFS root volume
+
+=item cachedir
+
+Location of the AFS cache directory
+
+=item cachesize
+
+AFS cache size
+
+=item hardcachesize
+
+Hard limit on AFS cache size (if specified; probably Mach-specific)
+
+=item translator
+
+Name of AFS/NFS translator server (if set)
+
+=back
+
+=cut
+
+$AFS_Help{conf_cacheinfo} = '=> %info';
+sub AFS_conf_cacheinfo {
+ my($path) = _confpath('cacheinfo');
+ my(%result, $line, $hcs);
+
+ if ($path) {
+ if (open(CACHEINFO, $path)) {
+ chop($line = <CACHEINFO>);
+ close(CACHEINFO);
+ (@result{'afsroot', 'cachedir', 'cachesize'} , $hcs) = split(/:/, $line);
+ $result{'hardcachesize'} = $hcs if ($hcs);
+ } else {
+ die "Unable to open $path: $!\n";
+ }
+ }
+ if ($ENV{'AFSSERVER'}) {
+ $result{'translator'} = $ENV{'AFSSERVER'};
+ } elsif (open(SRVFILE, "$ENV{HOME}/.AFSSERVER")
+ || open(SRVFILE, "/.AFSSERVER")) {
+ $result{'translator'} = <SRVFILE>;
+ close(SRVFILE);
+ }
+ %result;
+}
+
+
+1;
+
+=head1 COPYRIGHT
+
+The CMUCS AFStools, including this module are
+Copyright (c) 1996, Carnegie Mellon University. All rights reserved.
+For use and redistribution information, see CMUCS/CMU_copyright.pm
+
+=cut
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/select.h>
+#include <sys/stat.h>
+
+#include <afs/param.h>
+#include <afs/afsint.h>
+#include <sys/ioctl.h>
+#include <afs/venus.h>
+#include <afs/cellconfig.h>
+#include <afs/afs.h>
+
+/*#include <rx/rxkad.h>*/
+#include <rx/rx_null.h>
+
+/*#include <krb.h>*/
+#include <com_err.h>
+
+struct VenusFid {
+ afs_int32 Cell;
+ struct AFSFid Fid;
+};
+
+int statfile(char *path, char *cellname, afs_uint32 *server,
+ struct AFSFid *f)
+{
+
+ struct ViceIoctl v;
+ struct VenusFid vf;
+ afs_int32 srvbuf[MAXHOSTS];
+ int code;
+
+ v.in=0;
+ v.in_size=0;
+ v.out=cellname;
+ v.out_size=MAXCELLCHARS;
+ if ((code=pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
+ return code;
+
+ v.out=(char *)&vf;
+ v.out_size=sizeof(struct VenusFid);
+ if ((code=pioctl(path, VIOCGETFID, &v, 1)))
+ return code;
+ memcpy(f,&vf.Fid, sizeof(struct AFSFid));
+
+ v.out=(char *)srvbuf;
+ v.out_size=sizeof(srvbuf);
+ if ((code=pioctl(path, VIOCWHEREIS, &v, 1)))
+ return code;
+ if (v.out_size <= sizeof(afs_int32))
+ return EINVAL;
+
+ memcpy(server, srvbuf, sizeof(afs_int32));
+ return 0;
+}
+
+
+extern int RXAFSCB_ExecuteRequest();
+struct rx_securityClass *sc;
+
+extern int start_cb_server()
+{
+ struct rx_service *s;
+
+ sc=rxnull_NewServerSecurityObject();
+ s=rx_NewService(0,1,"afs", &sc, 1, RXAFSCB_ExecuteRequest);
+ if (!s)
+ return 1;
+ rx_StartServer(0);
+ return 0;
+}
+
+
+/*extern int rx_socket;*/
+extern unsigned short rx_port;
+int do_rx_Init(void)
+{
+ struct sockaddr_in s;
+ int len;
+
+ if (rx_Init(0)) {
+ fprintf(stderr, "Cannot initialize rx\n");
+ return 1;
+ }
+
+ len=sizeof(struct sockaddr_in);
+ if (getsockname(rx_socket, &s, &len)) {
+ perror("getsockname");
+ return 1;
+ }
+ rx_port=ntohs(s.sin_port);
+
+ return 0;
+}
+
+struct rx_securityClass *get_sc(char * cellname)
+{
+#if 0
+ char realm[REALM_SZ];
+ CREDENTIALS c;
+#endif
+
+ return rxnull_NewClientSecurityObject();
+#if 0
+
+ ucstring(realm, cellname, REALM_SZ);
+
+ if (krb_get_cred("afs", "", realm, &c)) {
+ if (get_ad_tkt("afs","",realm, DEFAULT_TKT_LIFE)) {
+ return NULL;
+ } else {
+ if (krb_get_cred("afs", "", realm, &c)) {
+ return NULL;
+ }
+ }
+ }
+
+ return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno,
+ c.ticket_st.length, c.ticket_st.dat);
+#endif
+}
+
+#define scindex_NULL 0
+#define scindex_RXKAD 2
+
+#define scindex scindex_RXKAD
+int main(int argc, char **argv)
+{
+ char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
+ afs_uint32 ssrv, dsrv;
+ char *databuffer,*srcf,*destd,*destf,*destpath;
+ struct stat statbuf;
+
+ struct AFSStoreStatus sst;
+ struct AFSFetchStatus fst,dfst;
+ struct AFSVolSync vs;
+ struct AFSCallBack scb,dcb;
+ struct AFSFid sf, dd, df;
+
+ int filesz;
+ int ch, blksize, bytesremaining, bytes;
+ struct timeval start, finish;
+ struct timezone tz;
+ struct rx_securityClass *ssc = 0, *dsc = 0;
+ int sscindex, dscindex;
+ struct rx_connection *sconn,*dconn;
+ struct rx_call *scall, *dcall;
+ int code,fetchcode,storecode,printcallerrs;
+ int slcl = 0, dlcl = 0;
+ int sfd, dfd, unauth = 0;
+
+ struct AFSCBFids theFids;
+ struct AFSCBs theCBs;
+
+
+ blksize=8*1024;
+
+ while ((ch=getopt(argc, argv, "ioub:")) != -1) {
+ switch(ch)
+ {
+ case 'b':
+ blksize=atoi(optarg);
+ break;
+ case 'i':
+ slcl=1;
+ break;
+ case 'o':
+ dlcl=1;
+ break;
+ case 'a':
+ unauth=1;
+ break;
+ default:
+ exit(1);
+ }
+ }
+
+
+ if (argc - optind < 2) {
+ fprintf(stderr, "Usage: afscp [-i|-o]] [-b xfersz] [-u] source dest\n");
+ fprintf(stderr, " -b Set block size\n");
+ fprintf(stderr, " -i Source is local (copy into AFS)\n");
+ fprintf(stderr, " -o Dest is local (copy out of AFS)\n");
+ fprintf(stderr, " -u Run unauthenticated\n");
+ exit(1);
+ }
+ srcf=argv[optind++];
+ destpath=argv[optind++];
+ destd=strdup(destpath);
+ if (!destd) {
+ perror("strdup");
+ exit(1);
+ }
+ if ((destf=strrchr(destd, '/'))) {
+ *destf++=0;
+ } else {
+ destf=destd;
+ destd=".";
+ }
+
+
+ if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
+ fprintf(stderr, "Cannot get attributes of %s\n", srcf);
+ exit(1);
+ }
+ if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
+ fprintf(stderr, "Cannot get attributes of %s\n", destd);
+ exit(1);
+ }
+
+ if ((databuffer=malloc(blksize)) == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+
+ if (do_rx_Init())
+ exit(1);
+
+ if (start_cb_server()) {
+ printf("Cannot start callback service\n");
+ goto Fail_rx;
+ }
+
+ if (!slcl) {
+ sscindex=scindex_RXKAD;
+ if (unauth || (ssc=get_sc(scell)) == NULL) {
+ ssc=rxnull_NewClientSecurityObject();
+ sscindex=scindex_NULL;
+ /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell);*/
+ }
+ sscindex=scindex_NULL;
+
+ if ((sconn=rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
+ sscindex))
+ ==NULL) {
+ struct in_addr s;
+ s.s_addr=ssrv;
+ printf("Cannot initialize rx connection to source server (%s)\n",
+ inet_ntoa(s));
+ goto Fail_sc;
+ }
+ }
+
+ if (!dlcl) {
+ if (!slcl && ssrv == dsrv) {
+ dconn=sconn;
+ dsc=NULL;
+ } else {
+ if (slcl || strcmp(scell, dcell)){
+ dscindex=scindex_RXKAD;
+ if (unauth || (dsc=get_sc(dcell)) == NULL) {
+ dsc=rxnull_NewClientSecurityObject();
+ dscindex=scindex_NULL;
+ /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell);*/
+ }
+ dscindex=scindex_NULL;
+ } else {
+ dsc=ssc;
+ dscindex=sscindex;
+ }
+
+ if ((dconn=rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
+ dscindex))
+ ==NULL) {
+ struct in_addr s;
+ s.s_addr=dsrv;
+ printf("Cannot initialize rx connection to dest server (%s)\n",
+ inet_ntoa(s));
+ goto Fail_sconn;
+ }
+ }
+ }
+
+
+ memset(&sst, 0, sizeof(struct AFSStoreStatus));
+
+ if (dlcl) {
+ dfd = open(destpath, O_RDWR|O_CREAT|O_EXCL, 0666);
+ if (dfd < 0 && errno == EEXIST) {
+ printf("%s already exists, overwriting\n", destpath);
+ dfd = open(destpath, O_RDWR|O_TRUNC, 0666);
+ if (dfd < 0) {
+ fprintf(stderr, "Cannot open %s (%s)\n", destpath,
+ error_message(errno));
+ goto Fail_dconn;
+ }
+ } else if (dfd < 0) {
+ fprintf(stderr, "Cannot open %s (%s)\n", destpath,
+ error_message(errno));
+ goto Fail_dconn;
+ }
+ } else {
+ if ((code=RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst,
+ &dfst, &dcb, &vs))) {
+ if (code == EEXIST) {
+ printf("%s already exits, overwriting\n", destpath);
+ if (statfile(destpath, dcell, &dsrv, &df))
+ fprintf(stderr, "Cannot get attributes of %s\n",
+ destpath);
+ else
+ code=0;
+ } else {
+ printf("Cannot create %s (%s)\n", destpath,
+ error_message(code));
+ if (code)
+ goto Fail_dconn;
+ }
+ }
+ }
+
+ if (slcl) {
+ sfd = open(srcf, O_RDONLY, 0);
+ if (sfd < 0) {
+ fprintf(stderr, "Cannot open %s (%s)\n", srcf,
+ error_message(errno));
+ goto Fail_dconn;
+ }
+ if (fstat(sfd, &statbuf) < 0) {
+ fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
+ error_message(errno));
+ close(sfd);
+ goto Fail_dconn;
+ }
+ } else {
+ if ((code=RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
+ printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
+ error_message(code));
+ goto Fail_dconn;
+ }
+ }
+
+
+
+ if (slcl) {
+ filesz=statbuf.st_size;
+ } else {
+ filesz=fst.Length;
+ }
+
+ printcallerrs=0;
+ fetchcode=0;
+ storecode=0;
+ if (!slcl) scall=rx_NewCall(sconn);
+ if (!dlcl) dcall=rx_NewCall(dconn);
+ gettimeofday(&start, &tz);
+
+ if (!slcl) {
+ if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
+ printf("Unable to fetch data from %s (%s)\n", srcf,
+ error_message(code));
+ goto Fail_call;
+ }
+ }
+
+ if (!dlcl) {
+ if (slcl) {
+ sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
+ sst.ClientModTime=statbuf.st_mtime;
+ sst.UnixModeBits=statbuf.st_mode & ~(S_IFMT|S_ISUID|S_ISGID);
+ } else {
+ sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
+ sst.ClientModTime=fst.ClientModTime;
+ sst.UnixModeBits=fst.UnixModeBits & ~(S_IFMT|S_ISUID|S_ISGID);
+ }
+
+ if ((code = StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
+ printf("Unable to store data to %s (%s)\n", destpath,
+ error_message(code));
+ goto Fail_call;
+ }
+ }
+
+ if (slcl) {
+ bytesremaining=statbuf.st_size;
+ } else {
+ rx_Read(scall,&bytesremaining,sizeof(afs_int32));
+ bytesremaining=ntohl(bytesremaining);
+ }
+
+ while (bytesremaining >0) {
+ /*printf("%d bytes remaining\n",bytesremaining);*/
+ if (slcl) {
+ if ((bytes=read(sfd, databuffer,
+ min(blksize,bytesremaining)))<= 0) {
+ fetchcode=errno;
+ break;
+ }
+ } else {
+ if ((bytes=rx_Read(scall, databuffer,
+ min(blksize,bytesremaining)))<= 0)
+ break;
+ }
+ if (dlcl) {
+ if (write(dfd, databuffer, bytes) != bytes) {
+ storecode=errno;
+ break;
+ }
+ } else {
+ if (rx_Write(dcall, databuffer, bytes) != bytes)
+ break;
+ }
+ bytesremaining -= bytes;
+ /*printf("%d bytes copied\n",bytes);*/
+ }
+
+
+ if (bytesremaining > 0) {
+ printf("Some network error occured while copying data\n");
+ goto Fail_call;
+ }
+
+ if (!slcl) fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
+ if (!dlcl) storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
+ printcallerrs=1;
+ Fail_call:
+
+ if (slcl) {
+ if (close(sfd) && !fetchcode) fetchcode = errno;
+ } else {
+ fetchcode = rx_EndCall(scall, fetchcode);
+ }
+ if (fetchcode && printcallerrs)
+ printf("Error returned from fetch: %s\n", error_message(fetchcode));
+
+ if (dlcl) {
+ if (close(dfd) && !storecode) storecode = errno;
+ } else {
+ storecode = rx_EndCall(dcall, storecode);
+ }
+ if (storecode && printcallerrs)
+ printf("Error returned from store: %s\n", error_message(storecode));
+
+ gettimeofday(&finish, &tz);
+
+ if (!slcl) {
+ theFids.AFSCBFids_len=1;
+ theFids.AFSCBFids_val=&sf;
+ theCBs.AFSCBs_len=1;
+ theCBs.AFSCBs_val=&scb;
+ scb.CallBackType = CB_DROPPED;
+ if ((code=RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
+ printf("Could not give up source callback: %s\n",
+ error_message(code));
+ }
+
+ if (!dlcl) {
+ theFids.AFSCBFids_len=1;
+ theFids.AFSCBFids_val=&df;
+ theCBs.AFSCBs_len=1;
+ theCBs.AFSCBs_val=&dcb;
+ dcb.CallBackType = CB_DROPPED;
+ if ((code=RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
+ printf("Could not give up target callback: %s\n",
+ error_message(code));
+ }
+
+ if (code==0)
+ code=storecode;
+ if (code==0)
+ code=fetchcode;
+
+ Fail_dconn:
+ if (!dlcl && (slcl || dconn != sconn))
+ rx_DestroyConnection(dconn);
+ Fail_sconn:
+ if (!slcl) rx_DestroyConnection(sconn);
+ Fail_sc:
+ if (dsc && dsc != ssc)
+ RXS_Close(dsc);
+ if (ssc) RXS_Close(ssc);
+ Fail_rx:
+ rx_Finalize();
+
+ free(databuffer);
+ if (printcallerrs) {
+ double rate,size,time;
+ if (finish.tv_sec == start.tv_sec) {
+ printf("Copied %d bytes in %d microseconds\n", filesz, finish.tv_usec
+ -start.tv_usec);
+ } else {
+ printf("Copied %d bytes in %d seconds\n", filesz, finish.tv_sec
+ -start.tv_sec);
+ }
+
+ size=filesz/1024.0;
+ time=finish.tv_sec-start.tv_sec + (finish.tv_usec-start.tv_usec)/1e+06;
+ rate=size/time;
+ printf("Transfer rate %g Kbytes/sec\n", rate);
+
+ }
+
+ exit(code != 0);
+}
--- /dev/null
+#include <afs/param.h>
+#include <afs/afscbint.h> /*Callback interface defs*/
+int afs_cb_inited = 0;
+struct interfaceAddr afs_cb_interface;
+static int init_afs_cb() {
+ int count;
+
+ afs_uuid_create(&afs_cb_interface.uuid);
+ count = rx_getAllAddr(&afs_cb_interface.addr_in, AFS_MAX_INTERFACE_ADDR);
+ if ( count <= 0 )
+ afs_cb_interface.numberOfInterfaces = 0;
+ else
+ afs_cb_interface.numberOfInterfaces = count;
+ afs_cb_inited = 1;
+ return 0;
+}
+afs_int32 SRXAFSCB_CallBack(rxcall, Fids_Array, CallBack_Array)
+ struct rx_call *rxcall;
+ AFSCBFids *Fids_Array;
+ AFSCBs *CallBack_Array;
+
+{ /*SRXAFSCB_CallBack*/
+ return(0);
+
+} /*SRXAFSCB_CallBack*/
+
+
+afs_int32 SRXAFSCB_InitCallBackState(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_InitCallBackState*/
+ return(0);
+
+} /*SRXAFSCB_InitCallBackState*/
+
+afs_int32 SRXAFSCB_Probe(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_Probe*/
+ return(0);
+
+} /*SRXAFSCB_Probe*/
+
+
+afs_int32 SRXAFSCB_GetCE(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_GetCE*/
+ return(0);
+} /*SRXAFSCB_GetCE*/
+
+
+afs_int32 SRXAFSCB_GetCE64(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_GetCE64*/
+ return(0);
+} /*SRXAFSCB_GetCE64*/
+
+
+afs_int32 SRXAFSCB_GetLock(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_GetLock*/
+ return(0);
+
+} /*SRXAFSCB_GetLock*/
+afs_int32 SRXAFSCB_XStatsVersion(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_XStatsVersion*/
+ return(0);
+
+} /*SRXAFSCB_XStatsVersion*/
+
+afs_int32 SRXAFSCB_GetXStats(rxcall)
+ struct rx_call *rxcall;
+
+{ /*SRXAFSCB_GetXStats*/
+ return(0);
+} /*SRXAFSCB_GetXStats*/
+
+int SRXAFSCB_InitCallBackState2(rxcall, addr)
+struct rx_call *rxcall;
+struct interfaceAddr * addr;
+{
+ return RXGEN_OPCODE;
+}
+
+int SRXAFSCB_WhoAreYou(rxcall, addr)
+struct rx_call *rxcall;
+struct interfaceAddr *addr;
+{
+ if ( rxcall && addr )
+ {
+ if (!afs_cb_inited) init_afs_cb();
+ *addr = afs_cb_interface;
+ }
+ return(0);
+}
+
+int SRXAFSCB_InitCallBackState3(rxcall, uuidp)
+struct rx_call *rxcall;
+afsUUID *uuidp;
+{
+ return(0);
+}
+int SRXAFSCB_ProbeUuid(rxcall, uuidp)
+struct rx_call *rxcall;
+afsUUID *uuidp;
+{
+ int code = 0;
+ if (!afs_cb_inited) init_afs_cb();
+ if (!afs_uuid_equal(uuidp, &afs_cb_interface.uuid))
+ code = 1; /* failure */
+ return code;
+}
+
+afs_int32 SRXAFSCB_GetServerPrefs(rxcall, serverIndex, srvrAddr, srvrRank)
+struct rx_call *rxcall;
+afs_int32 serverIndex;
+afs_int32 *srvrAddr;
+afs_int32 *srvrRank;
+{
+ return RXGEN_OPCODE;
+}
+
+
+afs_int32 SRXAFSCB_GetCellServDB(rxcall, cellIndex, cellName, cellHosts)
+struct rx_call *rxcall;
+afs_int32 cellIndex;
+char *cellName;
+afs_int32 *cellHosts;
+{
+ return RXGEN_OPCODE;
+}
+
+
+afs_int32 SRXAFSCB_GetLocalCell(rxcall, cellName)
+struct rx_call *rxcall;
+char *cellName;
+{
+ return RXGEN_OPCODE;
+}
+
+
+afs_int32 SRXAFSCB_GetCacheConfig(rxcall, callerVersion, serverVersion,
+ configCount, config)
+struct rx_call *rxcall;
+afs_uint32 callerVersion;
+afs_uint32 *serverVersion;
+afs_uint32 *configCount;
+cacheConfig *config;
+{
+ return RXGEN_OPCODE;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static char long_buf[] =
+"1000\n"
+"1001\n"
+"1002\n"
+"1003\n"
+"1004\n"
+"1005\n"
+"1006\n"
+"1007\n"
+"1008\n"
+"1009\n"
+"1010\n"
+"1011\n"
+"1012\n"
+"1013\n"
+"1014\n"
+"1015\n"
+"1016\n"
+"1017\n"
+"1018\n"
+"1019\n"
+"1020\n"
+"1021\n"
+"1022\n"
+"1023\n"
+"1024\n"
+"1025\n"
+"1026\n"
+"1027\n"
+"1028\n"
+"1029\n"
+"1030\n"
+"1031\n"
+"1032\n"
+"1033\n"
+"1034\n"
+"1035\n"
+"1036\n"
+"1037\n"
+"1038\n"
+"1039\n"
+"1040\n"
+"1041\n"
+"1042\n"
+"1043\n"
+"1044\n"
+"1045\n"
+"1046\n"
+"1047\n"
+"1048\n"
+"1049\n"
+"1050\n"
+"1051\n"
+"1052\n"
+"1053\n"
+"1054\n"
+"1055\n"
+"1056\n"
+"1057\n"
+"1058\n"
+"1059\n"
+"1060\n"
+"1061\n"
+"1062\n"
+"1063\n"
+"1064\n"
+"1065\n"
+"1066\n"
+"1067\n"
+"1068\n"
+"1069\n"
+"1070\n"
+"1071\n"
+"1072\n"
+"1073\n"
+"1074\n"
+"1075\n"
+"1076\n"
+"1077\n"
+"1078\n"
+"1079\n"
+"1080\n"
+"1081\n"
+"1082\n"
+"1083\n"
+"1084\n"
+"1085\n"
+"1086\n"
+"1087\n"
+"1088\n"
+"1089\n"
+"1090\n"
+"1091\n"
+"1092\n"
+"1093\n"
+"1094\n"
+"1095\n"
+"1096\n"
+"1097\n"
+"1098\n"
+"1099\n"
+"1100\n"
+"1101\n"
+"1102\n"
+"1103\n"
+"1104\n"
+"1105\n"
+"1106\n"
+"1107\n"
+"1108\n"
+"1109\n"
+"1110\n"
+"1111\n"
+"1112\n"
+"1113\n"
+"1114\n"
+"1115\n"
+"1116\n"
+"1117\n"
+"1118\n"
+"1119\n"
+"1120\n"
+"1121\n"
+"1122\n"
+"1123\n"
+"1124\n"
+"1125\n"
+"1126\n"
+"1127\n"
+"1128\n"
+"1129\n"
+"1130\n"
+"1131\n"
+"1132\n"
+"1133\n"
+"1134\n"
+"1135\n"
+"1136\n"
+"1137\n"
+"1138\n"
+"1139\n"
+"1140\n"
+"1141\n"
+"1142\n"
+"1143\n"
+"1144\n"
+"1145\n"
+"1146\n"
+"1147\n"
+"1148\n"
+"1149\n"
+"1150\n"
+"1151\n"
+"1152\n"
+"1153\n"
+"1154\n"
+"1155\n"
+"1156\n"
+"1157\n"
+"1158\n"
+"1159\n"
+"1160\n"
+"1161\n"
+"1162\n"
+"1163\n"
+"1164\n"
+"1165\n"
+"1166\n"
+"1167\n"
+"1168\n"
+"1169\n"
+"1170\n"
+"1171\n"
+"1172\n"
+"1173\n"
+"1174\n"
+"1175\n"
+"1176\n"
+"1177\n"
+"1178\n"
+"1179\n"
+"1180\n"
+"1181\n"
+"1182\n"
+"1183\n"
+"1184\n"
+"1185\n"
+"1186\n"
+"1187\n"
+"1188\n"
+"1189\n"
+"1190\n"
+"1191\n"
+"1192\n"
+"1193\n"
+"1194\n"
+"1195\n"
+"1196\n"
+"1197\n"
+"1198\n"
+"1199\n"
+"1200\n"
+"1201\n"
+"1202\n"
+"1203\n"
+"1204\n"
+"1205\n"
+"1206\n"
+"1207\n"
+"1208\n"
+"1209\n"
+"1210\n"
+"1211\n"
+"1212\n"
+"1213\n"
+"1214\n"
+"1215\n"
+"1216\n"
+"1217\n"
+"1218\n"
+"1219\n"
+"1220\n"
+"1221\n"
+"1222\n"
+"1223\n"
+"1224\n"
+"1225\n"
+"1226\n"
+"1227\n"
+"1228\n"
+"1229\n"
+"1230\n"
+"1231\n"
+"1232\n"
+"1233\n"
+"1234\n"
+"1235\n"
+"1236\n"
+"1237\n"
+"1238\n"
+"1239\n"
+"1240\n"
+"1241\n"
+"1242\n"
+"1243\n"
+"1244\n"
+"1245\n"
+"1246\n"
+"1247\n"
+"1248\n"
+"1249\n"
+"1250\n"
+"1251\n"
+"1252\n"
+"1253\n"
+"1254\n"
+"1255\n"
+"1256\n"
+"1257\n"
+"1258\n"
+"1259\n"
+"1260\n"
+"1261\n"
+"1262\n"
+"1263\n"
+"1264\n"
+"1265\n"
+"1266\n"
+"1267\n"
+"1268\n"
+"1269\n"
+"1270\n"
+"1271\n"
+"1272\n"
+"1273\n"
+"1274\n"
+"1275\n"
+"1276\n"
+"1277\n"
+"1278\n"
+"1279\n"
+"1280\n"
+"1281\n"
+"1282\n"
+"1283\n"
+"1284\n"
+"1285\n"
+"1286\n"
+"1287\n"
+"1288\n"
+"1289\n"
+"1290\n"
+"1291\n"
+"1292\n"
+"1293\n"
+"1294\n"
+"1295\n"
+"1296\n"
+"1297\n"
+"1298\n"
+"1299\n"
+"1300\n"
+"1301\n"
+"1302\n"
+"1303\n"
+"1304\n"
+"1305\n"
+"1306\n"
+"1307\n"
+"1308\n"
+"1309\n"
+"1310\n"
+"1311\n"
+"1312\n"
+"1313\n"
+"1314\n"
+"1315\n"
+"1316\n"
+"1317\n"
+"1318\n"
+"1319\n"
+"1320\n"
+"1321\n"
+"1322\n"
+"1323\n"
+"1324\n"
+"1325\n"
+"1326\n"
+"1327\n"
+"1328\n"
+"1329\n"
+"1330\n"
+"1331\n"
+"1332\n"
+"1333\n"
+"1334\n"
+"1335\n"
+"1336\n"
+"1337\n"
+"1338\n"
+"1339\n"
+"1340\n"
+"1341\n"
+"1342\n"
+"1343\n"
+"1344\n"
+"1345\n"
+"1346\n"
+"1347\n"
+"1348\n"
+"1349\n"
+"1350\n"
+"1351\n"
+"1352\n"
+"1353\n"
+"1354\n"
+"1355\n"
+"1356\n"
+"1357\n"
+"1358\n"
+"1359\n"
+"1360\n"
+"1361\n"
+"1362\n"
+"1363\n"
+"1364\n"
+"1365\n"
+"1366\n"
+"1367\n"
+"1368\n"
+"1369\n"
+"1370\n"
+"1371\n"
+"1372\n"
+"1373\n"
+"1374\n"
+"1375\n"
+"1376\n"
+"1377\n"
+"1378\n"
+"1379\n"
+"1380\n"
+"1381\n"
+"1382\n"
+"1383\n"
+"1384\n"
+"1385\n"
+"1386\n"
+"1387\n"
+"1388\n"
+"1389\n"
+"1390\n"
+"1391\n"
+"1392\n"
+"1393\n"
+"1394\n"
+"1395\n"
+"1396\n"
+"1397\n"
+"1398\n"
+"1399\n"
+"1400\n"
+"1401\n"
+"1402\n"
+"1403\n"
+"1404\n"
+"1405\n"
+"1406\n"
+"1407\n"
+"1408\n"
+"1409\n"
+"1410\n"
+"1411\n"
+"1412\n"
+"1413\n"
+"1414\n"
+"1415\n"
+"1416\n"
+"1417\n"
+"1418\n"
+"1419\n"
+"1420\n"
+"1421\n"
+"1422\n"
+"1423\n"
+"1424\n"
+"1425\n"
+"1426\n"
+"1427\n"
+"1428\n"
+"1429\n"
+"1430\n"
+"1431\n"
+"1432\n"
+"1433\n"
+"1434\n"
+"1435\n"
+"1436\n"
+"1437\n"
+"1438\n"
+"1439\n"
+"1440\n"
+"1441\n"
+"1442\n"
+"1443\n"
+"1444\n"
+"1445\n"
+"1446\n"
+"1447\n"
+"1448\n"
+"1449\n"
+"1450\n"
+"1451\n"
+"1452\n"
+"1453\n"
+"1454\n"
+"1455\n"
+"1456\n"
+"1457\n"
+"1458\n"
+"1459\n"
+"1460\n"
+"1461\n"
+"1462\n"
+"1463\n"
+"1464\n"
+"1465\n"
+"1466\n"
+"1467\n"
+"1468\n"
+"1469\n"
+"1470\n"
+"1471\n"
+"1472\n"
+"1473\n"
+"1474\n"
+"1475\n"
+"1476\n"
+"1477\n"
+"1478\n"
+"1479\n"
+"1480\n"
+"1481\n"
+"1482\n"
+"1483\n"
+"1484\n"
+"1485\n"
+"1486\n"
+"1487\n"
+"1488\n"
+"1489\n"
+"1490\n"
+"1491\n"
+"1492\n"
+"1493\n"
+"1494\n"
+"1495\n"
+"1496\n"
+"1497\n"
+"1498\n"
+"1499\n"
+"1500\n"
+"1501\n"
+"1502\n"
+"1503\n"
+"1504\n"
+"1505\n"
+"1506\n"
+"1507\n"
+"1508\n"
+"1509\n"
+"1510\n"
+"1511\n"
+"1512\n"
+"1513\n"
+"1514\n"
+"1515\n"
+"1516\n"
+"1517\n"
+"1518\n"
+"1519\n"
+"1520\n"
+"1521\n"
+"1522\n"
+"1523\n"
+"1524\n"
+"1525\n"
+"1526\n"
+"1527\n"
+"1528\n"
+"1529\n"
+"1530\n"
+"1531\n"
+"1532\n"
+"1533\n"
+"1534\n"
+"1535\n"
+"1536\n"
+"1537\n"
+"1538\n"
+"1539\n"
+"1540\n"
+"1541\n"
+"1542\n"
+"1543\n"
+"1544\n"
+"1545\n"
+"1546\n"
+"1547\n"
+"1548\n"
+"1549\n"
+"1550\n"
+"1551\n"
+"1552\n"
+"1553\n"
+"1554\n"
+"1555\n"
+"1556\n"
+"1557\n"
+"1558\n"
+"1559\n"
+"1560\n"
+"1561\n"
+"1562\n"
+"1563\n"
+"1564\n"
+"1565\n"
+"1566\n"
+"1567\n"
+"1568\n"
+"1569\n"
+"1570\n"
+"1571\n"
+"1572\n"
+"1573\n"
+"1574\n"
+"1575\n"
+"1576\n"
+"1577\n"
+"1578\n"
+"1579\n"
+"1580\n"
+"1581\n"
+"1582\n"
+"1583\n"
+"1584\n"
+"1585\n"
+"1586\n"
+"1587\n"
+"1588\n"
+"1589\n"
+"1590\n"
+"1591\n"
+"1592\n"
+"1593\n"
+"1594\n"
+"1595\n"
+"1596\n"
+"1597\n"
+"1598\n"
+"1599\n"
+"1600\n"
+"1601\n"
+"1602\n"
+"1603\n"
+"1604\n"
+"1605\n"
+"1606\n"
+"1607\n"
+"1608\n"
+"1609\n"
+"1610\n"
+"1611\n"
+"1612\n"
+"1613\n"
+"1614\n"
+"1615\n"
+"1616\n"
+"1617\n"
+"1618\n"
+"1619\n"
+"1620\n"
+"1621\n"
+"1622\n"
+"1623\n"
+"1624\n"
+"1625\n"
+"1626\n"
+"1627\n"
+"1628\n"
+"1629\n"
+"1630\n"
+"1631\n"
+"1632\n"
+"1633\n"
+"1634\n"
+"1635\n"
+"1636\n"
+"1637\n"
+"1638\n"
+"1639\n"
+"1640\n"
+"1641\n"
+"1642\n"
+"1643\n"
+"1644\n"
+"1645\n"
+"1646\n"
+"1647\n"
+"1648\n"
+"1649\n"
+"1650\n"
+"1651\n"
+"1652\n"
+"1653\n"
+"1654\n"
+"1655\n"
+"1656\n"
+"1657\n"
+"1658\n"
+"1659\n"
+"1660\n"
+"1661\n"
+"1662\n"
+"1663\n"
+"1664\n"
+"1665\n"
+"1666\n"
+"1667\n"
+"1668\n"
+"1669\n"
+"1670\n"
+"1671\n"
+"1672\n"
+"1673\n"
+"1674\n"
+"1675\n"
+"1676\n"
+"1677\n"
+"1678\n"
+"1679\n"
+"1680\n"
+"1681\n"
+"1682\n"
+"1683\n"
+"1684\n"
+"1685\n"
+"1686\n"
+"1687\n"
+"1688\n"
+"1689\n"
+"1690\n"
+"1691\n"
+"1692\n"
+"1693\n"
+"1694\n"
+"1695\n"
+"1696\n"
+"1697\n"
+"1698\n"
+"1699\n"
+"1700\n"
+"1701\n"
+"1702\n"
+"1703\n"
+"1704\n"
+"1705\n"
+"1706\n"
+"1707\n"
+"1708\n"
+"1709\n"
+"1710\n"
+"1711\n"
+"1712\n"
+"1713\n"
+"1714\n"
+"1715\n"
+"1716\n"
+"1717\n"
+"1718\n"
+"1719\n"
+"1720\n"
+"1721\n"
+"1722\n"
+"1723\n"
+"1724\n"
+"1725\n"
+"1726\n"
+"1727\n"
+"1728\n"
+"1729\n"
+"1730\n"
+"1731\n"
+"1732\n"
+"1733\n"
+"1734\n"
+"1735\n"
+"1736\n"
+"1737\n"
+"1738\n"
+"1739\n"
+"1740\n"
+"1741\n"
+"1742\n"
+"1743\n"
+"1744\n"
+"1745\n"
+"1746\n"
+"1747\n"
+"1748\n"
+"1749\n"
+"1750\n"
+"1751\n"
+"1752\n"
+"1753\n"
+"1754\n"
+"1755\n"
+"1756\n"
+"1757\n"
+"1758\n"
+"1759\n"
+"1760\n"
+"1761\n"
+"1762\n"
+"1763\n"
+"1764\n"
+"1765\n"
+"1766\n"
+"1767\n"
+"1768\n"
+"1769\n"
+"1770\n"
+"1771\n"
+"1772\n"
+"1773\n"
+"1774\n"
+"1775\n"
+"1776\n"
+"1777\n"
+"1778\n"
+"1779\n"
+"1780\n"
+"1781\n"
+"1782\n"
+"1783\n"
+"1784\n"
+"1785\n"
+"1786\n"
+"1787\n"
+"1788\n"
+"1789\n"
+"1790\n"
+"1791\n"
+"1792\n"
+"1793\n"
+"1794\n"
+"1795\n"
+"1796\n"
+"1797\n"
+"1798\n"
+"1799\n"
+"1800\n"
+"1801\n"
+"1802\n"
+"1803\n"
+"1804\n"
+"1805\n"
+"1806\n"
+"1807\n"
+"1808\n"
+"1809\n"
+"1810\n"
+"1811\n"
+"1812\n"
+"1813\n"
+"1814\n"
+"1815\n"
+"1816\n"
+"1817\n"
+"1818\n"
+"1819\n"
+"1820\n"
+"1821\n"
+"1822\n"
+"1823\n"
+"1824\n"
+"1825\n"
+"1826\n";
+
+/*
+ * compare this file with read and mmap.
+ * return 0 iff identical.
+ */
+
+static int
+compare_file (const char *filename)
+{
+ struct stat sb;
+ int fd;
+ int ret;
+ void *read_buf;
+ void *mmap_buf;
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0)
+ err(1, "open %s", filename);
+ ret = fstat (fd, &sb);
+ if (ret < 0)
+ err (1, "stat %s", filename);
+ read_buf = malloc (sb.st_size);
+ if (read_buf == NULL)
+ err (1, "malloc %u", (unsigned)sb.st_size);
+ ret = read (fd, read_buf, sb.st_size);
+ if (ret < 0)
+ err (1, "read %s", filename);
+ if (ret != sb.st_size)
+ errx (1, "short read from %s", filename);
+ mmap_buf = mmap (NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (mmap_buf == (void *)MAP_FAILED)
+ err (1, "mmap %s", filename);
+ ret = memcmp (read_buf, mmap_buf, sb.st_size);
+ close (fd);
+ free (read_buf);
+ return ret;
+}
+
+static void
+doit (const char *filename)
+{
+ int fd;
+ int ret;
+
+ fd = open (filename, O_WRONLY | O_APPEND | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close %s", filename);
+ fd = open (filename, O_WRONLY | O_APPEND);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = write (fd, "foobar\n", 7);
+ if (ret < 0)
+ err (1, "write %s", filename);
+ if (ret != 7)
+ errx (1, "short write to %s", filename);
+ ret = close (fd);
+ if (ret < 0)
+ err(1, "close %s", filename);
+
+ if(compare_file (filename))
+ errx (1, "compare 1 failed");
+
+ fd = open (filename, O_WRONLY | O_APPEND);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = write (fd, long_buf, strlen(long_buf));
+ if (ret < 0)
+ err (1, "write %s", filename);
+ if (ret != strlen(long_buf))
+ errx (1, "short write to %s", filename);
+ ret = close (fd);
+ if (ret < 0)
+ err(1, "close %s", filename);
+
+ if(compare_file (filename))
+ errx (1, "compare 2 failed");
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "blaha";
+
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+$objdir/echo-n hej > foo || exit 1
+if test `cat foo` != "hej"; then exit 1; fi
+$objdir/echo-n hopp >> foo || exit 1
+if test `cat foo` != "hejhopp"; then exit 1; fi
+rm foo || exit 1
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifndef MAXPATHLEN
+#ifdef PATH_MAX
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 4096
+#endif
+#endif
+
+RCSID("$Id$");
+
+static int verbose_flag;
+static FILE *verbose_fp = NULL;
+
+static int
+initial_string (char **buf, size_t *size, size_t new_size)
+{
+ char *tmp = malloc (new_size);
+
+ if (tmp == NULL)
+ return -1;
+ *buf = tmp;
+ *size = new_size;
+ return 0;
+}
+
+static int
+expand_string (char **buf, size_t *size, size_t new_size)
+{
+ char *tmp = realloc (*buf, new_size);
+
+ if (tmp == NULL)
+ return -1;
+ *buf = tmp;
+ *size = new_size;
+ return 0;
+}
+
+/*
+ * Verify that the dynamically allocated string `buf' of length
+ * `size', has room for `len' bytes. Returns -1 if realloc fails.
+ */
+
+static int
+guarantee_room (char **buf, size_t *size, size_t len)
+{
+ if (*size > len)
+ return 0;
+
+ return expand_string (buf, size, min(*size * 2, len));
+}
+
+static char *
+getcwd_classic (char *buf, size_t size)
+{
+ int dynamic_buf = 0;
+ struct stat root_sb, dot_sb, dotdot_sb;
+ char *work_string;
+ size_t work_length;
+ char slash_dot_dot[] = "/..";
+ char *curp;
+ char *endp;
+ DIR *dir = NULL;
+
+ if (initial_string (&work_string, &work_length, MAXPATHLEN) < 0)
+ return NULL;
+
+ if (buf == NULL) {
+ dynamic_buf = 1;
+ if (initial_string (&buf, &size, MAXPATHLEN) < 0) {
+ free (work_string);
+ return NULL;
+ }
+ }
+
+ endp = curp = buf + size - 1;
+
+ if (lstat (".", &dot_sb) < 0)
+ goto err_ret;
+ if (lstat ("/", &root_sb) < 0)
+ goto err_ret;
+ strcpy (work_string, "..");
+ fprintf (verbose_fp, "\".\" is (%u, %u), \"/\" is (%u, %u)\n",
+ (unsigned)dot_sb.st_dev, (unsigned)dot_sb.st_ino,
+ (unsigned)root_sb.st_dev, (unsigned)root_sb.st_ino);
+
+ while (dot_sb.st_dev != root_sb.st_dev
+ || dot_sb.st_ino != root_sb.st_ino) {
+ struct dirent *dp;
+ int found = 0;
+ int change_dev = 0;
+ int pattern_len = strlen (work_string);
+
+ if (lstat (work_string, &dotdot_sb) < 0)
+ goto err_ret;
+ fprintf (verbose_fp, "\"..\" is (%u, %u)\n",
+ (unsigned)dotdot_sb.st_dev, (unsigned)dotdot_sb.st_ino);
+ if (dot_sb.st_dev != dotdot_sb.st_dev)
+ change_dev = 1;
+ dir = opendir (work_string);
+ if (dir == NULL)
+ goto err_ret;
+ while ((dp = readdir (dir)) != NULL) {
+ size_t name_len = strlen (dp->d_name);
+
+ if (change_dev) {
+ struct stat sb;
+
+ if (guarantee_room (&work_string, &work_length,
+ pattern_len + name_len + 2) < 0) {
+ goto err_ret;
+ }
+
+ strcat (work_string, "/");
+ strcat (work_string, dp->d_name);
+
+ if (lstat (work_string, &sb) < 0) {
+ goto err_ret;
+ }
+ if (sb.st_dev == dot_sb.st_dev
+ && sb.st_ino == dot_sb.st_ino) {
+ fprintf (verbose_fp, "\"%s\" found\n", work_string);
+ found = 1;
+ }
+ work_string[pattern_len] = '\0';
+ } else if (dp->d_ino == dot_sb.st_ino) {
+ fprintf (verbose_fp, "\"%s\" found\n", dp->d_name);
+ found = 1;
+ }
+
+ if (found) {
+ while (buf + name_len >= curp) {
+ size_t old_len;
+
+ if (!dynamic_buf) {
+ errno = ERANGE;
+ goto err_ret;
+ }
+ old_len = endp - curp + 1;
+ if (expand_string (&buf, &size, size * 2) < 0)
+ goto err_ret;
+ memmove (buf + size - old_len,
+ buf + size / 2 - old_len,
+ old_len);
+ endp = buf + size - 1;
+ curp = endp - old_len + 1;
+ }
+ memcpy (curp - name_len, dp->d_name, name_len);
+ curp[-(name_len + 1)] = '/';
+ curp -= name_len + 1;
+ break;
+ }
+ }
+ closedir (dir);
+ dir = NULL;
+
+ if (!found)
+ goto err_ret;
+
+ dot_sb = dotdot_sb;
+ if (guarantee_room (&work_string, &work_length,
+ pattern_len + strlen(slash_dot_dot) + 1) < 0)
+ goto err_ret;
+ strcat (work_string, slash_dot_dot);
+ }
+ if (curp == endp) {
+ while (buf >= curp) {
+ if (!dynamic_buf) {
+ errno = ERANGE;
+ goto err_ret;
+ }
+ if (expand_string (&buf, &size, size * 2) < 0)
+ goto err_ret;
+ }
+ *--curp = '/';
+ }
+ *endp = '\0';
+ memmove (buf, curp, endp - curp + 1);
+ free (work_string);
+ return buf;
+
+err_ret:
+ if (dir)
+ closedir (dir);
+ if (dynamic_buf)
+ free (buf);
+ free (work_string);
+ return NULL;
+}
+
+#if linux
+
+static char *
+getcwd_proc (char *buf, size_t size)
+{
+ int dynamic_buf = 0;
+
+ if (buf == NULL) {
+ dynamic_buf = 1;
+ if (initial_string (&buf, &size, MAXPATHLEN) < 0)
+ return NULL;
+ } else if (size <= 1) {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ for (;;) {
+ int ret;
+
+ ret = readlink ("/proc/self/cwd", buf, size);
+ if (ret == -1)
+ goto err_ret;
+ if (buf[0] != '/') {
+ errno = EINVAL;
+ goto err_ret;
+ }
+ if (buf[ret-1] != '\0' && ret >= size) {
+ if (!dynamic_buf) {
+ errno = ERANGE;
+ goto err_ret;
+ }
+ if (expand_string (&buf, &size, size * 2) < 0)
+ goto err_ret;
+ } else {
+ if (buf[ret - 1] != '\0')
+ buf[ret] = '\0';
+ return buf;
+ }
+ }
+err_ret:
+ if (dynamic_buf)
+ free (buf);
+ return NULL;
+}
+
+#endif /* linux */
+
+static int
+test_1(char *(*func)(char *, size_t), const char *func_name, int init_size)
+{
+ char real_buf[2048];
+ char buf[2048], *buf2, buf3[4711];
+ int i;
+ int ret = 0;
+ int three_done = 1;
+
+ if (getcwd (real_buf, sizeof(real_buf)) == NULL) {
+ fprintf (verbose_fp, "getcwd(buf, %u) failed\n",
+ (unsigned)sizeof(real_buf));
+ ret = 1;
+ }
+ if (func (buf, sizeof(buf)) == NULL) {
+ fprintf (verbose_fp, "%s(buf, %u) failed\n", func_name,
+ (unsigned)sizeof(buf));
+ ret = 1;
+ } else {
+ fprintf (verbose_fp, "first *%s*\n", buf);
+ if (strcmp (real_buf, buf) != 0) {
+ fprintf (verbose_fp, "first comparison failed: *%s* != *%s*\n",
+ real_buf, buf);
+ ret = 1;
+ }
+ }
+
+ buf2 = func (NULL, 0);
+ if (buf2 == NULL) {
+ fprintf (verbose_fp, "%s(NULL, 0) failed\n", func_name);
+ ret = 1;
+ } else {
+ fprintf (verbose_fp, "second *%s*\n", buf2);
+ if (strcmp (real_buf, buf2) != 0) {
+ fprintf (verbose_fp, "second comparison failed: *%s* != *%s*\n",
+ real_buf, buf2);
+ ret = 1;
+ }
+ free (buf2);
+ }
+
+ for (i = init_size; i < sizeof(buf3); ++i) {
+ memset (buf3, '\x01', sizeof(buf3));
+ if (func (buf3, i) == NULL) {
+ if (errno != ERANGE) {
+ fprintf (verbose_fp, "%s(buf,%u) call failed\n", func_name, i);
+ three_done = 0;
+ break;
+ }
+ } else {
+ int j;
+
+ for (j = i; j < sizeof(buf3); ++j)
+ if (buf3[j] != '\x01') {
+ fprintf (verbose_fp, "buffer was overwritten at %d\n", j);
+ three_done = 0;
+ break;
+ }
+ break;
+ }
+ }
+
+ if (three_done) {
+ fprintf (verbose_fp, "third *%s*\n", buf3);
+ if (strcmp (real_buf, buf3) != 0) {
+ fprintf (verbose_fp, "third comparison failed: *%s* != *%s*\n",
+ real_buf, buf3);
+ ret = 1;
+ } else if (strlen (buf3) + 1 != i
+ && strlen (buf3) + 1 >= init_size) {
+ fprintf (verbose_fp, "wrong len in third call: %d != %d\n",
+ (unsigned)strlen(buf3) + 1, i);
+ ret = 1;
+ }
+ } else {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static int
+test_it(char *(*func)(char *, size_t), const char *name, int init_size)
+{
+ int ret;
+
+ fprintf (verbose_fp, "testing %s (initial size %d)\n", name, init_size);
+ ret = test_1 (func, name, init_size);
+ if (ret)
+ fprintf (verbose_fp, "FAILED!\n");
+ else
+ fprintf (verbose_fp, "passed\n");
+ return ret;
+}
+
+#ifdef linux
+#include <linux/unistd.h>
+#endif
+
+#ifdef __NR_getcwd
+
+#define __NR_sys_getcwd __NR_getcwd
+
+static
+_syscall2(int, sys_getcwd, char *, buf, size_t, size)
+
+static char *
+getcwd_syscall (char *buf, size_t size)
+{
+ int dynamic_buf = 0;
+
+ if (buf == NULL) {
+ dynamic_buf = 1;
+ if (initial_string (&buf, &size, MAXPATHLEN) < 0)
+ return NULL;
+ }
+
+ for (;;) {
+ int ret;
+
+ ret = sys_getcwd (buf, size);
+ if (ret >= 0)
+ return buf;
+ else if (errno == ERANGE) {
+ if (!dynamic_buf)
+ return NULL;
+ if (expand_string (&buf, &size, size * 2) < 0)
+ return NULL;
+ } else
+ return NULL;
+ }
+}
+
+#endif
+
+static int help_flag;
+
+static struct agetargs args[] = {
+ {"verbose", 'v', aarg_flag, &verbose_flag, "verbose", NULL},
+ {"help", 0, aarg_flag, &help_flag, NULL, NULL},
+ {NULL, 0, aarg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (int exit_val)
+{
+ aarg_printusage (args, NULL, "", AARG_GNUSTYLE);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+ int optind = 0;
+
+
+ verbose_flag = getenv ("VERBOSE") != NULL;
+
+ if (agetarg (args, argc, argv, &optind, AARG_GNUSTYLE))
+ usage (1);
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage (1);
+ if (help_flag)
+ usage (0);
+
+ verbose_fp = fdopen (4, "w");
+ if (verbose_fp == NULL) {
+ verbose_fp = fopen ("/dev/null", "w");
+ if (verbose_fp == NULL)
+ err (1, "fopen");
+ }
+
+ ret += test_it (getcwd, "getcwd", 3);
+#ifdef __NR_getcwd
+ ret += test_it (getcwd_syscall, "getcwd_syscall", 3);
+#endif
+ ret += test_it (getcwd_classic, "getcwd_classic", 0);
+#if linux
+ ret += test_it (getcwd_proc, "getcwd_proc", 0);
+#endif
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id$");
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <unistd.h>
+
+
+#include <err.h>
+
+static void
+usage(int exit_val)
+{
+ fprintf(stderr, "asu user program [arguments ...]\n");
+ exit(exit_val);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *user, *prog;
+
+
+ if (argc < 3)
+ usage(1);
+
+ user = argv[1];
+ prog = argv[2];
+
+ if (getuid() == 0) {
+ struct passwd *pw;
+ gid_t groups[1];
+ uid_t uid;
+ gid_t gid;
+
+ pw = getpwnam(user);
+ if(pw == NULL)
+ errx(1, "no such user %s", user);
+
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ groups[0] = gid;
+
+ if (setgroups(1, groups))
+ errx(1, "setgroups failed");
+
+ setgid(gid);
+ setuid(uid);
+ setegid(gid);
+ seteuid(uid);
+ }
+
+#if 0
+ if (k_hasafs()) {
+ int ret = k_setpag();
+ if (ret < 0)
+ warn("k_setpag");
+ }
+#endif
+
+ execvp(prog, &argv[2]);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <err.h>
+
+static void
+doit (const char *filename)
+{
+ int fd;
+ struct stat sb;
+
+ fd = open (filename, O_RDWR | O_TRUNC | O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ if (lseek (fd, (off_t)(1024*1024), SEEK_SET) != 1024*1024)
+ err (1, "lseek %s", filename);
+ if (write (fd, "hej", 3) != 3)
+ err (1, "write to %s", filename);
+ if (close (fd) < 0)
+ err (1, "close %s", filename);
+ if (stat (filename, &sb) < 0)
+ err (1, "stat %s", filename);
+ if (unlink (filename) < 0)
+ err (1, "unlink %s", filename);
+ if (sb.st_blocks == 0)
+ errx (1, "st_blocks == 0");
+}
+
+int
+main(int argc, char **argv)
+{
+
+ if (argc == 1)
+ doit ("foo");
+ else if (argc == 2)
+ doit (argv[1]);
+ else
+ errx (1, "usage: %s [filename]", argv[0]);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ;exit 0; fi
+
+ARLA_RELEASE=${AFSROOT}/stacken.kth.se/ftp/pub/arla/arla-0.34.tar.gz
+
+mkdir src || exit 1
+mkdir obj || exit 1
+
+cd src || exit 1
+gzip -dc $ARLA_RELEASE | tar xf -
+cd ../obj || exit 1
+../src/*/configure || exit 1
+make || exit 1
+cd milko || exit 1
+make || exit 1
+exit 0
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.ph for use and distribution information
+#
+#: * bos.pm - Wrappers around BOS commands (basic overseer server)
+#: * This module provides wrappers around the various bosserver
+#: * commands, giving them a nice perl-based interface. Someday, they might
+#: * talk to the servers directly instead of using 'bos', but not anytime
+#: * soon.
+#:
+
+package OpenAFS::bos;
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use OpenAFS::wrapper;
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_bos_create &AFS_bos_addhost
+ &AFS_bos_addkey &AFS_bos_adduser
+ &AFS_bos_delete &AFS_bos_exec
+ &AFS_bos_getdate &AFS_bos_getlog
+ &AFS_bos_getrestart &AFS_bos_install
+ &AFS_bos_listhosts &AFS_bos_listkeys
+ &AFS_bos_listusers &AFS_bos_prune
+ &AFS_bos_removehost &AFS_bos_removekey
+ &AFS_bos_removeuser &AFS_bos_restart
+ &AFS_bos_salvage &AFS_bos_setauth
+ &AFS_bos_setcellname &AFS_bos_setrestart
+ &AFS_bos_shutdown &AFS_bos_start
+ &AFS_bos_startup &AFS_bos_status
+ &AFS_bos_stop &AFS_bos_uninstall);
+
+#: AFS_bos_addhost($server, $host, [$clone], [$cell])
+#: Add a new database server host named $host to the database
+#: on $server.
+#: If $clone is specified, create an entry for a clone server.
+#: On success, return 1.
+#:
+$AFS_Help{bos_addhost} = '$server, $host, [$clone], [$cell] => Success?';
+sub AFS_bos_addhost {
+ my($server, $host, $clone, $cell) = @_;
+ my(@args);
+
+ @args = ('addhost', '-server', $server, '-host', $host);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-clone') if ($clone);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_addkey($server, $key, $kvno, [$cell])
+#: Add a key $key with key version number $kvno on server $server
+#: On success, return 1.
+#:
+$AFS_Help{bos_addkey} = '$server, $key, $kvno, [$cell] => Success?';
+sub AFS_bos_addkey {
+ my($server, $key, $kvno, $cell) = @_;
+ my(@args);
+
+ @args = ('addkey', '-server', $server, '-key', $key, '-kvno', $kvno);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_adduser($server, \@user, [$cell])
+#: Add users specified in @users to bosserver superuser list on $server.
+#: On success, return 1.
+#:
+$AFS_Help{bos_adduser} = '$server, \@user, [$cell] => Success?';
+sub AFS_bos_adduser {
+ my($server, $user, $cell) = @_;
+ my(@args);
+
+ @args = ('adduser', '-server', $server, '-user', @$user);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_create($server, $instance, $type, \@cmd, [$cell])
+#: Create a bnode with name $instance
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_create} = '$server, $instance, $type, \@cmd, [$cell] => Success?';
+sub AFS_bos_create {
+ my($server, $instance, $type, $cmd, $cell) = @_;
+ my(@args);
+
+ @args = ('create', '-server', $server, '-instance', $instance, '-type',
+ $type, '-cmd', @$cmd);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_delete($server, $instance, [$cell])
+#: Delete a bnode with name $instance
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_delete} = '$server, $instance, [$cell] => Success?';
+sub AFS_bos_delete {
+ my($server, $instance, $cell) = @_;
+ my(@args);
+
+ @args = ('delete', '-server', $server, '-instance', $instance);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_exec($server, $cmd, [$cell])
+#: Exec a process on server $server
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_exec} = '$server, $cmd, [$cell] => Success?';
+sub AFS_bos_exec {
+ my($server, $cmd, $cell) = @_;
+ my(@args);
+
+ @args = ('exec', '-server', $server, '-cmd', $cmd);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_getdate($server, $file, [$cell])
+#: Get the date for file $file from server $server
+#: On success, return ($exedate, $bakdate, $olddate).
+#:
+$AFS_Help{bos_getdate} = '$server, $file, [$cell] => ($exedate, $bakdate, $olddate)';
+sub AFS_bos_getdate {
+ my($server, $file, $cell) = @_;
+ my(@args, $exedate, $bakdate, $olddate);
+
+ @args = ('getdate', '-server', $server, '-file', $file);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args,
+ [[ 'dated (.*), (no )?\.BAK', \$exedate],
+ [ '\.BAK file dated (.*), (no )?\.OLD', \$bakdate],
+ [ '\.OLD file dated (.*)\.', \$olddate]]);
+ ($exedate, $bakdate, $olddate);
+}
+
+#: AFS_bos_getlog($server, $file, [$cell])
+#: Get log named $file from server $server
+#: On success, return 1.
+#:
+$AFS_Help{bos_getlog} = '$server, $file, [$cell] => Success?';
+sub AFS_bos_getlog {
+ my($server, $file, $cell) = @_;
+ my(@args);
+
+ @args = ('getlog', '-server', $server, '-file', $file);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args,
+ [[ '^Fetching log file .*', '.']], { pass_stdout });
+ 1;
+}
+
+#: AFS_bos_getrestart($server, [$cell])
+#: Get the restart time for server $server
+#: On success, return ($genrestart, $binrestart).
+#:
+$AFS_Help{bos_getrestart} = '$server, [$cell] => ($genrestart, $binrestart)';
+sub AFS_bos_getrestart {
+ my($server, $cell) = @_;
+ my(@args, $genrestart, $binrestart);
+
+ @args = ('getrestart', '-server', $server);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args,
+ [[ '^Server .* restarts at\s*(.*\S+)', \$genrestart],
+ [ '^Server .* restarts for new binaries at\s*(.*\S+)', \$binrestart]]);
+ ($genrestart, $binrestart);
+}
+
+#: AFS_bos_install($server, \@files, [$dir], [$cell])
+#: Install files in \@files on server $server in directory $dir
+#: or the default directory.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_install} = '$server, \@files, [$dir], [$cell] => Success?';
+sub AFS_bos_install {
+ my($server, $files, $dir, $cell) = @_;
+ my(@args, $file);
+
+ @args = ('install', '-server', $server, '-file', @$files);
+ push(@args, '-dir', $dir) if ($dir);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args, [[ 'bos: installed file .*', '.' ]],
+ { 'errors_last' => 1 });
+ 1;
+}
+
+#: AFS_bos_listhosts($server, [$cell])
+#: Get host list on server $server.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, an array of hosts with the first entry being the cellname.
+#:
+$AFS_Help{bos_listhosts} = '$server, [$cell] => @ret';
+sub AFS_bos_listhosts {
+ my($server, $cell) = @_;
+ my(@args, @ret);
+
+ @args = ('listhosts', '-server', $server);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args,
+ [[ '^Cell name is (.*)', sub {
+ push(@ret, $_[0]);
+ } ],
+ [ 'Host \S+ is (\S+)', sub {
+ push(@ret, $_[0]);
+ } ]
+ ]);
+ @ret;
+}
+
+#: AFS_bos_listkeys($server, [$showkey], [$cell])
+#: Get key list on server $server.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, $showkey indicates keys and not checksums should be shown.
+#: If specified, work in $cell instead of the default cell.
+#: On success, an array of hosts with the first entry being the cellname.
+#:
+$AFS_Help{bos_listkeys} = '$server, [$showkey], [$cell] => %ret';
+sub AFS_bos_listkeys {
+ my($server, $showkey, $cell) = @_;
+ my(@args, %ret);
+
+ @args = ('listkeys', '-server', $server);
+ push(@args, '-showkey') if ($showkey);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %ret = &wrapper('bos', \@args,
+ [[ '^key (\d+) has cksum (\d+)', sub {
+ my(%ret) = %OpenAFS::wrapper::result;
+ $ret{$_[0]} = $_[1];
+ %OpenAFS::wrapper::result = %ret;
+ } ],
+ [ '^key (\d+) is \'(\S+)\'', sub {
+ my(%ret) = %OpenAFS::wrapper::result;
+ $ret{$_[0]} = $_[1];
+ %OpenAFS::wrapper::result = %ret;
+ } ],
+ [ '^Keys last changed on\s*(.*\S+)', sub {
+ my(%ret) = %OpenAFS::wrapper::result;
+ $ret{'date'} = $_[0];
+ %OpenAFS::wrapper::result = %ret;
+ } ],
+ [ 'All done.', '.']]);
+ %ret;
+}
+
+#: AFS_bos_listusers($server, [$cell])
+#: Get superuser list on server $server.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, an array of users.
+#:
+$AFS_Help{bos_listusers} = '$server, [$cell] => @ret';
+sub AFS_bos_listusers {
+ my($server, $cell) = @_;
+ my(@args, @ret);
+
+ @args = ('listusers', '-server', $server);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args, [[ '^SUsers are: (\S+)', sub {
+ push(@ret, split(' ',$_[0]));
+ } ]]);
+ @ret;
+}
+
+#: AFS_bos_prune($server, [$bak], [$old], [$core], [$all], [$cell])
+#: Prune files on server $server
+#: If $bak is specified, remove .BAK files
+#: If $old is specified, remove .OLD files
+#: If $core is specified, remove core files
+#: If $all is specified, remove all junk files
+#: On success, return 1.
+#:
+$AFS_Help{bos_prune} = '$server, [$bak], [$old], [$core], [$all], [$cell] => Success?';
+sub AFS_bos_prune {
+ my($server, $bak, $old, $core, $all, $cell) = @_;
+ my(@args);
+
+ @args = ('prune', '-server', $server, '-bak', $bak, '-old', $old, '-core', $core, '-all', $all);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-bak') if ($bak);
+ push(@args, '-old') if ($old);
+ push(@args, '-core') if ($core);
+ push(@args, '-all') if ($all);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_removehost($server, $host, [$cell])
+#: Remove a new database server host named $host from the database
+#: on $server.
+#: On success, return 1.
+#:
+$AFS_Help{bos_removehost} = '$server, $host, [$cell] => Success?';
+sub AFS_bos_removehost {
+ my($server, $host, $cell) = @_;
+ my(@args);
+
+ @args = ('removehost', '-server', $server, '-host', $host);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_removekey($server, $kvno, [$cell])
+#: Remove a key with key version number $kvno on server $server
+#: On success, return 1.
+#:
+$AFS_Help{bos_removekey} = '$server, $kvno, [$cell] => Success?';
+sub AFS_bos_removekey {
+ my($server, $kvno, $cell) = @_;
+ my(@args);
+
+ @args = ('removekey', '-server', $server, '-kvno', $kvno);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_removeuser($server, \@user, [$cell])
+#: Remove users specified in @users to bosserver superuser list on $server.
+#: On success, return 1.
+#:
+$AFS_Help{bos_removeuser} = '$server, \@user, [$cell] => Success?';
+sub AFS_bos_removeuser {
+ my($server, $user, $cell) = @_;
+ my(@args);
+
+ @args = ('removeuser', '-server', $server, '-user', @$user);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_restart($server, [\@inst], [$bosserver], [$all], [$cell])
+#: Restart bosserver instances specified in \@inst, or if $all is
+#: specified, all instances.
+#: If $bosserver is specified, restart the bosserver.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_restart} = '$server, [\@inst], [$bosserver], [$all], [$cell] => Success?';
+sub AFS_bos_restart {
+ my($server, $inst, $bosserver, $all, $cell) = @_;
+ my(@args);
+
+ @args = ('restart', '-server', $server);
+ push(@args, '-instance', @$inst) if ($inst);
+ push(@args, '-bosserver') if ($bosserver);
+ push(@args, '-all') if ($all);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_salvage($server, [$partition], [$volume], [$file], [$all], [$showlog], [$parallel], [$tmpdir], [$orphans], [$cell])
+#: Invoke the salvager, providing a partition $partition if specified, and
+#: further a volume id $volume if specified.
+#: If specified, $file is a file to write the salvager output into.
+#: If specified, $all indicates all partitions should be salvaged.
+#: If specified, $showlog indicates the log should be displayed on completion.
+#: If specified, $parallel indicates the number salvagers that should be run
+#: in parallel.
+#: If specified, $tmpdir indicates a directory in which to store temporary
+#: files.
+#: If specified, $orphans indicates how to handle orphans in a volume
+#: (valid options are ignore, remove and attach).
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_salvage} = '$server, [$partition], [$volume], [$file], [$all], [$showlog], [$parallel], [$tmpdir], [$orphans], [$cell] => Success?';
+sub AFS_bos_salvage {
+ my($server, $partition, $volume, $file, $all, $showlog, $parallel, $tmpdir, $orphans, $cell) = @_;
+ my(@args);
+
+ @args = ('salvage', '-server', $server);
+ push(@args, '-partition', $partition)if ($partition);
+ push(@args, '-volume', $volume) if ($volume);
+ push(@args, '-file', $file) if ($file);
+ push(@args, '-all') if ($all);
+ push(@args, '-showlog') if ($showlog);
+ push(@args, '-parallel', $parallel) if ($parallel);
+ push(@args, '-tmpdir', $tmpdir) if ($tmpdir);
+ push(@args, '-orphans', $orphans)if ($orphans);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args, [['bos: shutting down fs.', '.'],
+ ['Starting salvage.', '.'],
+ ['bos: waiting for salvage to complete.', '.'],
+ ['bos: salvage completed', '.'],
+ ['bos: restarting fs.', '.']],
+ { 'errors_last' => 1 });
+ 1;
+}
+
+#: AFS_bos_setauth($server, $authrequired, [$cell])
+#: Set the authentication required flag for server $server to
+#: $authrequired.
+#: On success, return 1.
+#:
+$AFS_Help{bos_setauth} = '$server, $authrequired, [$cell] => Success?';
+sub AFS_bos_setauth {
+ my($server, $authrequired, $cell) = @_;
+ my(@args);
+
+ @args = ('setauth', '-server', $server, '-authrequired', $authrequired);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_setcellname($server, $name, [$cell])
+#: Set the cellname for server $server to $name
+#: On success, return 1.
+#:
+$AFS_Help{bos_setcellname} = '$server, $name, [$cell] => Success?';
+sub AFS_bos_setcellname {
+ my($server, $name, $cell) = @_;
+ my(@args);
+
+ @args = ('setcellname', '-server', $server, '-name', $name);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_setrestart($server, $time, [$general], [$newbinary], [$cell])
+#: Set the restart time for server $server to $time
+#: If specified, $general indicates only the general restart time should be
+#: set.
+#: If specified, $newbinary indicates only the binary restart time should be
+#: set.
+#: On success, return 1.
+#:
+$AFS_Help{bos_setrestart} = '$server, $time, [$general], [$newbinary], [$cell] => Success?';
+sub AFS_bos_setrestart {
+ my($server, $time, $general, $newbinary, $cell) = @_;
+ my(@args);
+
+ @args = ('setrestart', '-server', $server, '-time', $time);
+ push(@args, '-general') if ($general);
+ push(@args, '-newbinary') if ($newbinary);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_shutdown($server, [\@inst], [$wait], [$cell])
+#: Stop all bosserver instances or if \@inst is specified,
+#: only those in \@inst on server $server
+#: waiting for them to stop if $wait is specified.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_shutdown} = '$server, [\@inst], [$wait], [$cell] => Success?';
+sub AFS_bos_shutdown {
+ my($server, $inst, $wait, $cell) = @_;
+ my(@args);
+
+ @args = ('shutdown', '-server', $server);
+ push(@args, '-instance', @$inst) if ($inst);
+ push(@args, '-wait') if ($wait);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_start($server, \@inst, [$cell])
+#: Start bosserver instances in \@inst on server $server .
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_start} = '$server, \@inst, [$cell] => Success?';
+sub AFS_bos_start {
+ my($server, $inst, $cell) = @_;
+ my(@args);
+
+ @args = ('start', '-server', $server, '-instance', @$inst);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_startup($server, [\@inst], [$cell])
+#: Start all bosserver instances or if \@inst is specified, only
+#: those in \@inst on server $server .
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_startup} = '$server, [\@inst], [$cell] => Success?';
+sub AFS_bos_startup {
+ my($server, $inst, $cell) = @_;
+ my(@args);
+
+ @args = ('startup', '-server', $server);
+ push(@args, '-instance', @$inst) if ($inst);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_status($server, [\@bnodes], [$cell])
+#: Get status for the specified bnodes on $server, or for all bnodes
+#: if none are given.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return an associative array whose keys are the names
+#: of bnodes on the specified server, and each of whose values is
+#: an associative array describing the status of the corresponding
+#: bnode, containing some or all of the following elements:
+#: - name Name of this bnode (same as key)
+#: - type Type of bnode (simple, cron, fs)
+#: - status Basic status
+#: - aux_status Auxillary status string, for bnode types that provide it
+#: - num_starts Number of process starts
+#: - last_start Time of last process start
+#: - last_exit Time of last exit
+#: - last_error Time of last error exit
+#: - error_code Exit code from last error exit
+#: - error_signal Signal from last error exit
+#: - commands Ref to list of commands
+#:
+$AFS_Help{bos_status} = '$server, [\@bnodes], [$cell] => %bnodes';
+sub AFS_bos_status {
+ my($server, $bnodes, $cell) = @_;
+ my(@args, %finres, %blist, @cmds);
+
+ @args = ('status', '-server', $server, '-long');
+ push(@args, '-instance', @$bnodes) if ($bnodes);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %finres = &wrapper('bos', \@args,
+ [['^(Instance)', sub {
+ my(%binfo) = %OpenAFS::wrapper::result;
+
+ if ($binfo{name}) {
+ $binfo{commands} = [@cmds] if (@cmds);
+ $blist{$binfo{name}} = \%binfo;
+
+ @cmds = ();
+ %OpenAFS::wrapper::result = ();
+ }
+ }],
+ ['^Instance (.*), \(type is (\S+)\)\s*(.*)', 'name', 'type', 'status' ],
+ ['Auxilliary status is: (.*)\.', 'aux_status' ],
+ ['Process last started at (.*) \((\d+) proc starts\)', 'last_start', 'num_starts' ],
+ ['Last exit at (.*\S+)', 'last_exit' ],
+ ['Last error exit at (.*),', 'last_error' ],
+ ['by exiting with code (\d+)', 'error_code' ],
+ ['due to signal (\d+)', 'error_signal' ],
+ [q/Command \d+ is '(.*)'/, sub { push(@cmds, $_[0]) }],
+ ]);
+ if ($finres{name}) {
+ $finres{commands} = [@cmds] if (@cmds);
+ $blist{$finres{name}} = \%finres;
+ }
+ %blist;
+}
+
+#: AFS_bos_stop($server, \@inst, [$wait], [$cell])
+#: Stop bosserver instances in \@inst on server $server
+#: waiting for them to stop if $wait is specified.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_stop} = '$server, \@inst, [$wait], [$cell] => Success?';
+sub AFS_bos_stop {
+ my($server, $inst, $wait, $cell) = @_;
+ my(@args);
+
+ @args = ('stop', '-server', $server, '-instance', @$inst);
+ push(@args, '-wait') if ($wait);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args);
+ 1;
+}
+
+#: AFS_bos_uninstall($server, \@files, [$dir], [$cell])
+#: Uninstall files in \@files on server $server in directory $dir
+#: or the default directory.
+#: The server name ($server) may be a hostname or IP address
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{bos_uninstall} = '$server, \@files, [$dir], [$cell] => Success?';
+sub AFS_bos_uninstall {
+ my($server, $files, $dir, $cell) = @_;
+ my(@args);
+
+ @args = ('uninstall', '-server', $server, '-file', @$files);
+ push(@args, '-dir', $dir) if ($dir);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('bos', \@args, [[ '^bos: uninstalled file .*', '.' ]],
+ { 'errors_last' => 1 });
+ 1;
+}
+
+1;
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_addhost(localhost,"128.2.1.2",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_addkey(localhost,"\000\001\002\003\004\005\006\007",250,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_adduser(localhost,[testuser1],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+open(FOO, ">sleeper.sh");
+print FOO "#!/bin/sh\n";
+print FOO "while true; do sleep 60; done\n";
+print FOO "exit 0\n";
+close FOO;
+chmod 0755, "sleeper.sh";
+
+&AFS_bos_install(localhost,["sleeper.sh"],,);
+&AFS_bos_create(localhost,sleeper,simple,["/usr/afs/bin/sleeper.sh"],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_delete(localhost,sleeper,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+eval { &AFS_bos_delete(localhost,sleeper,); };
+
+if (! $@) {
+ exit (1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+use OpenAFS::ConfigUtils;
+use OpenAFS::Dirpath;
+use OpenAFS::OS;
+
+my ($host);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_exec(localhost,"$openafsdirpath->{'afssrvbindir'}/foo.sh",);
+if (-f "/usr/tmp/garbage") {
+} else {
+ exit(1);
+}
+unlink "/usr/tmp/garbage";
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host);
+$host = `hostname`;
+&AFS_Init();
+
+open(FOO, ">foo.sh");
+print FOO "#!/bin/sh\n";
+print FOO "touch /usr/tmp/garbage\n";
+print FOO "exit 0\n";
+close FOO;
+chmod 0755, "foo.sh";
+
+&AFS_bos_install(localhost,["foo.sh"],,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, @hosts, $this, $cell, $cnt);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+$cell = &AFS_fs_wscell();
+
+@hosts = &AFS_bos_listhosts(localhost,);
+$this = shift(@hosts);
+if ($this ne $cell) {
+ exit (1);
+}
+while ($this = shift(@hosts)) {
+ if ($this ne $host) {
+ if (($this ne "128.2.1.2")) {
+ exit (1);
+ }
+ }
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, @hosts, $this, $cell, $cnt, %ret);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+$cell = &AFS_fs_wscell();
+
+%ret = &AFS_bos_listkeys(localhost,,);
+foreach $this (keys %ret) {
+ if ($this == 250) {
+ if ($ret{250} ne 3288840443) {
+ exit(1);
+ }
+ }
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, @hosts, $this, $cell, $cnt);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+
+@hosts = &AFS_bos_listusers(localhost,);
+while ($this = shift(@hosts)) {
+ if ($this ne "admin") {
+ if (($this ne "testuser1")) {
+ exit (1);
+ }
+ }
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, @hosts, $this, $cell, $cnt);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+$cell = &AFS_fs_wscell();
+
+&AFS_bos_removehost(localhost,"128.2.1.2",);
+@hosts = &AFS_bos_listhosts(localhost,);
+$this = shift(@hosts);
+if ($this ne $cell) {
+ exit (1);
+}
+while ($this = shift(@hosts)) {
+ if ($this ne $host) {
+ exit (1);
+ }
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, @hosts, $this, $cell, $cnt, %ret);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+$cell = &AFS_fs_wscell();
+
+&AFS_bos_removekey(localhost,250,);
+foreach $this (keys %ret) {
+ if ($this == 250) {
+ exit(1);
+ }
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, @hosts, $this, $cell, $cnt);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+$cell = &AFS_fs_wscell();
+
+&AFS_bos_removeuser(localhost,[testuser1],);
+@hosts = &AFS_bos_listusers(localhost,);
+while ($this = shift(@hosts)) {
+ if ($this ne "admin") {
+ exit (1);
+ }
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, %info, %info2, $linfo);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_restart(localhost,[sleeper],,,);
+%info = &AFS_bos_status("localhost",[sleeper],);
+$linfo=$info{'sleeper'};
+%info2 = %$linfo;
+if ($info2{'num_starts'} != 2) {
+ exit 1;
+}
+if ($info2{'status'} ne "temporarily enabled, currently running normally.") {
+ exit 1;
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_salvage("localhost","a",,,,,,,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_salvage("localhost",,,,1,,,,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_salvage("localhost","a","unrep",,,,,,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, %info, %info2, $linfo);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_shutdown(localhost,[sleeper],1,);
+%info = &AFS_bos_status("localhost",[sleeper],);
+$linfo=$info{'sleeper'};
+%info2 = %$linfo;
+if ($info2{'num_starts'} != 2) {
+ exit 1;
+}
+if ($info2{'status'} ne "temporarily disabled, currently shutdown.") {
+ exit 1;
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, %info, %info2, $linfo);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_start(localhost,[sleeper],);
+%info = &AFS_bos_status("localhost",[sleeper],);
+$linfo=$info{'sleeper'};
+%info2 = %$linfo;
+if ($info2{'num_starts'} != 2) {
+ exit 1;
+}
+if ($info2{'status'} ne "currently running normally.") {
+ exit 1;
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, %info, %info2, $linfo);
+$host = `hostname`;
+&AFS_Init();
+
+%info = &AFS_bos_status("localhost",[sleeper],);
+$linfo=$info{'sleeper'};
+%info2 = %$linfo;
+if ($info2{'num_starts'} != 1) {
+ exit 1;
+}
+if ($info2{'status'} ne "currently running normally.") {
+ exit 1;
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, %info, %info2, $linfo);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_bos_stop(localhost,[sleeper],1,);
+%info = &AFS_bos_status("localhost",[sleeper],);
+$linfo=$info{'sleeper'};
+%info2 = %$linfo;
+if ($info2{'num_starts'} != 1) {
+ exit 1;
+}
+if ($info2{'status'} ne "disabled, currently shutdown.") {
+ exit 1;
+}
+exit(0);
+
+
+
--- /dev/null
+#!/bin/sh
+set -x
+# $Id$
+##if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+echo -n pwd before is ' '
+pwd
+#
+# copied from generic-build because rcs wants to put (hard)links into tar balls.
+#
+filename=$AFSROOT/stacken.kth.se/ftp/pub/gnu/rcs/rcs-5.7.tar.gz
+b=rcs-5.7
+obj=$b-obj
+gzip -dc $filename | tar xvf - >&4 2>&1
+mkdir $obj || exit 1
+cd $obj || exit 1
+../$b/configure >&4 || exit 1
+make $MAKEFLAGS || exit 1
+echo -n pwd after is ' '
+pwd
+echo row1 > testfile
+echo log1 | ./src/ci -u testfile
+./src/co -l testfile
+echo row2 >> testfile
+echo log2 | ./src/ci -u testfile
+./src/co -l testfile
+echo row3 >> testfile
+echo log3 | ./src/ci -u testfile
+wc -l testfile | grep '3 testfile' || exit 1
+
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$SHELL $SHELLVERBOSE $srcdir/generic-build $AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz emacs-20.7
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+env MAKEFLAGS="-j" $SHELL $SHELLVERBOSE $srcdir/generic-build $AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz emacs-20.7
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$SHELL $SHELLVERBOSE $srcdir/generic-build $AFSROOT/stacken.kth.se/ftp/pub/gnu/gdb/gdb-5.0.tar.gz
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+
+${FS} sq . 0
+wget http://www.openafs.org/dl/1.2.2/openafs-1.2.2-src.tar.gz >& 4
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$SHELL $SHELLVERBOSE $srcdir/generic-build openafs-1.2.2-src.tar.gz openafs-1.2.2
+openafs-1.2.2/src/finale/translate_et 180480 >& /dev/null
--- /dev/null
+#!/bin/sh
+# $Id$
+$objdir/apwd
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . system:anyuser all || exit 1
+${FS} mkm root.cell root.cell || exit 1
+$objdir/readdir-vs-lstat . || exit 1
+$objdir/readdir-vs-lstat root.cell || exit 1
+${FS} rmm root.cell || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+$objdir/create-files 100 0 || exit 1
+$objdir/readdir-vs-lstat . || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+#################################################################
+#
+# Copy file back and forth between $TMPDIR (defaults to /tmp)
+# which is hopefully on local disk or any other well tested
+# file system and the filesystem we want to test (in $PWD).
+#
+#################################################################
+
+test $SHELLVERBOSE && set $SHELLVERBOSE
+
+function compare () {
+ if cmp $1 $2; then
+ :
+ else
+ diff $1 $2
+ exit 1
+ fi
+}
+
+test $TMPDIR || TMPDIR=/tmp
+TMPDIR=$TMPDIR/compare-with-local-$$
+mkdir $TMPDIR || exit 1
+
+# Generate test file
+cat > $TMPDIR/bar << EOF
+This is an arla temporary test file.
+You may remove it any time.
+Kontrollen blinkar blå.
+EOF
+
+cp $TMPDIR/bar bar
+compare $TMPDIR/bar bar
+mv bar $TMPDIR/bas
+compare $TMPDIR/bar $TMPDIR/bas
+ # this is for later overwrite test
+ test -f bar && echo bar should not exist && exit 1
+ cp $TMPDIR/bar bar
+ compare $TMPDIR/bar bar
+cat $TMPDIR/bas > bat
+compare $TMPDIR/bar bat
+cat bat > $TMPDIR/bau
+compare $TMPDIR/bar $TMPDIR/bau
+mv $TMPDIR/bau bav
+compare $TMPDIR/bar bav
+ # this is for later overwrite test
+ test -f $TMPDIR/bau && echo $TMPDIR/bau should not exist && exit 1
+ cp $TMPDIR/bar $TMPDIR/bau
+cp bav $TMPDIR/baw
+compare $TMPDIR/bar $TMPDIR/baw
+
+# If we get so far we can write new files.
+# Now test overwrite.
+
+# Generate test file slightly different
+cat > $TMPDIR/bar << EOF
+This is an arla temporary test file.
+You may remove it any time.
+Mera jul.
+EOF
+
+cp $TMPDIR/bar bar
+compare $TMPDIR/bar bar
+mv bar $TMPDIR/bas
+compare $TMPDIR/bar $TMPDIR/bas
+cat $TMPDIR/bas > bat
+compare $TMPDIR/bar bat
+cat bat > $TMPDIR/bau
+compare $TMPDIR/bar $TMPDIR/bau
+mv $TMPDIR/bau bav
+compare $TMPDIR/bar bav
+cp bav $TMPDIR/baw
+compare $TMPDIR/bar $TMPDIR/baw
+
+${objdir}/rm-rf $TMPDIR
+exit 0
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.pm for use and distribution information
+
+package OpenAFS::config;
+
+=head1 NAME
+
+OpenAFS::config - AFStools configuration
+
+=head1 SYNOPSIS
+
+ use OpenAFS::config;
+
+=head1 DESCRIPTION
+
+This module contains various AFStools configuration variables which are used
+by the other AFStools modules. These describe how AFStools should act in a
+particular installation, and are mostly pretty mundane. All of the defaults
+here are pretty reasonable, so you shouldn't have to change anything unless
+your site is particularly exotic.
+
+Note that this file only describes how a particular B<installation> of AFStools
+should act, not how it should act upon a particular B<cell>. Since the cell
+AFStools is running in is not necessarily the same as the cell on which it
+is acting, most configuration that is really per-cell should be located in a
+cell-specific module.
+
+This module should only be used by other parts of AFStools. As such, the
+variables described here are not normally visible to user programs, and this
+file is mostly of interest to administrators who are installing AFStools.
+
+=over 4
+
+=cut
+
+use OpenAFS::CMU_copyright;
+use OpenAFS::Dirpath;
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw($def_ConfDir
+ @CmdList
+ @CmdPath
+ $err_table_dir
+ );
+
+# The following configuration variables are defined here. Mention them
+# all an extra time, to suppress annoying warnings. Doesn't perl have
+# a way of doing this???
+@x = ();
+@x = ($def_ConfDir, @CmdList, @CmdPath);
+
+=item $def_ConfDir - Default configuration directory
+
+This is the default AFS configuration directory, where files like ThisCell,
+CellServDB, and so on are found. If the AFStools parameter I<confdir> is
+set, it will generally be searched before this directory. Normally, this
+should be set to F</usr/vice/etc> and not changed, as that path is hardwired
+into AFS. However, it might be necessary to modify this if your site uses
+an exotic locally-compiled version of AFS.
+
+=cut
+
+$def_ConfDir = "$openafsdirpath->{'viceetcdir'}";
+#$def_ConfDir = "/usr/vice/etc";
+
+
+=item @CmdList - List of AFS commands
+
+This is a list of AFS commands that the AFStools package might want to invoke
+using B<OpenAFS::wrapper::wrapper>. Don't remove anything from this list if you
+know what's good for you. It's OK to add things, though, if you think you
+might use the wrapper features for something.
+
+=cut
+
+@CmdList = ('fs', 'pts', 'vos', 'bos', 'kas', 'krbkas', 'sys');
+
+
+=item @CmdPath - Path to search for AFS commands
+
+This is the list of directories where B<OpenAFS::wrapper::wrapper> will look for
+AFS commands. For AFStools to work properly, every command listed in
+I<@OpenAFS::config::CmdList> must appear in one of these directories. The default
+should be sufficient for most sites; we deal with Transarc's reccommendations
+as well as common practice. Note that on machines for which /usr/afs/bin
+exists (typically, AFS fileservers), that directory is first. This is probably
+what you want...
+
+=cut
+
+@CmdPath = (split(/:/, $ENV{PATH}),
+ "$openafsdirpath->{'afssrvbindir'}", # For servers
+ '/usr/local/bin', # Many sites put AFS in /usr/local
+ '/usr/local/etc',
+ '/usr/afsws/bin', # For people who use Transarc's
+ '/usr/afsws/etc'); # silly reccommendations
+
+=item $err_table_dir - Error table directory
+
+This is the location of error tables used by the errcode and errstr
+routines in OpenAFS::errtrans. Each file in this directory should be a
+com_err error table (in source form), and should be named the same
+as the com_err error package contained within.
+
+=cut
+
+$err_table_dir = '/usr/local/lib/errtbl';
+
+1;
+
+=back
+
+=head1 COPYRIGHT
+
+The CMUCS AFStools, including this module are
+Copyright (c) 1996, Carnegie Mellon University. All rights reserved.
+For use and redistribution information, see CMUCS/CMU_copyright.pm
+
+=cut
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+if test "X$LARGE" = "X" ; then echo "Not running large test $0" ; exit 0 ; fi
+original=${1-$AFSROOT/stacken.kth.se/ftp/pub}
+(cd $original; tar cvf - gnu) 2>&4 | tar xvf - >&4
+find gnu -type f -exec cmp '{}' $original/'{}' \;
--- /dev/null
+#!/bin/sh
+# $Id$
+cat > foo <<EOF
+hej love
+
+ska vi g|ra r{tt nu.
+EOF
+
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+cp foo foo2 || exit 1
+exit 0
--- /dev/null
+#!/bin/sh
+> foobar
+test -f foobar || exit 1
+test -s foobar && exit 1
+rm foobar || exit 1
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+creat_dirs (int count)
+{
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ char num[17];
+ int ret;
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ ret = mkdir (num, 0777);
+ if (ret < 0)
+ err (1, "mkdir %s", num);
+ }
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s number-of-dirs\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+
+
+ if (argc != 2)
+ usage (1);
+
+ count = strtol (argv[1], &ptr, 0);
+ if (count == 0 && ptr == argv[1])
+ errx (1, "'%s' not a number", argv[1]);
+
+ return creat_dirs (count);
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#undef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#undef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+creat_files (int count, long startsize)
+{
+ int i;
+ long size = 0;
+
+ for (i = 0; i < count; ++i) {
+ char num[17];
+ int fd;
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ fd = open (num, O_WRONLY | O_CREAT | O_EXCL, 0777);
+ if (fd < 0)
+ err (1, "open %s", num);
+ size = startsize;
+ while (size > 0) {
+ char buf[8192];
+ size_t len;
+ ssize_t ret;
+
+ len = min(sizeof(buf), size);
+
+ ret = write (fd, buf, len);
+ if (ret < 0)
+ err (1, "write to %s", num);
+ if (ret != len)
+ errx (1, "short write to %s", num);
+ size -= ret;
+ }
+ if (close (fd) < 0)
+ err (1, "close %s", num);
+ }
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s number-of-files size-of-files\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+ long size;
+
+
+ if (argc != 3)
+ usage (1);
+
+ count = strtol (argv[1], &ptr, 0);
+ if (count == 0 && ptr == argv[1])
+ errx (1, "'%s' not a number", argv[1]);
+
+ size = strtol (argv[2], &ptr, 0);
+ if (size == 0 && ptr == argv[2])
+ errx (1, "`%s' not a number", argv[2]);
+
+ return creat_files (count, size);
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/create-remove dir 1000
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/create-remove file 1000
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+creat_dir (const char *name)
+{
+ int ret = mkdir (name, 0777);
+ if (ret < 0) err (1, "mkdir %s", name);
+ return 0;
+}
+
+static int
+remove_dir (const char *name)
+{
+ int ret = rmdir (name);
+ if (ret < 0) err (1, "rmdir %s", name);
+ return 0;
+}
+
+static int
+creat_file (const char *name)
+{
+ int ret = open (name, O_CREAT|O_RDWR, 0777);
+ if (ret < 0) err (1, "mkdir %s", name);
+ close (ret);
+ return 0;
+}
+
+static int
+unlink_file (const char *name)
+{
+ int ret = unlink (name);
+ if (ret < 0) err (1, "unlink %s", name);
+ return 0;
+}
+
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s [file|dir] number-of-dirs\n", __progname);
+ exit (ret);
+}
+
+#ifndef MAXPATHLEN
+#ifdef PATH_MAX
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 4096
+#endif
+#endif
+
+static int
+creat_many (int num,
+ int (*c) (const char *name),
+ int (*d) (const char *name))
+{
+ char name[MAXPATHLEN];
+
+ if (num < 0)
+ errx (1, "not be negative");
+
+ snprintf (name, sizeof(name), "foo-%d-%d", num, getpid());
+
+ while (num-- > 0) {
+ (c) (name);
+ (d) (name);
+ }
+ return 0;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+
+
+ if (argc != 3)
+ usage (1);
+
+ count = strtol (argv[2], &ptr, 0);
+ if (count == 0 && ptr == argv[2])
+ errx (1, "'%s' not a number", argv[2]);
+
+ if (strcmp ("file", argv[1]) == 0)
+ return creat_many (count, creat_file, unlink_file);
+ else if (strcmp("dir", argv[1]) == 0)
+ return creat_many (count, creat_dir, remove_dir);
+ else
+ errx (1, "unknown type: %s", argv[1]);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <afs/afsint.h>
+#include <afs/auth.h>
+#include <afs/cellconfig.h>
+#include <afs/cmd.h>
+
+#include <err.h>
+
+struct VenusFid {
+ afs_int32 Cell;
+ struct AFSFid Fid;
+};
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s file\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *file;
+ int ret;
+ struct stat sb;
+ struct stat sb_new;
+ struct stat sb_old;
+ struct VenusFid fid;
+ char *filename;
+ ino_t afsfileid;
+
+ if (argc != 2)
+ usage (1);
+
+ file = argv[1];
+
+ asprintf (&filename, "%s.new", file);
+
+ ret = open (file, O_RDWR, 0600);
+ if (ret < 0)
+ err (1, "open");
+ close (ret);
+
+ ret = open (filename, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (ret < 0) {
+ unlink(file);
+ err (1, "open");
+ }
+ close (ret);
+
+ ret = stat (file, &sb);
+ if (ret < 0) {
+ unlink(filename);
+ unlink(file);
+ err (1, "stat");
+ }
+
+ ret = lstat (filename, &sb_new);
+ if (ret < 0) {
+ unlink(filename);
+ unlink(file);
+ err (1, "stat");
+ }
+
+ if (sb.st_ino == sb_new.st_ino)
+ err (1, "sb.st_ino == sb_new.st_ino");
+
+ ret = lstat (file, &sb_old);
+ if (ret < 0) {
+ unlink(filename);
+ unlink(file);
+ err (1, "stat");
+ }
+
+ if (sb_old.st_ino == sb_new.st_ino)
+ err (1, "sb_old.st_ino == sb_new.st_ino");
+ if (sb.st_ino == sb_new.st_ino)
+ err (1, "sb.st_ino == sb_new.st_ino");
+ if (sb_old.st_ino != sb.st_ino)
+ err (1, "sb_old.st_ino != sb.st_ino");
+
+ ret = fs_getfid (file, &fid);
+ if (ret) {
+ unlink(file);
+ unlink(filename);
+ err (1, "fs_getfid: %d", ret);
+ }
+
+ afsfileid = ((fid.Fid.Volume & 0x7FFF) << 16 | (fid.Fid.Vnode & 0xFFFFFFFF));
+ if (sb.st_ino != afsfileid) {
+ unlink(file);
+ unlink(filename);
+ errx (1, "sb.st_ino(%ld) != afsfileid(%ld) (%d.%d.%d.%d)",
+ (long)sb.st_ino, (long)afsfileid,
+ fid.Cell, fid.Fid.Volume, fid.Fid.Vnode, fid.Fid.Unique);
+ }
+
+ unlink(filename);
+ unlink(file);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <limits.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#define CONTENT_STRING "kaka"
+
+static FILE *verbose_fp = NULL;
+
+static int
+creat_symlinks (int count)
+{
+ int ret;
+ int i;
+
+ fprintf (verbose_fp, "creating:");
+
+ for (i = 0; i < count; ++i) {
+ char num[17];
+
+ fprintf (verbose_fp, " c%d", i);
+ fflush (verbose_fp);
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ ret = symlink (CONTENT_STRING, num);
+ if (ret < 0)
+ err (1, "symlink %s", num);
+ }
+ fprintf (verbose_fp, "\n");
+ return 0;
+}
+
+#ifndef MAXPATHLEN
+#ifdef PATH_MAX
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 4096
+#endif
+#endif
+
+static int
+verify_contents (int count)
+{
+ int ret, i;
+ char file[MAXPATHLEN];
+ char content[MAXPATHLEN];
+
+ fprintf (verbose_fp, "reading:");
+ for (i = 0; i < count; i++) {
+ fprintf (verbose_fp, " r%d", i);
+ fflush (verbose_fp);
+
+ snprintf (file, sizeof(file), "%d", i);
+ ret = readlink (file, content, sizeof(content) - 1);
+ if (ret < 0)
+ err (1, "readlink: %d", i);
+ content[ret] = '\0';
+ if (strcmp (CONTENT_STRING, content) != 0)
+ errx (1, "%s != %s", content, CONTENT_STRING);
+ }
+ fprintf (verbose_fp, "\n");
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s number-of-symlinks\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+
+
+ if (argc != 2)
+ usage (1);
+
+ verbose_fp = fdopen (4, "w");
+ if (verbose_fp == NULL) {
+ verbose_fp = fopen ("/dev/null", "w");
+ if (verbose_fp == NULL)
+ err (1, "fopen");
+ }
+
+ count = strtol (argv[1], &ptr, 0);
+ if (count == 0 && ptr == argv[1])
+ errx (1, "'%s' not a number", argv[1]);
+
+ return creat_symlinks (count) ||
+ verify_contents(count);
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test -r /dev/zero; then
+ dd if=/dev/zero of=foo bs=1k count=20 >/dev/null 2>/dev/null || exit 1
+ rm foo || exit 1
+else
+ echo "not running dd (you have no /dev/zero)"
+fi
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ;exit 0; fi
+
+mkdir foo && ( cd foo && $SHELL $SHELLVERBOSE ${srcdir}/dir-tree 5 "0 1 2 3 4" )
+${objdir}/rm-rf foo
--- /dev/null
+#!/bin/sh
+# $Id$
+
+mkdir foo
+
+b=foo
+for a in 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z å ä ö; do
+ b=$b/$a
+ mkdir $b
+done
+
+rm -rf foo
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ;exit 0; fi
+
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ ln -s hejsan qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq$i
+done
+find . -name 'qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq*' -print | xargs rm
+ln -s foo bar
+rm bar
--- /dev/null
+#!/bin/sh
+# $Id$
+
+#######################################################
+#
+# Make a directory tree of directories
+# dir-tree <depth> <dirnames>+
+#
+#######################################################
+
+DEPTH=$1; shift
+DIRNUMS="$*"
+export DIRNUMS DEPTH
+
+# catch non numeric args and recurse cond
+expr $DEPTH '>' 0 > /dev/null 2>&1 || exit 0
+
+for a in $DIRNUMS; do
+ (mkdir $a && cd $a && \
+ $SHELL $SHELLVERBOSE ${srcdir}/dir-tree \
+ `expr $DEPTH - 1` "$DIRNUMS") || exit 1
+done
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <err.h>
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+
+
+ fd = open ("foo", O_RDWR|O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open");
+
+ dup2 (fd + 1, fd);
+
+ if (write (fd, "foo\n", 4) != 4)
+ errx (1, "write");
+
+ ktc_ForgetAllTokens();
+
+ close (fd);
+ close (fd + 1);
+
+ exit (0);
+}
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ for (i = 1; i < argc ; i++) {
+ printf ("%s", argv[i]);
+ if (argc > i + 1)
+ printf (" ");
+ }
+ fflush (stdout);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id$");
+#endif
+
+#include "err.h"
+
+void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verr(eval, fmt, ap);
+ va_end(ap);
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/* $Id$ */
+
+#ifndef __ERR_H__
+#define __ERR_H__
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+extern const char *__progname;
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+#define __attribute__(x)
+#endif
+
+void warnerr(int doerrno, const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 2, 0)));
+
+void verr(int eval, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 2, 0)));
+void err(int eval, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+void verrx(int eval, const char *fmt, va_list ap)
+ __attribute__ ((noreturn, format (printf, 2, 0)));
+void errx(int eval, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+void vwarn(const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 1, 0)));
+void warn(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+void vwarnx(const char *fmt, va_list ap)
+ __attribute__ ((format (printf, 1, 0)));
+void warnx(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+#endif /* __ERR_H__ */
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMUCS/CMU_copyright.pm for use and distribution information
+
+package OpenAFS::errtrans;
+
+=head1 NAME
+
+OpenAFS::errtrans - com_err error translation
+
+=head1 SYNOPSIS
+
+ use OpenAFS::errtrans
+ $code = errcode($name);
+ $code = errcode($pkg, $err);
+ $string = errstr($code, [$volerrs]);
+
+=head1 DESCRIPTION
+
+This module translates "common" error codes such as those produced
+by MIT's com_err package, and used extensively in AFS. It also knows
+how to translate system error codes, negative error codes used by Rx,
+and a few "special" error codes used by AFS's volume package.
+
+In order to work, these routines depend on the existence of error
+table files in $err_table_dir, which is usually /usr/local/lib/errtbl.
+Each file should be named after a com_err error package, and contain
+the definition for that package.
+
+Note that the AFS version of com_err translates package names to uppercase
+before generating error codes, so a table which claims to define the 'pt'
+package actually defines the 'PT' package when compiled by AFS's compile_et.
+Tables that are normally fed to AFS's compile_et should be installed using
+the _uppercase_ version of the package name.
+
+The error tables used in AFS are part of copyrighted AFS source code, and
+are not included with this package. However, I have included a utility
+(gen_et) which can generate error tables from the .h files normally
+produced by compile_et, and Transarc provides many of these header files
+with binary AFS distributions (in .../include/afs). See the gen_et
+program for more details.
+
+=cut
+
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use OpenAFS::config qw($err_table_dir);
+use Symbol;
+use Exporter;
+use POSIX;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&errcode &errstr);
+
+
+@NumToChar = ('', 'A'..'Z', 'a'..'z', '0'..'9', '_');
+%CharToNum = map(($NumToChar[$_], $_), (1 .. $#NumToChar));
+
+%Vol_Codes = ( VSALVAGE => 101,
+ VNOVNODE => 102,
+ VNOVOL => 103,
+ VVOLEXISTS => 104,
+ VNOSERVICE => 105,
+ VOFFLINE => 106,
+ VONLINE => 107,
+ VDISKFULL => 108,
+ VOVERQUOTA => 109,
+ VBUSY => 110,
+ VMOVED => 111
+ );
+%Vol_Desc = ( 101 => "volume needs to be salvaged",
+ 102 => "no such entry (vnode)",
+ 103 => "volume does not exist / did not salvage",
+ 104 => "volume already exists",
+ 105 => "volume out of service",
+ 106 => "volume offline (utility running)",
+ 107 => "volume already online",
+ 108 => "unknown volume error 108",
+ 109 => "unknown volume error 109",
+ 110 => "volume temporarily busy",
+ 111 => "volume moved"
+ );
+%Rx_Codes = ( RX_CALL_DEAD => -1,
+ RX_INVALID_OPERATION => -2,
+ RX_CALL_TIMEOUT => -3,
+ RX_EOF => -4,
+ RX_PROTOCOL_ERROR => -5,
+ RX_USER_ABORT => -6,
+ RX_ADDRINUSE => -7,
+ RX_MSGSIZE => -8,
+ RXGEN_CC_MARSHAL => -450,
+ RXGEN_CC_UNMARSHAL => -451,
+ RXGEN_SS_MARSHAL => -452,
+ RXGEN_SS_UNMARSHAL => -453,
+ RXGEN_DECODE => -454,
+ RXGEN_OPCODE => -455,
+ RXGEN_SS_XDRFREE => -456,
+ RXGEN_CC_XDRFREE => -457
+ );
+%Rx_Desc = ( -1 => "server or network not responding",
+ -2 => "invalid RPC (Rx) operation",
+ -3 => "server not responding promptly",
+ -4 => "Rx unexpected EOF",
+ -5 => "Rx protocol error",
+ -6 => "Rx user abort",
+ -7 => "port address already in use",
+ -8 => "Rx message size incorrect",
+ -450 => "Rx client: XDR marshall failed",
+ -451 => "Rx client: XDR unmarshall failed",
+ -452 => "Rx server: XDR marshall failed",
+ -453 => "Rx server: XDR unmarshall failed",
+ -454 => "Rx: Decode failed",
+ -455 => "Rx: Invalid RPC opcode",
+ -456 => "Rx server: XDR free failed",
+ -457 => "Rx client: XDR free failed",
+ map(($_ => "RPC interface mismatch ($_)"), (-499 .. -458)),
+ -999 => "Unknown error"
+ );
+
+
+sub _tbl_to_num {
+ my(@tbl) = split(//, $_[0]);
+ my($n);
+
+ @tbl = @tbl[0..3] if (@tbl > 4);
+ foreach (@tbl) { $n = ($n << 6) + $CharToNum{$_} }
+ $n << 8;
+}
+
+
+sub _num_to_tbl {
+ my($n) = $_[0] >> 8;
+ my($tbl);
+
+ while ($n) {
+ $tbl = @NumToChar[$n & 0x3f] . $tbl;
+ $n >>= 6;
+ }
+ $tbl;
+}
+
+
+sub _load_system_errors {
+ my($file) = @_;
+ my($fh) = &gensym();
+
+ return if ($did_include{$file});
+# print "Loading $file...\n";
+ $did_include{$file} = 'yes';
+ if (open($fh, "/usr/include/$file")) {
+ while (<$fh>) {
+ if (/^\#define\s*(E\w+)\s*(\d+)/) {
+ $Codes{$1} = $2;
+ } elsif (/^\#include\s*\"([^"]+)\"/
+ || /^\#include\s*\<([^>]+)\>/) {
+ &_load_system_errors($1);
+ }
+ }
+ close($fh);
+ }
+}
+
+
+# Load an error table into memory
+sub _load_error_table {
+ my($pkg) = @_;
+ my($fh, @words, $curval, $tval, $nval);
+ my($tid, $tfn, $code, $val, $desc);
+
+ return if ($Have_Table{$pkg});
+ # Read in the input file, and split it into words
+ $fh = &gensym();
+ return unless open($fh, "$err_table_dir/$pkg");
+# print "Loading $pkg...\n";
+ line: while (<$fh>) {
+ s/^\s*//; # Strip leading whitespace
+ while ($_) {
+ next line if (/^#/);
+ if (/^(error_table|et)\s*/) { push(@words, 'et'); $_ = $' }
+ elsif (/^(error_code|ec)\s*/) { push(@words, 'ec'); $_ = $' }
+ elsif (/^end\s*/) { push(@words, 'end'); $_ = $' }
+ elsif (/^(\w+)\s*/) { push(@words, $1); $_ = $' }
+ elsif (/^\"([^"]*)\"\s*/) { push(@words, $1); $_ = $' }
+ elsif (/^([,=])\s*/) { push(@words, $1); $_ = $' }
+ else { close($fh); return }
+ }
+ }
+ close($fh);
+
+ # Parse the table header
+ $_ = shift(@words); return unless ($_ eq 'et');
+ if ($words[1] eq 'ec') { $tid = shift(@words) }
+ elsif ($words[2] eq 'ec') { ($tfn, $tid) = splice(@words, 0, 2) }
+ else { return; }
+ if ($tid ne $pkg) {
+ $Have_Table{$tid} = 'yes';
+ $_ = $tid;
+ $_ =~ tr/a-z/A-Z/;
+ $tid = $_ if ($_ eq $pkg);
+ }
+ $tval = &_tbl_to_num($tid);
+ $Have_Table{$pkg} = 'yes';
+# print "Package $pkg: table-id = $tid, table-fun = $tfn, base = $tval\n";
+
+ while (@words) {
+ $_ = shift(@words); return unless ($_ eq 'ec');
+ $code = shift(@words);
+ $_ = shift(@words);
+ if ($_ eq '=') {
+ $val = shift(@words);
+ $_ = shift(@words);
+ } else {
+ $val = $curval;
+ }
+ return unless ($_ eq ',');
+ $desc = shift(@words);
+ $nval = $tval + $val;
+ $curval = $val + 1;
+ $Desc{$nval} = $desc;
+ $Codes{$code} = $nval;
+# print " code $code: value = $nval ($tval + $val), desc = \"$desc\"\n";
+ }
+}
+
+=head2 errcode($name)
+
+Returns the numeric error code corresponding to the specified error
+name. This routine knows about names of system errors, a few special
+Rx and volume-package errors, and any errors defined in installed
+error tables. If the specified error code is not found, returns -999.
+
+=head2 errcode($pkg, $code)
+
+Shifts $code into the specified error package, and returns the
+resulting com_err code. This can be used to generate error codes
+for _any_ valid com_err package.
+
+=cut
+
+sub errcode {
+ if (@_ > 1) {
+ my($pkg, $code) = @_;
+ &_tbl_to_num($pkg) + $code;
+ } else {
+ my($name) = @_;
+ my($dir, @tbls, $code);
+
+ &_load_system_errors("errno.h");
+ if ($Vol_Codes{$name}) { $Vol_Codes{$name} }
+ elsif ($Rx_Codes{$name}) { $Rx_Codes{$name} }
+ elsif ($Codes{$name}) { $Codes{$name} }
+ else {
+ if ($name =~ /^E/) { # Might be a POSIX error constant
+ $! = 0;
+ $code = &POSIX::constant($name, 0);
+ if (!$!) { return $code; }
+ }
+ $dir = &gensym();
+ if (opendir($dir, $err_table_dir)) {
+ @tbls = grep(!/^\.?\.$/, readdir($dir));
+ close($dir);
+ foreach (@tbls) { &_load_error_table($_) }
+ }
+ $Codes{$name} ? $Codes{$name} : -999;
+ }
+ }
+}
+
+
+=head2 errstr($code, [$volerrs])
+
+Returns the error string corresponding to a specified com_err, Rx,
+or system error code. If $volerrs is specified and non-zero, then
+volume-package errors are considered before system errors with the
+same values.
+
+=cut
+
+sub errstr {
+ my($code, $volerrs) = @_;
+ my($pkg, $sub);
+
+ if ($Rx_Desc{$code}) { return $Rx_Desc{$code} }
+ if ($volerrs && $Vol_Desc{$code}) { return $Vol_Desc{$code} }
+ $sub = $code & 0xff;
+ $pkg = &_num_to_tbl($code);
+ if ($pkg eq '') {
+ $! = $sub + 0;
+ $_ = $! . '';
+ if (/^(Error )?\d+$/) { $Vol_Desc{$sub} ? $Vol_Desc{$sub} : "Error $sub" }
+ else { $_ }
+ } else {
+ &_load_error_table($pkg);
+ $Desc{$code} ? $Desc{$code} : "Unknown code $pkg $sub ($code)";
+ }
+}
+
+1;
+
+=head1 COPYRIGHT
+
+The CMUCS AFStools, including this module are
+Copyright (c) 1996, Carnegie Mellon University. All rights reserved.
+For use and redistribution information, see CMUCS/CMU_copyright.pm
+
+=cut
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id$");
+#endif
+
+#include "err.h"
+
+void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrx(eval, fmt, ap);
+ va_end(ap);
+}
--- /dev/null
+#!/bin/sh
+echo '#!/bin/sh' > foo.sh
+export objdir
+echo '$objdir/echo-n "foo"' >> foo.sh
+test -f foo.sh || exit 1
+chmod +x foo.sh
+test -x foo.sh || exit 1
+FOO=`./foo.sh`
+test "X"$FOO = "Xfoo" || exit 1
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+child (const char *filename)
+{
+ int fd;
+ int ret;
+
+ fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = write (fd, "hej", 3);
+ if (ret != 3)
+ err (1, "write %s", filename);
+ return 0;
+}
+
+static int
+parent (const char *filename, pid_t child_pid)
+{
+ int stat;
+ int ret;
+ int fd;
+ struct stat sb;
+ char buf[3];
+
+ ret = waitpid (child_pid, &stat, 0);
+ if (ret < 0)
+ err (1, "waitpid %u", (unsigned)child_pid);
+ if (!WIFEXITED(stat) || WEXITSTATUS(stat) != 0)
+ errx (1, "weird child %u", (unsigned)child_pid);
+ fd = open (filename, O_RDONLY, 0);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = fstat (fd, &sb);
+ if (ret < 0)
+ err (1, "fstat %s", filename);
+ if (sb.st_size != 3)
+ errx (1, "size of %s = %u != 3", filename, (unsigned)sb.st_size);
+ ret = read (fd, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read %s", filename);
+ if (ret != 3)
+ errx (1, "short read from %s", filename);
+ if (memcmp (buf, "hej", 3) != 0)
+ errx (1, "bad contents of %s = `%.3s'\n", filename, buf);
+ close (fd);
+ return 0;
+}
+
+static int
+doit (const char *filename)
+{
+ pid_t pid;
+
+ pid = fork ();
+ if (pid < 0)
+ err (1, "fork");
+
+ if (pid == 0)
+ return child (filename);
+ else
+ return parent (filename, pid);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "foo";
+
+
+ if (argc != 2 && argc != 1)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ return doit (file);
+}
--- /dev/null
+#!/bin/sh
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . system:anyuser all || exit 1
+${objdir}/write-rand /usr/tmp/$$ 262144 || exit 1
+${objdir}/afscp -i -b 56k /usr/tmp/$$ `pwd`/$$ || exit 1
+diff /usr/tmp/$$ `pwd`/$$ || exit 1
+${objdir}/afscp -i -b 32k /usr/tmp/$$ `pwd`/$$ || exit 1
+diff /usr/tmp/$$ `pwd`/$$ || exit 1
+exit 0
+
+
--- /dev/null
+#!/bin/sh
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . system:anyuser all || exit 1
+${objdir}/write-rand $$ 262144 || exit 1
+${objdir}/afscp -o -b 56k `pwd`/$$ /usr/tmp/$$ || exit 1
+diff /usr/tmp/$$ `pwd`/$$ || exit 1
+${objdir}/afscp -o -b 32k `pwd`/$$ /usr/tmp/$$ || exit 1
+diff /usr/tmp/$$ `pwd`/$$ || exit 1
+exit 0
+
+
--- /dev/null
+#!/bin/sh
+# $Id$
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+SIZE1=`$FS getcache -b | awk '{ print $4 ; exit }'`
+mkdir foo
+SIZE2=`$FS getcache -b | awk '{ print $4 ; exit }'`
+test $SIZE2 = `expr $SIZE1 + 2048` || exit 1
+rmdir foo
+#SIZE3=`$FS getcache -b | awk '{ print $4 ; exit }'`
+#test $SIZE3 = $SIZE1 || exit 1
+
+exit 0
--- /dev/null
+#!/bin/sh
+# $Id$
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+SIZE1=`$FS getcache -b | awk '{ print $4 ; exit }'`
+echo foo > foo
+SIZE2=`$FS getcache -b | awk '{ print $4 ; exit }'`
+test $SIZE2 = `expr $SIZE1 + 4` || exit 1
+rm foo
+#SIZE3=`$FS getcache -b | awk '{ print $4 ; exit }'`
+#test $SIZE3 = $SIZE1 || exit 1
+
+exit 0
--- /dev/null
+#!/bin/sh
+# $Id$
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+SIZE1=`$FS getcache | awk '{ print $8 ; exit }'`
+SIZE2=`expr $SIZE1 + 4`
+if test -w /dev/null; then
+ dd if=../foo of=/dev/null bs=1k count=$SIZE2 >/dev/null 2>/dev/null || exit 1
+ rm ../foo || exit 1
+else
+ echo "not running dd (you have no /dev/null)"
+fi
+
+exit 0
--- /dev/null
+#!/bin/sh
+# $Id$
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+SIZE1=`$FS getcache | awk '{ print $8 ; exit }'`
+SIZE2=`expr $SIZE1 + 4`
+if test -r /dev/zero; then
+ dd if=/dev/zero of=../foo bs=1k count=$SIZE2 >/dev/null 2>/dev/null || exit 1
+else
+ echo "not running dd (you have no /dev/zero)"
+fi
+
+exit 0
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+int
+main(int argc, char **argv)
+{
+ int fd, ret;
+ struct stat sb;
+
+
+ fd = open ("deps", O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd < 0)
+ err (1, "open");
+ ret = fstat (fd, &sb);
+ if (ret < 0)
+ err (1, "fstat");
+ ret = write (fd, "# DO NOT DELETE\n", 16);
+ if (ret != 16)
+ err (1, "write");
+ ret = fchmod (fd, 0100644);
+ if (ret < 0)
+ errx (1, "fchmod");
+ ret = close (fd);
+ if (ret < 0)
+ errx (1, "close");
+
+ unlink("deps");
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/mount.h>
+
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+
+#include <fcntl.h>
+
+#include <err.h>
+#include <agetarg.h>
+
+#include <atypes.h>
+#include <kafs.h>
+
+RCSID("$Id$");
+
+struct fhb_handle {
+ char data[512];
+};
+
+static int help_flag;
+static int num_files;
+static int write_file = 0;
+static int num_runs = 3;
+
+static struct agetargs args[] = {
+ {"num", 'n', aarg_integer, &num_files, "number of files"},
+ {"write", 'w', aarg_integer, &write_file, "write num kb"},
+ {"runs", 'r', aarg_integer, &num_runs, "number of runs"},
+ {"help", 0, aarg_flag, &help_flag, NULL, NULL},
+ {NULL, 0, aarg_end, NULL, NULL, NULL}
+};
+
+
+static void
+fhb_fhget (char *filename, struct fhb_handle *handle)
+{
+ int ret = 0;
+#if defined(HAVE_GETFH) && defined(HAVE_FHOPEN)
+ {
+ fhandle_t fh;
+
+ ret = getfh (filename, &fh);
+ if (ret)
+ err (1, "getfh");
+ memcpy (handle, &fh, sizeof(fh));
+ }
+#endif
+ {
+ struct ViceIoctl vice_ioctl;
+
+ vice_ioctl.in = NULL;
+ vice_ioctl.in_size = 0;
+
+ vice_ioctl.out = (caddr_t)handle;
+ vice_ioctl.out_size = sizeof(*handle);
+
+ ret = pioctl (filename, VIOC_FHGET, &vice_ioctl, 0);
+ if (ret)
+ errx (1, "k_pioctl");
+ }
+}
+
+
+static int
+fhb_fhopen (struct fhb_handle *handle, int flags)
+{
+ int ret;
+#if defined(HAVE_GETFH) && defined(HAVE_FHOPEN)
+ {
+ fhandle_t fh;
+
+ memcpy (&fh, handle, sizeof(fh));
+ ret = fhopen (&fh, flags);
+ if (ret >= 0)
+ return ret;
+ }
+#endif
+
+#ifdef KERBEROS /* really KAFS */
+ {
+ struct ViceIoctl vice_ioctl;
+
+ vice_ioctl.in = (caddr_t)handle;
+ vice_ioctl.in_size = sizeof(*handle);
+
+ vice_ioctl.out = NULL;
+ vice_ioctl.out_size = 0;
+
+ ret = k_pioctl (NULL, VIOC_FHOPEN, &vice_ioctl, flags);
+ if (ret >= 0)
+ return ret;
+ }
+#endif
+ errx (1, "fhopen/k_pioctl");
+}
+
+static void
+nop_call (void)
+{
+#ifdef KERBEROS /* really KAFS */
+ {
+ struct ViceIoctl vice_ioctl;
+ char c[8];
+ int ret;
+
+ vice_ioctl.in = (caddr_t)&c;
+ vice_ioctl.in_size = sizeof(c);
+
+ vice_ioctl.out = NULL;
+ vice_ioctl.out_size = 0;
+
+ ret = k_pioctl (NULL, VIOC_XFSDEBUG, &vice_ioctl, 0);
+ if (ret < 0)
+ err (1, "k_pioctl");
+ }
+#else
+ {
+ static first = 1;
+ if (first) {
+ warnx ("can't test this");
+ first = 0;
+ }
+ }
+#endif
+}
+
+static void
+create_file (int num, struct fhb_handle *handle)
+{
+ int fd;
+ char filename[1024];
+
+ snprintf (filename, sizeof(filename), "file-%d", num);
+
+ fd = open (filename, O_CREAT|O_EXCL|O_RDWR, 0666);
+ if (fd < 0)
+ err (1, "open");
+
+ close (fd);
+
+ fhb_fhget(filename, handle);
+}
+
+char databuf[1024];
+
+static void
+write_to_file (int fd, int num)
+{
+ int ret;
+ while (num > 0) {
+ ret = write (fd, databuf, sizeof(databuf));
+ if (ret != sizeof(databuf))
+ err (1, "write");
+ num--;
+ }
+}
+
+static void
+fhopen_file (int num, struct fhb_handle *handle)
+{
+ int fd;
+
+ fd = fhb_fhopen(handle, O_RDWR);
+ if (fd < 0)
+ err (1, "open");
+
+ if (write_file)
+ write_to_file(fd, write_file);
+ close(fd);
+}
+
+static void
+open_file (int num)
+{
+ int fd;
+ char filename[1024];
+
+ snprintf (filename, sizeof(filename), "file-%d", num);
+
+ fd = open (filename, O_RDWR, 0666);
+ if (fd < 0)
+ err (1, "open");
+
+ if (write_file)
+ write_to_file(fd, write_file);
+
+ close (fd);
+}
+
+static void
+unlink_file (int num)
+{
+ int ret;
+ char filename[1024];
+
+ snprintf (filename, sizeof(filename), "file-%d", num);
+
+ ret = unlink(filename);
+ if (ret < 0)
+ err (1, "unlink");
+}
+
+struct timeval time1, time2;
+
+static void
+starttesting(char *msg)
+{
+ printf("testing %s...\n", msg);
+ fflush (stdout);
+ gettimeofday(&time1, NULL);
+}
+
+static void
+endtesting(void)
+{
+ gettimeofday(&time2, NULL);
+ timevalsub(&time2, &time1);
+ printf("timing: %ld.%06ld\n", (long)time2.tv_sec, (long)time2.tv_usec);
+}
+
+static void
+usage (int exit_val)
+{
+ aarg_printusage (args, NULL, "number of files", AARG_GNUSTYLE);
+ exit (exit_val);
+}
+
+static void
+open_bench (int i, struct fhb_handle *handles)
+{
+ printf ("====== test run %d\n"
+ "==================\n",
+ i);
+
+ starttesting ("fhopening files");
+ for (i = 0; i < num_files; i++)
+ fhopen_file (i, &handles[i]);
+ endtesting ();
+
+ starttesting ("opening files");
+ for (i = 0; i < num_files; i++)
+ open_file (i);
+ endtesting ();
+}
+
+int
+main (int argc, char **argv)
+{
+ int optind = 0;
+ int i;
+ struct fhb_handle *handles;
+
+
+ if (agetarg (args, argc, argv, &optind, AARG_GNUSTYLE))
+ usage (1);
+
+ if (help_flag)
+ usage (0);
+
+ if (num_files <= 0)
+ usage (1);
+
+ if (write_file < 0)
+ usage (1);
+
+#ifdef KERBEROS
+ if (!k_hasafs())
+#endif
+ errx (1, "no afs kernel module");
+
+ handles = emalloc (num_files * sizeof(*handles));
+
+ starttesting ("creating files");
+ for (i = 0; i < num_files; i++)
+ create_file (i, &handles[i]);
+ endtesting ();
+
+ for (i = 0 ; i < num_runs; i++)
+ open_bench (i, handles);
+
+ printf ( "==================\n");
+ starttesting ("unlink files");
+ for (i = 0; i < num_files; i++)
+ unlink_file (i);
+ endtesting ();
+
+ printf ( "==================\n");
+ starttesting ("nop call");
+ for (i = 0; i < num_files; i++)
+ nop_call ();
+ endtesting ();
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+netbsd_ftp_mirror=${1-$AFSROOT/stacken.kth.se/ftp/pub/NetBSD/NetBSD-1.4/}
+find ${netbsd_ftp_mirror} -type f -exec cat '{}' \; > /dev/null
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+linux_src=${1-$AFSROOT/pdc.kth.se/src/OS/Linux/}
+(cd ${linux_src} ; find . ) >&4
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+> foobar
+${FS} flush
+test -f foobar || exit 1
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . kalle-anka-nu rl 2>&4
+${FS} la >&4 2>&4
+exit 0
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, 2001 Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.ph for use and distribution information
+#
+#: * fs.pm - Wrappers around the FS commands (fileserver/cache manager)
+#: * This module provides wrappers around the various FS commands, which
+#: * perform fileserver and cache manager control operations. Right now,
+#: * these are nothing more than wrappers around 'fs'; someday, we might
+#: * talk to the cache manager directly, but not anytime soon.
+#:
+
+package OpenAFS::fs;
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use OpenAFS::wrapper;
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_fs_getacl &AFS_fs_setacl
+ &AFS_fs_cleanacl &AFS_fs_getquota
+ &AFS_fs_setquota &AFS_fs_whereis
+ &AFS_fs_examine &AFS_fs_setvol
+ &AFS_fs_getmount &AFS_fs_mkmount
+ &AFS_fs_rmmount &AFS_fs_checkvolumes
+ &AFS_fs_flush &AFS_fs_flushmount
+ &AFS_fs_flushvolume &AFS_fs_messages
+ &AFS_fs_newcell &AFS_fs_rxstatpeer
+ &AFS_fs_rxstatproc &AFS_fs_setcachesize
+ &AFS_fs_setcell &AFS_fs_setcrypt
+ &AFS_fs_setclientaddrs &AFS_fs_copyacl
+ &AFS_fs_storebehind &AFS_fs_setserverprefs
+ &AFS_fs_checkservers &AFS_fs_checkservers_interval
+ &AFS_fs_exportafs &AFS_fs_getcacheparms
+ &AFS_fs_getcellstatus &AFS_fs_getclientaddrs
+ &AFS_fs_getcrypt &AFS_fs_getserverprefs
+ &AFS_fs_listcells &AFS_fs_setmonitor
+ &AFS_fs_getmonitor &AFS_fs_getsysname
+ &AFS_fs_setsysname &AFS_fs_whichcell
+ &AFS_fs_wscell);
+
+#: ACL-management functions:
+#: AFS access control lists are represented as a Perl list (or usually, a
+#: reference to such a list). Each element in such a list corresponds to
+#: a single access control entry, and is a reference to a 2-element list
+#: consisting of a PTS entity (name or ID), and a set of rights. The
+#: rights are expressed in the usual publically-visible AFS notation, as
+#: a string of characters drawn from the class [rlidwkaABCDEFGH]. No
+#: rights are denoted by the empty string; such an ACE will never returned
+#: by this library, but may be used as an argument to remove a particular
+#: ACE from a directory's ACL.
+#:
+#: One might be inclined to ask why we chose this representation, instead of
+#: using an associative array, as might seem obvious. The answer is that
+#: doing so would have implied a nonambiguity that isn't there. Suppose you
+#: have an ACL %x, and want to know if there is an entry for user $U on that
+#: list. You might think you could do this by looking at $x{$U}. The
+#: problem here is that two values for $U (one numeric and one not) refer to
+#: the same PTS entity, even though they would reference different elements
+#: in such an ACL. So, we instead chose a representation that wasn't a hash,
+#: so people wouldn't try to do hash-like things to it. If you really want
+#: to be able to do hash-like operations, you should turn the list-form ACL
+#: into a hash table, and be sure to do name-to-number translation on all the
+#: keys as you go.
+#:
+#: AFS_fs_getacl($path)
+#: Get the ACL on a specified path.
+#: On success, return a list of two references to ACLs; the first is the
+#: positive ACL for the specified path, and the second is the negative ACL.
+#:
+$AFS_Help{fs_getacl} = '$path => (\@posacl, \@negacl)';
+sub AFS_fs_getacl {
+ my($path) = @_;
+ my(@args, @posacl, @negacl, $neg);
+
+ @args = ('listacl', '-path', $path);
+ &wrapper('fs', \@args,
+ [
+ [ '^(Normal|Negative) rights\:', sub {
+ $neg = ($_[0] eq 'Negative');
+ }],
+ [ '^ (.*) (\S+)$', sub { #',{
+ if ($neg) {
+ push(@negacl, [@_]);
+ } else {
+ push(@posacl, [@_]);
+ }
+ }]]);
+ (\@posacl, \@negacl);
+}
+
+#: AFS_fs_setacl(\@paths, \@posacl, \@negacl, [$clear])
+#: Set the ACL on a specified path. Like the 'fs setacl' command, this
+#: function normally only changes ACEs that are mentioned in one of the two
+#: argument lists. If a given ACE already exists, it is changed; if not, it
+#: is added. To delete a single ACE, specify the word 'none' or the empty
+#: string in the rights field. ACEs that already exist but are not mentioned
+#: are left untouched, unless $clear is specified. In that case, all
+#: existing ACE's (both positive and negative) are deleted.
+$AFS_Help{fs_setacl} = '\@paths, \@posacl, \@negacl, [$clear] => Success?';
+sub AFS_fs_setacl {
+ my($paths, $posacl, $negacl, $clear) = @_;
+ my($ace, $U, $access);
+
+ if (@$posacl) {
+ @args = ('setacl', '-dir', @$paths);
+ push(@args, '-clear') if ($clear);
+ push(@args, '-acl');
+ foreach $e (@$posacl) {
+ ($U, $access) = @$e;
+ $access = 'none' if ($access eq '');
+ push(@args, $U, $access);
+ }
+ &wrapper('fs', \@args);
+ }
+ if (@$negacl) {
+ @args = ('setacl', '-dir', @$paths, '-negative');
+ push(@args, '-clear') if ($clear && !@$posacl);
+ push(@args, '-acl');
+ foreach $e (@$negacl) {
+ ($U, $access) = @$e;
+ $access = 'none' if ($access eq '');
+ push(@args, $U, $access);
+ }
+ &wrapper('fs', \@args);
+ }
+ if ($clear && !@$posacl && !@$negacl) {
+ @args = ('setacl', '-dir', @$paths,
+ '-acl', 'system:anyuser', 'none', '-clear');
+ &wrapper('fs', \@args);
+ }
+ 1;
+}
+
+#: AFS_fs_cleanacl(\@paths)
+#: Clean the ACL on the specified path, removing any ACEs which refer to PTS
+#: entities that no longer exist. All the work is done by 'fs'.
+#:
+$AFS_Help{'fs_cleanacl'} = '\@paths => Success?';
+sub AFS_fs_cleanacl {
+ my($paths) = @_;
+ my(@args);
+
+ @args = ('cleanacl', '-path', @$paths);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_getquota($path) [listquota]
+#: Get the quota on the specified path.
+#: On success, returns the quota.
+#:
+$AFS_Help{'fs_getquota'} = '$path => $quota';
+sub AFS_fs_getquota {
+ my($path) = @_;
+ my(@args, $quota);
+
+ @args = ('listquota', '-path', $path);
+ &wrapper('fs', \@args,
+ [[ '^\S+\s+(\d+)\s+\d+\s+\d+\%', \$quota ]]);
+ $quota;
+}
+
+#: AFS_fs_setquota($path, $quota) [setquota]
+#: Set the quota on the specified path to $quota. If $quota is
+#: given as 0, there will be no limit to the volume's size.
+#: On success, return 1
+#:
+$AFS_Help{'fs_setquota'} = '$path, $quota => Success?';
+sub AFS_fs_setquota {
+ my($path, $quota) = @_;
+ my(@args);
+
+ @args = ('setquota', '-path', $path, '-max', $quota);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_whereis($path) [whereis, whichcell]
+#: Locate the fileserver housing the specified path, and the cell in which it
+#: is located.
+#: On success, returns a list of 2 or more elements. The first element is the
+#: name of the cell in which the volume is located. The remaining elements
+#: the names of servers housing the volume; for a replicated volume, there may
+#: (should) be more than one such server.
+#:
+$AFS_Help{'fs_whereis'} = '$path => ($cell, @servers)';
+sub AFS_fs_whereis {
+ my($path) = @_;
+ my(@args, $cell, @servers);
+
+ @args = ('whichcell', '-path', $path);
+ &wrapper('fs', \@args,
+ [[ "lives in cell \'(.*)\'", \$cell ]]);
+
+ @args = ('whereis', '-path', $path);
+ &wrapper('fs', \@args,
+ [[ 'is on host(s?)\s*(.*)', sub {
+ @servers = split(' ', $_[1]);
+ }]]);
+ ($cell, @servers);
+}
+
+#: AFS_fs_examine($path)
+#: Get information about the volume containing the specified path.
+#: On success, return an associative array containing some or all
+#: of the following elements:
+#: - vol_name
+#: - vol_id
+#: - quota_max
+#: - quota_used
+#: - quota_pctused
+#: - part_size
+#: - part_avail
+#: - part_used
+#: - part_pctused
+#:
+$AFS_Help{'fs_examine'} = '$path => %info';
+sub AFS_fs_examine {
+ my($path) = @_;
+ my(@args, %info);
+
+ @args = ('examine', '-path', $path);
+ %info = &wrapper('fs', \@args,
+ [[ 'vid = (\d+) named (\S+)', 'vol_id', 'vol_name' ],
+ [ 'disk quota is (\d+|unlimited)', 'quota_max' ],
+ [ 'blocks used are (\d+)', 'quota_used' ],
+ [ '(\d+) blocks available out of (\d+)',
+ 'part_avail', 'part_size']]);
+ if ($info{'quota_max'} eq 'unlimited') {
+ $info{'quota_max'} = 0;
+ $info{'quota_pctused'} = 0;
+ } else {
+ $info{'quota_pctused'} = ($info{'quota_used'} / $info{'quota_max'}) * 100;
+ $info{'quota_pctused'} =~ s/\..*//;
+ }
+ $info{'part_used'} = $info{'part_size'} - $info{'part_avail'};
+ $info{'part_pctused'} = ($info{'part_used'} / $info{'part_size'}) * 100;
+ $info{'part_pctused'} =~ s/\..*//;
+ %info;
+}
+
+#: AFS_fs_setvol($path, [$maxquota], [$motd])
+#: Set information about the volume containing the specified path.
+#: On success, return 1.
+$AFS_Help{'fs_setvol'} = '$path, [$maxquota], [$motd] => Success?';
+sub AFS_fs_setvol {
+ my($path, $maxquota, $motd) = @_;
+ my(@args);
+
+ @args = ('setvol', '-path', $path);
+ push(@args, '-max', $maxquota) if ($maxquota || $maxquota eq '0');
+ push(@args, '-motd', $motd) if ($motd);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+
+#: AFS_fs_getmount($path)
+#: Get the contents of the specified AFS mount point.
+#: On success, return the contents of the specified mount point.
+#: If the specified path is not a mount point, return the empty string.
+$AFS_Help{'fs_getmount'} = '$path => $vol';
+sub AFS_fs_getmount {
+ my($path) = @_;
+ my(@args, $vol);
+
+ @args = ('lsmount', '-dir', $path);
+ &wrapper('fs', \@args,
+ [[ "mount point for volume '(.+)'", \$vol ]]);
+ $vol;
+}
+
+
+#: AFS_fs_mkmount($path, $vol, [$cell], [$rwmount], [$fast])
+#: Create an AFS mount point at $path, leading to the volume $vol.
+#: If $cell is specified, create a cellular mount point to that cell.
+#: If $rwmount is specified and nonzero, create a read-write mount point.
+#: If $fast is specified and nonzero, don't check to see if the volume exists.
+#: On success, return 1.
+$AFS_Help{'fs_mkmount'} = '$path, $vol, [$cell], [$rwmount], [$fast] => Success?';
+sub AFS_fs_mkmount {
+ my($path, $vol, $cell, $rwmount, $fast) = @_;
+ my(@args);
+
+ @args = ('mkmount', '-dir', $path, '-vol', $vol);
+ push(@args, '-cell', $cell) if ($cell);
+ push(@args, '-rw') if ($rwmount);
+ push(@args, '-fast') if ($fast);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_rmmount($path) [rmmount]
+#: Remove an AFS mount point at $path
+#: On success, return 1
+$AFS_Help{'fs_rmmount'} = '$path => Success?';
+sub AFS_fs_rmmount {
+ my($path) = @_;
+ my(@args);
+
+ @args = ('rmmount', '-dir', $path);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_checkvolumes()
+#: Check/update volume ID cache
+#: On success, return 1
+$AFS_Help{'fs_checkvolumes'} = '=> Success?';
+sub AFS_fs_checkvolumes {
+ my(@args);
+
+ @args = ('checkvolumes');
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_flush(\@paths)
+#: Flush files named by @paths from the cache
+#: On success, return 1
+$AFS_Help{'fs_flush'} = '\@paths => Success?';
+sub AFS_fs_flush {
+ my($paths) = @_;
+ my(@args);
+
+ @args = ('flush');
+ push(@args, '-path', @$paths) if $paths;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_flushmount(\@paths)
+#: Flush mount points named by @paths from the cache
+#: On success, return 1
+$AFS_Help{'fs_flushmount'} = '\@paths => Success?';
+sub AFS_fs_flushmount {
+ my($paths) = @_;
+ my(@args);
+
+ @args = ('flushmount');
+ push(@args, '-path', @$paths) if $paths;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_flushvolume(\@paths)
+#: Flush volumes containing @paths from the cache
+#: On success, return 1
+$AFS_Help{'fs_flushvolume'} = '\@paths => Success?';
+sub AFS_fs_flushvolume {
+ my($paths) = @_;
+ my(@args);
+
+ @args = ('flushvolume');
+ push(@args, '-path', @$paths) if $paths;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_messages($mode)
+#: Set cache manager message mode
+#: Valid modes are 'user', 'console', 'all', 'none'
+#: On success, return 1
+$AFS_Help{'fs_messages'} = '$mode => Success?';
+sub AFS_fs_messages {
+ my($mode) = @_;
+ my(@args);
+
+ @args = ('messages', '-show', $mode);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_newcell($cell, \@dbservers, [$linkedcell])
+#: Add a new cell to the cache manager's list, or updating an existing cell
+#: On success, return 1
+$AFS_Help{'fs_newcell'} = '$cell, \@dbservers, [$linkedcell] => Success?';
+sub AFS_fs_newcell {
+ my($cell, $dbservers, $linkedcell) = @_;
+ my(@args);
+
+ @args = ('newcell', '-name', $cell, '-servers', @$dbservers);
+ push(@args, '-linkedcell', $linkedcell) if $linkedcell;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_rxstatpeer($enable, [$clear])
+#: Control per-peer Rx statistics:
+#: - if $enable is 1, enable stats
+#: - if $enable is 0, disable stats
+#: - if $clear is 1, clear stats
+#: On success, return 1
+$AFS_Help{'fs_rxstatpeer'} = '$enable, [$clear] => Success?';
+sub AFS_fs_rxstatpeer {
+ my($enable, $clear) = @_;
+ my(@args);
+
+ @args = ('rxstatpeer');
+ push(@args, '-enable') if $enable;
+ push(@args, '-disable') if defined($enable) && !$enable;
+ push(@args, '-clear') if $clear;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_rxstatproc($enable, [$clear])
+#: Control per-process Rx statistics:
+#: - if $enable is 1, enable stats
+#: - if $enable is 0, disable stats
+#: - if $clear is 1, clear stats
+#: On success, return 1
+$AFS_Help{'fs_rxstatproc'} = '$enable, [$clear] => Success?';
+sub AFS_fs_rxstatproc {
+ my($enable, $clear) = @_;
+ my(@args);
+
+ @args = ('rxstatproc');
+ push(@args, '-enable') if $enable;
+ push(@args, '-disable') if defined($enable) && !$enable;
+ push(@args, '-clear') if $clear;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_setcachesize($size)
+#: Set the cache size to $size K
+#: On success, return 1
+$AFS_Help{'fs_setcachesize'} = '$size => Success?';
+sub AFS_fs_setcachesize {
+ my($size) = @_;
+ my(@args);
+
+ @args = ('setcachesize', '-blocks', $size);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_setcell(\@cells, $suid)
+#: Set cell control bits for @cells
+#: - if $suid is 1, enable suid programs
+#: - if $suid is 0, disable suid programs
+#: On success, return 1
+$AFS_Help{'fs_setcell'} = '\@cells, [$suid] => Success?';
+sub AFS_fs_setcell {
+ my($cells, $suid) = @_;
+ my(@args);
+
+ @args = ('setcell', '-cell', @$cells);
+ push(@args, '-suid') if $suid;
+ push(@args, '-nosuid') if defined($suid) && !$suid;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_setcrypt($enable)
+#: Control cache manager encryption
+#: - if $enable is 1, enable encrypted connections
+#: - if $enable is 0, disable encrypted connections
+#: On success, return 1
+$AFS_Help{'fs_setcrypt'} = '$enable => Success?';
+sub AFS_fs_setcrypt {
+ my($enable) = @_;
+ my(@args);
+
+ @args = ('setcrypt', '-crypt', $enable ? 'on' : 'off');
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_setclientaddrs(\@addrs)
+#: Set client network interface addresses
+#: On success, return 1
+$AFS_Help{'fs_setclientaddrs'} = '\@addrs => Success?';
+sub AFS_fs_setclientaddrs {
+ my($addrs) = @_;
+ my(@args);
+
+ @args = ('setclientaddrs');
+ push(@args, '-address', @$addrs) if $addrs;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_copyacl($from, \@to, [$clear])
+#: Copy the access control list on $from to each directory named in @to.
+#: If $clear is specified and nonzero, the target ACL's are cleared first
+#: On success, return 1
+$AFS_Help{'fs_copyacl'} = '$from, \@to, [$clear] => Success?';
+sub AFS_fs_copyacl {
+ my($from, $to, $clear) = @_;
+ my(@args);
+
+ @args = ('copyacl', '-fromdir', $from, '-todir', @$to);
+ push(@args, '-clear') if $clear;
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_storebehind(\@paths, [$size], [$def])
+#: Set amount of date to store after file close
+#: If $size is specified, the size for each file in @paths is set to $size.
+#: If $default is specified, the default size is set to $default.
+#: Returns the new or current default value, and a hash mapping filenames
+#: to their storebehind sizes. A hash entry whose value is undef indicates
+#: that the corresponding file will use the default size.
+$AFS_Help{'fs_storebehind'} = '\@paths, [$size], [$def] => ($def, \%sizes)';
+sub AFS_fs_storebehind {
+ my($paths, $size, $def) = @_;
+ my(@args, %sizes, $ndef);
+
+ @args = ('storebehind', '-verbose');
+ push(@args, '-kbytes', $size) if defined($size);
+ push(@args, '-files', @$paths) if $paths && @$paths;
+ push(@args, '-allfiles', $def) if defined($def);
+ &wrapper('fs', \@args, [
+ ['^Will store up to (\d+) kbytes of (.*) asynchronously',
+ sub { $sizes{$_[1]} = $_[0] }],
+ ['^Will store (.*) according to default',
+ sub { $sizes{$_[0]} = undef }],
+ ['^Default store asynchrony is (\d+) kbytes', \$ndef],
+ ]);
+ ($ndef, \%sizes);
+}
+
+#: AFS_fs_setserverprefs(\%fsprefs, \%vlprefs)
+#: Set fileserver and/or VLDB server preference ranks
+#: Each of %fsprefs and %vlprefs maps server names to the rank to be
+#: assigned to the specified servers.
+#: On success, return 1.
+$AFS_Help{'fs_setserverprefs'} = '\%fsprefs, \%vlprefs => Success?';
+sub AFS_fs_setserverprefs {
+ my($fsprefs, $vlprefs) = @_;
+ my(@args, $srv);
+
+ @args = ('setserverprefs');
+ if ($fsprefs && %$fsprefs) {
+ push(@args, '-servers');
+ foreach $srv (keys %$fsprefs) {
+ push(@args, $srv, $$fsprefs{$srv});
+ }
+ }
+ if ($vlprefs && %$vlprefs) {
+ push(@args, '-vlservers');
+ foreach $srv (keys %$vlprefs) {
+ push(@args, $srv, $$vlprefs{$srv});
+ }
+ }
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_checkservers([$fast], [$allcells], [$cell])
+#: Check to see what fileservers are down
+#: If $cell is specified, fileservers in the specified cell are checked
+#: If $allcells is specified and nonzero, fileservers in all cells are checked
+#: If $fast is specified and nonzero, don't probe servers
+$AFS_Help{'fs_checkservers'} = '[$fast], [$allcells], [$cell] => @down';
+sub AFS_fs_checkservers {
+ my($fast, $allcells, $cell) = @_;
+ my(@args, @down);
+
+ @args = ('checkservers');
+ push(@args, '-all') if $allcells;
+ push(@args, '-fast') if $fast;
+ push(@args, '-cell', $cell) if $cell;
+ &wrapper('fs', \@args, [
+ ['^These servers unavailable due to network or server problems: (.*)\.',
+ sub { push(@down, split(' ', $_[0])) }],
+ ]);
+ @down;
+}
+
+#: AFS_fs_checkservers_interval([$interval])
+#: Get and/or set the down server check interval
+#: If $interval is specified and nonzero, it is set as the new interval
+#: On success, returns the old interval in seconds
+$AFS_Help{'fs_checkservers_interval'} = '$interval => $oldinterval';
+sub AFS_fs_checkservers_interval {
+ my($interval) = @_;
+ my(@args, $oldinterval);
+
+ @args = ('checkservers', '-interval', $interval);
+ &wrapper('fs', \@args, [
+ ['^The new down server probe interval \((\d+) secs\)', \$oldinterval],
+ ['^The current down server probe interval is (\d+) secs', \$oldinterval],
+ ]);
+ $oldinterval;
+}
+
+#: AFS_fs_exportafs($type, \%options);
+#: Get and/or modify protocol translator settings
+#: $type is the translator type, which must be 'nfs'
+#: %options specifies the options to be set. Each key is the name of an
+#: option, which is enabled if the value is 1, and disabled if the value
+#: is 0. The following options are supported:
+#: start Enable exporting of AFS
+#: convert Copy AFS owner mode bits to UNIX group/other mode bits
+#: uidcheck Strict UID checking
+#: submounts Permit mounts of /afs subdirectories
+#: On success, returns an associative array %modes, which is of the same
+#: form, indicating which options are enabled.
+$AFS_Help{'fs_exportafs'} = '$type, \%options => %modes';
+sub AFS_fs_exportafs {
+ my($type, $options) = @_;
+ my(@args, %modes);
+
+ @args = ('exportafs', '-type', $type);
+ foreach (qw(start convert uidcheck submounts)) {
+ push(@args, "-$_", $$options{$_} ? 'on' : 'off') if exists($$options{$_});
+ }
+
+ &wrapper('fs', \@args, [
+ ['translator is disabled', sub { $modes{'start'} = 0 }],
+ ['translator is enabled', sub { $modes{'start'} = 1 }],
+ ['strict unix', sub { $modes{'convert'} = 0 }],
+ ['convert owner', sub { $modes{'convert'} = 1 }],
+ [q/no 'passwd sync'/, sub { $modes{'uidcheck'} = 0 }],
+ [q/strict 'passwd sync'/, sub { $modes{'uidcheck'} = 1 }],
+ ['Only mounts', sub { $modes{'submounts'} = 0 }],
+ ['Allow mounts', sub { $modes{'submounts'} = 1 }],
+ ]);
+ %modes;
+}
+
+
+#: AFS_fs_getcacheparms()
+#: Returns the size of the cache, and the amount of cache space used.
+#: Sizes are returned in 1K blocks.
+$AFS_Help{'fs_getcacheparms'} = 'void => ($size, $used)';
+sub AFS_fs_getcacheparms {
+ my(@args, $size, $used);
+
+ @args = ('getcacheparms');
+ &wrapper('fs', \@args, [
+ [q/AFS using (\d+) of the cache's available (\d+) 1K byte blocks/,
+ \$used, \$size],
+ ]);
+ ($size, $used);
+}
+
+#: AFS_fs_getcellstatus(\@cells)
+#: Get cell control bits for cells listed in @cells.
+#: On success, returns a hash mapping cells to their status; keys are
+#: cell names, and values are 1 if SUID programs are permitted for that
+#: cell, and 0 if not.
+$AFS_Help{'fs_getcellstatus'} = '\@cells => %status';
+sub AFS_fs_getcellstatus {
+ my($cells) = @_;
+ my(@args, %status);
+
+ @args = ('getcellstatus', '-cell', @$cells);
+ &wrapper('fs', \@args, [
+ ['Cell (.*) status: setuid allowed', sub { $status{$_[0]} = 1 }],
+ ['Cell (.*) status: no setuid allowed', sub { $status{$_[0]} = 0 }],
+ ]);
+ %status;
+}
+
+#: AFS_fs_getclientaddrs
+#: Returns a list of the client interface addresses
+$AFS_Help{'fs_getclientaddrs'} = 'void => @addrs';
+sub AFS_fs_getclientaddrs {
+ my(@args, @addrs);
+
+ @args = ('getclientaddrs');
+ &wrapper('fs', \@args, [
+ ['^(\d+\.\d+\.\d+\.\d+)', \@addrs ]
+ ]);
+ @addrs;
+}
+
+#: AFS_fs_getcrypt
+#: Returns the cache manager encryption flag
+$AFS_Help{'fs_getcrypt'} = 'void => $crypt';
+sub AFS_fs_getcrypt {
+ my(@args, $crypt);
+
+ @args = ('getcrypt');
+ &wrapper('fs', \@args, [
+ ['^Security level is currently clear', sub { $crypt = 0 }],
+ ['^Security level is currently crypt', sub { $crypt = 1 }],
+ ]);
+ $crypt;
+}
+
+#: AFS_fs_getserverprefs([$vlservers], [$numeric])
+#: Get fileserver or vlserver preference ranks
+#: If $vlservers is specified and nonzero, VLDB server ranks
+#: are retrieved; otherwise fileserver ranks are retrieved.
+#: If $numeric is specified and nonzero, servers are identified
+#: by IP address instead of by hostname.
+#: Returns a hash whose keys are server names or IP addresses, and
+#: whose values are the ranks of those servers.
+$AFS_Help{'fs_getserverprefs'} = '[$vlservers], [$numeric] => %prefs';
+sub AFS_fs_getserverprefs {
+ my($vlservers, $numeric) = @_;
+ my(@args, %prefs);
+
+ @args = ('getserverprefs');
+ push(@args, '-numeric') if $numeric;
+ push(@args, '-vlservers') if $vlservers;
+ &wrapper('fs', \@args, [
+ ['^(\S+)\s*(\d+)', \%prefs],
+ ]);
+ %prefs;
+}
+
+#: AFS_fs_listcells([$numeric')
+#: Get a list of cells known to the cache manager, and the VLDB
+#: servers for each cell.
+#: If $numeric is specified and nonzero, VLDB servers are identified
+#: by IP address instead of by hostname.
+#: Returns a hash where each key is a cell name, and each value is
+#: a list of VLDB servers for the corresponding cell.
+$AFS_Help{'fs_listcells'} = '[$numeric] => %cells';
+sub AFS_fs_listcells {
+ my($numeric) = @_;
+ my(@args, %cells);
+
+ @args = ('listcells');
+ push(@args, '-numeric') if $numeric;
+ &wrapper('fs', \@args, [
+ ['^Cell (\S+) on hosts (.*)\.',
+ sub { $cells{$_[0]} = [ split(' ', $_[1]) ] }],
+ ]);
+ %cells;
+}
+
+#: AFS_fs_setmonitor($server)
+#: Set the cache manager monitor host to $server.
+#: If $server is 'off' or undefined, monitoring is disabled.
+#: On success, return 1.
+$AFS_Help{'fs_setmonitor'} = '$server => Success?';
+sub AFS_fs_setmonitor {
+ my($server) = @_;
+ my(@args);
+
+ @args = ('monitor', '-server', defined($server) ? $server : 'off');
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_getmonitor
+#: Return the cache manager monitor host, or undef if monitoring is disabled.
+$AFS_Help{'fs_getmonitor'} = 'void => $server';
+sub AFS_fs_getmonitor {
+ my(@args, $server);
+
+ @args = ('monitor');
+ &wrapper('fs', \@args, [
+ ['Using host (.*) for monitor services\.', \$server],
+ ]);
+ $server;
+}
+
+#: AFS_fs_getsysname
+#: Returns the current list of system type names
+$AFS_Help{'fs_getsysname'} = 'void => @sys';
+sub AFS_fs_getsysname {
+ my(@args, @sys);
+
+ @args = ('sysname');
+ &wrapper('fs', \@args, [
+ [q/Current sysname is '(.*)'/, \@sys],
+ [q/Current sysname list is '(.*)'/,
+ sub { push(@sys, split(q/' '/, $_[0])) }],
+ ]);
+ @sys;
+}
+
+#: AFS_fs_setsysname(\@sys)
+#: Sets the system type list to @sys
+#: On success, return 1.
+$AFS_Help{'fs_setsysname'} = '$server => Success?';
+sub AFS_fs_setsysname {
+ my($sys) = @_;
+ my(@args);
+
+ @args = ('sysname', '-newsys', @$sys);
+ &wrapper('fs', \@args);
+ 1;
+}
+
+#: AFS_fs_whichcell(\@paths)
+#: Get the cells containing the specified paths
+#: Returns a hash in which each key is a pathname, and each value
+#: is the name of the cell which contains the corresponding file.
+$AFS_Help{'fs_whichcell'} = '\@paths => %where';
+sub AFS_fs_whichcell {
+ my($paths) = @_;
+ my(@args, %where);
+
+ @args = ('whichcell', '-path', @$paths);
+ &wrapper('fs', \@args, [
+ [q/^File (.*) lives in cell '(.*)'/, \%where],
+ ]);
+ %where;
+}
+
+#: AFS_fs_wscell
+#: Returns the name of the workstation's home cell
+$AFS_Help{'fs_wscell'} = 'void => $cell';
+sub AFS_fs_wscell {
+ my(@args, $cell);
+
+ @args = ('wscell');
+ &wrapper('fs', \@args, [
+ [q/^This workstation belongs to cell '(.*)'/, \$cell],
+ ]);
+ $cell;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 1998 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <afs/stds.h>
+#include <afs/vice.h>
+#include <afs/venus.h>
+#include <afs/afsint.h>
+#include <afs/auth.h>
+#include <afs/cellconfig.h>
+#include <afs/cmd.h>
+
+enum { PIOCTL_MAXSIZE = 2000 };
+
+struct VenusFid {
+ afs_int32 Cell;
+ struct AFSFid Fid;
+};
+
+/*
+ * fs_getfid, the the `fid' that `path' points on.
+ */
+
+int
+fs_getfid(char *path, struct VenusFid *fid)
+{
+ struct ViceIoctl a_params;
+
+ if (path == NULL || fid == NULL)
+ return EINVAL;
+
+ a_params.in_size=0;
+ a_params.out_size=sizeof(struct VenusFid);
+ a_params.in=NULL;
+ a_params.out=(void*) fid;
+
+ if(pioctl(path,VIOCGETFID,&a_params,1) == -1)
+ return errno;
+
+ return 0;
+}
+
+/*
+ * Do nothing
+ */
+
+int
+fs_nop(void)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size=0;
+ a_params.out_size=0;
+ a_params.in=NULL;
+ a_params.out=NULL;
+
+ if (pioctl(NULL,VIOCNOP,&a_params,1) == -1)
+ return errno;
+
+ return 0;
+}
+
+/*
+ * Get the `cell' that the `path' ends up in
+ */
+
+int
+fs_getfilecellname(char *path, char *cell, size_t len)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size=0;
+ a_params.out_size=len;
+ a_params.in=NULL;
+ a_params.out=cell;
+
+ if (pioctl(path,VIOC_FILE_CELL_NAME,&a_params,1) == -1)
+ return errno;
+
+ return 0;
+}
+
+/*
+ * set the level of crypt
+ */
+
+#ifdef VIOC_SETRXKCRYPT
+int
+fs_setcrypt (u_int32_t n)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = sizeof(n);
+ a_params.out_size = 0;
+ a_params.in = (char *)&n;
+ a_params.out = NULL;
+
+ if (pioctl (NULL, VIOC_SETRXKCRYPT, &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ * get currernt level of crypt
+ */
+
+#ifdef VIOC_GETRXKCRYPT
+int
+fs_getcrypt (u_int32_t *level)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = sizeof(*level);
+ a_params.in = NULL;
+ a_params.out = (char *) level;
+
+ if (pioctl (NULL, VIOC_GETRXKCRYPT, &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ * get and set the connect-mode
+ */
+
+#ifdef VIOCCONNECTMODE
+int
+fs_connect(int32_t type, int32_t *flags)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = sizeof(type);
+ a_params.out_size = sizeof (int32_t);
+ a_params.in = (char *) &type;
+ a_params.out = (char *) flags;
+
+ if (pioctl (NULL, VIOCCONNECTMODE, &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef VIOC_FPRIOSTATUS
+int
+fs_setfprio(struct VenusFid fid, int16_t prio)
+{
+ struct ViceIoctl a_params;
+ struct vioc_fprio fprio;
+
+ fprio.cmd = FPRIO_SET;
+ fprio.Cell = fid.Cell;
+ fprio.Volume = fid.fid.Volume;
+ fprio.Vnode = fid.fid.Vnode;
+ fprio.Unique = fid.fid.Unique;
+ fprio.prio = prio;
+
+ a_params.in_size = sizeof(fprio);
+ a_params.out_size = 0;
+ a_params.in = (char *) &fprio;
+ a_params.out = NULL;
+
+ if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+#ifdef VIOC_FPRIOSTATUS
+int
+fs_getfprio(struct VenusFid fid, int16_t *prio)
+{
+ struct ViceIoctl a_params;
+ struct vioc_fprio fprio;
+
+ fprio.cmd = FPRIO_GET;
+ fprio.Cell = fid.Cell;
+ fprio.Volume = fid.fid.Volume;
+ fprio.Vnode = fid.fid.Vnode;
+ fprio.Unique = fid.fid.Unique;
+
+ a_params.in_size = sizeof(fprio);
+ a_params.out_size = sizeof(*prio);
+ a_params.in = (char *) &fprio;
+ a_params.out = (char *) prio;
+
+ if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+#ifdef VIOC_FPRIOSTATUS
+int
+fs_setmaxfprio(int16_t maxprio)
+{
+ struct ViceIoctl a_params;
+ struct vioc_fprio fprio;
+
+ fprio.cmd = FPRIO_SETMAX;
+ fprio.prio = maxprio;
+
+ a_params.in_size = sizeof(fprio);
+ a_params.out_size = 0;
+ a_params.in = (char *) &fprio;
+ a_params.out = NULL;
+
+ if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+#ifdef VIOC_FPRIOSTATUS
+int
+fs_getmaxfprio(int16_t *maxprio)
+{
+ struct ViceIoctl a_params;
+ struct vioc_fprio fprio;
+
+ fprio.cmd = FPRIO_GETMAX;
+
+ a_params.in_size = sizeof(fprio);
+ a_params.out_size = sizeof(*maxprio);
+ a_params.in = (char *) &fprio;
+ a_params.out = (char *) maxprio;
+
+ if (pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef VIOCGETCACHEPARAMS
+int
+fs_getfilecachestats(u_int32_t *max_bytes,
+ u_int32_t *used_bytes,
+ u_int32_t *max_vnodes,
+ u_int32_t *used_vnodes)
+{
+ u_int32_t parms[16];
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = sizeof(parms);
+ a_params.in = NULL;
+ a_params.out = (char *) parms;
+
+ memset (parms, 0, sizeof(parms));
+
+ if (pioctl (NULL, VIOCGETCACHEPARAMS , &a_params, 0) == -1)
+ return errno;
+
+ /* param[0] and param[1] send maxbytes and usedbytes in kbytes */
+
+ if (max_vnodes)
+ *max_vnodes = parms[2];
+ if (used_vnodes)
+ *used_vnodes = parms[3];
+ if (max_bytes)
+ *max_bytes = parms[4];
+ if (used_bytes)
+ *used_bytes = parms[5];
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef VIOC_AVIATOR
+int
+fs_getaviatorstats(u_int32_t *max_workers,
+ u_int32_t *used_workers)
+{
+ u_int32_t parms[16];
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = sizeof(parms);
+ a_params.in = NULL;
+ a_params.out = (char *) parms;
+
+ if (pioctl (NULL, VIOC_AVIATOR , &a_params, 0) == -1)
+ return errno;
+
+ if (max_workers)
+ *max_workers = parms[0];
+ if (used_workers)
+ *used_workers = parms[1];
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef VIOC_GCPAGS
+int
+fs_gcpags(void)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = 0;
+ a_params.in = NULL;
+ a_params.out = NULL;
+
+
+ if (pioctl(NULL, VIOC_GCPAGS, &a_params, 0) != 0)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef VIOC_CALCULATE_CACHE
+int
+fs_calculate_cache(u_int32_t *calculated,
+ u_int32_t *usedbytes)
+{
+ u_int32_t parms[16];
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = sizeof(parms);
+ a_params.in = NULL;
+ a_params.out = (char *) parms;
+
+ if (pioctl (NULL, VIOC_CALCULATE_CACHE , &a_params, 0) == -1)
+ return errno;
+
+ if (calculated)
+ *calculated = parms[0];
+ if (usedbytes)
+ *usedbytes = parms[1];
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef VIOC_BREAKCALLBACK
+int
+fs_invalidate (const char *path)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = 0;
+ a_params.in = NULL;
+ a_params.out = NULL;
+
+ if (pioctl ((char *)path, VIOC_BREAKCALLBACK, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+#endif
+
+/*
+ * Get/set debug levels with pioctl_cmd.
+ *
+ * inflags == -1 -> don't change
+ * outflags == NULL -> don't return
+ */
+
+static int
+debug (int pioctl_cmd, int inflags, int *outflags, char *pathname)
+{
+ struct ViceIoctl a_params;
+
+ int32_t rinflags = inflags;
+ int32_t routflags;
+
+ if (inflags != -1) {
+ a_params.in_size = sizeof(rinflags);
+ a_params.in = (char *) &rinflags;
+ } else {
+ a_params.in_size = 0;
+ a_params.in = NULL;
+ }
+
+ if (outflags) {
+ a_params.out_size = sizeof(routflags);
+ a_params.out = (char *) &routflags;
+ } else {
+ a_params.out_size = 0;
+ a_params.out = NULL;
+ }
+
+ if (pioctl (pathname, pioctl_cmd, &a_params, 0) == -1)
+ return errno;
+
+ if (outflags)
+ *outflags = routflags;
+
+ return 0;
+}
+
+/*
+ * xfs_debug
+ */
+
+#ifdef VIOC_XFSDEBUG
+int
+xfs_debug(int inflags, int *outflags)
+{
+ return debug (VIOC_XFSDEBUG, inflags, outflags, NULL);
+}
+#endif
+
+/*
+ * xfs_debug_print
+ */
+
+#ifdef VIOC_XFSDEBUG_PRINT
+int
+xfs_debug_print(int inflags, char *pathname)
+{
+ return debug (VIOC_XFSDEBUG_PRINT, inflags, NULL, pathname);
+}
+#endif
+
+/*
+ * arla_debug
+ */
+
+#ifdef VIOC_ARLADEBUG
+int
+arla_debug (int inflags, int *outflags)
+{
+ return debug (VIOC_ARLADEBUG, inflags, outflags, NULL);
+}
+#endif
+
+/*
+ * checkservers
+ *
+ * flags is the same flags as in CKSERV flags
+ *
+ */
+
+int
+fs_checkservers(char *cell, int32_t flags, u_int32_t *hosts, int numhosts)
+{
+ struct ViceIoctl a_params;
+ char *in = NULL;
+ int ret;
+ size_t insize;
+
+ if (cell != NULL) {
+ insize = strlen(cell) + sizeof(int32_t) + 1;
+ in = malloc (insize);
+ if (in == NULL)
+ errx (1, "malloc");
+
+ memcpy (in, &flags, sizeof(flags));
+
+ memcpy (in + sizeof(int32_t), cell, strlen(cell));
+ in[sizeof(int32_t) + strlen(cell)] = '\0';
+
+ a_params.in_size = insize;
+ a_params.in = in;
+ } else {
+ a_params.in_size = sizeof(flags);
+ a_params.in = (caddr_t )&flags;
+ }
+
+ a_params.out_size = numhosts * sizeof(u_int32_t);
+ a_params.out = (caddr_t)hosts;
+
+ ret = 0;
+
+ if (pioctl (NULL, VIOCCKSERV, &a_params, 0) == -1)
+ ret = errno;
+
+ if (in)
+ free(in);
+
+ return ret;
+}
+
+/*
+ * check validity of cached volume information
+ */
+
+int
+fs_checkvolumes (void)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in = NULL;
+ a_params.in_size = 0;
+ a_params.out = NULL;
+ a_params.out_size = 0;
+
+ if (pioctl (NULL, VIOCCKBACK, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * set current sysname to `sys'
+ */
+
+int
+fs_set_sysname (const char *sys)
+{
+ struct ViceIoctl a_params;
+ int32_t set = 1;
+
+ a_params.in_size = sizeof(set) + strlen(sys) + 1;
+ a_params.in = malloc(a_params.in_size);
+ if (a_params.in == NULL)
+ return ENOMEM;
+ a_params.out = NULL;
+ a_params.out_size = 0;
+ memcpy (a_params.in, &set, sizeof(set));
+ strcpy (a_params.in + sizeof(set), sys);
+
+ if(pioctl (NULL, VIOC_AFS_SYSNAME, &a_params, 1) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+fs_setcache(int lv, int hv, int lb, int hb)
+{
+ struct ViceIoctl a_params;
+ u_int32_t s[4];
+
+ s[0] = lv;
+ s[1] = hv;
+ s[2] = lb;
+ s[3] = hb;
+
+ a_params.in_size = ((hv == 0) ? 1 : 4) * sizeof(u_int32_t);
+ a_params.out_size = 0;
+ a_params.in = (void *)s;
+ a_params.out = NULL;
+
+ if (pioctl(NULL, VIOCSETCACHESIZE, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * return the local cell in `cell' (of size `cell_sz').
+ */
+
+int
+fs_wscell (char *cell, size_t cell_sz)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.in = NULL;
+ a_params.out_size = cell_sz;
+ a_params.out = cell;
+
+ if (pioctl (NULL, VIOC_GET_WS_CELL, &a_params, 0) < 0)
+ return errno;
+ return 0;
+}
+
+/*
+ * Flush the contents of the volume pointed to by `path'.
+ */
+
+int
+fs_flushvolume (const char *path)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = 0;
+ a_params.in = NULL;
+ a_params.out = NULL;
+
+ if (pioctl ((char *)path, VIOC_FLUSHVOLUME, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * Flush the file `path' from the cache.
+ */
+
+int
+fs_flush (const char *path)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = 0;
+ a_params.in = NULL;
+ a_params.out = NULL;
+
+ if (pioctl ((char *)path, VIOCFLUSH, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+fs_venuslog (void)
+{
+ struct ViceIoctl a_params;
+ int32_t status = 0; /* XXX not really right, but anyway */
+
+ a_params.in_size = sizeof(int32_t);
+ a_params.out_size = 0;
+ a_params.in = (caddr_t) &status;
+ a_params.out = NULL;
+
+ if (pioctl (NULL, VIOC_VENUSLOG, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * Get status for `cell' and put the flags in `flags'.
+ */
+
+int
+fs_getcellstatus (char *cellname, u_int32_t *flags)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = strlen (cellname) + 1;
+ a_params.out_size = sizeof (u_int32_t);
+ a_params.in = cellname;
+ a_params.out = (caddr_t) flags;
+
+ if (pioctl (NULL, VIOC_GETCELLSTATUS, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * Separate `path' into directory and last component and call
+ * pioctl with `pioctl_cmd'.
+ */
+
+static int
+internal_mp (const char *path, int pioctl_cmd, char **res)
+{
+ struct ViceIoctl a_params;
+ char *last;
+ char *path_bkp;
+ int error;
+
+ path_bkp = strdup (path);
+ if (path_bkp == NULL) {
+ printf ("fs: Out of memory\n");
+ return ENOMEM;
+ }
+
+ a_params.out = malloc (PIOCTL_MAXSIZE);
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ free (path_bkp);
+ return ENOMEM;
+ }
+
+ /* If path contains more than the filename alone - split it */
+
+ last = strrchr (path_bkp, '/');
+ if (last != NULL) {
+ *last = '\0';
+ a_params.in = last + 1;
+ } else
+ a_params.in = (char *)path;
+
+ a_params.in_size = strlen (a_params.in) + 1;
+ a_params.out_size = PIOCTL_MAXSIZE;
+
+ error = pioctl (last ? path_bkp : "." ,
+ pioctl_cmd, &a_params, 1);
+ if (error < 0) {
+ error = errno;
+ free (path_bkp);
+ free (a_params.out);
+ return error;
+ }
+
+ if (res != NULL)
+ *res = a_params.out;
+ else
+ free (a_params.out);
+ free (path_bkp);
+ return 0;
+}
+
+int
+fs_lsmount (const char *path)
+{
+ char *res;
+ int error = internal_mp (path, VIOC_AFS_STAT_MT_PT, &res);
+
+ if (error == 0) {
+ printf ("'%s' is a mount point for volume '%s'\n", path, res);
+ free (res);
+ }
+ return error;
+}
+
+int
+fs_rmmount (const char *path)
+{
+ return internal_mp (path, VIOC_AFS_DELETE_MT_PT, NULL);
+}
+
+int
+fs_incompat_renumber (int *ret)
+{
+ struct ViceIoctl a_params;
+ unsigned char buf[1024];
+
+ a_params.in_size = 0;
+ a_params.out_size = sizeof(buf);
+ a_params.in = 0;
+ a_params.out = (caddr_t) buf;
+
+ /* getcrypt or getinitparams */
+ if (pioctl (NULL, _VICEIOCTL(49), &a_params, 0) < 0) {
+ if (errno == EINVAL) {
+
+ /* not openafs or old openafs */
+
+ a_params.in_size = 0;
+ a_params.out_size = 4;
+ a_params.in = 0;
+ a_params.out = (caddr_t) buf;
+
+ if (pioctl (NULL, _VICEIOCTL(49), &a_params, 0) < 0) {
+ if (errno == EINVAL) {
+
+ a_params.in_size = 0;
+ a_params.out_size = 4;
+ a_params.in = 0;
+ a_params.out = (caddr_t) buf;
+
+ /* might be new interface */
+
+ if (pioctl (NULL, _VICEIOCTL(55), &a_params, 0) < 0)
+ return errno; /* dunno */
+
+ *ret = 1;
+ return 0;
+ } else {
+ return errno;
+ }
+ }
+ *ret = 0;
+ return 0;
+ } else
+ return errno;
+ }
+ *ret = 1;
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 1991, NeXT Computer, Inc. All Rights Reserverd.
+ *
+ * File: fsx.c
+ * Author: Avadis Tevanian, Jr.
+ *
+ * File system exerciser.
+ *
+ * Rewritten 8/98 by Conrad Minshall.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(_UWIN) || defined(__linux)
+# include <sys/param.h>
+# include <limits.h>
+# include <time.h>
+# include <strings.h>
+# define MAP_FILE 0
+#else
+# include <sys/dirent.h>
+#endif
+#include <sys/file.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <err.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define NUMPRINTCOLUMNS 32 /* # columns of data to print on each line */
+
+/*
+ * A log entry is an operation and a bunch of arguments.
+ */
+
+struct log_entry {
+ int operation;
+ int args[3];
+};
+
+#define LOGSIZE 1000
+
+struct log_entry oplog[LOGSIZE]; /* the log */
+int logptr = 0; /* current position in log */
+int logcount = 0; /* total ops */
+
+/*
+ * Define operations
+ */
+
+#define OP_READ 1
+#define OP_WRITE 2
+#define OP_TRUNCATE 3
+#define OP_CLOSEOPEN 4
+#define OP_MAPREAD 5
+#define OP_MAPWRITE 6
+#define OP_SKIPPED 7
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+#define PAGE_MASK (PAGE_SIZE - 1)
+
+char *original_buf; /* a pointer to the original data */
+char *good_buf; /* a pointer to the correct data */
+char *temp_buf; /* a pointer to the current data */
+char *fname; /* name of our test file */
+int fd; /* fd for our test file */
+
+off_t file_size = 0;
+off_t biggest = 0;
+char state[256];
+unsigned long testcalls = 0; /* calls to function "test" */
+
+unsigned long simulatedopcount = 0; /* -b flag */
+int closeprob = 0; /* -c flag */
+int debug = 0; /* -d flag */
+unsigned long debugstart = 0; /* -D flag */
+unsigned long maxfilelen = 256 * 1024; /* -l flag */
+int sizechecks = 1; /* -n flag disables them */
+int maxoplen = 64 * 1024; /* -o flag */
+int quiet = 0; /* -q flag */
+unsigned long progressinterval = 0; /* -p flag */
+int readbdy = 1; /* -r flag */
+int style = 0; /* -s flag */
+int truncbdy = 1; /* -t flag */
+int writebdy = 1; /* -w flag */
+long monitorstart = -1; /* -m flag */
+long monitorend = -1; /* -m flag */
+int lite = 0; /* -L flag */
+long numops = -1; /* -N flag */
+int randomoplen = 1; /* -O flag disables it */
+int seed = 1; /* -S flag */
+int mapped_writes = 1; /* -W flag disables */
+int mapped_reads = 1; /* -R flag disables it */
+int fsxgoodfd = 0;
+FILE * fsxlogf = NULL;
+int badoff = -1;
+int closeopen = 0;
+
+
+void
+prt(char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ if (fsxlogf)
+ vfprintf(fsxlogf, fmt, args);
+ va_end(args);
+}
+
+void
+prterr(char *prefix)
+{
+ prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno));
+}
+
+
+void
+log4(int operation, int arg0, int arg1, int arg2)
+{
+ struct log_entry *le;
+
+ le = &oplog[logptr];
+ le->operation = operation;
+ if (closeopen)
+ le->operation = ~ le->operation;
+ le->args[0] = arg0;
+ le->args[1] = arg1;
+ le->args[2] = arg2;
+ logptr++;
+ logcount++;
+ if (logptr >= LOGSIZE)
+ logptr = 0;
+}
+
+
+void
+logdump(void)
+{
+ int i, count, down;
+ struct log_entry *lp;
+
+ prt("LOG DUMP (%d total operations):\n", logcount);
+ if (logcount < LOGSIZE) {
+ i = 0;
+ count = logcount;
+ } else {
+ i = logptr;
+ count = LOGSIZE;
+ }
+ for ( ; count > 0; count--) {
+ int opnum;
+
+ opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE;
+ prt("%d(%d mod 256): ", opnum, opnum%256);
+ lp = &oplog[i];
+ if ((closeopen = lp->operation < 0))
+ lp->operation = ~ lp->operation;
+
+ switch (lp->operation) {
+ case OP_MAPREAD:
+ prt("MAPREAD\t0x%x thru 0x%x\t(0x%x bytes)",
+ lp->args[0], lp->args[0] + lp->args[1] - 1,
+ lp->args[1]);
+ if (badoff >= lp->args[0] && badoff <
+ lp->args[0] + lp->args[1])
+ prt("\t***RRRR***");
+ break;
+ case OP_MAPWRITE:
+ prt("MAPWRITE 0x%x thru 0x%x\t(0x%x bytes)",
+ lp->args[0], lp->args[0] + lp->args[1] - 1,
+ lp->args[1]);
+ if (badoff >= lp->args[0] && badoff <
+ lp->args[0] + lp->args[1])
+ prt("\t******WWWW");
+ break;
+ case OP_READ:
+ prt("READ\t0x%x thru 0x%x\t(0x%x bytes)",
+ lp->args[0], lp->args[0] + lp->args[1] - 1,
+ lp->args[1]);
+ if (badoff >= lp->args[0] &&
+ badoff < lp->args[0] + lp->args[1])
+ prt("\t***RRRR***");
+ break;
+ case OP_WRITE:
+ prt("WRITE\t0x%x thru 0x%x\t(0x%x bytes)",
+ lp->args[0], lp->args[0] + lp->args[1] - 1,
+ lp->args[1]);
+ if (lp->args[0] > lp->args[2])
+ prt(" HOLE");
+ else if (lp->args[0] + lp->args[1] > lp->args[2])
+ prt(" EXTEND");
+ if ((badoff >= lp->args[0] || badoff >=lp->args[2]) &&
+ badoff < lp->args[0] + lp->args[1])
+ prt("\t***WWWW");
+ break;
+ case OP_TRUNCATE:
+ down = lp->args[0] < lp->args[1];
+ prt("TRUNCATE %s\tfrom 0x%x to 0x%x",
+ down ? "DOWN" : "UP", lp->args[1], lp->args[0]);
+ if (badoff >= lp->args[!down] &&
+ badoff < lp->args[!!down])
+ prt("\t******WWWW");
+ break;
+ case OP_SKIPPED:
+ prt("SKIPPED (no operation)");
+ break;
+ default:
+ prt("BOGUS LOG ENTRY (operation code = %d)!",
+ lp->operation);
+ }
+ if (closeopen)
+ prt("\n\t\tCLOSE/OPEN");
+ prt("\n");
+ i++;
+ if (i == LOGSIZE)
+ i = 0;
+ }
+}
+
+
+void
+save_buffer(char *buffer, off_t bufferlength, int fd)
+{
+ off_t ret;
+ ssize_t byteswritten;
+
+ if (fd <= 0 || bufferlength == 0)
+ return;
+
+ if (bufferlength > SSIZE_MAX) {
+ prt("fsx flaw: overflow in save_buffer\n");
+ exit(67);
+ }
+ if (lite) {
+ off_t size_by_seek = lseek(fd, (off_t)0, L_XTND);
+ if (size_by_seek == (off_t)-1)
+ prterr("save_buffer: lseek eof");
+ else if (bufferlength > size_by_seek) {
+ warn("save_buffer: .fsxgood file too short... will save 0x%qx bytes instead of 0x%qx\n", (unsigned long long)size_by_seek,
+ (unsigned long long)bufferlength);
+ bufferlength = size_by_seek;
+ }
+ }
+
+ ret = lseek(fd, (off_t)0, SEEK_SET);
+ if (ret == (off_t)-1)
+ prterr("save_buffer: lseek 0");
+
+ byteswritten = write(fd, buffer, (size_t)bufferlength);
+ if (byteswritten != bufferlength) {
+ if (byteswritten == -1)
+ prterr("save_buffer write");
+ else
+ warn("save_buffer: short write, 0x%x bytes instead of 0x%qx\n",
+ (unsigned)byteswritten,
+ (unsigned long long)bufferlength);
+ }
+}
+
+
+void
+report_failure(int status)
+{
+ logdump();
+
+ if (fsxgoodfd) {
+ if (good_buf) {
+ save_buffer(good_buf, file_size, fsxgoodfd);
+ prt("Correct content saved for comparison\n");
+ prt("(maybe hexdump \"%s\" vs \"%s.fsxgood\")\n",
+ fname, fname);
+ }
+ close(fsxgoodfd);
+ }
+ exit(status);
+}
+
+
+#define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \
+ *(((unsigned char *)(cp)) + 1)))
+
+void
+check_buffers(unsigned offset, unsigned size)
+{
+ unsigned char c, t;
+ unsigned i = 0;
+ unsigned n = 0;
+ unsigned op = 0;
+ unsigned bad = 0;
+
+ if (bcmp(good_buf + offset, temp_buf, size) != 0) {
+ prt("READ BAD DATA: offset = 0x%x, size = 0x%x\n",
+ offset, size);
+ prt("OFFSET\tGOOD\tBAD\tRANGE\n");
+ while (size > 0) {
+ c = good_buf[offset];
+ t = temp_buf[i];
+ if (c != t) {
+ if (n == 0) {
+ bad = short_at(&temp_buf[i]);
+ prt("0x%5x\t0x%04x\t0x%04x", offset,
+ short_at(&good_buf[offset]), bad);
+ op = temp_buf[offset & 1 ? i+1 : i];
+ }
+ n++;
+ badoff = offset;
+ }
+ offset++;
+ i++;
+ size--;
+ }
+ if (n) {
+ prt("\t0x%5x\n", n);
+ if (bad)
+ prt("operation# (mod 256) for the bad data may be %u\n", ((unsigned)op & 0xff));
+ else
+ prt("operation# (mod 256) for the bad data unknown, check HOLE and EXTEND ops\n");
+ } else
+ prt("????????????????\n");
+ report_failure(110);
+ }
+}
+
+
+void
+check_size(void)
+{
+ struct stat statbuf;
+ off_t size_by_seek;
+
+ if (fstat(fd, &statbuf)) {
+ prterr("check_size: fstat");
+ statbuf.st_size = -1;
+ }
+ size_by_seek = lseek(fd, (off_t)0, L_XTND);
+ if (file_size != statbuf.st_size || file_size != size_by_seek) {
+ prt("Size error: expected 0x%qx stat 0x%qx seek 0x%qx\n",
+ (unsigned long long)file_size,
+ (unsigned long long)statbuf.st_size,
+ (unsigned long long)size_by_seek);
+ report_failure(120);
+ }
+}
+
+
+void
+check_trunc_hack(void)
+{
+ struct stat statbuf;
+
+ ftruncate(fd, (off_t)0);
+ ftruncate(fd, (off_t)100000);
+ fstat(fd, &statbuf);
+ if (statbuf.st_size != (off_t)100000) {
+ prt("no extend on truncate! not posix!\n");
+ exit(130);
+ }
+ ftruncate(fd, 0);
+}
+
+
+void
+doread(unsigned offset, unsigned size)
+{
+ off_t ret;
+ unsigned iret;
+
+ offset -= offset % readbdy;
+ if (size == 0) {
+ if (!quiet && testcalls > simulatedopcount)
+ prt("skipping zero size read\n");
+ log4(OP_SKIPPED, OP_READ, offset, size);
+ return;
+ }
+ if (size + offset > file_size) {
+ if (!quiet && testcalls > simulatedopcount)
+ prt("skipping seek/read past end of file\n");
+ log4(OP_SKIPPED, OP_READ, offset, size);
+ return;
+ }
+
+ log4(OP_READ, offset, size, 0);
+
+ if (testcalls <= simulatedopcount)
+ return;
+
+ if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ debug &&
+ (monitorstart == -1 ||
+ offset + size > monitorstart &&
+ (monitorend == -1 || offset <= monitorend))))
+ prt("%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ offset, offset + size - 1, size);
+ ret = lseek(fd, (off_t)offset, SEEK_SET);
+ if (ret == (off_t)-1) {
+ prterr("doread: lseek");
+ report_failure(140);
+ }
+ iret = read(fd, temp_buf, size);
+ if (iret != size) {
+ if (iret == -1)
+ prterr("doread: read");
+ else
+ prt("short read: 0x%x bytes instead of 0x%x\n",
+ iret, size);
+ report_failure(141);
+ }
+ check_buffers(offset, size);
+}
+
+
+void
+domapread(unsigned offset, unsigned size)
+{
+ unsigned pg_offset;
+ unsigned map_size;
+ char *p;
+
+ offset -= offset % readbdy;
+ if (size == 0) {
+ if (!quiet && testcalls > simulatedopcount)
+ prt("skipping zero size read\n");
+ log4(OP_SKIPPED, OP_MAPREAD, offset, size);
+ return;
+ }
+ if (size + offset > file_size) {
+ if (!quiet && testcalls > simulatedopcount)
+ prt("skipping seek/read past end of file\n");
+ log4(OP_SKIPPED, OP_MAPREAD, offset, size);
+ return;
+ }
+
+ log4(OP_MAPREAD, offset, size, 0);
+
+ if (testcalls <= simulatedopcount)
+ return;
+
+ if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ debug &&
+ (monitorstart == -1 ||
+ offset + size > monitorstart &&
+ (monitorend == -1 || offset <= monitorend))))
+ prt("%lu mapread\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ offset, offset + size - 1, size);
+
+ pg_offset = offset & PAGE_MASK;
+ map_size = pg_offset + size;
+
+ if ((p = (char *)mmap(0, map_size, PROT_READ, MAP_FILE, fd,
+ (off_t)(offset - pg_offset))) == (char *)-1) {
+ prterr("domapread: mmap");
+ report_failure(190);
+ }
+ memcpy(temp_buf, p + pg_offset, size);
+ if (munmap(p, map_size) != 0) {
+ prterr("domapread: munmap");
+ report_failure(191);
+ }
+
+ check_buffers(offset, size);
+}
+
+
+void
+gendata(char *original_buf, char *good_buf, unsigned offset, unsigned size)
+{
+ while (size--) {
+ good_buf[offset] = testcalls % 256;
+ if (offset % 2)
+ good_buf[offset] += original_buf[offset];
+ offset++;
+ }
+}
+
+
+void
+dowrite(unsigned offset, unsigned size)
+{
+ off_t ret;
+ unsigned iret;
+
+ offset -= offset % writebdy;
+ if (size == 0) {
+ if (!quiet && testcalls > simulatedopcount)
+ prt("skipping zero size write\n");
+ log4(OP_SKIPPED, OP_WRITE, offset, size);
+ return;
+ }
+
+ log4(OP_WRITE, offset, size, file_size);
+
+ gendata(original_buf, good_buf, offset, size);
+ if (file_size < offset + size) {
+ if (file_size < offset)
+ bzero(good_buf + file_size, offset - file_size);
+ file_size = offset + size;
+ if (lite) {
+ warn("Lite file size bug in fsx!");
+ report_failure(149);
+ }
+ }
+
+ if (testcalls <= simulatedopcount)
+ return;
+
+ if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ debug &&
+ (monitorstart == -1 ||
+ offset + size > monitorstart &&
+ (monitorend == -1 || offset <= monitorend))))
+ prt("%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ offset, offset + size - 1, size);
+ ret = lseek(fd, (off_t)offset, SEEK_SET);
+ if (ret == (off_t)-1) {
+ prterr("dowrite: lseek");
+ report_failure(150);
+ }
+ iret = write(fd, good_buf + offset, size);
+ if (iret != size) {
+ if (iret == -1)
+ prterr("dowrite: write");
+ else
+ prt("short write: 0x%x bytes instead of 0x%x\n",
+ iret, size);
+ report_failure(151);
+ }
+}
+
+
+void
+domapwrite(unsigned offset, unsigned size)
+{
+ unsigned pg_offset;
+ unsigned map_size;
+ off_t cur_filesize;
+ char *p;
+
+ offset -= offset % writebdy;
+ if (size == 0) {
+ if (!quiet && testcalls > simulatedopcount)
+ prt("skipping zero size write\n");
+ log4(OP_SKIPPED, OP_MAPWRITE, offset, size);
+ return;
+ }
+ cur_filesize = file_size;
+
+ log4(OP_MAPWRITE, offset, size, 0);
+
+ gendata(original_buf, good_buf, offset, size);
+ if (file_size < offset + size) {
+ if (file_size < offset)
+ bzero(good_buf + file_size, offset - file_size);
+ file_size = offset + size;
+ if (lite) {
+ warn("Lite file size bug in fsx!");
+ report_failure(200);
+ }
+ }
+
+ if (testcalls <= simulatedopcount)
+ return;
+
+ if (!quiet && (progressinterval && testcalls % progressinterval == 0 ||
+ debug &&
+ (monitorstart == -1 ||
+ offset + size > monitorstart &&
+ (monitorend == -1 || offset <= monitorend))))
+ prt("%lu mapwrite\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls,
+ offset, offset + size - 1, size);
+
+ if (file_size > cur_filesize) {
+ if (ftruncate(fd, file_size) == -1) {
+ prterr("domapwrite: ftruncate");
+ exit(201);
+ }
+ }
+ pg_offset = offset & PAGE_MASK;
+ map_size = pg_offset + size;
+
+ if ((p = (char *)mmap(0, map_size, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fd,
+ (off_t)(offset - pg_offset))) == (char *)-1) {
+ prterr("domapwrite: mmap");
+ report_failure(202);
+ }
+ memcpy(p + pg_offset, good_buf + offset, size);
+ if (msync(p, map_size, 0) != 0) {
+ prterr("domapwrite: msync");
+ report_failure(203);
+ }
+ if (munmap(p, map_size) != 0) {
+ prterr("domapwrite: munmap");
+ report_failure(204);
+ }
+}
+
+
+void
+dotruncate(unsigned size)
+{
+ int oldsize = file_size;
+
+ size -= size % truncbdy;
+ if (size > biggest) {
+ biggest = size;
+ if (!quiet && testcalls > simulatedopcount)
+ prt("truncating to largest ever: 0x%x\n", size);
+ }
+
+ log4(OP_TRUNCATE, size, (unsigned)file_size, 0);
+
+ if (size > file_size)
+ bzero(good_buf + file_size, size - file_size);
+ file_size = size;
+
+ if (testcalls <= simulatedopcount)
+ return;
+
+ if (progressinterval && testcalls % progressinterval == 0 ||
+ debug && (monitorstart == -1 || monitorend == -1 ||
+ size <= monitorend))
+ prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, size);
+ if (ftruncate(fd, (off_t)size) == -1) {
+ prt("ftruncate1: %x\n", size);
+ prterr("dotruncate: ftruncate");
+ report_failure(160);
+ }
+}
+
+
+void
+writefileimage()
+{
+ ssize_t iret;
+
+ if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
+ prterr("writefileimage: lseek");
+ report_failure(171);
+ }
+ iret = write(fd, good_buf, file_size);
+ if ((off_t)iret != file_size) {
+ if (iret == -1)
+ prterr("writefileimage: write");
+ else
+ prt("short write: 0x%x bytes instead of 0x%qx\n",
+ iret, (unsigned long long)file_size);
+ report_failure(172);
+ }
+ if (lite ? 0 : ftruncate(fd, file_size) == -1) {
+ prt("ftruncate2: %qx\n", (unsigned long long)file_size);
+ prterr("writefileimage: ftruncate");
+ report_failure(173);
+ }
+}
+
+
+void
+docloseopen(void)
+{
+ if (testcalls <= simulatedopcount)
+ return;
+
+ if (debug)
+ prt("%lu close/open\n", testcalls);
+ if (close(fd)) {
+ prterr("docloseopen: close");
+ report_failure(180);
+ }
+ fd = open(fname, O_RDWR, 0);
+ if (fd < 0) {
+ prterr("docloseopen: open");
+ report_failure(181);
+ }
+}
+
+
+void
+test(void)
+{
+ unsigned long offset;
+ unsigned long size = maxoplen;
+ unsigned long rv = random();
+ unsigned long op = rv % (3 + !lite + mapped_writes);
+
+ /* turn off the map read if necessary */
+
+ if (op == 2 && !mapped_reads)
+ op = 0;
+
+ if (simulatedopcount > 0 && testcalls == simulatedopcount)
+ writefileimage();
+
+ testcalls++;
+
+ closeopen = (rv >> 3) < (1 << 28) / closeprob;
+
+ if (debugstart > 0 && testcalls >= debugstart)
+ debug = 1;
+
+ if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0)
+ prt("%lu...\n", testcalls);
+
+ /*
+ * READ: op = 0
+ * WRITE: op = 1
+ * MAPREAD: op = 2
+ * TRUNCATE: op = 3
+ * MAPWRITE: op = 3 or 4
+ */
+ if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */
+ dotruncate(random() % maxfilelen);
+ else {
+ if (randomoplen)
+ size = random() % (maxoplen+1);
+ if (lite ? 0 : op == 3)
+ dotruncate(size);
+ else {
+ offset = random();
+ if (op == 1 || op == (lite ? 3 : 4)) {
+ offset %= maxfilelen;
+ if (offset + size > maxfilelen)
+ size = maxfilelen - offset;
+ if (op != 1)
+ domapwrite(offset, size);
+ else
+ dowrite(offset, size);
+ } else {
+ if (file_size)
+ offset %= file_size;
+ else
+ offset = 0;
+ if (offset + size > file_size)
+ size = file_size - offset;
+ if (op != 0)
+ domapread(offset, size);
+ else
+ doread(offset, size);
+ }
+ }
+ }
+ if (sizechecks && testcalls > simulatedopcount)
+ check_size();
+ if (closeopen)
+ docloseopen();
+}
+
+
+void
+cleanup(sig)
+ int sig;
+{
+ if (sig)
+ prt("signal %d\n", sig);
+ prt("testcalls = %lu\n", testcalls);
+ exit(sig);
+}
+
+
+void
+usage(void)
+{
+ fprintf(stdout, "usage: %s",
+ "fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\
+ -b opnum: beginning operation number (default 1)\n\
+ -c P: 1 in P chance of file close+open at each op (default infinity)\n\
+ -d: debug output for all operations\n\
+ -l flen: the upper bound on file size (default 262144)\n\
+ -m startop:endop: monitor (print debug output) specified byte range (default 0:infinity)\n\
+ -n: no verifications of file size\n\
+ -o oplen: the upper bound on operation size (default 65536)\n\
+ -p progressinterval: debug output at specified operation interval\n\
+ -q: quieter operation\n\
+ -r readbdy: 4096 would make reads page aligned (default 1)\n\
+ -s style: 1 gives smaller truncates (default 0)\n\
+ -t truncbdy: 4096 would make truncates page aligned (default 1)\n\
+ -w writebdy: 4096 would make writes page aligned (default 1)\n\
+ -D startingop: debug output starting at specified operation\n\
+ -L: fsxLite - no file creations & no file size changes\n\
+ -N numops: total # operations to do (default infinity)\n\
+ -O: use oplen (see -o flag) for every op (default random)\n\
+ -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\
+ -S seed: for random # generator (default 1) 0 gets timestamp\n\
+ -W: mapped write operations DISabled\n\
+ -R: read() system calls only (mapped reads disabled)\n\
+ fname: this filename is REQUIRED (no default)\n");
+ exit(90);
+}
+
+
+int
+getnum(char *s, char **e)
+{
+ int ret = -1;
+
+ *e = (char *) 0;
+ ret = strtol(s, e, 0);
+ if (*e)
+ switch (**e) {
+ case 'b':
+ case 'B':
+ ret *= 512;
+ *e = *e + 1;
+ break;
+ case 'k':
+ case 'K':
+ ret *= 1024;
+ *e = *e + 1;
+ break;
+ case 'm':
+ case 'M':
+ ret *= 1024*1024;
+ *e = *e + 1;
+ break;
+ case 'w':
+ case 'W':
+ ret *= 4;
+ *e = *e + 1;
+ break;
+ }
+ return (ret);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int i, style, ch;
+ char *endp;
+ char goodfile[1024];
+ char logfile[1024];
+
+ goodfile[0] = 0;
+ logfile[0] = 0;
+
+ setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */
+
+ while ((ch = getopt(argc, argv, "b:c:dl:m:no:p:qr:s:t:w:D:LN:OP:RS:W"))
+ != EOF)
+ switch (ch) {
+ case 'b':
+ simulatedopcount = getnum(optarg, &endp);
+ if (!quiet)
+ fprintf(stdout, "Will begin at operation %ld\n",
+ simulatedopcount);
+ if (simulatedopcount == 0)
+ usage();
+ simulatedopcount -= 1;
+ break;
+ case 'c':
+ closeprob = getnum(optarg, &endp);
+ if (!quiet)
+ fprintf(stdout,
+ "Chance of close/open is 1 in %d\n",
+ closeprob);
+ if (closeprob <= 0)
+ usage();
+ break;
+ case 'd':
+ debug = 1;
+ break;
+ case 'l':
+ maxfilelen = getnum(optarg, &endp);
+ if (maxfilelen <= 0)
+ usage();
+ break;
+ case 'm':
+ monitorstart = getnum(optarg, &endp);
+ if (monitorstart < 0)
+ usage();
+ if (!endp || *endp++ != ':')
+ usage();
+ monitorend = getnum(endp, &endp);
+ if (monitorend < 0)
+ usage();
+ if (monitorend == 0)
+ monitorend = -1; /* aka infinity */
+ debug = 1;
+ case 'n':
+ sizechecks = 0;
+ break;
+ case 'o':
+ maxoplen = getnum(optarg, &endp);
+ if (maxoplen <= 0)
+ usage();
+ break;
+ case 'p':
+ progressinterval = getnum(optarg, &endp);
+ if (progressinterval < 0)
+ usage();
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 'r':
+ readbdy = getnum(optarg, &endp);
+ if (readbdy <= 0)
+ usage();
+ break;
+ case 's':
+ style = getnum(optarg, &endp);
+ if (style < 0 || style > 1)
+ usage();
+ break;
+ case 't':
+ truncbdy = getnum(optarg, &endp);
+ if (truncbdy <= 0)
+ usage();
+ break;
+ case 'w':
+ writebdy = getnum(optarg, &endp);
+ if (writebdy <= 0)
+ usage();
+ break;
+ case 'D':
+ debugstart = getnum(optarg, &endp);
+ if (debugstart < 1)
+ usage();
+ break;
+ case 'L':
+ lite = 1;
+ break;
+ case 'N':
+ numops = getnum(optarg, &endp);
+ if (numops < 0)
+ usage();
+ break;
+ case 'O':
+ randomoplen = 0;
+ break;
+ case 'P':
+ strncpy(goodfile, optarg, sizeof(goodfile));
+ strcat(goodfile, "/");
+ strncpy(logfile, optarg, sizeof(logfile));
+ strcat(logfile, "/");
+ break;
+ case 'R':
+ mapped_reads = 0;
+ break;
+ case 'S':
+ seed = getnum(optarg, &endp);
+ if (seed == 0)
+ seed = time(0) % 10000;
+ if (!quiet)
+ fprintf(stdout, "Seed set to %d\n", seed);
+ if (seed < 0)
+ usage();
+ break;
+ case 'W':
+ mapped_writes = 0;
+ if (!quiet)
+ fprintf(stdout, "mapped writes DISABLED\n");
+ break;
+
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 1)
+ usage();
+ fname = argv[0];
+
+ signal(SIGHUP, cleanup);
+ signal(SIGINT, cleanup);
+ signal(SIGPIPE, cleanup);
+ signal(SIGALRM, cleanup);
+ signal(SIGTERM, cleanup);
+ signal(SIGXCPU, cleanup);
+ signal(SIGXFSZ, cleanup);
+ signal(SIGVTALRM, cleanup);
+ signal(SIGUSR1, cleanup);
+ signal(SIGUSR2, cleanup);
+
+ initstate(seed, state, 256);
+ setstate(state);
+ fd = open(fname, O_RDWR|(lite ? 0 : O_CREAT|O_TRUNC), 0666);
+ if (fd < 0) {
+ prterr(fname);
+ exit(91);
+ }
+ strncat(goodfile, fname, 256);
+ strcat (goodfile, ".fsxgood");
+ fsxgoodfd = open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ if (fsxgoodfd < 0) {
+ prterr(goodfile);
+ exit(92);
+ }
+ strncat(logfile, fname, 256);
+ strcat (logfile, ".fsxlog");
+ fsxlogf = fopen(logfile, "w");
+ if (fsxlogf == NULL) {
+ prterr(logfile);
+ exit(93);
+ }
+ if (lite) {
+ off_t ret;
+ file_size = maxfilelen = lseek(fd, (off_t)0, L_XTND);
+ if (file_size == (off_t)-1) {
+ prterr(fname);
+ warn("main: lseek eof");
+ exit(94);
+ }
+ ret = lseek(fd, (off_t)0, SEEK_SET);
+ if (ret == (off_t)-1) {
+ prterr(fname);
+ warn("main: lseek 0");
+ exit(95);
+ }
+ }
+ original_buf = (char *) malloc(maxfilelen);
+ for (i = 0; i < maxfilelen; i++)
+ original_buf[i] = random() % 256;
+ good_buf = (char *) malloc(maxfilelen);
+ bzero(good_buf, maxfilelen);
+ temp_buf = (char *) malloc(maxoplen);
+ bzero(temp_buf, maxoplen);
+ if (lite) { /* zero entire existing file */
+ ssize_t written;
+
+ written = write(fd, good_buf, (size_t)maxfilelen);
+ if (written != maxfilelen) {
+ if (written == -1) {
+ prterr(fname);
+ warn("main: error on write");
+ } else
+ warn("main: short write, 0x%x bytes instead of 0x%x\n",
+ (unsigned)written, maxfilelen);
+ exit(98);
+ }
+ } else
+ check_trunc_hack();
+
+ while (numops == -1 || numops--)
+ test();
+
+ if (close(fd)) {
+ prterr("close");
+ report_failure(99);
+ }
+ prt("All operations completed A-OK!\n");
+
+ exit(0);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+/*
+ * Test if agetarg works as expected
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <err.h>
+
+#include <agetarg.h>
+
+RCSID("$Id$");
+
+typedef struct {
+ int style;
+ int argc;
+ char *argv[10];
+ enum { GA_SUCCESS = 0, GA_FAILURE } retval ;
+} ga_tests;
+
+
+/* XXX TODO: aarg_negative_flag, manualpage generation ? */
+
+/*
+ *
+ */
+
+static void
+test_simple_string (void)
+{
+ char *string;
+ int i, optind;
+ ga_tests tests[] = {
+ { AARG_GNUSTYLE, 2, { "string", "--string=foo", NULL } },
+ { AARG_GNUSTYLE, 3, { "string", "-s", "foo", NULL} },
+ { AARG_AFSSTYLE, 3, { "string", "-string", "foo", NULL} },
+ { AARG_AFSSTYLE, 3, { "string", "-strin", "foo", NULL} },
+ { AARG_AFSSTYLE, 3, { "string", "-st", "foo", NULL}, GA_FAILURE },
+ { AARG_AFSSTYLE, 2, { "string", "--flag"}, GA_FAILURE },
+ { AARG_AFSSTYLE, 2, { "string", "foo", NULL} }
+ };
+
+ struct agetargs args[] = {
+ { "string", 's', aarg_string, NULL,
+ "string test", "stringfoo", aarg_mandatory},
+ { "strip", 0, aarg_string, NULL,
+ "strip test", "stripfoo", aarg_optional},
+ { NULL, 0, aarg_end, NULL, NULL }
+ }, *a = args;
+
+ a->value = &string;
+
+ for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ string = NULL;
+ optind = 0;
+
+ if (agetarg (args, tests[i].argc, tests[i].argv, &optind,
+ tests[i].style)) {
+ if (tests[i].retval == GA_FAILURE)
+ continue;
+ warnx ("test_string: %s failed for test %d",
+ tests[i].argv[1], i);
+ continue;
+ } else {
+ if (tests[i].retval != GA_SUCCESS) {
+ warnx ("test_string: %s failed to fail for test %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+ }
+
+ if (optind != tests[i].argc) {
+ warnx ("argc != optind for test %s, %d", tests[i].argv[1], i);
+ continue;
+ }
+
+ if (string == NULL || strcmp (string, "foo") != 0) {
+ warnx ("error parsing for test %d: string", i);
+ continue;
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static void
+test_simple_strings (void)
+{
+ agetarg_strings strings;
+
+ int i, optind;
+ ga_tests tests[] = {
+ { AARG_GNUSTYLE, 3, { "strings",
+ "--strings=foo", "--strings=bar", NULL } },
+ { AARG_GNUSTYLE, 5, { "strings", "-s", "foo", "-s", "bar", NULL} },
+ { AARG_AFSSTYLE, 4, { "strings", "-string", "foo", "bar", NULL} }
+#if 0
+ { AARG_AFSSTYLE, 3, { "strings", "foo", "bar", NULL} }
+#endif
+ };
+
+ struct agetargs args[] = {
+ { "strings", 's', aarg_strings, NULL,
+ "strings test", "stringsfoo", aarg_optional},
+ { NULL, 0, aarg_end, NULL, NULL }
+ }, *a = args;
+
+ a->value = &strings;
+
+ for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ strings.num_strings = 0;
+ strings.strings = NULL;
+ optind = 0;
+
+ if (agetarg (args, tests[i].argc, tests[i].argv, &optind,
+ tests[i].style)) {
+ if (tests[i].retval == GA_FAILURE)
+ continue;
+ warnx ("test_strings: %s failed for test %d",
+ tests[i].argv[1], i);
+ continue;
+ } else {
+ if (tests[i].retval != GA_SUCCESS) {
+ warnx ("test_strings: %s failed to fail for test %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+ }
+
+ if (optind != tests[i].argc) {
+ warnx ("argc != optind for test %s, %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+
+ if (strings.num_strings != 2
+ || strcmp(strings.strings[0], "foo") != 0
+ || strcmp(strings.strings[1], "bar") != 0)
+ {
+ warnx ("error parsing for test %d: strings", i);
+ continue;
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static void
+test_simple_integer (void)
+{
+ int integer;
+ int i, optind;
+ ga_tests tests[] = {
+ { AARG_GNUSTYLE, 2, { "integer", "--integer=4711", NULL } },
+ { AARG_GNUSTYLE, 3, { "integer", "-i", "4711", NULL} },
+ { AARG_AFSSTYLE, 3, { "integer", "-integer", "4711", NULL} },
+ { AARG_AFSSTYLE, 2, { "integer", "4711", NULL} }
+ };
+
+ struct agetargs args[] = {
+ { "integer", 'i', aarg_integer, NULL,
+ "integer test", "integer", aarg_mandatory},
+ { NULL, 0, aarg_end, NULL, NULL }
+ }, *a = args;
+
+ a->value = &integer;
+
+ for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ integer = 0;
+ optind = 0;
+
+ if (agetarg (args, tests[i].argc, tests[i].argv, &optind,
+ tests[i].style)) {
+ if (tests[i].retval == GA_FAILURE)
+ continue;
+ warnx ("test_integer: %s failed for test %d",
+ tests[i].argv[1], i);
+ continue;
+ } else {
+ if (tests[i].retval != GA_SUCCESS) {
+ warnx ("test_integer: %s failed to fail for test %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+ }
+
+ if (optind != tests[i].argc) {
+ warnx ("argc != optind for test %s, %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+
+ if (integer != 4711) {
+ warnx ("error parsing for test %d: integer 4711", i);
+ continue;
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static void
+test_simple_flag (void)
+{
+ int flag;
+ int i, optind;
+ ga_tests tests[] = {
+ { AARG_GNUSTYLE, 2, { "flag", "--flag=yes", NULL }, GA_SUCCESS },
+ { AARG_GNUSTYLE, 2, { "flag", "-g", NULL}, GA_SUCCESS },
+ { AARG_AFSSTYLE, 2, { "flag", "--flag"}, GA_FAILURE },
+ { AARG_AFSSTYLE, 2, { "flag", "-flag", NULL}, GA_SUCCESS },
+#if 0
+ /* XXX */
+ { AARG_AFSSTYLE, 2, { "flag", "yes", NULL}, GA_SUCCESS },
+#endif
+ { AARG_GNUSTYLE, 2, { "flag", "--no-flag", NULL}, GA_SUCCESS }
+ };
+
+ struct agetargs args[] = {
+ { "flag", 'g', aarg_flag, NULL,
+ "flag", "flag bar", aarg_optional},
+ { NULL, 0, aarg_end, NULL, NULL }
+ }, *a = args;
+
+ a->value = &flag;
+
+ for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ if (i < 4)
+ flag = 0;
+ else
+ flag = 1;
+ optind = 0;
+
+ if (agetarg (args, tests[i].argc, tests[i].argv, &optind,
+ tests[i].style)) {
+ if (tests[i].retval == GA_FAILURE)
+ continue;
+ warnx ("test_flag: %s failed for test %d",
+ tests[i].argv[1], i);
+ continue;
+ } else {
+ if (tests[i].retval != GA_SUCCESS) {
+ warnx ("test_flag: %s failed to fail for test %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+ }
+
+ if (optind != tests[i].argc) {
+ warnx ("argc != optind for test %s, %d",
+ tests[i].argv[1], i);
+ continue;
+ }
+
+ if (i < 4) {
+ if (flag == 0) {
+ warnx ("error parsing for test %d: flag %s",
+ i,
+ tests[i].argv[1]);
+ continue;
+ }
+ } else {
+ if (flag != 0) {
+ warnx ("error parsing test %d: flag %s",
+ i,
+ tests[i].argv[1]);
+ continue;
+ }
+ }
+ }
+}
+
+/*
+ *
+ */
+
+int
+main (int argc, char **argv)
+{
+
+ test_simple_string();
+ test_simple_strings();
+ test_simple_integer();
+ test_simple_flag();
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test $# -ne 1 -a $# -ne 2; then
+ echo "Usage: $0 file [directory]"
+ exit 1
+fi
+filename=$1
+if test $# -gt 1; then
+ b=$2
+else
+ b=`basename $filename .tar.gz`
+fi
+obj=$b-obj
+
+gzip -dc $filename | tar xvf - >&4 2>&1 || exit 1
+cd $b || exit 1
+./configure >&4 || exit 1
+make $MAKEFLAGS || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz |
+tar vxf - >&4 2>&1 || exit 1
+cd emacs-20.7 || exit 1
+$objdir/kill-softer lisp || exit 1
+test -d lisp && exit 1
+exit 0
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz |
+tar vxf - >&4 2>&1 || exit 1
+cd emacs-20.7 || exit 1
+$objdir/rm-rf lisp || exit 1
+test -d lisp && exit 1
+exit 0
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz |
+tar vxf - >&4 2>&1 || exit 1
+cd emacs-20.7 || exit 1
+$objdir/kill-softly lisp || exit 1
+test -d lisp && exit 1
+exit 0
--- /dev/null
+#!/bin/sh
+
+if [ x`uname` != xLinux ] ; then
+ echo This test does not run on this architecture
+ exit 1
+fi
+
+echo '***********************************************************'
+echo '* *'
+echo '* Infinite run until error *'
+echo '* *'
+echo '***********************************************************'
+sleep 5
+
+# First argument is our working dir
+test $1 || exit 1
+mkdir $1
+cd $1 || exit 1
+
+TOPDIR=$PWD
+export TOPDIR
+CVSROOT=/afs/stacken.kth.se/src/SourceRepository
+export CVSROOT
+
+# test if cvs takes -R
+cvs -R help 2>&1 | grep Usage: > /dev/null && exit 1
+
+cvs -R checkout arla
+while true; do
+ echo Starting at $TOPDIR
+
+ cd $TOPDIR || exit 1
+ cd arla || exit 1
+ cvs -R update -A -d
+ sh HACKING
+ cd $TOPDIR || exit 1
+ mkdir arla-obj
+ cd arla-obj || exit 1
+
+ ../arla/configure && mv xfs/linux/Makefile xfs/linux/Makefile.old && sed 's/ -Werror//g' < xfs/linux/Makefile.old > xfs/linux/Makefile && make || exit 1
+
+ cd $TOPDIR || exit 1
+ cd arla || exit 1
+ cvs -R update -r arla-0-35-branch -d
+ sh HACKING
+ cd $TOPDIR || exit 1
+ mkdir arla-obj
+ cd arla-obj || exit 1
+ ../arla/configure && mv xfs/linux/Makefile xfs/linux/Makefile.old && sed 's/ -Werror//g' < xfs/linux/Makefile.old > xfs/linux/Makefile && make || exit 1
+done
+
+
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd1, fd2;
+ int ret;
+ struct stat sb1, sb2;
+
+
+ fd1 = open("foo", O_RDWR|O_CREAT, 0666);
+ if (fd1 < 0)
+ err (1, "open foo");
+
+ ret = fstat (fd1, &sb1);
+ if (ret < 0)
+ err (1, "stat foo");
+
+ if (sb1.st_nlink != 1)
+ errx (1, "foo.st_nlink != 1");
+
+ ret = link ("foo", "bar");
+ if (ret < 0)
+ err (1, "link foo, bar");
+
+ ret = fstat (fd1, &sb1);
+ if (ret < 0)
+ err (1, "stat foo");
+
+ ret = lstat ("bar", &sb2);
+ if (ret < 0)
+ err (1, "stat bar");
+
+ if (sb1.st_nlink != 2)
+ errx (1, "foo.st_nlink != 2");
+
+ if (sb2.st_nlink != 2)
+ errx (1, "bar.st_nlink != 2");
+
+ if (sb1.st_dev != sb2.st_dev
+ || sb1.st_ino != sb2.st_ino)
+ errx (1, "dev and ino differ");
+
+ fd2 = open("bar", O_RDONLY, 0);
+ if (fd2 < 0)
+ err (1, "open bar");
+
+ ret = fstat (fd2, &sb2);
+ if (ret < 0)
+ err (1, "fstat bar");
+
+ if (sb2.st_nlink != 2)
+ errx (1, "bar.st_nlink != 2");
+
+ if (write (fd1, "hej", 3) != 3)
+ errx (1, "write to foo");
+
+ ret = fstat (fd1, &sb1);
+ if (ret < 0)
+ err (1, "stat foo");
+
+ if (sb1.st_size != 3)
+ errx (1, "foo.st_size != 3");
+
+ ret = close (fd1);
+ if (ret < 0)
+ err (1, "close foo");
+
+ ret = fstat (fd2, &sb2);
+ if (ret < 0)
+ err (1, "fstat bar");
+
+ if (sb2.st_size != 3)
+ errx (1, "bar.st_size != 3");
+
+ ret = close (fd2);
+ if (ret < 0)
+ err (1, "close bar");
+
+ if (unlink ("foo") < 0)
+ err (1, "unlink foo");
+
+ fd2 = open("bar", O_RDONLY, 0);
+ if (fd2 < 0)
+ err (1, "open bar");
+
+ ret = fstat (fd2, &sb2);
+ if (ret < 0)
+ err (1, "fstat bar");
+
+ if (sb2.st_nlink != 1)
+ errx (1, "bar.st_nlink != 1");
+
+ ret = close (fd2);
+ if (ret < 0)
+ err (1, "close bar");
+
+ if (unlink ("bar") < 0)
+ err (1, "unlink bar");
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd1;
+ int ret;
+ struct stat sb1;
+
+
+ ret = mkdir ("1", 0777);
+ if (ret < 0)
+ err (1, "mkdir 1");
+
+ ret = link ("1", "2");
+ if (ret == 0)
+ errx (1, "link 1 2 should have failed");
+
+ ret = rmdir ("1");
+ if (ret < 0)
+ err (1, "rmdir 1");
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+
+touch file
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ ln file file$i
+done
+
+# now trigger bulkstatus
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ ls -l file > /dev/null 2>&1 || exit 1
+ ${FS} flush file
+done
+
+# just stat them all
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ ls -l file$i > /dev/null 2>&1 || exit 1
+done
+
+#clean up
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ rm file$i > /dev/null 2>&1 || exit 1
+done
+rm file
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd1;
+ int ret;
+ struct stat sb1;
+
+
+ ret = mkdir ("1", 0777);
+ if (ret < 0)
+ err (1, "mkdir 1");
+
+ ret = mkdir ("2", 0777);
+ if (ret < 0)
+ err (1, "mkdir 2");
+
+ fd1 = open("1/foo", O_RDWR|O_CREAT, 0666);
+ if (fd1 < 0)
+ err (1, "open 1/foo");
+
+ ret = fstat (fd1, &sb1);
+ if (ret < 0)
+ err (1, "stat foo");
+
+ if (sb1.st_nlink != 1)
+ errx (1, "foo.st_nlink != 1");
+
+ ret = close (fd1);
+ if (ret < 0)
+ err (1, "close 1/foo");
+
+ ret = link ("1/foo", "2/foo");
+ if (ret == 0)
+ unlink ("2/foo");
+ if (ret < 0 && errno != EXDEV)
+ err (1, "link 1/foo, 2/foo");
+
+ ret = unlink ("1/foo");
+ if (ret < 0)
+ err (1, "unlink 1/foo");
+
+ ret = rmdir ("1");
+ if (ret < 0)
+ err (1, "rmdir 1");
+
+ ret = rmdir ("2");
+ if (ret < 0)
+ err (1, "rmdir 2");
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+
+touch file
+ln file ../../service/file && exit 1
+rm file
+
--- /dev/null
+#!/bin/sh
+# $Id$
+cat <<FOO > foo.c
+int main() { return 0; }
+FOO
+%CC% -o foo foo.c || exit 1
+./foo || exit 1
+rm -f foo foo.c
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <dirent.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#include <err.h>
+
+#define RETSIGTYPE void
+#ifndef MAXPATHLEN
+#ifdef PATH_MAX
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 4096
+#endif
+#endif
+
+static sig_atomic_t set_alarm = 1;
+
+static RETSIGTYPE
+sigalrm(int foo)
+{
+ signal(SIGALRM, sigalrm);
+ set_alarm = 1;
+}
+
+static void
+try_read(const char *filename)
+{
+ int fd;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ if (errno == EINTR)
+ err(1, "open %s was interrupted", filename);
+ } else {
+ close(fd);
+ }
+}
+
+static void
+find(const char *dirname)
+{
+ DIR *dir;
+ struct dirent *dp;
+
+ dir = opendir(dirname);
+ if (dir == NULL)
+ err (1, "opendir %s", dirname);
+ while ((dp = readdir(dir)) != NULL) {
+ char fname[MAXPATHLEN];
+ struct stat sb;
+
+ if (set_alarm) {
+ alarm(1);
+ set_alarm = 0;
+ }
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+ snprintf(fname, sizeof(fname), "%s/%s", dirname, dp->d_name);
+ if (lstat(fname, &sb) < 0)
+ err(1, "stat %s", fname);
+ if (S_ISDIR(sb.st_mode))
+ find(fname);
+ else
+ try_read(fname);
+ }
+ closedir(dir);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction sa;
+
+ sa.sa_handler = sigalrm;
+ sigfillset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGALRM, &sa, NULL);
+ while (--argc)
+ find(*++argv);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+$objdir/intr-read ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/gnu-0.2 || exit 1
+exit 0
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <atypes.h>
+
+#include <kafs.h>
+
+#include <fs.h>
+#include <arlalib.h>
+
+#include <err.h>
+
+RCSID("$Id$");
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#ifdef KERBEROS
+
+static void
+create_write_file (char *filename)
+{
+ int ret;
+ int fd;
+
+ fs_invalidate (filename);
+
+ fd = open(filename, O_RDWR|O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open(rw): %s", filename);
+
+ ret = write (fd, "foo", 3);
+ if (ret < 0)
+ err (1, "write");
+
+ fs_invalidate (filename);
+
+ ret = write (fd, "foo", 3);
+ if (ret < 0)
+ err (1, "write2");
+
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close");
+}
+
+static void
+read_file (char *filename)
+{
+ int ret;
+ int fd;
+ char buf[3];
+
+ fs_invalidate (filename);
+
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd < 0)
+ err (1, "open(ro)");
+
+ ret = read (fd, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+
+ fs_invalidate (filename);
+
+ ret = read (fd, buf, sizeof(buf));
+ if (ret < 0)
+ err (1, "read");
+
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close");
+}
+
+static void
+mmap_read_file (char *filename)
+{
+ int fd;
+ void *v;
+ char buf[6];
+
+ fs_invalidate (filename);
+
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd < 0)
+ err (1, "open(ro-mmap)");
+
+ v = mmap (NULL, 6, PROT_READ, MAP_SHARED, fd, 0);
+ if (v == (void *)MAP_FAILED)
+ err (1, "mmap(ro) %s", filename);
+
+ memcpy (buf, v, 3);
+ fs_invalidate (filename);
+ memcpy (buf, v, 3);
+
+ munmap (v, 6);
+}
+
+static void
+mmap_write_file (char *filename)
+{
+ int fd;
+ void *v;
+
+ fs_invalidate (filename);
+
+ fd = open (filename, O_RDWR, 0666);
+ if (fd < 0)
+ err (1, "open(rw-mmap)");
+
+ v = mmap (NULL, 6, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (v == (void *)MAP_FAILED)
+ err (1, "mmap(rw) %s", filename);
+
+ memcpy (v, "foo", 3);
+ fs_invalidate (filename);
+ memcpy (v, "foo", 3);
+
+ munmap (v, 6);
+ close (fd);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *filename = "foo";
+
+
+#ifdef KERBEROS
+ if (!k_hasafs())
+#endif
+ exit (1);
+
+ create_write_file (filename);
+ read_file (filename);
+ read_file (filename);
+ read_file (filename);
+ read_file (filename);
+ mmap_read_file (filename);
+ mmap_read_file (filename);
+ mmap_read_file (filename);
+ mmap_read_file (filename);
+ mmap_write_file (filename);
+ mmap_write_file (filename);
+ mmap_write_file (filename);
+ mmap_write_file (filename);
+
+ return 0;
+}
+
+#else
+
+int
+main(int argc, char **argv)
+{
+
+ errx (1, "no kafs support");
+}
+#endif
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.ph for use and distribution information
+#
+#: * kas.pm - Wrappers around KAS commands (authentication maintenance)
+#: * This module provides wrappers around the various kaserver commands
+#: * giving them a nice perl-based interface. At present, this module
+#: * requires a special 'krbkas' which uses existing Kerberos tickets
+#: * which the caller must have already required (using 'kaslog').
+#:
+
+package OpenAFS::kas;
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use OpenAFS::wrapper;
+use POSIX ();
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_kas_create &AFS_kas_setf
+ &AFS_kas_delete &AFS_kas_setkey
+ &AFS_kas_examine &AFS_kas_setpw
+ &AFS_kas_randomkey &AFS_kas_stringtokey
+ &AFS_kas_list);
+
+# Instructions to parse kas error messages
+@kas_err_parse = ( [ ' : \[.*\] (.*), wait one second$', '.' ],
+ [ ' : \[.*\] (.*) \(retrying\)$', '.' ],
+ [ ' : \[.*\] (.*)', '-' ]);
+
+# Instructions to parse attributes of an entry
+@kas_entry_parse = (
+ [ '^User data for (.*) \((.*)\)$', 'princ', 'flags', '.' ],
+ [ '^User data for (.*)', 'princ' ],
+ [ 'key \((\d+)\) cksum is (\d+),', 'kvno', 'cksum' ],
+ [ 'last cpw: (.*)', \&parsestamp, 'stamp_cpw' ],
+ [ 'password will (never) expire', 'stamp_pwexp' ],
+ [ 'password will expire: ([^\.]*)', \&parsestamp, 'stamp_pwexp' ],
+ [ 'An (unlimited) number of', 'max_badauth' ],
+ [ '(\d+) consecutive unsuccessful', 'max_badauth' ],
+ [ 'for this user is ([\d\.]+) minutes', 'locktime' ],
+ [ 'for this user is (not limited)', 'locktime' ],
+ [ 'User is locked (forever)', 'locked' ],
+ [ 'User is locked until (.*)', \&parsestamp, 'locked' ],
+ [ 'entry (never) expires', 'stamp_expire' ],
+ [ 'entry expires on ([^\.]*)\.', \&parsestamp, 'stamp_expire' ],
+ [ 'Max ticket lifetime (.*) hours', 'maxlife' ],
+ [ 'Last mod on (.*) by', \&parsestamp, 'stamp_update' ],
+ [ 'Last mod on .* by (.*)', 'last_writer' ]);
+
+
+@Months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
+%Months = map(($Months[$_] => $_), 0..11);
+
+# Parse a timestamp
+sub parsestamp {
+ my($stamp) = @_;
+ my($MM, $DD, $YYYY, $hh, $mm, $ss);
+
+ if ($stamp =~ /^\S+ (\S+) (\d+) (\d+):(\d+):(\d+) (\d+)/) {
+ ($MM, $DD, $hh, $mm, $ss, $YYYY) = ($1, $2, $3, $4, $5, $6);
+ $YYYY -= 1900;
+ $MM = $Months{$MM};
+ if (defined($MM)) {
+ $stamp = POSIX::mktime($ss, $mm, $hh, $DD, $MM, $YYYY);
+ }
+ }
+ $stamp;
+}
+
+
+# Turn an 8-byte key into a string we can give to kas
+sub stringize_key {
+ my($key) = @_;
+ my(@chars) = unpack('CCCCCCCC', $key);
+
+ sprintf("\\%03o" x 8, @chars);
+}
+
+
+# Turn a string into an 8-byte DES key
+sub unstringize_key {
+ my($string) = @_;
+ my($char, $key);
+
+ while ($string ne '') {
+ if ($string =~ /^\\(\d\d\d)/) {
+ $char = $1;
+ $string = $';
+ $key .= chr(oct($char));
+ } else {
+ $key .= substr($string, 0, 1);
+ $string =~ s/^.//;
+ }
+ }
+ $key;
+}
+
+
+#: AFS_kas_create($princ, $initpass, [$cell])
+#: Create a principal with name $princ, and initial password $initpass
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{kas_create} = '$princ, $initpass, [$cell] => Success?';
+sub AFS_kas_create {
+ my($print, $initpass, $cell) = @_;
+ my(@args, $id);
+
+ @args = ('create', '-name', $princ, '-initial_password', $initpass);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+ 1;
+}
+
+
+#: AFS_kas_delete($princ, [$cell])
+#: Delete the principal $princ.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{kas_delete} = '$princ, [$cell] => Success?';
+sub AFS_kas_delete {
+ my($princ, $cell) = @_;
+ my(@args);
+
+ @args = ('delete', '-name', $princ);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+ 1;
+}
+
+
+#: AFS_kas_examine($princ, [$cell])
+#: Examine the prinicpal $princ, and return information about it.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return an associative array with some or all of the following:
+#: - princ Name of this principal
+#: - kvno Key version number
+#: - cksum Key checksum
+#: - maxlife Maximum ticket lifetime (in hours)
+#: - stamp_expire Time this principal expires, or 'never'
+#: - stamp_pwexp Time this principal's password expires, or 'never'
+#: - stamp_cpw Time this principal's password was last changed
+#: - stamp_update Time this princiapl was last modified
+#: - last_writer Administrator who last modified this principal
+#: - max_badauth Maximum number of bad auth attempts, or 'unlimited'
+#: - locktime Penalty time for bad auth (in minutes), or 'not limited'
+#: - locked Set and non-empty if account is locked
+#: - expired Set and non-empty if account is expired
+#: - flags Reference to a list of flags
+#:
+$AFS_Help{kas_examine} = '$princ, [$cell] => %info';
+sub AFS_kas_examine {
+ my($vol, $cell) = @_;
+ my(%result, @args, $flags);
+
+ @args = ('examine', '-name', $princ);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %result = &wrapper('krbkas', \@args, [ @kas_err_parse, @kas_entry_parse ]);
+
+ if ($result{flags}) {
+ $result{expired} = 1 if ($result{flags} =~ /expired/);
+ $result{flags} = [ split(/\+/, $result{flags}) ];
+ }
+ %result;
+}
+
+
+#: AFS_kas_list([$cell])
+#: Get a list of principals in the kaserver database
+#: If specified, work in $cell instead of the default cell.
+#: On success, return an associative array whose keys are names of kaserver
+#: principals, and each of whose values is an associative array describing
+#: the corresponding principal, containing some or all of the same elements
+#: that may be returned by AFS_kas_examine
+#:
+$AFS_Help{kas_list} = '[$cell] => %princs';
+sub AFS_kas_list {
+ my($cell) = @_;
+ my(@args, %finres, %plist);
+
+ @args = ('list', '-long');
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %finres = &wrapper('krbkas', \@args,
+ [ @kas_err_parse,
+ [ '^User data for (.*)', sub {
+ my(%pinfo) = %OpenAFS::wrapper::result;
+
+ if ($pinfo{name}) {
+ $plist{$pinfo{name}} = \%pinfo;
+ %OpenAFS::wrapper::result = ();
+ }
+ }],
+ @kas_entry_parse ]);
+
+ if ($finres{name}) {
+ $plist{$finres{name}} = \%finres;
+ }
+ %plist;
+}
+
+
+#: AFS_kas_setf($princ, \%attrs, [$cell])
+#: Change the attributes of the principal $princ.
+#: If specified, operate in cell $cell instead of the default cell.
+#: The associative array %attrs specifies the attributes to change and
+#: their new values. Any of the following attributes may be changed:
+#: - flags Entry flags
+#: - expire Expiration time (mm/dd/yy)
+#: - lifetime Maximum ticket lifetime (seconds)
+#: - pwexpires Maximum password lifetime (days)
+#: - reuse Permit password reuse (yes/no)
+#: - attempts Maximum failed authentication attempts
+#: - locktime Authentication failure penalty (minutes or hh:mm)
+#:
+#: On success, return 1.
+#:
+$AFS_Help{kas_setf} = '$princ, \%attrs, [$cell] => Success?';
+sub AFS_kas_setf {
+ my($princ, $attrs, $cell) = @_;
+ my(%result, @args);
+
+ @args = ('setfields', '-name', $princ);
+ push(@args, '-flags', $$attrs{flags}) if ($$attrs{flags});
+ push(@args, '-expiration', $$attrs{expire}) if ($$attrs{expire});
+ push(@args, '-lifetime', $$attrs{lifetime}) if ($$attrs{lifetime});
+ push(@args, '-pwexpires', $$attrs{pwexpires}) if ($$attrs{pwexpires});
+ push(@args, '-reuse', $$attrs{reuse}) if ($$attrs{reuse});
+ push(@args, '-attempts', $$attrs{attempts}) if ($$attrs{attempts});
+ push(@args, '-locktime', $$attrs{locktime}) if ($$attrs{locktime});
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+ 1;
+}
+
+
+#: AFS_kas_setkey($princ, $key, [$kvno], [$cell])
+#: Change the key of principal $princ to the specified value.
+#: $key is the 8-byte DES key to use for this principal.
+#: If specified, set the key version number to $kvno.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{kas_setkey} = '$princ, $key, [$kvno], [$cell] => Success?';
+sub AFS_kas_setkey {
+ my($princ, $key, $kvno, $cell) = @_;
+ my(@args);
+
+ @args = ('setkey', '-name', $princ, '-new_key', &stringize_key($key));
+ push(@args, '-kvno', $kvno) if (defined($kvno));
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+ 1;
+}
+
+
+#: AFS_kas_setpw($princ, $password, [$kvno], [$cell])
+#: Change the key of principal $princ to the specified value.
+#: $password is the new password to use.
+#: If specified, set the key version number to $kvno.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{kas_setpw} = '$princ, $password, [$kvno], [$cell] => Success?';
+sub AFS_kas_setpw {
+ my($princ, $password, $kvno, $cell) = @_;
+ my(@args);
+
+ @args = ('setpasswd', '-name', $princ, '-new_password', $password);
+ push(@args, '-kvno', $kvno) if (defined($kvno));
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args, [ @kas_err_parse ]);
+ 1;
+}
+
+
+#: AFS_kas_stringtokey($string, [$cell])
+#: Convert the specified string to a DES key
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return the resulting key
+$AFS_Help{kas_stringtokey} = '$string, [$cell] => $key';
+sub AFS_kas_stringtokey {
+ my($string, $cell) = @_;
+ my(@args, $key);
+
+ @args = ('stringtokey', '-string', $string);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args,
+ [ @kas_err_parse,
+ [ q/^Converting .* in realm .* yields key='(.*)'.$/, \$key ]]);
+ &unstringize_key($key);
+}
+
+
+#: AFS_kas_randomkey([$cell])
+#: Ask the kaserver to generate a random DES key
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return the resulting key
+$AFS_Help{kas_randomkey} = '[$cell] => $key';
+sub AFS_kas_randomkey {
+ my($cell) = @_;
+ my(@args, $key);
+
+ @args = ('getrandomkey');
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('krbkas', \@args,
+ [ @kas_err_parse,
+ [ '^Key: (\S+)', \$key ]]);
+ &unstringize_key($key);
+}
+
+1;
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static FILE *verbose;
+
+struct entry {
+ char *name;
+ int status;
+};
+
+static void
+kill_one (struct entry *ents, int ind, int curents);
+
+static void
+do_dir (const char *dirname);
+
+static void
+kill_dir (const char *dirname);
+
+static void
+kill_one (struct entry *ents, int ind, int curents)
+{
+ int ret;
+ int i;
+
+ ret = unlink (ents[ind].name);
+ if (ret < 0) {
+ if (errno == EISDIR || errno == EPERM)
+ do_dir (ents[ind].name);
+ else
+ err (1, "unlink %s", ents[ind].name);
+ }
+ ents[ind].status = 0;
+ for (i = 0; i <= ind; ++i) {
+ struct stat sb;
+
+ ret = lstat (ents[i].name, &sb);
+ if (ret == 0 || errno != ENOENT)
+ err (1, "%s still exists?", ents[i].name);
+ }
+
+ for (i = ind + 1; i < curents; ++i) {
+ struct stat sb;
+
+ ret = lstat (ents[i].name, &sb);
+ if (ret < 0)
+ err (1, "stat %s", ents[i].name);
+ }
+}
+
+static void
+do_dir (const char *dirname)
+{
+ int ret;
+
+ ret = chdir (dirname);
+ if (ret < 0)
+ err (1, "chdir %s", dirname);
+ kill_dir (dirname);
+ ret = chdir ("..");
+ if (ret < 0)
+ err (1, "chdir ..");
+ ret = rmdir (dirname);
+ if (ret < 0)
+ err (1, "rmdir %s", dirname);
+}
+
+static void
+kill_dir (const char *dirname)
+{
+ struct entry *ents;
+ int maxents;
+ int curents = 0;
+ DIR *dir;
+ struct dirent *dp;
+ int i;
+
+ fprintf (verbose, "reading %s\n", dirname);
+
+ dir = opendir (".");
+ if (dir == NULL)
+ err (1, "opendir %s", dirname);
+ maxents = 10;
+ ents = malloc (sizeof (*ents) * maxents);
+ if (ents == NULL)
+ err (1, "malloc");
+ while ((dp = readdir (dir)) != NULL) {
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ if (curents >= maxents) {
+ maxents *= 2;
+ ents = realloc (ents, sizeof(*ents) * maxents);
+ if (ents == NULL)
+ err (1, "realloc");
+ }
+ ents[curents].name = strdup (dp->d_name);
+ ents[curents].status = 1;
+ ++curents;
+ fprintf (verbose, " adding %s\n", dp->d_name);
+ }
+ closedir (dir);
+ dir = opendir (".");
+ if (dir == NULL)
+ err (1, "opendir %s", dirname);
+ i = 0;
+ while((dp = readdir (dir)) != NULL) {
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ if (strcmp (ents[i].name, dp->d_name) != 0) {
+ errx (1, "%s != %s", ents[i].name, dp->d_name);
+ }
+ fprintf (verbose, " deleting %s\n", ents[i].name);
+ kill_one (ents, i, curents);
+ ++i;
+ }
+ if (i != curents)
+ errx (1, "missing %d entries in %s", curents - i, dirname);
+ closedir (dir);
+ free (ents);
+ fprintf (verbose, "end of %s\n", dirname);
+}
+
+int
+main(int argc, char **argv)
+{
+
+ verbose = fdopen (4, "w");
+ if (verbose == NULL) {
+ verbose = fopen ("/dev/null", "w");
+ if (verbose == NULL)
+ err (1, "fopen /dev/null");
+ }
+
+ if (argc != 2)
+ errx (1, "usage: %s directory", argv[0]);
+ do_dir (argv[1]);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+struct entry {
+ char *name;
+ int status;
+};
+
+static void
+kill_one (struct entry *ents, int ind, int curents);
+
+static void
+do_dir (const char *dirname);
+
+static void
+kill_dir (const char *dirname);
+
+static void
+kill_one (struct entry *ents, int ind, int curents)
+{
+ int ret;
+ int i;
+
+ ret = unlink (ents[ind].name);
+ if (ret < 0) {
+ if (errno == EISDIR || errno == EPERM)
+ do_dir (ents[ind].name);
+ else
+ err (1, "unlink %s", ents[ind].name);
+ }
+ ents[ind].status = 0;
+ for (i = 0; i <= ind; ++i) {
+ struct stat sb;
+
+ ret = lstat (ents[i].name, &sb);
+ if (ret == 0 || errno != ENOENT)
+ err (1, "%s still exists?", ents[i].name);
+ }
+
+ for (i = ind + 1; i < curents; ++i) {
+ struct stat sb;
+
+ ret = lstat (ents[i].name, &sb);
+ if (ret < 0)
+ err (1, "stat %s", ents[i].name);
+ }
+}
+
+static void
+do_dir (const char *dirname)
+{
+ int ret;
+
+ ret = chdir (dirname);
+ if (ret < 0)
+ err (1, "chdir %s", dirname);
+ kill_dir (dirname);
+ ret = chdir ("..");
+ if (ret < 0)
+ err (1, "chdir ..");
+ ret = rmdir (dirname);
+ if (ret < 0)
+ err (1, "rmdir %s", dirname);
+}
+
+static void
+kill_dir (const char *dirname)
+{
+ struct entry *ents;
+ int maxents;
+ int curents = 0;
+ DIR *dir;
+ struct dirent *dp;
+ int i;
+
+ dir = opendir (".");
+ if (dir == NULL)
+ err (1, "opendir %s", dirname);
+ maxents = 10;
+ ents = malloc (sizeof (*ents) * maxents);
+ if (ents == NULL)
+ err (1, "malloc");
+ while ((dp = readdir (dir)) != NULL) {
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ if (curents >= maxents) {
+ maxents *= 2;
+ ents = realloc (ents, sizeof(*ents) * maxents);
+ if (ents == NULL)
+ err (1, "realloc");
+ }
+ ents[curents].name = strdup (dp->d_name);
+ ents[curents].status = 1;
+ ++curents;
+ }
+ closedir (dir);
+ for (i = 0; i < curents; ++i)
+ kill_one (ents, i, curents);
+ free (ents);
+}
+
+int
+main(int argc, char **argv)
+{
+
+ if (argc != 2)
+ errx (1, "usage: %s directory", argv[0]);
+ do_dir (argv[1]);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+
+exec ${objdir}/../lib/ko/kotest
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/large-dir large-dir-16384 16384
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+for i in 10 20 30 31 40 50 60 70 80 90 100; do
+ $objdir/large-dir2 large-dir-$i $i || exit 1
+ $objdir/large-dir3 large-dir-$i $i || exit 1
+done
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+creat_files (const char *dirname, int count)
+{
+ struct stat sb;
+ int i;
+ DIR *d;
+ struct dirent *dp;
+
+ if (mkdir (dirname, 0777) < 0)
+ err (1, "mkdir %s", dirname);
+
+ if (chdir (dirname) < 0)
+ err (1, "chdir %s", dirname);
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+ if (sb.st_size != 2048)
+ errx (1, "size != 2048");
+ for (i = 0; i < count; ++i) {
+ char num[17];
+ int fd;
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ fd = open (num, O_CREAT | O_EXCL, 0777);
+ if (fd < 0)
+ err (1, "open %s", num);
+ if (close (fd) < 0)
+ err (1, "close %s", num);
+ }
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+
+ d = opendir (".");
+ if (d == NULL)
+ err (1, "opendir .");
+ for (i = -2; i < count; ++i) {
+ char num[17];
+
+ dp = readdir (d);
+ if (dp == NULL)
+ errx (1, "out of entries at %d?", i);
+ if (i == -2)
+ strcpy (num, ".");
+ else if (i == -1)
+ strcpy (num, "..");
+ else
+ snprintf (num, sizeof(num), "%d", i);
+ if (strcmp (num, dp->d_name) != 0)
+ errx (1, "'%s' != '%s'", num, dp->d_name);
+ }
+ if (readdir (d) != NULL)
+ errx (1, "more entries?");
+ closedir (d);
+ for (i = 0; i < count; ++i) {
+ char num[17];
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ if (unlink (num) < 0)
+ err (1, "unlink %s", num);
+ }
+ d = opendir (".");
+ if (d == NULL)
+ err (1, "opendir .");
+ dp = readdir (d);
+ if (dp == NULL || strcmp (dp->d_name, ".") != 0)
+ errx (1, "where's .?");
+ dp = readdir (d);
+ if (dp == NULL || strcmp (dp->d_name, "..") != 0)
+ errx (1, "where's ..?");
+ if (readdir (d) != NULL)
+ errx (1, "even more entries?");
+ closedir (d);
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+#if 0
+ if (sb.st_size != 2048)
+ errx (1, "size != 2048");
+#endif
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s directory number-of-files\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+
+
+ if (argc != 3)
+ usage (1);
+
+ count = strtol (argv[2], &ptr, 0);
+ if (count == 0 && ptr == argv[2])
+ errx (1, "'%s' not a number", argv[2]);
+
+ return creat_files (argv[1], count);
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+creat_files (const char *dirname, int count)
+{
+ struct stat sb;
+ int i;
+ DIR *d;
+ struct dirent *dp;
+
+ srand (time (NULL));
+
+ if (mkdir (dirname, 0777) < 0)
+ err (1, "mkdir %s", dirname);
+
+ if (chdir (dirname) < 0)
+ err (1, "chdir %s", dirname);
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+#if 0
+ if (sb.st_size != 2048)
+ errx (1, "size != 2048");
+#endif
+ for (i = 0; i < count; ++i) {
+ char fname[256];
+ int len;
+ int j;
+ int fd;
+
+ len = 1 + rand () % (sizeof(fname) - 2);
+
+ for (j = 0; j < len; ++j)
+ fname[j] = 'A' + rand() % ('z' - 'A');
+ fname[j] = '\0';
+
+ fd = open (fname, O_CREAT | O_EXCL, 0777);
+ if (fd < 0)
+ err (1, "open %s", fname);
+ if (close (fd) < 0)
+ err (1, "close %s", fname);
+ }
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+
+ d = opendir (".");
+ if (d == NULL)
+ err (1, "opendir .");
+ while ((dp = readdir (d)) != NULL) {
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ if (unlink (dp->d_name) < 0)
+ err (1, "unlink %s", dp->d_name);
+ }
+ closedir (d);
+ if (chdir ("..") < 0)
+ err (1, "chdir ..");
+ if (rmdir (dirname) < 0)
+ err (1, "rmdir");
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s directory number-of-files\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+
+
+ if (argc != 3)
+ usage (1);
+
+ count = strtol (argv[2], &ptr, 0);
+ if (count == 0 && ptr == argv[2])
+ errx (1, "'%s' not a number", argv[2]);
+
+ return creat_files (argv[1], count);
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+creat_files (const char *dirname, int count)
+{
+ struct stat sb;
+ int i;
+ DIR *d;
+ struct dirent *dp;
+
+ if (mkdir (dirname, 0777) < 0)
+ err (1, "mkdir %s", dirname);
+
+ if (chdir (dirname) < 0)
+ err (1, "chdir %s", dirname);
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+ for (i = 0; i < count; ++i) {
+ char num[17];
+ int fd;
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ fd = open (num, O_CREAT | O_EXCL, 0777);
+ if (fd < 0)
+ err (1, "open %s", num);
+ if (close (fd) < 0)
+ err (1, "close %s", num);
+ }
+ if (stat (".", &sb) < 0)
+ err (1, "stat .");
+
+ d = opendir (".");
+ if (d == NULL)
+ err (1, "opendir .");
+ while ((dp = readdir (d)) != NULL) {
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ if (unlink (dp->d_name) < 0)
+ err (1, "unlink %s", dp->d_name);
+ }
+ closedir (d);
+ if (chdir ("..") < 0)
+ err (1, "chdir ..");
+ if (rmdir (dirname) < 0)
+ err (1, "rmdir");
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s directory number-of-files\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *ptr;
+ int count;
+
+
+ if (argc != 3)
+ usage (1);
+
+ count = strtol (argv[2], &ptr, 0);
+ if (count == 0 && ptr == argv[2])
+ errx (1, "'%s' not a number", argv[2]);
+
+ return creat_files (argv[1], count);
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+
+touch aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2>/dev/null >/dev/null || exit 1
+rm aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2>/dev/null >/dev/null || exit 1
+exit 0
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+ls -l $AFSROOT >/dev/null
+true
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+int
+main (int argc, char **argv)
+{
+ int mb = 10;
+ int ret;
+ size_t sz;
+ void *mmap_buf;
+
+ srand(getpid() * time(NULL));
+
+ sz = mb * 1024 * 1024;
+
+#ifdef MAP_ANON
+ mmap_buf = mmap (NULL, sz, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0);
+#else
+ {
+ int fd;
+
+ fd = open ("/dev/zero", O_RDWR);
+ if (fd < 0)
+ err (1, "open /dev/zero");
+ mmap_buf = mmap (NULL, sz, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fd, 0);
+ close (fd);
+ }
+#endif
+ if (mmap_buf == (void *)MAP_FAILED)
+ err (1, "mmap");
+
+ while (1) {
+ int *foo = (int *) ((unsigned char *) mmap_buf + (((rand() % (sz - 9)) + 7) & ~7));
+ struct timeval tv = { 0, 1000} ;
+ *foo = 10;
+ select (0, NULL, NULL, NULL, &tv);
+ }
+
+ ret = munmap (mmap_buf, sz);
+ if (ret)
+ err (1, "munmap");
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+
+mkdir foobar || exit 1
+(cd foobar && $objdir/create-dirs 1000) || exit 1
+$objdir/rm-rf foobar || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+
+FS=${FS:-${objdir}/../appl/fs/fs}
+
+touch foo
+
+echo "foobar" > foo
+
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ ${FS} flush foo
+ cat foo > /dev/null || exit 1
+done
+
+rm foo
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+# $Id$
+
+$objdir/create-files 1000 0
--- /dev/null
+#!/bin/sh
+# $Id$
+
+$objdir/create-files 1000 10
--- /dev/null
+#!/bin/sh
+# $Id$
+
+touch foo
+
+for i in `awk 'BEGIN {for(i=0; i < 1000; ++i) printf "%d\n", i}' /dev/null`; do
+ echo "foo$i" >> foo || exit 1
+done
+
+rm foo
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+# $Id$
+
+$objdir/create-symlinks 1000
--- /dev/null
+#!/bin/sh
+# $Id$
+mkdir foo || exit 1
+echo hej > foo/1 || exit 1
+rmdir foo >/dev/null 2>&1
+test -d foo || exit 1
+rm -f foo/1 || exit 1
+rmdir foo || exit 1
+test -d foo && exit 1
+exit 0
--- /dev/null
+#!/bin/sh
+mkdir foo || exit 1
+ls -ld foo | awk '{if($2 != 2) { exit(1) }}' || exit 1
+mkdir foo/1 || exit 1
+ls -ld foo | awk '{if($2 != 3) { exit(1) }}' || exit 1
+mkdir foo/2 || exit 1
+ls -ld foo | awk '{if($2 != 4) { exit(1) }}' || exit 1
+rmdir foo/1 || exit 1
+ls -ld foo | awk '{if($2 != 3) { exit(1) }}' || exit 1
+rmdir foo/2 || exit 1
+ls -ld foo | awk '{if($2 != 2) { exit(1) }}' || exit 1
+rmdir foo || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+mkdir foobar || exit 1
+test -d foobar || exit 1
+test -d foobar/. || exit 1
+test -d foobar/.. || exit 1
+rmdir foobar || exit 1
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ struct stat dot_sb, sb;
+
+
+ ret = mkdir ("foo", 0777);
+ if (ret < 0)
+ err (1, "mkdir foo");
+ ret = lstat (".", &dot_sb);
+ if (ret < 0)
+ err (1, "lstat .");
+ ret = lstat ("foo", &sb);
+ if (ret < 0)
+ err (1, "lstat foo");
+ if (sb.st_nlink != 2)
+ errx (1, "sb.st_link != 2");
+ ret = lstat ("foo/.", &sb);
+ if (ret < 0)
+ err (1, "lstat foo/.");
+ if (sb.st_nlink != 2)
+ errx (1, "sb.st_link != 2");
+ ret = lstat ("foo/..", &sb);
+ if (ret < 0)
+ err (1, "lstat foo");
+ if (sb.st_nlink != dot_sb.st_nlink)
+ errx (1, "sb.st_link != dot_sb.st_nlink");
+ ret = rmdir ("foo");
+ if (ret < 0)
+ err (1, "rmdir foo");
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ struct stat dot_sb, sb;
+ int fd;
+
+ ret = mkdir ("foo", 0777);
+ if (ret < 0)
+ err (1, "mkdir foo");
+ ret = lstat (".", &dot_sb);
+ if (ret < 0)
+ err (1, "lstat .");
+ ret = lstat ("foo", &sb);
+ if (ret < 0)
+ err (1, "lstat foo");
+ if (sb.st_nlink != 2)
+ errx (1, "sb.st_link != 2");
+ ret = lstat ("foo/.", &sb);
+ if (ret < 0)
+ err (1, "lstat foo/.");
+ if (sb.st_nlink != 2)
+ errx (1, "sb.st_link != 2");
+ ret = lstat ("foo/..", &sb);
+ if (ret < 0)
+ err (1, "lstat foo");
+ if (sb.st_nlink != dot_sb.st_nlink)
+ errx (1, "sb.st_link != dot_sb.st_nlink");
+ ret = mkdir ("foo/bar", 0777);
+ if (ret < 0)
+ err (1, "mkdir bar");
+ fd = open ("foo/baz", O_CREAT|O_RDWR, 0600);
+ if (fd < 0)
+ err (1, "creat baz");
+ close(fd);
+ ret = lstat ("foo", &sb);
+ if (ret < 0)
+ err (1, "lstat foo");
+ if (sb.st_nlink != 3)
+ errx (1, "sb.st_link != 3");
+ ret = unlink ("foo/baz");
+ if (ret < 0)
+ err (1, "unlink baz");
+ ret = rmdir ("foo/bar");
+ if (ret < 0)
+ err (1, "rmdir bar");
+ ret = rmdir ("foo");
+ if (ret < 0)
+ err (1, "rmdir foo");
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . system:anyuser all || exit 1
+${FS} mkm root.cell root.cell || exit 1
+test -d root.cell || exit 1
+${FS} rmm root.cell || exit 1
+test -d root.cell && exit 1
+${FS} mkm root.cell root.cell || exit 1
+test -d root.cell || exit 1
+${FS} rmm root.cell || exit 1
+test -d root.cell && exit 1
+exit 0
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static char *
+generate_random_file (const char *filename,
+ unsigned npages,
+ unsigned pagesize,
+ int writep)
+{
+ int fd;
+ char *buf, *fbuf;
+ int i;
+ int prot;
+ int flags;
+ size_t sz = npages * pagesize;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ for (i = 0; i < npages; ++i)
+ memset (buf + pagesize * i, '0' + i, pagesize);
+
+ fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+
+ if (ftruncate (fd, sz) < 0)
+ err (1, "ftruncate");
+
+ prot = PROT_READ | PROT_WRITE;
+ flags = MAP_SHARED;
+
+ fbuf = mmap (0, sz, prot, flags, fd, 0);
+ if (fbuf == (void *)MAP_FAILED)
+ err (1, "mmap");
+
+ if (writep) {
+ if(write(fd, "hej\n", 4) != 4)
+ err(1, "write");
+ }
+
+ memcpy (fbuf, buf, sz);
+
+#if 0
+ if (msync (fbuf, sz, MS_SYNC))
+ err(1, "msync");
+#endif
+
+ if (munmap (fbuf, sz) != 0)
+ err (1, "munmap");
+
+ if (close (fd))
+ err (1, "close");
+ return buf;
+}
+
+static char *
+read_file (int fd, size_t sz)
+{
+ char *buf;
+ ssize_t ret;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+ ret = read (fd, buf, sz);
+ if (ret < 0)
+ err (1, "read");
+ if (ret != sz)
+ errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+ return buf;
+}
+
+static int
+test (const char *file, int writep)
+{
+ const size_t sz = 4 * getpagesize();
+ char *buf;
+ char *malloc_buf;
+ int fd;
+ int ret;
+
+ buf = generate_random_file (file, 4, getpagesize(), writep);
+
+ fd = open (file, O_RDONLY, 0);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ malloc_buf = read_file (fd, sz);
+ close (fd);
+ ret = memcmp (buf, malloc_buf, sz);
+ free (buf);
+
+ return ret;
+}
+
+
+int
+main (int argc, char **argv)
+{
+
+
+ srand (time(NULL));
+
+ if (test ("foo", 1) != 0)
+ errx (1, "test(1)");
+ if (test ("bar", 0) != 0)
+ errx (1, "test(2)");
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void
+doit_mmap(int fd, struct stat *sb)
+{
+ void *mmap_buf;
+ int ret;
+
+ mmap_buf = mmap (NULL, sb->st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (mmap_buf == (void *)MAP_FAILED)
+ err (1, "mmap");
+ ret = write (1, mmap_buf, sb->st_size);
+ if (ret != sb->st_size)
+ err(1, "write returned %d wanted to write %d",
+ ret, (int)sb->st_size);
+ munmap(mmap_buf, sb->st_size);
+}
+
+
+static void
+doit_read(int fd, struct stat *sb)
+{
+ int ret;
+ void *read_buf;
+
+ read_buf = malloc(sb->st_size);
+ if (read_buf == NULL)
+ err(1, "malloc(%d)", (int)sb->st_size);
+ ret = read(fd, read_buf, sb->st_size);
+ if (ret != sb->st_size)
+ err(1, "read returned %d wanted to write %d",
+ ret, (int)sb->st_size);
+ ret = write (1, read_buf, sb->st_size);
+ if (ret != sb->st_size)
+ err(1, "write returned %d wanted to write %d",
+ ret, (int)sb->st_size);
+ free(read_buf);
+}
+
+static void
+doit (const char *filename, void (*func)(int, struct stat *))
+{
+ struct stat sb;
+ int fd;
+ int ret;
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0)
+ err(1, "open %s", filename);
+ ret = fstat (fd, &sb);
+ (*func)(fd, &sb);
+ if (ret < 0)
+ err (1, "stat %s", filename);
+ close (fd);
+}
+
+static int read_flag;
+static int mmap_flag;
+static int help_flag;
+
+static void
+usage (int exit_val)
+{
+ fprintf(stderr, "mmap-cat [-m|-r] filename\n");
+ exit (exit_val);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (argc != 2)
+ usage(1);
+
+ if (!strcmp(argv[1],"-m")) {
+ mmap_flag++;
+ } else
+ if (!strcmp(argv[1],"-r")) {
+ read_flag++;
+ } else
+ usage (1);
+
+ if (read_flag && mmap_flag)
+ errx(1, "can't do both mmap and read");
+
+ if (read_flag)
+ doit(argv[0], doit_read);
+ if (mmap_flag)
+ doit(argv[0], doit_mmap);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+doit (const char *filename)
+{
+ int fd;
+ size_t sz = getpagesize ();
+ void *v;
+
+ fd = open (filename, O_RDWR | O_CREAT, 0600);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ if (ftruncate (fd, sz) < 0)
+ err (1, "ftruncate %s", filename);
+ v = mmap (NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (v == (void *)MAP_FAILED)
+ err (1, "mmap %s", filename);
+
+ memset (v, 'z', sz);
+
+ msync (v, sz, MS_SYNC);
+
+ if (close (fd) < 0)
+ err (1, "close %s", filename);
+ return 0;
+}
+
+static void
+usage(void)
+{
+ errx (1, "usage: [filename]");
+}
+
+int
+main (int argc, char **argv)
+{
+ const char *filename = "foo";
+
+
+ if (argc != 1 && argc != 2)
+ usage ();
+
+ if (argc == 2)
+ filename = argv[1];
+
+ return doit (filename);
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int debug = 0;
+
+static void
+generate_file (const char *filename, int randomp, size_t sz)
+{
+ int fd;
+ char *buf;
+ int i;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ fd = open (filename, O_WRONLY | O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+
+ for (i = 0; i < sz; ++i)
+ if (randomp)
+ buf[i] = rand();
+ else
+ buf[0] = 0;
+
+ if (write (fd, buf, sz) != sz)
+ err (1, "write");
+ if (close (fd))
+ err (1, "close");
+ free (buf);
+}
+
+static char *
+read_file (int fd, size_t sz)
+{
+ char *buf;
+ ssize_t ret;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+ ret = read (fd, buf, sz);
+ if (ret < 0)
+ err(1, "read");
+ if (ret != sz)
+ errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+ return buf;
+}
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void *
+mmap_file (int fd, size_t sz)
+{
+ void *ret;
+
+ ret = mmap (0, sz, PROT_READ, MAP_SHARED, fd, 0);
+ if (ret == (void *)MAP_FAILED)
+ err (1, "mmap");
+ return ret;
+}
+
+static void __attribute__ ((__unused__))
+print_area (unsigned char *ptr, size_t len)
+{
+ while (len--) {
+ printf ("%x", *ptr);
+ ptr++;
+ }
+}
+
+static int
+do_test (int randomp)
+{
+ unsigned char *malloc_buf;
+ void *mmap_buf;
+ int fd;
+ const char *file = "foo";
+ const size_t sz = 4 * getpagesize();
+
+ generate_file (file, randomp, sz);
+
+ fd = open (file, O_RDONLY, 0);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ mmap_buf = mmap_file (fd, sz);
+ malloc_buf = read_file (fd, sz);
+ close (fd);
+ unlink (file);
+ if (memcmp (malloc_buf, mmap_buf, sz) != 0) {
+ if (debug) {
+ printf ("type: %s\n", randomp ? "random" : "allzero");
+ printf ("read: ");
+ print_area (malloc_buf, sz);
+ printf ("\nmmap: ");
+ print_area (mmap_buf, sz);
+ printf ("\n");
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+
+ if (argc != 1)
+ debug = 1;
+
+ srand (time(NULL));
+
+ if (do_test (0))
+ return 1;
+ if (do_test (1))
+ return 2;
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int debug = 0;
+
+static void
+generate_file (const char *filename, int randomp, size_t sz)
+{
+ int fd;
+ char *buf;
+ int i;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ fd = open (filename, O_WRONLY | O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+
+ for (i = 0; i < sz; ++i)
+ if (randomp)
+ buf[i] = rand();
+ else
+ buf[0] = 0;
+
+ if (write (fd, buf, sz) != sz)
+ err (1, "write");
+ if (close (fd))
+ err (1, "close");
+ free (buf);
+}
+
+static unsigned char *
+read_file (int fd, size_t sz)
+{
+ unsigned char *buf;
+ ssize_t ret;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+ ret = read(fd, buf, sz);
+ if(ret < 0)
+ err(1, "read");
+ if (ret != sz)
+ errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+ return buf;
+}
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void *
+mmap_file (int fd, size_t sz)
+{
+ void *ret;
+
+ ret = mmap (0, sz, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (ret == (void *)MAP_FAILED)
+ err (1, "mmap");
+ return ret;
+}
+
+static void __attribute__ ((__unused__))
+print_area (unsigned char *ptr, size_t len)
+{
+ while (len--) {
+ printf ("%x", *ptr);
+ ptr++;
+ }
+}
+
+static int
+do_test (int randomp)
+{
+ unsigned char *malloc_buf;
+ void *mmap_buf;
+ int fd;
+ const char *file = "foo";
+ const size_t sz = 3 * getpagesize() / 2;
+
+ generate_file (file, randomp, sz);
+
+ fd = open (file, O_RDONLY, 0);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ mmap_buf = mmap_file (fd, sz);
+ malloc_buf = read_file (fd, sz);
+ close (fd);
+ unlink (file);
+ if (memcmp (malloc_buf, mmap_buf, sz) != 0) {
+ if (debug) {
+ printf ("type: %s\n", randomp ? "random" : "allzero");
+ printf ("read: ");
+ print_area (malloc_buf, sz);
+ printf ("\nmmap: ");
+ print_area (mmap_buf, sz);
+ printf ("\n");
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+
+ if (argc != 1)
+ debug = 1;
+
+ srand (time(NULL));
+
+ if (do_test (0))
+ return 1;
+ if (do_test (1))
+ return 2;
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . system:anyuser all || exit 1
+${FS} mkm no-such-volume no-such-volume 2>/dev/null || exit 1
+if ls no-such-volume 2>/dev/null && touch no-such-volume/foo 2>/dev/null; then
+ ${FS} rmm no-such-volume; exit 1
+fi
+${FS} rmm no-such-volume || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/test-parallel1 1>&4
+
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+#define LOCK "mailbox-name.lock"
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ struct stat sb;
+ char unique[1024];
+ int retrycount = 0;
+
+
+ snprintf (unique, sizeof(unique), LOCK ".%d.%d",
+ getpid(), (int)time(NULL));
+
+ ret = umask(077);
+ if (ret < 0)
+ err (1, "umask");
+
+ ret = open(unique, O_WRONLY|O_CREAT|O_EXCL, 0666);
+ if (ret < 0)
+ errx (1, "open");
+
+ close (ret);
+
+ retry:
+ retrycount++;
+ if (retrycount > 10000000)
+ errx (1, "failed getting the lock");
+ ret = link(unique, LOCK);
+ if (ret < 0)
+ goto retry;
+
+ ret = stat(unique, &sb);
+ if (ret < 0)
+ errx (1, "stat");
+
+ if (sb.st_nlink != 2)
+ goto retry;
+
+ ret = chmod (LOCK, 0666);
+ if (ret < 0)
+ errx (1, "chmod");
+
+ ret = unlink (LOCK);
+ if (ret < 0)
+ err (1, "unlink " LOCK);
+
+ ret = unlink (unique);
+ if (ret < 0)
+ err (1, "unlink: %s", unique);
+
+ return 0;
+}
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.ph for use and distribution information
+#
+#: * pts.pm - Wrappers around PTS commands (user/group maintenance)
+#: * This module provides wrappers around the various PTS commands, giving
+#: * them a nice perl-based interface. Someday, they might talk to the
+#: * ptserver directly instead of using 'pts', but not anytime soon.
+#:
+
+package OpenAFS::pts;
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use OpenAFS::wrapper;
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_pts_createuser &AFS_pts_listmax
+ &AFS_pts_creategroup &AFS_pts_setmax
+ &AFS_pts_delete &AFS_pts_add
+ &AFS_pts_rename &AFS_pts_remove
+ &AFS_pts_examine &AFS_pts_members
+ &AFS_pts_chown &AFS_pts_listown
+ &AFS_pts_setf);
+
+
+#: AFS_pts_createuser($user, [$id], [$cell])
+#: Create a PTS user with $user as its name.
+#: If specified, use $id as the PTS id; otherwise, AFS picks one.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return the PTS id of the newly-created user.
+#:
+$AFS_Help{pts_createuser} = '$user, [$id], [$cell] => $uid';
+sub AFS_pts_createuser {
+ my($user, $id, $cell) = @_;
+ my(@args, $uid);
+
+ @args = ('createuser', '-name', $user);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ push(@args, '-id', $id) if ($id);
+ &wrapper('pts', \@args, [[ '^User .* has id (\d+)', \$uid ]]);
+ $uid;
+}
+
+
+#: AFS_pts_creategroup($group, [$id], [$owner], [$cell])
+#: Create a PTS group with $group as its name.
+#: If specified, use $id as the PTS id; otherwise, AFS picks one.
+#: If specified, use $owner as the owner, instead of the current user.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return the PTS id of the newly-created group.
+#:
+$AFS_Help{pts_creategroup} = '$group, [$id], [$owner], [$cell] => $gid';
+sub AFS_pts_creategroup {
+ my($group, $id, $owner, $cell) = @_;
+ my(@args, $uid);
+
+ @args = ('creategroup', '-name', $group);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ push(@args, '-id', $id) if ($id);
+ push(@args, '-owner', $owner) if ($owner);
+ &wrapper('pts', \@args, [[ '^group .* has id (\-\d+)', \$uid ]]);
+ $uid;
+}
+
+
+#: AFS_pts_delete(\@objs, [$cell])
+#: Attempt to destroy PTS objects listed in @objs.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#: If multiple objects are specified and only some are destroyed, some
+#: operations may be left untried.
+#:
+$AFS_Help{pts_delete} = '\@objs, [$cell] => Success?';
+sub AFS_pts_delete {
+ my($objs, $cell) = @_;
+ my(@args);
+
+ @args = ('delete', '-nameorid', @$objs);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+
+#: AFS_pts_rename($old, $new, [$cell])
+#: Rename the PTS object $old to have the name $new.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{pts_rename} = '$old, $new, [$cell] => Success?';
+sub AFS_pts_rename {
+ my($old, $new, $cell) = @_;
+ my(@args);
+
+ @args = ('rename', '-oldname', $old, '-newname', $new);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+
+#: AFS_pts_examine($obj, [$cell])
+#: Examine the PTS object $obj, and return information about it.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return an associative array with some or all of the following:
+#: - name Name of this object
+#: - id ID of this object
+#: - owner Name or ID of owner
+#: - creator Name or ID of creator
+#: - mem_count Number of members (group) or memberships (user)
+#: - flags Privacy/access flags (as a string)
+#: - group_quota Remaining group quota
+#:
+$AFS_Help{pts_examine} = '$obj, [$cell] => %info';
+sub AFS_pts_examine {
+ my($obj, $cell) = @_;
+ my(@args);
+
+ @args = ('examine', '-nameorid', $obj);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args,
+ [[ '^Name\: (.*)\, id\: ([\-0-9]+)\, owner\: (.*)\, creator\: (.*)\,$', #',
+ 'name', 'id', 'owner', 'creator' ],
+ [ '^ membership\: (\d+)\, flags\: (.....)\, group quota\: (\d+)\.$', #',
+ 'mem_count', 'flags', 'group_quota' ]
+ ]);
+}
+
+
+#: AFS_pts_chown($obj, $owner, [$cell])
+#: Change the owner of the PTS object $obj to be $owner.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{pts_chown} = '$obj, $owner, [$cell] => Success?';
+sub AFS_pts_chown {
+ my($obj, $owner, $cell) = @_;
+ my(@args);
+
+ @args = ('chown', '-name', $obj, '-owner', $owner);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+
+#: AFS_pts_setf($obj, [$access], [$gquota], [$cell])
+#: Change the access flags and/or group quota for the PTS object $obj.
+#: If specified, $access specifies the new access flags in the standard 'SOMAR'
+#: format; individual flags may be specified as '.' to keep the current value.
+#: If specified, $gquota specifies the new group quota.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{pts_setf} = '$obj, [$access], [$gquota], [$cell] => Success?';
+sub AFS_pts_setf {
+ my($obj, $access, $gquota, $cell) = @_;
+ my(%result, @args);
+
+ @args = ('setfields', '-nameorid', $obj);
+ push(@args, '-groupquota', $gquota) if ($gquota ne '');
+ if ($access) {
+ my(@old, @new, $i);
+ # Ensure access is 5 characters
+ if (length($access) < 5) {
+ $access .= ('.' x (5 - length($access)));
+ } elsif (length($access) > 5) {
+ substr($access, 5) = '';
+ }
+
+ %result = &AFS_pts_examine($obj, $cell);
+
+ @old = split(//, $result{'flags'});
+ @new = split(//, $access);
+ foreach $i (0 .. 4) {
+ $new[$i] = $old[$i] if ($new[$i] eq '.');
+ }
+ $access = join('', @new);
+ if ($access ne $result{'flags'}) {
+ push(@args, '-access', $access);
+ }
+ }
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+
+#: AFS_pts_listmax([$cell])
+#: Fetch the maximum assigned group and user ID.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, returns (maxuid, maxgid)
+#:
+$AFS_Help{pts_listmax} = '[$cell] => ($maxuid, $maxgid)';
+sub AFS_pts_listmax {
+ my($cell) = @_;
+ my(@args, $uid, $gid);
+
+ @args = ('listmax');
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args,
+ [[ '^Max user id is (\d+) and max group id is (\-\d+).',
+ \$uid, \$gid ]]);
+ ($uid, $gid);
+}
+
+
+#: AFS_pts_setmax([$maxuser], [$maxgroup], [$cell])
+#: Set the maximum assigned group and/or user ID.
+#: If specified, $maxuser is the new maximum user ID
+#: If specified, $maxgroup is the new maximum group ID
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{pts_setmax} = '[$maxuser], [$maxgroup], [$cell] => Success?';
+sub AFS_pts_setmax {
+ my($maxuser, $maxgroup, $cell) = @_;
+ my(@args);
+
+ @args = ('setmax');
+ push(@args, '-group', $maxgroup) if ($maxgroup);
+ push(@args, '-user', $maxuser) if ($maxuser);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+#: AFS_pts_add(\@users, \@groups, [$cell])
+#: Add users specified in @users to groups specified in @groups.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#: If multiple users and/or groups are specified and only some memberships
+#: are added, some operations may be left untried.
+#:
+$AFS_Help{pts_add} = '\@users, \@groups, [$cell] => Success?';
+sub AFS_pts_add {
+ my($users, $groups, $cell) = @_;
+ my(@args);
+
+ @args = ('adduser', '-user', @$users, '-group', @$groups);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+
+#: AFS_pts_remove(\@users, \@groups, [$cell])
+#: Remove users specified in @users from groups specified in @groups.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return 1.
+#: If multiple users and/or groups are specified and only some memberships
+#: are removed, some operations may be left untried.
+#:
+$AFS_Help{pts_remove} = '\@users, \@groups, [$cell] => Success?';
+sub AFS_pts_remove {
+ my($users, $groups, $cell) = @_;
+ my(@args);
+
+ @args = ('removeuser', '-user', @$users, '-group', @$groups);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args);
+ 1;
+}
+
+
+#: AFS_pts_members($obj, [$cell])
+#: If $obj specifies a group, retrieve a list of its members.
+#: If $obj specifies a user, retrieve a list of groups to which it belongs.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return the resulting list.
+#:
+$AFS_Help{pts_members} = '$obj, [$cell] => @members';
+sub AFS_pts_members {
+ my($obj, $cell) = @_;
+ my(@args, @grouplist);
+
+ @args = ('membership', '-nameorid', $obj);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args, [[ '^ (.*)', \@grouplist ]]);
+ @grouplist;
+}
+
+
+#: AFS_pts_listown($owner, [$cell])
+#: Retrieve a list of PTS groups owned by the PTS object $obj.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return the resulting list.
+#:
+$AFS_Help{pts_listown} = '$owner, [$cell] => @owned';
+sub AFS_pts_listown {
+ my($owner, $cell) = @_;
+ my(@args, @grouplist);
+
+ @args = ('listowned', '-nameorid', $owner);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('pts', \@args, [[ '^ (.*)', \@grouplist ]]);
+ @grouplist;
+}
+
+
+1;
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_add([testuser1],[testgroup1],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_chown(testgroup1,testuser1,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_creategroup(testgroup1,,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_createuser(testuser1,,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_delete([testgroup1],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_delete([testuser1],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (%info);
+&AFS_Init();
+
+%info = &AFS_pts_examine(testgroup1,);
+if ($info{'creator'} ne "admin") {
+ exit(1);
+}
+if ($info{'mem_count'} != 1) {
+ exit(1);
+}
+if ($info{'owner'} ne "testuser1") {
+ exit(1);
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (%info);
+&AFS_Init();
+
+%info = &AFS_pts_examine(testuser1,);
+if ($info{'creator'} ne "admin") {
+ exit(1);
+}
+if ($info{'mem_count'} != 1) {
+ exit(1);
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (@info);
+&AFS_Init();
+
+@info = &AFS_pts_listmax();
+if ($info[0] != 100) {
+ exit(1);
+}
+if ($info[1] != -300) {
+ exit(1);
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (@owned, $group);
+&AFS_Init();
+
+@owned = &AFS_pts_listown(testuser1,);
+while ($group = pop(@owned)) {
+ if ($group ne "testgroup1") {
+ exit(1);
+ }
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (@membership, $group);
+&AFS_Init();
+
+@membership = &AFS_pts_members(testgroup1,);
+while ($group = pop(@membership)) {
+ if ($group ne "testuser1") {
+ exit(1);
+ }
+}
+&AFS_pts_add([admin],[testgroup1],);
+@membership = &AFS_pts_members(testgroup1,);
+while ($group = pop(@membership)) {
+ if ($group eq "testuser1") {
+ } else {
+ if ($group eq "admin") {
+ } else {
+ exit(1);
+ }
+ }
+}
+&AFS_pts_remove([admin],["testgroup1"],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (@membership, $group);
+&AFS_Init();
+
+@membership = &AFS_pts_members(testuser1,);
+while ($group = pop(@membership)) {
+ if ($group ne "testgroup1") {
+ exit(1);
+ }
+}
+&AFS_pts_add([testuser1],["system:administrators"],);
+@membership = &AFS_pts_members(testuser1,);
+while ($group = pop(@membership)) {
+ if ($group eq "testgroup1") {
+ } else {
+ if ($group eq "system:administrators") {
+ } else {
+ exit(1);
+ }
+ }
+}
+&AFS_pts_remove([testuser1],["system:administrators"],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_remove([testuser1],[testgroup1],);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my (%info);
+&AFS_Init();
+
+&AFS_pts_setf(testuser1,"S-M--",30,);
+%info = &AFS_pts_examine(testuser1,);
+if ($info{'creator'} ne "admin") {
+ exit(1);
+}
+if ($info{'flags'} ne "S-M--") {
+ exit(1);
+}
+if ($info{'group_quota'} != 30) {
+ exit(1);
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+&AFS_Init();
+
+&AFS_pts_setmax(100,-300,);
+
+exit(0);
+
+
+
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int debug = 0;
+
+static void
+generate_file (const char *filename, int randomp, size_t sz)
+{
+ int fd;
+ char *buf;
+ int i;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ fd = open (filename, O_WRONLY | O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+
+ for (i = 0; i < sz; ++i)
+ if (randomp)
+ buf[i] = rand();
+ else
+ buf[0] = 0;
+
+ if (write (fd, buf, sz) != sz)
+ err (1, "write");
+ if (close (fd))
+ err (1, "close");
+ free (buf);
+}
+
+static unsigned char *
+read_file (int fd, size_t sz)
+{
+ unsigned char *buf;
+ ssize_t ret;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+ ret = read(fd, buf, sz);
+ if(ret < 0)
+ err(1, "read");
+ if(ret != sz)
+ errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+ return buf;
+}
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void *
+mmap_file (int fd, size_t sz)
+{
+ void *ret;
+
+ ret = mmap (0, sz, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (ret == (void *)MAP_FAILED)
+ err (1, "mmap");
+ return ret;
+}
+
+static void __attribute__ ((__unused__))
+print_area (unsigned char *ptr, size_t len)
+{
+ while (len--) {
+ printf ("%x", *ptr);
+ ptr++;
+ }
+}
+
+static int
+do_test (int randomp)
+{
+ unsigned char *malloc_buf;
+ void *mmap_buf;
+ int fd;
+ const char *file = "foo";
+ const size_t sz = 16384;
+
+ generate_file (file, randomp, sz);
+
+ fd = open (file, O_RDONLY, 0);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ malloc_buf = read_file (fd, sz);
+ mmap_buf = mmap_file (fd, sz);
+ close (fd);
+ unlink (file);
+ if (memcmp (malloc_buf, mmap_buf, sz) != 0) {
+ if (debug) {
+ printf ("type: %s\n", randomp ? "random" : "allzero");
+ printf ("read: ");
+ print_area (malloc_buf, sz);
+ printf ("\nmmap: ");
+ print_area (mmap_buf, sz);
+ printf ("\n");
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc != 1)
+ debug = 1;
+
+ srand (time(NULL));
+
+ if (do_test (0))
+ return 1;
+ if (do_test (1))
+ return 2;
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static void
+generate_random_file (const char *filename, size_t sz)
+{
+ int fd;
+ char *buf;
+ int i;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ fd = open (filename, O_WRONLY | O_CREAT, 0666);
+ if (fd < 0)
+ err (1, "open %s", filename);
+
+ for (i = 0; i < sz; ++i)
+ buf[i] = rand();
+
+ if (write (fd, buf, sz) != sz)
+ err (1, "write");
+ if (close (fd))
+ err (1, "close");
+ free (buf);
+}
+
+static char *
+read_file (int fd, size_t sz)
+{
+ char *buf;
+ ssize_t ret;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+ ret = read(fd, buf, sz);
+ if(ret < 0)
+ err(1, "read");
+ if(ret != sz)
+ errx(1, "short read %d < %u", (int)ret, (unsigned)sz);
+ return buf;
+}
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void *
+mmap_file (int fd, size_t sz)
+{
+ void *ret;
+
+ ret = mmap (0, sz, PROT_READ, MAP_SHARED, fd, 0);
+ if (ret == (void *)MAP_FAILED)
+ err (1, "mmap");
+ return ret;
+}
+
+int
+main (int argc, char **argv)
+{
+ const char *file = "foo";
+ const size_t sz = 16384;
+ char *malloc_buf;
+ void *mmap_buf;
+ int fd;
+
+ srand (time(NULL));
+
+ generate_random_file (file, sz);
+
+ fd = open (file, O_RDONLY, 0);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ malloc_buf = read_file (fd, sz);
+ mmap_buf = mmap_file (fd, sz);
+ close (fd);
+ unlink (file);
+ if (memcmp (malloc_buf, mmap_buf, sz) != 0)
+ return 1;
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static char *
+write_random_file (int fd, size_t sz)
+{
+ char *buf;
+ int i;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ for (i = 0; i < sz; ++i)
+ buf[i] = rand();
+
+ if (write (fd, buf, sz) != sz)
+ err (1, "write");
+
+ return buf;
+}
+
+static void
+write_null_file (int fd, size_t sz)
+{
+ char *buf;
+ int i;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ for (i = 0; i < sz; ++i)
+ buf[i] = 0;
+
+ if (write (fd, buf, sz) != sz)
+ err (1, "write");
+
+ free (buf);
+}
+
+static char *
+read_file (int fd, size_t sz)
+{
+ char *buf;
+ ssize_t ret;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+ ret = read(fd, buf, sz);
+ if(ret < 0)
+ err (1, "read");
+ else if(ret == 0)
+ errx(1, "EOF on read");
+ return buf;
+}
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+int
+main (int argc, char **argv)
+{
+ const char *file = "foo";
+ const size_t sz = 16384;
+ char *random_buf;
+ char *read_buf1;
+ char *read_buf2;
+ int fd;
+
+
+ srand (time(NULL));
+
+ fd = open (file, O_RDWR | O_CREAT, 0);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err (1, "lseek");
+ write_null_file(fd, sz);
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err (1, "lseek");
+ read_buf1 = read_file (fd, sz);
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err (1, "lseek");
+ random_buf = write_random_file(fd, sz);
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err (1, "lseek");
+ read_buf2 = read_file (fd, sz);
+
+ close (fd);
+ unlink (file);
+ if (memcmp (random_buf, read_buf2, sz) != 0)
+ return 1;
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static int
+verify_inodes (const char *dirname)
+{
+ DIR *d;
+ struct dirent *dp;
+
+ if (chdir (dirname) < 0)
+ err (1, "chdir %s", dirname);
+
+ d = opendir (".");
+ if (d == NULL)
+ err (1, "opendir %s", dirname);
+ while ((dp = readdir (d)) != NULL) {
+ struct stat sb;
+
+ if (lstat (dp->d_name, &sb) < 0) {
+ if (errno == EACCES)
+ continue;
+ err (1, "lstat %s", dp->d_name);
+ }
+ if (dp->d_ino != sb.st_ino)
+ errx (1, "%s: inode %u != %u", dp->d_name,
+ (unsigned)dp->d_ino, (unsigned)sb.st_ino);
+ }
+ closedir (d);
+ return 0;
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s [directory]\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *name = ".";
+
+
+ if (argc > 2)
+ usage (1);
+
+ if (argc > 1)
+ name = argv[1];
+
+ return verify_inodes (name);
+}
--- /dev/null
+#!/bin/sh
+FOO=`cat $AFSROOT/stacken.kth.se/ftp/pub/arla/tests/used-by-arla-check`
+test "X"$FOO = "Xfoo" || exit 1
--- /dev/null
+#!/usr/bin/env perl -w
+use Term::ReadLine;
+use strict;
+use OpenAFS::ConfigUtils;
+use OpenAFS::Dirpath;
+use OpenAFS::OS;
+use OpenAFS::Auth;
+use Getopt::Long;
+use vars qw($admin $server $cellname $cachesize $part
+ $requirements_met $shutdown_needed $csdb);
+
+&OpenAFS::Auth::authadmin();
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#define RETSIGTYPE void
+
+static void
+emkdir (const char *path, mode_t mode)
+{
+ int ret = mkdir (path, mode);
+ if (ret < 0)
+ err (1, "mkdir %s", path);
+}
+
+static pid_t child_pid;
+
+static sig_atomic_t term_sig = 0;
+
+static RETSIGTYPE
+child_sigterm (int signo)
+{
+ term_sig = 1;
+}
+
+static int
+child_chdir (const char *path)
+{
+ int ret;
+ int pfd[2];
+
+ ret = pipe (pfd);
+ if (ret < 0)
+ err (1, "pipe");
+
+ child_pid = fork ();
+ if (child_pid < 0)
+ err (1, "fork");
+ if (child_pid != 0) {
+ close (pfd[1]);
+ return pfd[0];
+ } else {
+ char buf[256];
+ struct sigaction sa;
+ FILE *fp;
+
+ sa.sa_handler = child_sigterm;
+ sigfillset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction (SIGTERM, &sa, NULL);
+
+ close (pfd[0]);
+ ret = chdir (path);
+ if (ret < 0)
+ err (1, "chdir %s", path);
+ ret = write (pfd[1], "", 1);
+ if (ret != 1)
+ err (1, "write");
+ while (!term_sig)
+ pause ();
+#if 0
+ if(getcwd (buf, sizeof(buf)) == NULL)
+ err (1, "getcwd");
+#endif
+ fp = fdopen (4, "w");
+ if (fp != NULL)
+ fprintf (fp, "child: cwd = %s\n", buf);
+ exit (0);
+ }
+}
+
+static void
+kill_child (void)
+{
+ kill (child_pid, SIGTERM);
+}
+
+int
+main (int argc, char **argv)
+{
+ struct stat sb;
+ int ret;
+ int fd;
+ char buf[1];
+ int status;
+
+
+ emkdir ("one", 0777);
+ emkdir ("two", 0777);
+ emkdir ("one/a", 0777);
+
+ fd = child_chdir ("one/a");
+ atexit (kill_child);
+ ret = read (fd, buf, 1);
+ if (ret < 0)
+ err(1, "read");
+ if (ret == 0)
+ errx(1, "EOF on read");
+
+ ret = rename ("one/a", "two/a");
+ if (ret < 0)
+ err (1, "rename one/a two");
+ ret = lstat ("two/a", &sb);
+ if (ret < 0)
+ err (1, "lstat two/a");
+ ret = lstat ("one/a", &sb);
+ if (ret != -1 || errno != ENOENT)
+ errx (1, "one/a still exists");
+ kill_child ();
+ waitpid (child_pid, &status, 0);
+ ret = lstat ("one/a", &sb);
+ if (ret != -1 || errno != ENOENT)
+ errx (1, "one/a still exists after child");
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ rmdir ("one/a");
+ rmdir ("two/a");
+ rmdir ("one");
+ rmdir ("two");
+ return 0;
+ } else
+ return 1;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+touch foo || exit 1
+mv foo bar || exit 1
+test -f foo && exit 1
+test -f bar || exit 1
+rm bar || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+touch foo bar || exit 1
+mv foo bar || exit 1
+test -f foo && exit 1
+test -f bar || exit 1
+rm bar || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+echo foo > foo || exit 1
+sed 's/foo/bar/' foo > bar || exit 1
+rm foo || exit 1
+test -f foo && exit 1
+mv bar foo || exit 1
+test -f bar && exit 1
+test -f foo || exit 1
--- /dev/null
+#!/bin/sh
+# $Id$
+mkdir old_parent new_parent old_parent/victim || exit 1
+mv old_parent/victim new_parent || exit 1
+test -d old_parent || exit 1
+test -d new_parent || exit 1
+test -d old_parent/victim && exit 1
+test -d new_parent/victim || exit 1
+rmdir new_parent/victim new_parent old_parent
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+
+#include <err.h>
+
+static void
+emkdir (const char *path, mode_t mode)
+{
+ int ret;
+
+ ret = mkdir (path, mode);
+ if (ret < 0)
+ err (1, "mkdir %s", path);
+}
+
+static void
+elstat (const char *path, struct stat *sb)
+{
+ int ret;
+
+ ret = lstat (path, sb);
+ if (ret < 0)
+ err (1, "lstat %s", path);
+}
+
+static void
+check_inum (const struct stat *sb1, const struct stat *sb2)
+{
+ if (sb1->st_ino != sb2->st_ino)
+ errx (1, "wrong inode-number %u != %u",
+ (unsigned)sb1->st_ino, (unsigned)sb2->st_ino);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ struct stat old_sb, new_sb, dot_sb;
+
+ emkdir ("old_parent", 0777);
+ emkdir ("new_parent", 0777);
+ emkdir ("old_parent/victim", 0777);
+
+ elstat ("old_parent", &old_sb);
+ elstat ("new_parent", &new_sb);
+ elstat ("old_parent/victim/..", &dot_sb);
+ check_inum (&old_sb, &dot_sb);
+
+ ret = rename("old_parent/victim", "new_parent/victim");
+ if (ret < 0)
+ err (1, "rename old_parent/victim new_parent/victim");
+
+ elstat ("new_parent/victim/..", &dot_sb);
+
+ check_inum (&new_sb, &dot_sb);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+
+#include <err.h>
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ int fd;
+ struct stat old_sb, new_sb, dot_sb;
+
+ fd = open("foo", O_RDWR|O_CREAT|O_TRUNC, 0644);
+ if (fd < 0)
+ err (1, "open1");
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close1");
+
+ ret = rename("foo", "../../service/foo");
+ if (ret == 0)
+ err (1, "rename didn't fail");
+
+ unlink("foo");
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+emacsver=20.7
+gzip -dc ${AFSROOT}/stacken.kth.se/ftp/pub/gnu/emacs/emacs-${emacsver}.tar.gz |
+tar vxf - >&4 2>&1 || exit 1
+find emacs-${emacsver} -size 0 -print | xargs rm || exit 1
+find emacs-${emacsver} -print | xargs chmod u+w || exit 1
+$objdir/truncate-files emacs-${emacsver} || exit 1
+exit 0
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static void
+kill_one (const char *filename);
+
+static void
+kill_dir (const char *dirname);
+
+static void
+do_dir (const char *dirname);
+
+static void
+kill_one (const char *filename)
+{
+ int ret;
+
+ ret = unlink (filename);
+ if (ret < 0) {
+ if (errno == EISDIR || errno == EPERM)
+ do_dir (filename);
+ else
+ err (1, "unlink %s", filename);
+ }
+}
+
+static void
+do_dir (const char *dirname)
+{
+ int ret;
+
+ ret = fs_rmmount (dirname);
+ if (ret == 0)
+ return;
+
+ ret = chdir (dirname);
+ if (ret < 0)
+ err (1, "chdir %s", dirname);
+ kill_dir (dirname);
+ ret = chdir ("..");
+ if (ret < 0)
+ err (1, "chdir ..");
+ ret = rmdir (dirname);
+ if (ret < 0)
+ err (1, "rmdir %s", dirname);
+}
+
+static void
+kill_dir (const char *dirname)
+{
+ DIR *dir;
+ struct dirent *dp;
+
+ dir = opendir (".");
+ if (dir == NULL)
+ err (1, "opendir %s", dirname);
+ while ((dp = readdir (dir)) != NULL) {
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ kill_one (dp->d_name);
+ }
+ closedir(dir);
+}
+
+int
+main(int argc, char **argv)
+{
+
+ if (argc < 2)
+ errx (1, "usage: %s directory [...]", argv[0]);
+ while (argc >= 2) {
+ do_dir (argv[1]);
+ argc--;
+ argv++;
+ }
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+FS=${FS:-${objdir}/../appl/fs/fs}
+
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+${objdir}/fsx -N 25000 -RW -c 1 fsxtmp
+
--- /dev/null
+#!/bin/sh
+echo row1 > testfile
+echo log1 | ci -u testfile
+co -l testfile
+echo row2 >> testfile
+echo log2 | ci -u testfile
+co -l testfile
+echo row3 >> testfile
+echo log3 | ci -u testfile
+wc -l testfile | grep '3 testfile' || exit 1
+
--- /dev/null
+#!/bin/sh
+#
+# $Id$
+#
+srcdir=@srcdir@
+objdir=`pwd`
+SHELL=/bin/sh
+VERSION=@VERSION@
+PACKAGE=@PACKAGE@
+host=@host@
+RUNAS=nobody
+FS=/usr/local/bin/fs
+export FS
+
+AFSROOT=${AFSROOT-/afs}
+export AFSROOT
+
+BASIC_TESTS="creat1 \
+ mkdir1 \
+ mkdir2 \
+ symlink \
+ hardlink1 \
+ hardlink4 \
+ hardlink2 \
+ hardlink5 \
+ touch1 \
+ write1 \
+ write3 \
+ rename1 \
+ hardlink3 \
+ write2 \
+ append1 \
+ rename2 \
+ rename4 \
+ rename6 \
+ rename-under-feet \
+ large-filename \
+ fchmod \
+ utime-file \
+ utime-dir \
+ mkdir3"
+
+MTPT_TESTS="mkm-rmm \
+ mountpoint"
+
+ACL_TESTS="acladduser.pl \
+ acladdgroup.pl \
+ acladdrights.pl \
+ acladdnegrights.pl \
+ aclclearnegrights.pl \
+ aclremoveuser.pl \
+ aclremovegroup.pl \
+ aclcopy.pl"
+
+EXEC_TESTS="exec \
+ hello-world \
+ build-openafs"
+
+MMAP_TESTS="append-over-page \
+ mmap-shared-write \
+ mmap-vs-read2 \
+ mmap-vs-read \
+ read-vs-mmap2 \
+ read-vs-mmap"
+
+FS_TESTS="strange-characters \
+ pine \
+ parallel1 \
+ write-large"
+
+AFS_TESTS="write-ro \
+ too-many-files \
+ setpag \
+ setgroups"
+
+RMT_TESTS="extcopyin \
+ extcopyout"
+
+ABUSE_TESTS="read-write \
+ create-remove-files \
+ run-fsx"
+
+PTS_TESTS="ptscreateuser.pl \
+ ptscreategroup.pl \
+ ptsadduser.pl \
+ ptschown.pl \
+ ptsmembersuser.pl \
+ ptsmembersgroup.pl \
+ ptsexamineuser.pl \
+ ptsexaminegroup.pl \
+ ptsremove.pl \
+ ptslistown.pl \
+ ptssetmax.pl \
+ ptslistmax.pl \
+ ptssetf.pl \
+ ptsdeletegroup.pl \
+ ptsdeleteuser.pl"
+
+VOS_TESTS="voscreate.pl \
+ vosmove.pl \
+ vosaddsite.pl \
+ vosrelease.pl \
+ vosremsite.pl \
+ vosremove.pl \
+ vosdelentry.pl \
+ vossyncvldb.pl \
+ voszap.pl \
+ vossyncserv.pl \
+ voslock.pl \
+ vosunlock.pl \
+ vosunlockall.pl \
+ vosrename.pl \
+ voslistvol.pl \
+ voslistvldb.pl \
+ vospartinfo.pl \
+ voslistpart.pl \
+ vosbackup.pl \
+ vosexamine.pl \
+ vosdump.pl \
+ vosrestore.pl"
+
+BOS_TESTS="bosaddhost.pl \
+ boslisthosts.pl \
+ bosremovehost.pl \
+ bosadduser.pl \
+ boslistusers.pl \
+ bosremoveuser.pl \
+ bosinstall.pl \
+ bosexec.pl \
+ boscreate.pl \
+ bosdeleterunning.pl \
+ bosstatus.pl \
+ bosstop.pl \
+ bosrestartstopped.pl \
+ bosstart.pl \
+ bosshutdown.pl \
+ bosdelete.pl \
+ bosaddkey.pl \
+ boslistkeys.pl \
+ bosremovekey.pl \
+ bossalvagevolume.pl \
+ bossalvagepart.pl \
+ bossalvageserver.pl"
+
+REG_TESTS="fcachesize-write-file \
+ fcachesize-read-file"
+
+ALL_TESTS="creat1 \
+ mkdir1 \
+ mkdir2 \
+ symlink \
+ hardlink1 \
+ hardlink4 \
+ hardlink2 \
+ hardlink5 \
+ touch1 \
+ write1 \
+ write3 \
+ rename1 \
+ hardlink3 \
+ write2 \
+ append1 \
+ rename2 \
+ rename4 \
+ rename6 \
+ rename-under-feet \
+ large-filename \
+ fchmod \
+ utime-file \
+ utime-dir \
+ mkdir3 \
+ mkm-rmm \
+ mountpoint \
+ acladduser.pl \
+ acladdgroup.pl \
+ acladdrights.pl \
+ acladdnegrights.pl \
+ aclclearnegrights.pl \
+ aclremoveuser.pl \
+ aclremovegroup.pl \
+ aclcopy.pl \
+ exec \
+ hello-world \
+ build-openafs \
+ append-over-page \
+ mmap-shared-write \
+ mmap-vs-read2 \
+ mmap-vs-read \
+ read-vs-mmap2 \
+ read-vs-mmap \
+ strange-characters \
+ pine \
+ parallel1 \
+ write-large \
+ write-ro \
+ too-many-files \
+ setpag \
+ setgroups \
+ extcopyin \
+ extcopyout \
+ read-write \
+ create-remove-files \
+ run-fsx \
+ ptscreateuser.pl \
+ ptscreategroup.pl \
+ ptsadduser.pl \
+ ptschown.pl \
+ ptsmembersuser.pl \
+ ptsmembersgroup.pl \
+ ptsexamineuser.pl \
+ ptsexaminegroup.pl \
+ ptsremove.pl \
+ ptslistown.pl \
+ ptssetmax.pl \
+ ptslistmax.pl \
+ ptssetf.pl \
+ ptsdeletegroup.pl \
+ ptsdeleteuser.pl \
+ voscreate.pl \
+ vosmove.pl \
+ vosaddsite.pl \
+ vosrelease.pl \
+ vosremsite.pl \
+ vosremove.pl \
+ vosdelentry.pl \
+ vossyncvldb.pl \
+ voszap.pl \
+ vossyncserv.pl \
+ voslock.pl \
+ vosunlock.pl \
+ vosunlockall.pl \
+ vosrename.pl \
+ voslistvol.pl \
+ voslistvldb.pl \
+ vospartinfo.pl \
+ voslistpart.pl \
+ vosbackup.pl \
+ vosexamine.pl \
+ vosdump.pl \
+ vosrestore.pl \
+ bosaddhost.pl \
+ boslisthosts.pl \
+ bosremovehost.pl \
+ bosadduser.pl \
+ boslistusers.pl \
+ bosremoveuser.pl \
+ bosinstall.pl \
+ bosexec.pl \
+ boscreate.pl \
+ bosdeleterunning.pl \
+ bosstatus.pl \
+ bosstop.pl \
+ bosrestartstopped.pl \
+ bosstart.pl \
+ bosshutdown.pl \
+ bosdelete.pl \
+ bosaddkey.pl \
+ boslistkeys.pl \
+ bosremovekey.pl \
+ bossalvagevolume.pl \
+ bossalvagepart.pl \
+ bossalvageserver.pl \
+ fcachesize-write-file \
+ fcachesize-read-file"
+
+TESTS="$ALL_TESTS"
+TEST_MODE="all"
+
+linebreak=":-------------------------------;"
+
+PARALLELL=
+FAST=
+LARGE=
+PRINT_CACHESIZE=
+usage="Usage: $0 [-user user] [-all] [-fast] [-large] [-j] [-verbose] [-x] tests ..."
+while true
+do
+ case $1 in
+ -all) ALL=yes;;
+ -fast) FAST=yes;;
+ -large) LARGE=yes;;
+ -j) PARALLELL="&";;
+ -verbose) VERBOSE=yes;;
+ -user) RUNAS=$1; shift;;
+ -x) SHELLVERBOSE="-x";;
+ -p) PRINT_CACHESIZE="yes";;
+ -basic) TESTS="$BASIC_TESTS";TEST_MODE="basic";;
+ -mtpt) TESTS="$MTPT_TESTS";TEST_MODE="mtpt";;
+ -acl) TESTS="$ACL_TESTS";TEST_MODE="acl";;
+ -exec) TESTS="$EXEC_TESTS";TEST_MODE="exec";;
+ -mmap) TESTS="$MMAP_TESTS";TEST_MODE="mmap";;
+ -fs) TESTS="$FS_TESTS";TEST_MODE="fs";;
+ -afs) TESTS="$AFS_TESTS";TEST_MODE="afs";;
+ -rmt) TESTS="$RMT_TESTS";TEST_MODE="rmt";;
+ -abuse) TESTS="$ABUSE_TESTS";TEST_MODE="abuse";;
+ -pts) TESTS="$PTS_TESTS";TEST_MODE="pts";;
+ -vos) TESTS="$VOS_TESTS";TEST_MODE="vos";;
+ -bos) TESTS="$BOS_TESTS";TEST_MODE="bos";;
+ -reg) TESTS="$REG_TESTS";TEST_MODE="reg";;
+ -help|--help) echo $usage;
+ echo "tests available: $linebreak"; for a in "$ALL_TESTS"; do echo $a ; done;
+ exit 0;;
+ -version|--version) echo "$0 $Id$"; exit 0;;
+ -*) echo "$0: Bad option $1"; echo $usage; exit 1;;
+ *) break;;
+ esac
+ shift
+done
+
+if test "X$WORKDIR" = "X";then
+ echo "WORKDIR=workdir $0 $* or env WORKDIR=workdir $0 $*"; exit 1;
+fi
+
+RUNTESTS=
+if test "X$ALL" != "X" ; then
+ RUNTESTS="$TESTS"
+elif test $# -lt 1; then
+ echo $usage; exit
+else
+ RUNTESTS=$*
+fi
+
+# these are variables exported to the scripts
+
+export FAST
+export LARGE
+export VERBOSE
+export SHELLVERBOSE
+
+# and file descriptors
+
+# 3 - progress
+# 4 - details
+
+if test "$VERBOSE" = "yes"; then
+ exec 3>/dev/null
+ exec 4>&1
+else
+ exec 3>&1
+ exec 4>/dev/null
+fi
+
+# Find out where we really are
+
+srcdir=`cd $srcdir; pwd`
+objdir=`cd $objdir; pwd`
+
+export srcdir
+export objdir
+
+echo "-------------------------------------------------"
+echo "$PACKAGE-$VERSION"
+echo "hosttype $host"
+echo "${SHELL},${SHELLVERBOSE},${VERBOSE},${PARALLELL},${FAST}"
+echo "testmode ${TEST_MODE}"
+echo "runas ${RUNAS}"
+echo "${srcdir}"
+echo "${objdir}"
+echo "${WORKDIR}"
+date
+echo "-------------------------------------------------"
+
+test "X$VERBOSE" != "X" && echo "Running tests"
+
+FAILEDTESTS=
+exitval=0
+
+for a in $RUNTESTS; do
+ #
+ # XXX Test if binary in $srcdir, shellscript in $srcdir else
+ # its a binary in objdir
+ #
+ if test -x ${srcdir}/$a ; then
+ b="${srcdir}/$a"
+ elif test -f ${srcdir}/$a ; then
+ b="${SHELL} ${SHELLVERBOSE} ${srcdir}/$a"
+ else
+ b="${objdir}/$a"
+ fi
+ echo "Running $a"
+ test "X$VERBOSE" != "X" && echo "Running test $a ($b)."
+ if test "$a" = "setgroups" ; then
+ b="${objdir}/asu root $b"
+ else
+ b="${objdir}/asu $RUNAS $b"
+ fi
+ tmpdir="`hostname`-$a-`date +%Y-%m-%d-%H-%M-%S`-$$"
+ cd $WORKDIR && mkdir $tmpdir && (cd $tmpdir && $b ${PARALLELL})
+ saved_res=$?
+ test "X$VERBOSE" != "X" && echo "Saved res = $saved_res"
+ if test "X${PARALLELL}" = "X" ;then
+ if test $saved_res != 0 ; then
+ echo "Test $a FAILED"
+ FAILEDTESTS="${FAILEDTESTS} $a";
+ exitval=$savedres
+ else
+ test "X$VERBOSE" != "X" && echo "Test $a succeeded, tmpdir is removed"
+ ${objdir}/rm-rf $tmpdir
+ fi
+ test "X$VERBOSE" != "X" && echo "Done test $a."
+ fi
+ test "X${PRINT_CACHESIZE}" = Xyes && $objdir/../appl/fs/fs calculate
+done
+
+wait
+date
+
+if test "$FAILEDTESTS"; then
+ echo "-----------------------------------------------------------"
+ echo "Failed test(s) were: $FAILEDTESTS"
+else
+ echo "All test(s) were succesful!"
+fi
+
+exit $exitval
--- /dev/null
+#!/bin/sh
+# $Id$
+
+$objdir/test-setgroups nobody 1>&4
--- /dev/null
+#!/bin/sh
+# $Id$
+
+$objdir/test-setpag 1>&4
--- /dev/null
+#!/bin/sh
+# $Id$
+
+mkdir foo && ( cd foo && $SHELL $SHELLVERBOSE ${srcdir}/dir-tree 3 "0 1 2 3 4" )
+${objdir}/rm-rf foo
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+
+#include <err.h>
+
+#define TEST_BUFFER_SZ (1024*8)
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "foo";
+ char otherbuf[TEST_BUFFER_SZ];
+ char buf[TEST_BUFFER_SZ];
+ int fd;
+
+
+ fd = open (file, O_RDWR|O_TRUNC|O_CREAT, 0644);
+ if (fd < 0)
+ err(1, "open(%s)", file);
+
+ if (write (fd, buf, sizeof(buf)) != sizeof(buf))
+ errx(1, "write");
+
+ while (1) {
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err(1, "lseek");
+
+ if (read(fd, otherbuf, sizeof(otherbuf)) != sizeof(otherbuf)) {
+ struct stat sb;
+
+ if (fstat(fd, &sb) < 0)
+ err(1, "fstat");
+ printf("size: %d\n", (int)sb.st_size);
+ printf ("lseek(SEEK_CUR): %d\n", (int)lseek(fd, 0, SEEK_CUR));
+ errx(1, "read");
+ }
+
+ if (memcmp(buf, otherbuf, sizeof(buf)) != 0)
+ errx (1, "buf != otherbuf");
+ }
+ close(fd);
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+for i in å ä ö åäö; do
+ touch $i || exit 1
+ test -f $i || exit 1
+ rm $i || exit 1
+done
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static void
+creat_file (char *name)
+{
+ int fd;
+
+ fd = open (name, O_WRONLY | O_CREAT | O_EXCL, 0777);
+ if (fd < 0)
+ err (1, "open %s", name);
+ if (close (fd) < 0)
+ err (1, "close %s", name);
+}
+
+static void
+look_at_file (char *name)
+{
+ int fd;
+
+ fd = open (name, O_RDONLY | O_EXCL, 0777);
+ if (fd < 0)
+ err (1, "open %s", name);
+ if (close (fd) < 0)
+ err (1, "close %s", name);
+}
+
+static void
+usage (int ret)
+{
+ fprintf (stderr, "%s\n", __progname);
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *file = "åäö";
+
+
+ if (argc != 1)
+ usage (1);
+
+ creat_file (file);
+ look_at_file (file);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+dir=$AFSROOT/stacken.kth.se/ftp/pub/arla/tests
+
+test -f $dir/åäö || exit 1
--- /dev/null
+/*
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ struct stat sb;
+
+
+ ret = symlink ("foo", "bar");
+ if (ret < 0)
+ err (1, "symlink foo,bar");
+ ret = lstat ("bar", &sb);
+ if (ret < 0)
+ err (1, "lstat bar");
+ if ((sb.st_mode & S_IFLNK) != S_IFLNK)
+ errx (1, "bar is not symlink");
+ ret = unlink ("bar");
+ if (ret < 0)
+ err (1, "unlink bar");
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+original=${1-$AFSROOT/stacken.kth.se/ftp/pub/gnu}
+cd $original || exit 1
+find . -name '*.gz' -print | while read i; do
+ foo=`gunzip --verbose --test $i 2>&1`
+ echo $foo >& 4
+ case "$foo" in
+*not*in*gzip*format*) ;;
+*OK*) ;;
+*) exit 1 ;;
+ esac
+done
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+#include <err.h>
+
+#include <fcntl.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#define WORKER_TIMES 100
+#define NUM_WORKER 10
+
+static int
+worker (int num)
+{
+ int i, fd;
+
+ for (i = 0 ; i < WORKER_TIMES ; i++) {
+ fd = open ("foo", O_CREAT|O_RDWR, 0600);
+ if (fd >= 0) {
+ fchmod (fd, 0700);
+ close (fd);
+ }
+ unlink("foo");
+ if (i % 1000) {
+ printf (" %d", num);
+ fflush (stdout);
+ }
+ }
+ return 0;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int i, ret;
+
+
+ for (i = 0; i < NUM_WORKER ; i++) {
+ int ret;
+
+ ret = fork();
+ switch (ret) {
+ case 0:
+ return worker(i);
+ case -1:
+ err (1, "fork");
+ }
+ }
+ i = NUM_WORKER;
+ while (i && wait (&ret)) {
+ i--;
+ if (ret)
+ err (1, "wait: %d", ret);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <err.h>
+
+#include <fcntl.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#define WORKER_TIMES 1000
+#define NUM_WORKER 100
+
+static int
+getcwd_worker (int num)
+{
+ char name[17];
+ int i;
+
+ snprintf (name, sizeof(name), "%d", num);
+ if (mkdir (name, 0777) < 0)
+ err (1, "mkdir %s", name);
+ if (chdir (name) < 0)
+ err (1, "chdir %s", name);
+ for (i = 0; i < WORKER_TIMES; ++i) {
+ char buf[256];
+
+ getcwd (buf, sizeof(buf));
+ }
+ return 0;
+}
+
+static int
+mkdir_worker (int num)
+{
+ int i;
+
+ for (i = 0; i < WORKER_TIMES; ++i){
+ char name[256];
+
+ snprintf (name, sizeof(name), "m%d-%d", num, i);
+ mkdir (name, 0777);
+ }
+ return 0;
+}
+
+static int
+mkdir_rmdir_worker (int num)
+{
+ int i;
+
+ for (i = 0; i < WORKER_TIMES; ++i){
+ char name[256];
+
+ snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ mkdir (name, 0777);
+ }
+ for (i = 0; i < WORKER_TIMES; ++i){
+ char name[256];
+
+ snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ rmdir (name);
+ }
+ return 0;
+}
+
+static int
+rename_worker (int num)
+{
+ int i;
+
+ for (i = 0; i < WORKER_TIMES; ++i){
+ char name[256];
+ int fd;
+
+ snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ fd = open (name, O_WRONLY | O_CREAT, 0777);
+ close (fd);
+ }
+ for (i = 0; i < WORKER_TIMES; ++i){
+ char name[256], name2[256];
+
+ snprintf (name, sizeof(name), "rm%d-%d", num, i);
+ snprintf (name2, sizeof(name2), "rn%d-%d", num, i);
+ rename (name, name2);
+ }
+ return 0;
+}
+
+static int
+stat_worker (int num)
+{
+ char name[17];
+ int i;
+ char buf[256];
+ struct stat sb;
+
+ snprintf (name, sizeof(name), "%d", num);
+ if (mkdir (name, 0777) < 0)
+ err (1, "mkdir %s", name);
+ if (chdir (name) < 0)
+ err (1, "chdir %s", name);
+ for (i = 0; i < WORKER_TIMES; ++i) {
+ getcwd (buf, sizeof(buf));
+ stat (buf, &sb);
+ }
+ return 0;
+}
+
+static int (*workers[])(int) = {getcwd_worker, mkdir_worker,
+ mkdir_rmdir_worker, rename_worker,
+ stat_worker};
+
+static int nworkers = sizeof(workers)/sizeof(*workers);
+
+int
+main(int argc, char **argv)
+{
+ int i, ret;
+
+
+ for (i = 0; i < NUM_WORKER ; i++) {
+ int ret;
+
+ ret = fork();
+ switch (ret) {
+ case 0:
+ return (*workers[i % nworkers])(i);
+ case -1:
+ err (1, "fork");
+ }
+ }
+ i = NUM_WORKER;
+ while (i && wait (&ret)) {
+ i--;
+ if (ret)
+ err (1, "wait: %d", ret);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <limits.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#if !defined(NGROUPS) && defined(NGROUPS_MAX)
+#define NGROUPS NGROUPS_MAX
+#endif
+
+static void
+print_groups (int ngroups, gid_t groups[NGROUPS])
+{
+ int i;
+
+ printf ("groups: ");
+ for (i = 0; i < ngroups; ++i)
+ printf ("%d%s", groups[i], (i < ngroups - 1) ? ", " : "");
+ printf ("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ char *user;
+ char *this_user;
+ struct passwd *this_pwd, *pwd;
+ int ret;
+ gid_t groups[NGROUPS];
+ int ngroups;
+ gid_t pag0, pag1, pag2;
+
+
+ if (argc != 2)
+ errx (1, "Usage: %s user", argv[0]);
+ user = argv[1];
+
+ this_pwd = getpwuid (getuid ());
+ if (this_pwd == NULL)
+ errx (1, "Who are you?");
+ this_user = strdup (this_pwd->pw_name);
+
+ pwd = getpwnam (user);
+ if (pwd == NULL)
+ errx (1, "User %s not found", user);
+
+ ngroups = getgroups (NGROUPS, groups);
+ if (ngroups < 0)
+ err (1, "getgroups %d", NGROUPS);
+ printf ("user %s ", this_user);
+ print_groups (ngroups, groups);
+ printf ("doing setpag()\n");
+ ret = setpag ();
+ if (ret < 0)
+ err (1, "setpag");
+
+ ngroups = getgroups (NGROUPS, groups);
+ if (ngroups < 0)
+ err (1, "getgroups %d", NGROUPS);
+ pag0 = groups[0];
+ pag1 = groups[1];
+ pag2 = groups[2];
+ printf ("user %s ", this_user);
+ print_groups (ngroups, groups);
+
+ ret = initgroups (user, pwd->pw_gid);
+ if (ret < 0)
+ err (1, "initgroups");
+
+ ngroups = getgroups (NGROUPS, groups);
+ if (ngroups < 0)
+ err (1, "getgroups %d", NGROUPS);
+ printf ("user %s ", user);
+ print_groups (ngroups, groups);
+ if ((groups[0] == pag0 && groups[1] == pag1)
+ || (groups[1] == pag1 && groups[2] == pag2))
+ return 0;
+ else
+ return 1;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <limits.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#if !defined(NGROUPS) && defined(NGROUPS_MAX)
+#define NGROUPS NGROUPS_MAX
+#endif
+
+static void
+print_groups (int ngroups, gid_t groups[NGROUPS])
+{
+ int i;
+
+ printf ("groups: ");
+ for (i = 0; i < ngroups; ++i)
+ printf ("%d%s", groups[i], (i < ngroups - 1) ? ", " : "");
+ printf ("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ gid_t groups[NGROUPS];
+ int ngroups;
+ gid_t pag1, pag2;
+ pid_t pid;
+
+ if (argc != 1)
+ errx (1, "Usage: %s", argv[0]);
+
+ ngroups = getgroups (NGROUPS, groups);
+ if (ngroups < 0)
+ err (1, "getgroups %d", NGROUPS);
+ pag1 = groups[1];
+ pag2 = groups[2];
+ printf ("in parent ");
+ print_groups (ngroups, groups);
+ pid = fork ();
+ if (pid < 0)
+ err (1, "fork");
+ if (pid == 0) {
+ ret = setpag ();
+ if (ret < 0)
+ err (1, "setpag");
+ ngroups = getgroups (NGROUPS, groups);
+ if (ngroups < 0)
+ err (1, "getgroups %d", NGROUPS);
+ printf ("in child ");
+ print_groups (ngroups, groups);
+ return 0;
+ } else {
+ int status;
+
+ while(waitpid (pid, &status, WNOHANG | WUNTRACED) != pid)
+ ;
+ if (status)
+ return 1;
+ ngroups = getgroups (NGROUPS, groups);
+ if (ngroups < 0)
+ err (1, "getgroups %d", NGROUPS);
+ printf ("in parent ");
+ print_groups (ngroups, groups);
+ if (groups[1] == pag1 && groups[2] == pag2)
+ return 0;
+ else
+ return 1;
+ }
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+
+$objdir/create-files 31707 0
--- /dev/null
+#!/bin/sh
+touch foobar || exit 1
+test -f foobar || exit 1
+rm foobar || exit 1
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static void do_dir(const char *);
+static void repeat_dir(const char *);
+
+static void
+do_dir(const char *dirname)
+{
+ int ret;
+
+ ret = chdir (dirname);
+ if (ret < 0)
+ err (1, "chdir %s", dirname);
+ repeat_dir (dirname);
+ ret = chdir ("..");
+ if (ret < 0)
+ err (1, "chdir ..");
+}
+
+static void
+read_and_truncate (const char *filename, const struct stat *sb)
+{
+ int fd;
+ char *buf;
+ int ret;
+ struct stat sb2;
+
+ buf = malloc (sb->st_size);
+ if (buf == NULL)
+ err (1, "malloc %lu", (unsigned long)sb->st_size);
+ fd = open (filename, O_RDONLY);
+ if (fd < 0)
+ err (1, "open readonly %s", filename);
+ ret = read (fd, buf, sb->st_size);
+ if (ret < 0)
+ err (1, "read %s", filename);
+ if (ret != sb->st_size)
+ errx (1, "short read from %s", filename);
+ if (close (fd))
+ err (1, "close reading %s", filename);
+ fd = open (filename, O_WRONLY | O_TRUNC, 0);
+ if (fd < 0)
+ err(1, "open wronly-trunc %s", filename);
+ ret = write (fd, buf, sb->st_size);
+ if (ret < 0)
+ err (1, "write %s", filename);
+ if (ret != sb->st_size)
+ errx (1, "short write %s", filename);
+ if (close (fd))
+ err (1, "close writing %s", filename);
+ ret = lstat (filename, &sb2);
+ if (ret < 0)
+ err (1, "stat %s", filename);
+ if (sb2.st_size != sb->st_size)
+ errx (1, "wrong size after re-writing %s: %lu != %lu",
+ filename,
+ (unsigned long)sb->st_size, (unsigned long)sb2.st_size);
+ free(buf);
+}
+
+static void
+repeat_dir (const char *dirname)
+{
+ DIR *dir;
+ struct dirent *dp;
+
+ dir = opendir (".");
+ if (dir == NULL)
+ err(1, "opendir %s", dirname);
+ while ((dp = readdir (dir)) != NULL) {
+ struct stat sb;
+ int ret;
+
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ ret = lstat (dp->d_name, &sb);
+ if (ret < 0)
+ err (1, "lstat %s", dp->d_name);
+ if (S_ISDIR(sb.st_mode))
+ do_dir (dp->d_name);
+ else if (S_ISREG(sb.st_mode))
+ read_and_truncate (dp->d_name, &sb);
+ }
+ closedir (dir);
+}
+
+
+int
+main(int argc, char **argv)
+{
+
+ if (argc != 2)
+ errx (1, "usage: %s directory", argv[0]);
+ do_dir (argv[1]);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+
+static void
+create_and_write (char *name, const char *buf)
+{
+ int fd, ret;
+ int len = strlen(buf);
+
+ fd = open (name, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd < 0)
+ err (1, "open");
+ ret = write (fd, buf, len);
+ if (ret != len)
+ err (1, "write");
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close");
+}
+
+static void
+check_size (char *name, int len)
+{
+ struct stat sb;
+ int ret;
+
+ ret = stat(name, &sb);
+ if (ret < 0)
+ err (1, "stat");
+
+ if (len != sb.st_size)
+ errx (1, "len != sb.st_size");
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+
+
+ create_and_write ("foo", "hej\n");
+
+ ret = truncate ("foo", 0);
+ if (ret < 0)
+ err (1, "truncate(0)");
+
+ check_size ("foo", 0);
+
+ ret = unlink("foo");
+ if (ret < 0)
+ errx (1, "unlink");
+
+ create_and_write ("bar", "hej\nhej\n");
+
+ ret = truncate ("bar", 16);
+ if (ret < 0)
+ err (1, "truncate(16)");
+
+ check_size ("bar", 16);
+
+ ret = unlink("bar");
+ if (ret < 0)
+ errx (1, "unlink");
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+for i in 1 2 3 4 5 6 7 8 9 10; do
+ $objdir/echo-n '.' >&3
+ gzip -dc $AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.7.tar.gz | tar xvf - >&4 || exit 1
+ rm -rf emacs-20.7
+done
+echo >&3
--- /dev/null
+#!/bin/sh
+# $Id$
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+wget http://www.openafs.org/dl/1.2.2/openafs-1.2.2-src.tar.gz
+for i in 1 2 3 4 5 6 7 8 9 10; do
+ $objdir/echo-n '.' >&3
+ gzip -dc openafs-1.2.2-src.tar.gz | tar xvf - >&4 || exit 1
+ rm -rf openafs-1.2.2
+done
+echo >&3
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMUCS/CMU_copyright.ph for use and distribution information
+
+package OpenAFS::util;
+
+=head1 NAME
+
+OpenAFS::util - General AFS utilities
+
+=head1 SYNOPSIS
+
+ use OpenAFS::util;
+
+ AFS_Init();
+ AFS_Trace($subject, $level);
+ AFS_SetParm($parm, $value);
+
+ use OpenAFS::util qw(GetOpts_AFS);
+ %options = GetOpts_AFS(\@argv, \@optlist);
+
+=head1 DESCRIPTION
+
+This module defines a variety of AFS-related utility functions. Virtually
+every application that uses AFStools will need to use some of the utilities
+defined in this module. In addition, a variety of global variables are
+defined here for use by all the AFStools modules. Most of these are
+private, but a few are semi-public.
+
+=cut
+
+use OpenAFS::CMU_copyright;
+use OpenAFS::config;
+require OpenAFS::afsconf; ## Avoid circular 'use' dependencies
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_Init
+ &AFS_Trace
+ &AFS_SetParm);
+@EXPORT_OK = qw(%AFS_Parms
+ %AFS_Trace
+ %AFS_Help
+ %AFScmd
+ &GetOpts_AFS
+ &GetOpts_AFS_Help);
+%EXPORT_TAGS = (afs_internal => [qw(%AFS_Parms %AFS_Trace %AFScmd %AFS_Help)],
+ afs_getopts => [qw(&GetOpts_AFS &GetOpts_AFS_Help)] );
+
+
+=head2 AFS_Init()
+
+This function does basic initialization of AFStools. It must be called before
+any other AFStools function.
+
+=cut
+
+sub AFS_Init
+{
+ my(@dirs, $c, $i, $x);
+
+ $AFS_Parms{'authlvl'} = 1;
+ $AFS_Parms{'confdir'} = $def_ConfDir;
+ $AFS_Parms{'cell'} = OpenAFS::afsconf::AFS_conf_localcell();
+
+ # Search for AFS commands
+ @dirs = @CmdPath;
+ foreach $c (@CmdList)
+ {
+ $AFScmd{$c} = '';
+ foreach $i ($[ .. $#dirs)
+ {
+ $x = $dirs[$i];
+ if (-x "$x/$c" && ! -d "$x/$c")
+ {
+ $AFScmd{$c} = "$x/$c";
+ splice(@dirs, $i, 1); # Move this item to the start of the array
+ unshift(@dirs, $x);
+ last;
+ }
+ }
+ return "Unable to locate $c!" if (!$AFScmd{$c});
+ }
+ 0;
+}
+
+
+=head2 AFS_Trace($subject, $level)
+
+Sets the tracing level for a particular "subject" to the specified level.
+All tracing levels start at 0, and can be set to higher values to get debugging
+information from different parts of AFStools. This function is generally
+only of use to people debugging or extending AFStools.
+
+=cut
+
+$AFS_Help{Trace} = '$subject, $level => void';
+sub AFS_Trace {
+ my($subject, $level) = @_;
+
+ $AFS_Trace{$subject} = $level;
+}
+
+
+=head2 AFS_SetParm($parm, $value)
+
+Sets the AFStools parameter I<$parm> to I<$value>. AFStools parameters are
+used to alter the behaviour of various parts of the system. The following
+parameters are currently defined:
+
+=over 10
+
+=item authlvl
+
+The authentication level to use for commands that talk directly to AFS
+servers (bos, vos, pts, etc.). Set to 0 for unauthenticated access (-noauth),
+1 to use the user's existing tokens, or 2 to use the AFS service key
+(-localauth).
+
+=item cell
+
+The default AFS cell in which to work. This is initially the workstation's
+local cell.
+
+=item confdir
+
+The AFS configuration directory to use. If none is specified, the default
+(as defined in OpenAFS::config) will be used.
+
+=item vostrace
+
+Set the tracing level used by various B<vos> utilities. The default is 0,
+which disables any tracing of activity of B<vos> commands. A setting of 1
+copies output from all commands except those which are invoked solely to
+get information; a setting of 2 additionally uses the "-verbose" command
+on any command whose output is copied. If a setting of 3 is used, all
+B<vos> commands will be invoked with "-verbose", and have their output
+copied to stdout.
+
+=back
+
+=cut
+
+$AFS_Help{SetParm} = '$parm, $value => void';
+sub AFS_SetParm {
+ my($parm, $value) = @_;
+
+ $AFS_Parms{$parm} = $value;
+}
+
+
+#: GetOpts_AFS(\@argv, \@optlist)
+#: Parse AFS-style options.
+#: \@argv is a hard reference to the list of arguments to be parsed.
+#: \@optlist is a hard reference to the list of option specifications for valid
+#: options; in their default order. Each option specification, in turn, is a
+#: hard reference to an associative array containing some of the following
+#: elements:
+#: name => The name of the argument
+#: numargs => Number of arguments (0, 1, or -1 for multiple)
+#: required => If nonzero, this argument is required
+#: default => Value to give this option if not specified
+#: noauto => Don't use this option for unadorned arguments
+#:
+#: Results are returned in the form of an associative array of options and
+#: their values:
+#: - Boolean (0-argument) options have a value of 1 if specified. This type
+#: of option may not be marked 'required'.
+#: - Simple (1-argument) options have a value which is the string given by the
+#: user.
+#: - Multiple-argument options have a value which is a hard reference to an
+#: array of values given by the user.
+#:
+#: Argument parsing is done in a similar manner to the argument parser used by
+#: various AFS utilities. Options have multi-character names, and may not be
+#: combined with their arguments or other options. Those options which take
+#: arguments use up at least the next argument, regardless of whether it begins
+#: with a dash. Options which can take multiple arguments will eat at least
+#: one argument, as well as any following argument up to the next option (i.e.,
+#: the next argument beginning with a dash). An "unadorned" argument will be
+#: used by the next argument-taking option. If there are multiple unadorned
+#: arguments, they will be used up by successive arguments much in the same
+#: way Perl handles list assignment - each one-argument (scalar) option will
+#: use one argument; the first multi-argument (list) option will use up any
+#: remaining unadorned arguments.
+#:
+#: On completion, @argv will be left with any unparsed arguments (this can
+#: happen if the last option specified is _not_ a multi-argument option, and
+#: there are no "defaulted" options). This is considered to be an error
+#: condition.
+#:
+sub GetOpts_AFS_Help {
+ my($cmd, $optlist) = @_;
+ my($option, $optname, $desc);
+
+ foreach $option (@$optlist) {
+ $optname = '-' . $$option{name};
+ if ($$option{numargs}) {
+ $desc = $$option{desc} ? $$option{desc} : $$option{name};
+ $desc = " <$desc>";
+ $desc .= '+' if ($$option{numargs} < 0);
+ $optname .= $desc;
+ }
+ $optname = "[$optname]" if (!$$option{required});
+ $cmd .= " $optname";
+ }
+ $cmd;
+}
+
+sub _which_opt {
+ my($optname, @options) = @_;
+ my($o, $which, $n);
+
+ foreach $o (@options) {
+ next unless ($o =~ /^$optname/);
+ $n++;
+ $which = $o;
+ }
+ ($n == 1) ? $which : $optname;
+}
+
+sub GetOpts_AFS {
+ my($argv, $optlist) = @_;
+ my(@autolist, %opttbl, %result);
+ my($stop, $key, $value, $diemsg);
+
+ # Initialization:
+ @autolist = map {
+ if ($_->{numargs} && !$_->{noauto} && !$stop) {
+ $stop = 1 if ($_->{numargs} < 0);
+ ($_->{name});
+ } else {
+ ();
+ }
+ } (@$optlist, { name=>'-help', numargs=>0, required=>0 } );
+ %opttbl = map { $_->{name} => $_ } @$optlist;
+
+ while (@$argv) {
+ my($optname, $optkind);
+
+ # Parse the next argument. It can either be an option, or an
+ # unadorned argument. If the former, shift it off and process it.
+ # Otherwise, grab the next "automatic" option. If there are no
+ # more automatic options, we have extra arguments and should return.
+ if ($argv->[0] =~ /^-(.+)/) { # Got an option!
+ $optname = $1;
+ shift(@$argv);
+ } else { # An unadorned argument
+ if (@autolist) {
+ $optname = shift(@autolist);
+ } else {
+ $diemsg = join(' ', "Extra arguments:", @$argv) unless ($diemsg);
+ shift @$argv;
+ next;
+ }
+ }
+ $optname = &_which_opt($optname, keys %opttbl);
+
+ # Find out how many arguments this thing wants, then remove it from
+ # the option table and automatic option list.
+ $optkind = $opttbl{$optname}->{numargs};
+ delete $opttbl{$optname};
+ @autolist = grep($_ ne $optname, @autolist);
+
+ # Parse arguments (if any), and set the result value
+ if (!$optkind) { # Boolean!
+ $result{$optname} = 1;
+ } elsif ($optkind == 1) { # Single argument
+ # Shift off a single argument, or signal an error
+ if (!@$argv) {
+ $diemsg = "No argument for -$optname" unless ($diemsg);
+ next;
+ }
+ $result{$optname} = shift(@$argv);
+ } elsif ($optkind < 0) { # Multiple arguments
+ # Shift off at least one argument, and any additional
+ # ones that are present. EXCEPT, if there are no more
+ # explicitly-specified options but there ARE automatic
+ # options left in our list, then only eat up one.
+ my($val, @val);
+ if (!@$argv) {
+ $diemsg = "No argument for -$optname" unless ($diemsg);
+ next;
+ }
+ $val = shift(@$argv);
+ push(@val, shift @$argv) while (@$argv && $argv->[0] !~ /^-/);
+ if (@autolist && !@$argv) {
+ unshift(@$argv, @val);
+ @val = ($val);
+ } else {
+ unshift(@val, $val);
+ }
+ $result{$optname} = [@val];
+ } else {
+ die "Invalid argument spec for -$optname ($optkind)\n";
+ }
+ }
+
+ # Now for a little clean-up
+ # Set default values for any unspecified option that has them.
+ # Set an error condition if there are any required options that
+ # were not specified.
+ while (($key, $value) = each %opttbl) {
+ if ($value->{required}) {
+ $diemsg = "Required option -$key not specified" unless($diemsg);
+ }
+ $result{$key} = $value->{default};
+ }
+ if ($diemsg && !$result{help}) { die $diemsg . "\n" }
+ %result;
+}
+
+
+1;
+
+=head1 VARIABLES
+
+The following global variables are defined by B<OpenAFS::util>. None of these
+are exported by default. Those marked "Private" should not be used outside
+AFStools; their names, meaning, and even existence may change at any time.
+
+=over 12
+
+=item %AFS_Help - Help info
+
+This array contains argument lists for all publicly-exported AFStools
+functions with names of the form AFS_*. It is intended for programs like
+B<testbed>, which provide a direct interactive interface to AFStools.
+
+=item %AFS_Parms - Parameter settings [Private]
+
+This array contains the settings of AFStools parameters set with
+B<OpenAFS::util::AFS_SetParm>.
+
+=item %AFS_Trace - Tracing levels [Private]
+
+This array contains the tracing levels set with B<OpenAFS::util::AFS_Trace>.
+
+=item %AFScmd - AFS command locations [Private]
+
+This array contains paths to the various AFS command binaries, for use
+by B<OpenAFS::wrapper::wrapper> and possibly other AFStools functions.
+
+=back
+
+=head1 COPYRIGHT
+
+The CMUCS AFStools, including this module are
+Copyright (c) 1996, Carnegie Mellon University. All rights reserved.
+For use and redistribution information, see CMUCS/CMU_copyright.pm
+
+=cut
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <err.h>
+
+static void
+doit (const char *filename)
+{
+ int ret;
+ struct timeval tv[2];
+
+ ret = mkdir (filename, 0700);
+ if (ret < 0)
+ err (1, "mkdir %s", filename);
+ gettimeofday (&tv[0], NULL);
+ tv[1] = tv[0];
+ ret = utimes (filename, tv);
+ if (ret < 0)
+ err(1, "utimes %s", filename);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "blaha";
+
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utime.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <err.h>
+
+int
+main (int argc, char ** argv)
+{
+ int len;
+ int ret;
+ int fd;
+ char *filename = "foo";
+ char *buf;
+ struct stat sb;
+ struct utimbuf t;
+
+ switch (argc) {
+ case 1:
+ len = 8 * 1024; break;
+ case 2:
+ len = atoi(argv[1]);
+ if (len == 0)
+ errx (1, "invalid len");
+ default:
+ errx (1, "argv != [12]");
+ }
+
+ buf = malloc (len);
+ memset (buf, 'a', len);
+
+ fd = open (filename, O_RDWR|O_CREAT|O_EXCL, 0744);
+ if (fd < 0)
+ errx (1, "open");
+ ret = fstat (fd, &sb);
+ if (ret < 0)
+ errx (1, "open");
+
+ ret = ftruncate (fd, len);
+ fstat (fd, &sb);
+ lseek (fd, 0, SEEK_SET);
+ write (fd, buf, len);
+ fstat (fd, &sb);
+
+ t.modtime = t.actime = time (NULL);
+ utime (filename, &t);
+
+ close (fd);
+ free (buf);
+
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+# $Id$
+ls ${AFSROOT}/nada.kth.se/* >&4 2>&4 || exit 1
+ls -l ${AFSROOT}/nada.kth.se/* >&4 2>&4 || exit 1
+ls ${AFSROOT}/nada.kth.se/*/* >&4 2>&4 || exit 1
+ls -l ${AFSROOT}/nada.kth.se/*/* >&4 2>&4 || exit 1
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.ph for use and distribution information
+#
+#: * vos.pm - Wrappers around VOS commands (volume maintenance)
+#: * This module provides wrappers around the various volserver and VLDB
+#: * commands, giving them a nice perl-based interface. Someday, they might
+#: * talk to the servers directly instead of using 'vos', but not anytime
+#: * soon.
+#:
+
+package OpenAFS::vos;
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use OpenAFS::wrapper;
+use Exporter;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&AFS_vos_create &AFS_vos_listvldb
+ &AFS_vos_remove &AFS_vos_delentry
+ &AFS_vos_rename &AFS_vos_syncserv
+ &AFS_vos_move &AFS_vos_syncvldb
+ &AFS_vos_examine &AFS_vos_lock
+ &AFS_vos_addsite &AFS_vos_unlock
+ &AFS_vos_remsite &AFS_vos_unlockvldb
+ &AFS_vos_release &AFS_vos_changeaddr
+ &AFS_vos_backup &AFS_vos_listpart
+ &AFS_vos_backupsys &AFS_vos_partinfo
+ &AFS_vos_dump &AFS_vos_listvol
+ &AFS_vos_restore &AFS_vos_zap
+ &AFS_vos_status);
+
+$vos_err_parse = [ 'Error in vos (.*) command', '-(.*)' ];
+
+
+#: AFS_vos_create($vol, $server, $part, [$quota], [$cell])
+#: Create a volume with name $vol
+#: The server name ($server) may be a hostname or IP address
+#: The partition may be a partition name (/vicepx), letter (x), or number (24)
+#: If specified, use $quota for the initial quota instead of 5000 blocks.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return the volume ID.
+#:
+$AFS_Help{vos_create} = '$vol, $server, $part, [$quota], [$cell] => $volid';
+sub AFS_vos_create {
+ my($vol, $server, $part, $quota, $cell) = @_;
+ my(@args, $id);
+
+ @args = ('create', '-name', $vol, '-server', $server, '-part', $part);
+ push(@args, '-maxquota', $quota) if ($quota ne '');
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ ['^Volume (\d+) created on partition \/vicep\S+ of \S+', \$id ],
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ $id;
+}
+
+
+#: AFS_vos_remove($vol, $server, $part, [$cell])
+#: Remove the volume $vol from the server and partition specified by $server and
+#: $part. If appropriate, also remove the corresponding VLDB entry.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_remove} = '$vol, $server, $part, [$cell] => Success?';
+sub AFS_vos_remove {
+ my($vol, $server, $part, $cell) = @_;
+ my(@args);
+
+ @args = ('remove', '-id', $vol, '-server', $server, '-part', $part);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_rename($old, $new, [$cell])
+#: Rename the volume $old to have the name $new.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_rename} = '$old, $new, [$cell] => Success?';
+sub AFS_vos_rename {
+ my($old, $new, $cell) = @_;
+ my(@args);
+
+ @args = ('rename', '-oldname', $old, '-newname', $new);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_move($vol, $fromsrv, $frompart, $tosrv, $topart, [$cell])
+#: Move the volume specified by $vol.
+#: The source location is specified by $fromsrv and $frompart.
+#: The destination location is specified by $tosrv and $topart.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+
+#:
+$AFS_Help{vos_move} = '$vol, $fromsrv, $frompart, $tosrv, $topart, [$cell] => Success?';
+sub AFS_vos_move {
+ my($vol, $fromsrv, $frompart, $tosrv, $topart, $cell) = @_;
+ my(@args);
+
+ @args = ('move', '-id', $vol,
+ '-fromserver', $fromsrv, '-frompartition', $frompart,
+ '-toserver', $tosrv, '-topartition', $topart);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_examine($vol, [$cell])
+#: Examine the volume $vol, and return information about it.
+#: If specified, operate in cell $cell instead of the default cell.
+#: On success, return an associative array with some or all of the following:
+#: - name Name of this volume
+#: - id ID of this volume
+#: - kind Kind of volume (RW, RO, or BK)
+#: - inuse Disk space in use
+#: - maxquota Maximum disk usage quota
+#: - minquota Minimum disk usage quota (optional)
+#: - stamp_create Time when volume was originally created
+#: - stamp_update Time volume was last modified
+#: - stamp_backup Time backup volume was cloned, or 'Never'
+#: - stamp_copy Time this copy of volume was made
+#: - backup_flag State of automatic backups: empty or 'disabled'
+#: - dayuse Number of accesses in the past day
+#: - rwid ID of read-write volume (even if this is RO or BK)
+#: - roid ID of read-only volume (even if this is RW or BK)
+#: - bkid ID of backup volume (even if this is RW or RO)
+#: - rwserv Name of server where read/write volume is
+#: - rwpart Name of partition where read/write volume is
+#: - rosites Reference to a list of read-only sites. Each site, in turn,
+#: is a reference to a two-element list (server, part).
+#:
+$AFS_Help{vos_examine} = '$vol, [$cell] => %info';
+sub AFS_vos_examine {
+ my($vol, $cell) = @_;
+ my(%result, @args, @rosites);
+
+ @args = ('examine', '-id', $vol);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %result = &wrapper('vos', \@args,
+ [$vos_err_parse,
+ ['^(\S+)\s*(\d+)\s*(RW|RO|BK)\s*(\d+)\s*K', 'name', 'id', 'kind', 'inuse'],
+ ['MaxQuota\s*(\d+)\s*K', 'maxquota' ],
+ ['MinQuota\s*(\d+)\s*K', 'minquota' ],
+ ['Creation\s*(.*\S+)', 'stamp_create' ],
+ ['Last Update\s*(.*\S+)', 'stamp_update' ],
+ ['Backup\s+([^\d\s].*\S+)', 'stamp_backup' ],
+ ['Copy\s*(.*\S+)', 'stamp_copy' ],
+ ['Automatic backups are (disabled) for this volume', 'backup_flag' ],
+ ['(\d+) accesses in the past day', 'dayuse' ],
+ ['RWrite\:\s*(\d+)', 'rwid' ],
+ ['ROnly\:\s*(\d+)', 'roid' ],
+ ['Backup\:\s*(\d+)', 'bkid' ],
+ ['server (\S+) partition /vicep(\S+) RW Site', 'rwserv', 'rwpart'],
+ ['server (\S+) partition /vicep(\S+) RO Site', sub {
+ push(@rosites, [$_[0], $_[1]]);
+ }],
+ ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+
+ $result{'rosites'} = \@rosites if (@rosites);
+ %result;
+}
+
+
+
+#: AFS_vos_addsite($vol, $server, $part, [$cell])
+#: Add a replication site for volume $vol
+#: The server name ($server) may be a hostname or IP address
+#: The partition may be a partition name (/vicepx), letter (x), or number (24)
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_addsite} = '$vol, $server, $part, [$cell] => Success?';
+sub AFS_vos_addsite {
+ my($vol, $server, $part, $cell) = @_;
+ my(@args);
+
+ @args = ('addsite', '-id', $vol, '-server', $server, '-part', $part);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_remsite($vol, $server, $part, [$cell])
+#: Remove a replication site for volume $vol
+#: The server name ($server) may be a hostname or IP address
+#: The partition may be a partition name (/vicepx), letter (x), or number (24)
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_remsite} = '$vol, $server, $part, [$cell] => Success?';
+sub AFS_vos_remsite {
+ my($vol, $server, $part, $cell) = @_;
+ my(@args);
+
+ @args = ('remsite', '-id', $vol, '-server', $server, '-part', $part);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_release($vol, [$cell], [$force])
+#: Release the volume $vol.
+#: If $force is specified and non-zero, use the "-f" switch.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_release} = '$vol, [$cell], [$force] => Success?';
+sub AFS_vos_release {
+ my($vol, $cell, $force) = @_;
+ my(@args);
+
+ @args = ('release', '-id', $vol);
+ push(@args, '-f') if ($force);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_backup($vol, [$cell])
+#: Make a backup of the volume $vol.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_backup} = '$vol, [$cell] => Success?';
+sub AFS_vos_backup {
+ my($vol, $cell) = @_;
+ my(@args);
+
+ @args = ('backup', '-id', $vol);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_backupsys([$prefix], [$server, [$part]], [$exclude], [$cell])
+#: Do en masse backups of AFS volumes.
+#: If specified, match only volumes whose names begin with $prefix
+#: If specified, limit work to the $server and, if given, $part.
+#: If $exclude is specified and non-zero, backup only volumes NOT matched.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_backupsys} = '[$prefix], [$server, [$part]], [$exclude], [$cell] => Success?';
+sub AFS_vos_backupsys {
+ my($prefix, $server, $part, $exclude, $cell) = @_;
+ my(@args);
+
+ @args = ('backupsys');
+ push(@args, '-prefix', $prefix) if ($prefix);
+ push(@args, '-server', $server) if ($server);
+ push(@args, '-partition', $part) if ($server && $part);
+ push(@args, '-exclude') if ($exclude);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_dump($vol, [$time], [$file], [$cell])
+#: Dump the volume $vol
+#: If specified, do an incremental dump since $time instead of a full dump.
+#: If specified, dump to $file instead of STDOUT
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_dump} = '$vol, [$time], [$file], [$cell] => Success?';
+sub AFS_vos_dump {
+ my($vol, $time, $file, $cell) = @_;
+ my(@args);
+
+ @args = ('dump', '-id', $vol);
+ push(@args, '-time', ($time ? $time : 0));
+ push(@args, '-file', $file) if ($file);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ],
+ { pass_stdout => !$file });
+ 1;
+}
+
+
+#: AFS_vos_restore($vol, $server, $part, [$file], [$id], [$owmode], [$cell])
+#: Restore the volume $vol to partition $part on server $server.
+#: If specified, restore from $file instead of STDIN
+#: If specified, use the volume ID $id
+#: If specified, $owmode must be 'abort', 'full', or 'incremental', and
+#: indicates what to do if the volume exists.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_restore} = '$vol, $server, $part, [$file], [$id], [$owmode], [$cell] => Success?';
+sub AFS_vos_restore {
+ my($vol, $server, $part, $file, $id, $owmode, $cell) = @_;
+ my(@args);
+
+ @args = ('restore', '-name', $vol, '-server', $server, '-partition', $part);
+ push(@args, '-file', $file) if ($file);
+ push(@args, '-id', $id) if ($id);
+ push(@args, '-overwrite', $owmode) if ($owmode);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_listvldb([$vol], [$server, [$part]], [$locked], [$cell])
+#: Get a list of volumes in the VLDB.
+#: If specified, list only the volume $vol
+#: If specified, list only volumes on the server $server.
+#: If specified with $server, list only volumes on the partition $part.
+#: If $locked is specified and nonzero, list only locked VLDB entries
+#: If specified, work in $cell instead of the default cell.
+#: On success, return an associative array whose keys are names of volumes
+#: on the specified server, and each of whose values is an associative
+#: array describing the corresponding volume, containing some or all of
+#: these elements:
+#: - name Name of this volume (same as key)
+#: - rwid ID of read-write volume (even if this is RO or BK)
+#: - roid ID of read-only volume (even if this is RW or BK)
+#: - bkid ID of backup volume (even if this is RW or RO)
+#: - locked Empty or LOCKED to indicate VLDB entry is locked
+#: - rwserv Name of server where read/write volume is
+#: - rwpart Name of partition where read/write volume is
+#: - rosites Reference to a list of read-only sites. Each site, in turn,
+#: is a reference to a two-element list (server, part).
+#:
+$AFS_Help{vos_listvldb} = '[$vol], [$server, [$part]], [$locked], [$cell] => %vols';
+sub AFS_vos_listvldb {
+ my($vol, $server, $part, $locked, $cell) = @_;
+ my(%finres, %vlist, @rosites);
+
+ @args = ('listvldb');
+ push(@args, '-name', $vol) if ($vol);
+ push(@args, '-server', $server) if ($server);
+ push(@args, '-partition', $part) if ($part && $server);
+ push(@args, '-locked') if ($locked);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %finres = &wrapper('vos', \@args,
+ [$vos_err_parse,
+ ['^(VLDB|Total) entries', '.'],
+ ['^(\S+)', sub {
+ my(%vinfo) = %OpenAFS::wrapper::result;
+
+ if ($vinfo{name}) {
+ $vinfo{rosites} = [@rosites] if (@rosites);
+ $vlist{$vinfo{name}} = \%vinfo;
+
+ @rosites = ();
+ %OpenAFS::wrapper::result = ();
+ }
+ }],
+ ['^(\S+)', 'name' ],
+ ['RWrite\:\s*(\d+)', 'rwid' ],
+ ['ROnly\:\s*(\d+)', 'roid' ],
+ ['Backup\:\s*(\d+)', 'bkid' ],
+ ['Volume is currently (LOCKED)', 'locked' ],
+ ['server (\S+) partition /vicep(\S+) RW Site', 'rwserv', 'rwpart'],
+ ['server (\S+) partition /vicep(\S+) RO Site', sub {
+ push(@rosites, [$_[0], $_[1]]);
+ }],
+ ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+
+ if ($finres{name}) {
+ $finres{rosites} = [@rosites] if (@rosites);
+ $vlist{$finres{name}} = \%finres;
+ }
+ %vlist;
+}
+
+
+
+#: AFS_vos_delentry($vol, [$cell])
+#: Delete the VLDB entry for the volume $vol
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_delentry} = '$vol, [$cell] => Success?';
+sub AFS_vos_delentry {
+ my($vol, $cell) = @_;
+ my(@args);
+
+ @args = ('delentry', '-id', $vol);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_syncserv($server, [$part], [$cell], [$force])
+#: Synchronize the server $server with the VLDB
+#: If specified, synchronize only partition $part
+#: If specified, work in $cell instead of the default cell
+#: If $force is specified, force updates to occur
+#: On success, return 1.
+#:
+$AFS_Help{vos_syncserv} = '$server, [$part], [$cell], [$force] => Success?';
+sub AFS_vos_syncserv {
+ my($server, $part, $cell, $force) = @_;
+ my(@args);
+
+ @args = ('syncserv', '-server', $server);
+ push(@args, '-partition', $part) if ($part);
+ push(@args, '-force') if ($force);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_syncvldb($server, [$part], [$cell], [$force])
+#: Synchronize the VLDB with server $server
+#: If specified, synchronize only partition $part
+#: If specified, work in $cell instead of the default cell
+#: If $force is specified, force updates to occur
+#: On success, return 1.
+#:
+$AFS_Help{vos_syncvldb} = '$server, [$part], [$cell], [$force] => Success?';
+sub AFS_vos_syncvldb {
+ my($server, $part, $cell, $force) = @_;
+ my(@args);
+
+ @args = ('syncvldb', '-server', $server);
+ push(@args, '-partition', $part) if ($part);
+ push(@args, '-force') if ($force);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_lock($vol, [$cell])
+#: Lock the VLDB entry for volume $vol.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_lock} = '$vol, [$cell] => Success?';
+sub AFS_vos_lock {
+ my($vol, $cell) = @_;
+ my(@args);
+
+ @args = ('lock', '-id', $vol);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_unlock($vol, [$cell])
+#: Unlock the VLDB entry for volume $vol.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_unlock} = '$vol, [$cell] => Success?';
+sub AFS_vos_unlock {
+ my($vol, $cell) = @_;
+ my(@args);
+
+ @args = ('unlock', '-id', $vol);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_unlockvldb([$server, [$part]], [$cell])
+#: Unlock some or all VLDB entries
+#: If specified, unlock only entries for volumes on server $server
+#: If specified with $server, unlock only entries for volumes on
+#: partition $part, instead of entries for volumes on all partitions
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_unlockvldb} = '[$server, [$part]], [$cell] => Success?';
+sub AFS_vos_unlockvldb {
+ my($server, $part, $cell) = @_;
+ my(@args);
+
+ @args = ('unlockvldb');
+ push(@args, '-server', $server) if ($server);
+ push(@args, '-partition', $part) if ($server && $part);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_changeaddr($old, $new, [$cell])
+#: Change the IP address of server $old to $new.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return 1.
+#:
+$AFS_Help{vos_changeaddr} = '$old, $new, [$cell] => Success?';
+sub AFS_vos_changeaddr {
+ my($old, $new, $cell) = @_;
+ my(@args);
+
+ @args = ('changeaddr', '-oldaddr', $old, '-newaddr', $new);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_listpart($server, [$cell])
+#: Retrieve a list of partitions on server $server
+#: If specified, work in $cell instead of the default cell.
+#: On success, return a list of partition letters
+#:
+$AFS_Help{vos_listpart} = '$server, [$cell] => @parts';
+sub AFS_vos_listpart {
+ my($server, $cell) = @_;
+ my(@args, @parts);
+
+ @args = ('listpart', '-server', $server);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ [ '^(.*\/vicep.*)$', #',
+ sub {
+ push(@parts, map {
+ my($x) = $_;
+ $x =~ s/^\/vicep//;
+ $x;
+ } split(' ', $_[0]));
+ }],
+ ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+ @parts;
+}
+
+
+#: AFS_vos_partinfo($server, [$part], [$cell])
+#: Get information about partitions on server $server.
+#: If specified, only get info about partition $part.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return an associative array whose keys are partition letters,
+#: and each of whose values is a reference to a 2-element list, consisting
+#: of the total size of the partition and the amount of space used.
+#:
+$AFS_Help{vos_partinfo} = '$server, [$part], [$cell] => %info';
+sub AFS_vos_partinfo {
+ my($server, $part, $cell) = @_;
+ my(@args, %parts);
+
+ @args = ('partinfo', '-server', $server);
+ push(@args, '-partition', $part) if ($part);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ [ '^Free space on partition /vicep(.+)\: (\d+) K blocks out of total (\d+)',
+ sub {
+ $parts{$_[0]} = [ $_[1], $_[2] ];
+ }],
+ ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+ %parts;
+}
+
+
+#: AFS_vos_listvol($server, [$part], [$cell])
+#: Get a list of volumes on the server $server.
+#: If specified, list only volumes on the partition $part.
+#: If specified, work in $cell instead of the default cell.
+#: On success, return an associative array whose keys are names of volumes
+#: on the specified server, and each of whose values is an associative
+#: array describing the corresponding volume, containing some or all of
+#: these elements:
+#: - name Name of this volume (same as key)
+#: - id ID of this volume
+#: - kind Kind of volume (RW, RO, or BK)
+#: - inuse Disk space in use
+#: - maxquota Maximum disk usage quota
+#: - minquota Minimum disk usage quota (optional)
+#: - stamp_create Time when volume was originally created
+#: - stamp_update Time volume was last modified
+#: - stamp_backup Time backup volume was cloned, or 'Never'
+#: - stamp_copy Time this copy of volume was made
+#: - backup_flag State of automatic backups: empty or 'disabled'
+#: - dayuse Number of accesses in the past day
+#: - serv Server where this volume is located
+#: - part Partition where this volume is located
+#:
+$AFS_Help{vos_listvol} = '$server, [$part], [$cell] => %vols';
+sub AFS_vos_listvol {
+ my($server, $part, $cell) = @_;
+ my(%finres, %vlist);
+
+ @args = ('listvol', '-server', $server, '-long');
+ push(@args, '-partition', $part) if ($part);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ %finres = &wrapper('vos', \@args,
+ [$vos_err_parse,
+ ['^\S+\s*\d+\s*(RW|RO|BK)', sub {
+ my(%vinfo) = %OpenAFS::wrapper::result;
+
+ if ($vinfo{name}) {
+ $vlist{$vinfo{name}} = \%vinfo;
+ %OpenAFS::wrapper::result = ();
+ }
+ }],
+ ['^(\S+)\s*(\d+)\s*(RW|RO|BK)\s*(\d+)\s*K', 'name', 'id', 'kind', 'inuse'],
+ ['(\S+)\s*\/vicep(\S+)\:', 'serv', 'part' ],
+ ['MaxQuota\s*(\d+)\s*K', 'maxquota' ],
+ ['MinQuota\s*(\d+)\s*K', 'minquota' ],
+ ['Creation\s*(.*\S+)', 'stamp_create' ],
+ ['Last Update\s*(.*\S+)', 'stamp_update' ],
+ ['Backup\s+([^\d\s].*\S+)', 'stamp_backup' ],
+ ['Copy\s*(.*\S+)', 'stamp_copy' ],
+ ['Automatic backups are (disabled) for this volume', 'backup_flag' ],
+ ['(\d+) accesses in the past day', 'dayuse' ],
+ ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+
+ if ($finres{name}) {
+ $vlist{$finres{name}} = \%finres;
+ }
+ %vlist;
+}
+
+#: AFS_vos_zap($vol, $server, $part, [$cell], [$force])
+#: Remove the volume $vol from the server and partition specified by $server and
+#: $part. Don't bother messing with the VLDB.
+#: If specified, work in $cell instead of the default cell.
+#: If $force is specified, force the zap to happen
+#: On success, return 1.
+#:
+$AFS_Help{vos_zap} = '$vol, $server, $part, [$cell], [$force] => Success?';
+sub AFS_vos_zap {
+ my($vol, $server, $part, $cell, $force) = @_;
+ my(@args);
+
+ @args = ('zap', '-id', $vol, '-server', $server, '-part', $part);
+ push(@args, '-force') if ($force);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 1);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ $AFS_Parms{'vostrace'} ? ([ '', '?']) : () ]);
+ 1;
+}
+
+
+#: AFS_vos_status($server, [$cell])
+#: Get information about outstanding transactions on $server
+#: If specified, work in $cell instead of the default cell
+#: On success, return a list of transactions, each of which is a reference
+#: to an associative array containing some or all of these elements:
+#: - transid Transaction ID
+#: - stamp_create Time the transaction was created
+#: - volid Volume ID
+#: - part Partition letter
+#: - action Action or procedure
+#: - flags Volume attach flags
+#: If there are no transactions, the list will be empty.
+#:
+$AFS_Help{vos_status} = '$server, [$cell] => @trans';
+sub AFS_vos_status {
+ my($server, $cell) = @_;
+ my(@trlist);
+
+ @args = ('status', '-server', $server);
+ push(@args, '-noauth') if ($AFS_Parms{'authlvl'} == 0);
+ push(@args, '-localauth') if ($AFS_Parms{'authlvl'} == 2);
+ push(@args, '-verbose') if ($AFS_Parms{'vostrace'} > 2);
+ push(@args, '-cell', $cell ? $cell : $AFS_Parms{'cell'});
+ &wrapper('vos', \@args,
+ [$vos_err_parse,
+ ['^(\-)', sub {
+ my(%trinfo) = %OpenAFS::wrapper::result;
+
+ if ($trinfo{transid}) {
+ push(@trlist, \%trinfo);
+ %OpenAFS::wrapper::result = ();
+ }
+ }],
+ ['^transaction\:\s*(\d+)\s*created: (.*\S+)', 'transid', 'stamp_create'],
+ ['^attachFlags:\s*(.*\S+)', 'flags'],
+ ['^volume:\s*(\d+)\s*partition\: \/vicep(\S+)\s*procedure\:\s*(\S+)',
+ 'volid', 'part', 'action'],
+ ($AFS_Parms{'vostrace'} > 2) ? ([ '', '?']) : () ]);
+
+ @trlist;
+}
+
+1;
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_addsite("testvol","localhost","b",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_backup("rep",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+$ret = &AFS_vos_create("testvol","localhost","a",,);
+$ret = &AFS_vos_create("testvol2","localhost","a",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_delentry("testvol",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_dump("service",0,"/usr/tmp/service.dump",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, %info, %info2, @rosites, $tmp, @rosite);
+$host = `hostname`;
+chomp $host;
+&AFS_Init();
+
+%info = &AFS_vos_examine("rep",);
+if ($info{'rwpart'} ne "a") {
+ exit 1;
+}
+
+$ret = $info{'rosites'};
+@rosites = @$ret;
+while ($ret = pop(@rosites)) {
+ @rosite = @$ret;
+ if ($rosite[1] ne "a") {
+ exit 1;
+ }
+}
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret, @parts, $count);
+$host = `hostname`;
+&AFS_Init();
+
+@parts = &AFS_vos_listpart("localhost",);
+$ret = shift(@parts);
+if ($ret ne "a") {
+ exit (1);
+}
+$ret = shift(@parts);
+if ($ret ne "b") {
+ exit (1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret, %vols, $lvol, %vol);
+$host = `hostname`;
+&AFS_Init();
+
+%vols = &AFS_vos_listvldb(undef,"localhost","b",,);
+$lvol=$vols{'testvol3'};
+%vol=%$lvol;
+# if it worked it worked...
+if ($vol{'rwpart'} ne "b") {
+ exit(1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret, %vols, $lvol, %vol);
+$host = `hostname`;
+&AFS_Init();
+
+%vols = &AFS_vos_listvol("localhost","b",);
+$lvol=$vols{'testvol3'};
+%vol=%$lvol;
+# if it worked it worked...
+if ($vol{'part'} ne "b") {
+ exit(1);
+}
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_lock("testvol",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_move("testvol","localhost","a","localhost","b",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret, %info);
+$host = `hostname`;
+&AFS_Init();
+
+%info = &AFS_vos_partinfo("localhost",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_release("testvol",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_remove("testvol.readonly","localhost","b",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_remsite("testvol","localhost","b",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_rename("testvol","testvol3",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_restore("service2","localhost","a","/usr/tmp/service.dump",,"full",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_syncserv("localhost","a",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_syncvldb("localhost","b",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_unlock("testvol",);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_lock("testvol",);
+&AFS_vos_lock("service",);
+&AFS_vos_unlockvldb("localhost",,);
+
+exit(0);
+
+
+
--- /dev/null
+#!/usr/bin/env perl
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT %AFS_Help);
+use OpenAFS::afsconf;
+use OpenAFS::fs;
+use OpenAFS::pts;
+use OpenAFS::vos;
+use OpenAFS::bos;
+
+my ($host, $ret);
+$host = `hostname`;
+&AFS_Init();
+
+&AFS_vos_zap("testvol2","localhost","a",,);
+
+exit(0);
+
+
+
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id$");
+#endif
+
+#include "err.h"
+
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarn(fmt, ap);
+ va_end(ap);
+}
--- /dev/null
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id$");
+#endif
+
+#include "err.h"
+
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
--- /dev/null
+# CMUCS AFStools
+# Copyright (c) 1996, 2001 Carnegie Mellon University
+# All rights reserved.
+#
+# See CMU_copyright.ph for use and distribution information
+
+package OpenAFS::wrapper;
+
+=head1 NAME
+
+OpenAFS::wrapper - AFS command wrapper
+
+=head1 SYNOPSIS
+
+ use OpenAFS::wrapper;
+ %result = &wrapper($cmd, \@args, \@pspec, \%options);
+
+=head1 DESCRIPTION
+
+This module provides a generic wrapper for calling an external program and
+parsing its output. It is primarily intended for use by AFStools for calling
+AFS commands, but is general enough to be used for running just about any
+utility program. The wrapper is implemented by a single function,
+B<OpenAFS::wrapper::wrapper>, which takes several arguments:
+
+=over 4
+
+=item $cmd
+
+The command to run. This can be a full path, or it can be a simple command
+name, in which case B<wrapper()> will find the binary on its internal path.
+
+=item \@args
+
+A reference to the list of arguments to be passed to the command. Each
+element of the list is passed as a single argument, as in B<exec()>.
+
+=item \@pspec
+
+A reference to the list describing how to parse the command's output.
+See below for details.
+
+=item \%options
+
+A reference to a table of command execution and parsing options.
+
+=back
+
+On success, B<wrapper()> returns an associative array of data gathered
+from the command's output. The exact contents of this array are
+caller-defined, and depend on the parsing instructions given. On failure,
+an exception will be thrown (using B<die>), describing the reason for the
+failure.
+
+The I<%options> table may be used to pass any or all of the following
+options into B<wrapper()>, describing how the command should be executed
+and its output parsed:
+
+=over 4
+
+=item pass_stderr
+
+If specified and nonzero, the command's stderr will be passed directly
+to the calling program's, instead of being parsed. This is useful when
+we want to process the command's output, but let the user see any
+diagnostic output or error messages.
+
+=item pass_stdout
+
+If specified and nonzero, the command's stdout will be passed directly
+to the calling program's, instead of being parsed. This is useful when
+the command being run produces diagnostic or error messages on stderr
+that we want to parse, but provides bulk data on stdout that we don't
+want to touch (e.g. B<vos dump> when the output file is stdout).
+
+=item path
+
+If specified, the path to be used for the program to execute, instead of
+deriving it from the command name. This is useful when we want the
+command's argv[0] (which is always I<$cmd}) to be different from the
+path to the program.
+
+=item errors_last
+
+If specified and nonzero, the built-in instructions for catching errors
+from the command will be added to the end of the instructions in @pspec
+instead of to the beginning.
+
+=back
+
+=head1 PARSING COMMAND OUTPUT
+
+The I<@pspec> list describes how to parse command output. Each element
+of the list acts like an "instruction" describing how to parse the command's
+output. As each line of output is received from the program, the parsing
+instructions are run over that line in order. This process continues for
+every line of output until the program terminates, or the process is
+aborted early by flow-control operators.
+
+Each parsing instruction is a reference to a list, which consists of a
+regular expression and a list of "actions". As a line of output is
+processed, it is compared to each instruction's regexp in turn. Whenever
+a match is found, the actions associated with that instruction are taken,
+in order. Each instruction's regexp may contain one or more parenthesized
+subexpressions; generally, each "action" uses up one subexpression, but there
+are some exceptions. Due to the current design of B<wrapper()>, each regexp
+must have at least one subexpression, even if it is not used.
+
+The acceptable actions are listed below, each followed by a number in brackets
+indicating how many subexpressions are "used" by this action. It is an error
+if there are not enough subexpressions left to satisfy an action. In the
+following descriptions, I<$action> is the action itself (typically a string or
+reference), I<$value> is the value of the subexpression that will be used, and
+I<%result> is the result table that will be returned by B<wrapper> when the
+command completes.
+
+=over 4
+
+=item string [1]
+
+Sets $result{$action} to $value. Note that several specific strings have
+special meaning, and more may be added in the future. To ensure compatibility
+with future versions of B<wrapper>, use only valid Perl identifiers as
+"string" actions.
+
+=item scalar ref [1]
+
+Sets $$action to $value.
+
+=item list ref [*]
+
+Pushes the remaining subexpression values onto @$action. This action uses
+all remaining subexpression values.
+
+=item hash ref [2]
+
+Sets $$action{$value0} to $value1.
+
+=item code ref [*]
+
+Calls the referenced function, with all remaining subexpression values as
+its arguments. Any values returned by the function will be used to refill
+the (now empty) subexpression value list, and thus may be used as arguments
+by subsequent actions. If only a few values are required, use a function
+like this:
+
+ sub usetwo { # uses two values and preserves the rest
+ my($val1, $val2, @rest) = @_;
+
+ print STDOUT "Got $val1, $val2\n";
+ @rest;
+ }
+
+=item '.' [0]
+
+End processing for this line of output, ignoring any remaining instructions.
+Remaining actions in this instruction will be processed.
+
+=item '+n' [0]
+
+Skip the next I<n> instructions. This, along with the '.' action, can be
+used to build simple flow-control constructs based on the contents of
+lines of output.
+
+=item '-x' [0..1]
+
+Signal an error after this instruction. Remaining actions in this instruction
+will be processed, but no further instructions will be processed for this
+line, and no further lines of output will be processed. If I<x> is given,
+it will be used as a regexp to match against the B<previous> line of output,
+and the first parenthesized subexpression resulting from that match will be
+used as the error string. Otherwise, one subexpression from the current
+line will be used up as the error string.
+
+=item '?' [1]
+
+Prints $value to STDOUT.
+
+=back
+
+=cut
+
+use OpenAFS::CMU_copyright;
+use OpenAFS::util qw(:DEFAULT :afs_internal);
+use Exporter;
+use Symbol;
+
+$VERSION = '';
+$VERSION = '1.00';
+@ISA = qw(Exporter);
+@EXPORT = qw(&wrapper);
+@EXPORT_OK = qw(&wrapper &fast_wrapper);
+
+sub wrapper {
+ my($cmd, $args, $instrs, $options) = @_;
+ my($prevline, $pid, $exception);
+ my(@instrs, $instr, $action, @values, $path);
+ local(%result);
+ my(@werrinstrs) = ([ '^(wrapper\:.*)', '-' ]);
+ my(@cerrinstrs) = ([ '^(' . $cmd . '\:.*)', '-' ],
+ [ '^(' . $path . '\:.*)', '-' ]);
+
+ if ($options->{errors_last}) {
+ @instrs = (@werrinstrs, @$instrs, @cerrinstrs);
+ } else {
+ @instrs = (@werrinstrs, @cerrinstrs, @$instrs);
+ }
+
+ if ($options->{path}) {
+ $path = $options->{path};
+ } elsif ($cmd =~ /^\//) {
+ $path = $cmd;
+ } else {
+ $path = $AFScmd{$cmd};
+ }
+
+ if ($AFS_Trace{wrapper}) {
+ print STDERR "Instructions:\n";
+ foreach $instr (@$instrs) {
+ print STDERR " /", $instr->[0], "/\n";
+ if ($AFS_Trace{wrapper} > 2) {
+ my(@actions) = @$instr;
+ shift(@actions);
+ print " => ",
+ join(', ', map { ref($_) ? "<" . ref($_) . " reference>"
+ : $_ } @actions),
+ "\n";
+ }
+ }
+ }
+
+ ## Start the child
+ if ($options->{pass_stdout}) {
+ open(REALSTDOUT, ">&STDOUT");
+ }
+ $pid = open(AFSCMD, "-|");
+ if (!defined($pid)) {
+ die "wrapper: Fork failed for $cmd: $!\n";
+ }
+
+ ## Run the appropriate program
+ if (!$pid) {
+
+ if ($AFS_Trace{wrapper} > 1) {
+ print STDERR "Command: $path ", join(' ', @$args), "\n";
+ }
+
+ open(STDERR, ">&STDOUT") if (!$options{pass_stderr});
+ if ($options{pass_stdout}) {
+ open(STDOUT, ">&REALSTDOUT");
+ close(REALSTDOUT);
+ }
+
+ { exec($path $cmd, @$args); }
+ # Need to be careful here - we might be doing "vos dump" to STDOUT
+ if ($options{pass_stdout}) {
+ print STDERR "wrapper: Exec failed for $cmd: $!\n";
+ } else {
+ print STDOUT "wrapper: Exec failed for $cmd: $!\n";
+ }
+ exit(127);
+ }
+ if ($options{pass_stdout}) {
+ close(REALSTDOUT);
+ }
+
+ ## Now, parse the output
+ line:
+ while (<AFSCMD>) {
+ my($skip) = 0;
+
+ print STDERR $_ if ($AFS_Trace{wrapper} > 3);
+ chop;
+
+ instr:
+ foreach $instr (@instrs) {
+ my($dot, $action, @actions);
+
+ if ($skip) {
+ $skip--;
+ next instr;
+ }
+ $dot = 0;
+ if ($instr->[0]) {
+ @values = ($_ =~ $instr->[0]);
+ next instr if (!@values);
+ } else {
+ @values = ();
+ }
+
+ act:
+ @actions = @$instr;
+ shift(@actions);
+ foreach $action (@actions) {
+ if (ref($action) eq 'SCALAR') {
+ if (@values) {
+ $$action = shift(@values);
+ } else {
+ last act;
+ }
+ } elsif (ref($action) eq 'ARRAY') {
+ push(@$action, @values);
+ @values = ();
+ } elsif (ref($action) eq 'HASH') {
+ if (@values > 1) {
+ $$action{$values[0]} = $values[1];
+ shift(@values); shift(@values);
+ } elsif (@values) {
+ $$action{shift @values} = '';
+ last act;
+ } else {
+ last act;
+ }
+ } elsif (ref($action) eq 'CODE') {
+ @values = &$action(@values);
+ } elsif (ref($action)) {
+ $exception = "Unknown reference to " . ref($action)
+ . "in parse instructions";
+ last line;
+ } else { ## Must be a string!
+ if ($action eq '.') {
+ $dot = 1;
+ } elsif ($action =~ /\+(\d+)/) {
+ $skip = $1;
+ } elsif ($action =~ /-(.*)/) {
+ my($pat) = $1;
+
+ if ($pat && $prevline) {
+ ($exception) = ($prevline =~ $pat);
+ } elsif (@values) {
+ $exception = shift(@values);
+ } else {
+ $exception = $_;
+ }
+ } elsif ($action eq '?') {
+ print STDOUT (@values ? shift(@values) : $_), "\n";
+ } elsif (@values) {
+ $result{$action} = shift(@values);
+ } else {
+ last act;
+ }
+ }
+ }
+
+ last line if ($exception);
+ last instr if ($dot);
+ }
+ $prevline = $_;
+ }
+ close(AFSCMD);
+ $exception .= "\n" if ($exception && $exception !~ /\n$/);
+ die $exception if ($exception);
+ %result;
+}
+
+
+## Generate code for a fast wrapper (see example below)
+sub _fastwrap_gen {
+ my($instrs, $refs) = @_;
+ my($SRC, $N, $N1, $X, $instr, $pattern, @actions, $action);
+
+ $N = $X = 0;
+ $N1 = 1;
+
+ $SRC = <<'#####';
+sub {
+ my($FD, $refs) = @_;
+ my($prevline, @values, $skip, $exception);
+
+ line: while (<$FD>) {
+#####
+
+ $SRC .= " print STDERR \$_;\n" if ($AFS_Trace{'wrapper'} > 3);
+ $SRC .= " chop;\n";
+
+ foreach $instr (@$instrs) {
+ ($pattern, @actions) = (@$instr);
+ $SRC .= ($pattern ? <<"#####" : <<"#####");
+
+ instr_$N:
+ die \$exception if \$exception;
+ if (\$skip) { \$skip-- } else {
+ \@values = (\$_ =~ /$pattern/);
+ if (\@values) {
+#####
+
+ instr_$N:
+ die \$exception if \$exception;
+ if (\$skip) { \$skip-- } else {
+ \@values = ();
+ if (1) {
+#####
+
+ foreach $action (@actions) {
+ if (ref($action) eq 'SCALAR') {
+ $refs[++$X] = $action;
+ $SRC .= <<"#####";
+
+ if (\@values) { \${\$refs[$X]} = shift (\@values) }
+ else { goto instr_$N1 }
+#####
+
+ } elsif (ref($action) eq 'ARRAY') {
+ $refs[++$X] = $action;
+ $SRC .= <<"#####";
+
+ push(\@{\$refs[$X]}, \@values);
+ \@values = ();
+#####
+
+ } elsif (ref($action) eq 'HASH') {
+ $refs[++$X] = $action;
+ $SRC .= <<"#####";
+
+ if (\@values > 1) {
+ \$refs[$X]{\$values[0]} = shift(\$values[1]);
+ shift(\@values); shift(\@values);
+ } elsif (\@values) {
+ \$refs[$X]{shift(\@values)} = '';
+ goto instr_$N1;
+ } else {
+ goto instr_$N1;
+ }
+#####
+
+ } elsif (ref($action) eq 'CODE') {
+ $refs[++$X] = $action;
+ $SRC .= "\n \@values = \$refs[$X]->(\@values);\n";
+
+ } elsif (ref($action)) {
+ die "Unknown reference to " . ref($action) . "in parse instructions\n";
+
+ } elsif ($action eq '.') {
+ $SRC .= "\n next line;\n";
+
+ } elsif ($action eq '?') {
+ $SRC .= <<"#####";
+
+ if (\@values) { print STDOUT shift(\@values), "\\n" }
+ else { print STDOUT \$_, "\\n" }
+#####
+
+ } elsif ($action =~ /\+(\d+)/) {
+ $SRC .= "\n \$skip = $1;\n";
+
+ } elsif ($action =~ /-(.*)/) {
+ $SRC .= $1 ? <<"#####" : <<"#####";
+
+ if (\$prevline) { (\$exception) = (\$prevline =~ /$1/) }
+ elsif (\@values) { \$exception = shift(\@values) }
+ else { \$exception = \$_ }
+#####
+
+ if (\@values) { \$exception = shift(\@values) }
+ else { \$exception = \$_ }
+#####
+
+ } else {
+ $SRC .= <<"#####";
+
+ if (\@values) { \$result{"\Q$action\E"} = shift(\@values) }
+ else { goto instr_$N1 }
+#####
+ }
+ }
+
+ $N++; $N1++;
+ $SRC .= <<'#####';
+ }
+ }
+#####
+ }
+
+ $SRC .= <<'#####';
+ } continue {
+ die $exception if $exception;
+ $prevline = $_;
+ }
+}
+#####
+
+ $SRC;
+}
+
+####################### Example code #######################
+# sub {
+# my($FD, $refs) = @_;
+# my($prevline, @values, $skip, $exception);
+#
+# line: while (<$FD>) {
+# print STDERR $_; ## if ($AFS_Trace{'wrapper'} > 3);
+# chop;
+#
+# ## Following block repeated for each instruction
+# instr_N:
+# die $exception if $exception;
+# if ($skip) { $skip-- } else {
+# @values = ($_ =~ /## pattern ##/); ## () if no pattern
+# if (@values) { ## 1 if no pattern
+# ## For each action, include one of the following blocks:
+#
+# ## SCALAR ref
+# if (@values) { ${$refs[X]} = shift (@values) }
+# else { goto instr_N+1 }
+#
+# ## ARRAY ref
+# push(@{$refs[X]}, @values);
+# @values = ();
+#
+# ## HASH ref
+# if (@values > 1) {
+# $refs[X]{shift(@values)} = shift(@values);
+# } elsif (@values) {
+# $refs[X]{shift(@values)} = '';
+# goto instr_N+1;
+# } else {
+# goto instr_N+1;
+# }
+#
+# ## CODE ref
+# @values = $refs[X]->(@values);
+#
+# ## string '.'
+# next line;
+#
+# ## string '?'
+# if (@values) { print STDOUT shift(@values), "\n" }
+# else { print STDOUT $_, "\n" }
+#
+# ## string '+DDD'
+# $skip = DDD;
+#
+# ## string '-XXX'
+# if ($prevline) { ($exception) = ($prefline =~ /XXX/) }
+# elsif (@values) { $exception = shift(@values) }
+# else { $exception = $_ }
+#
+# ## string '-'
+# if (@values) { $exception = shift(@values) }
+# else { $exception = $_ }
+#
+# ## anything else
+# if (@values) { $result{XXX} = shift(@values) }
+# else { goto instr_N+1 }
+# }
+# }
+#
+# } continue {
+# die $exception if $exception;
+# $prevline = $_;
+# }
+# }
+############################################################
+
+
+## The following does exactly the same thing as wrapper(),
+## but should be considerably faster. Instead of interpreting
+## parsing instructions, it translates them into perl code,
+## which is then compiled into the interpreter. The chief
+## benefit to this approach is that we no longer compile
+## one RE per instruction per line of input.
+
+sub fast_wrapper {
+ my($cmd, $args, $instrs, $options) = @_;
+ my(@instrs, $SRC, $CODE, $path, $pid, $refs, $FD, $exception);
+ local(%result);
+ my(@werrinstrs) = ([ '^(wrapper\:.*)', '-' ]);
+ my(@cerrinstrs) = ([ '^(' . $cmd . '\:.*)', '-' ],
+ [ '^(' . $path . '\:.*)', '-' ]);
+
+ $FD = gensym;
+ $refs = [];
+ if ($options->{errors_last}) {
+ @instrs = (@werrinstrs, @$instrs, @cerrinstrs);
+ } else {
+ @instrs = (@werrinstrs, @cerrinstrs, @$instrs);
+ }
+ $SRC = _fastwrap_gen(\@instrs, $refs);
+ $CODE = eval $SRC;
+
+ if ($options->{path}) {
+ $path = $options->{path};
+ } elsif ($cmd =~ /^\//) {
+ $path = $cmd;
+ } else {
+ $path = $AFScmd{$cmd};
+ }
+
+ if ($AFS_Trace{'wrapper'}) {
+ print STDERR "Instructions:\n";
+ foreach $instr (@$instrs) {
+ print STDERR " /", $instr->[0], "/\n";
+ if ($AFS_Trace{'wrapper'} > 2) {
+ my(@actions) = @$instr;
+ shift(@actions);
+ print " => ",
+ join(', ', map { ref($_) ? "<" . ref($_) . " reference>"
+ : $_ } @actions),
+ "\n";
+ }
+ }
+ }
+
+ if ($AFS_Trace{'wrapper'} > 2) { print STDERR "Input parse code:\n$SRC\n" }
+
+ ## Start the child
+ if ($options->{pass_stdout}) {
+ open(REALSTDOUT, ">&STDOUT");
+ }
+ $pid = open($FD, "-|");
+ if (!defined($pid)) {
+ die "wrapper: Fork failed for $cmd: $!\n";
+ }
+
+ ## Run the appropriate program
+ if (!$pid) {
+ if ($AFS_Trace{'wrapper'} > 1) {
+ print STDERR "Command: $path ", join(' ', @$args), "\n";
+ }
+
+ open(STDERR, ">&STDOUT") if (!$options{pass_stderr});
+ if ($options{pass_stdout}) {
+ open(STDOUT, ">&REALSTDOUT");
+ close(REALSTDOUT);
+ }
+
+ { exec($path $cmd, @$args) }
+ # Need to be careful here - we might be doing "vos dump" to STDOUT
+ if ($options{pass_stdout}) {
+ print STDERR "wrapper: Exec failed for $cmd: $!\n";
+ } else {
+ print STDOUT "wrapper: Exec failed for $cmd: $!\n";
+ }
+ exit(127);
+ }
+ if ($options{pass_stdout}) {
+ close(REALSTDOUT);
+ }
+
+ ## Now, parse the output
+ eval { $CODE->($FD, $refs) };
+ $exception = $@;
+
+ close($FD);
+
+ $exception .= "\n" if ($exception && $exception !~ /\n$/);
+ die $exception if ($exception);
+ %result;
+}
+
+
+1;
+
+=head1 EXAMPLES
+
+The following set of instructions is used by B<wrapper> to detect errors
+issued by the command, or by the child process spawned to invoke the command.
+I<$cmd> is the name of the command to run, and I<$path> is the path to the
+binary actually invoked.
+
+ [ '^(wrapper\:.*)', '-' ]
+ [ '^(' . $cmd . '\:.*)', '-' ]
+ [ '^(' . $path . '\:.*)', '-' ]
+
+The following instruction is added by the B<OpenAFS::vos> module to catch errors
+generated by B<vos> commands, which often take the form of a generic error
+message (Error in vos XXX command), with a description of the specific problem
+on the preceeding line:
+
+ [ 'Error in vos (.*) command', '-(.*)' ]
+
+If the AFStools parameter I<vostrace> is nonzero, the following instruction
+is added to force all lines of output to be copied to STDOUT. Note that this
+is different from specifying the I<pass_stdout> option, which would pass the
+command's STDOUT directly to ours without parsing it.
+
+ [ '', '?' ]
+
+B<OpenAFS::vos::AFS_vos_listvldb> uses the following instructions to parse the
+output of "vos listvldb". This is a fairly complex example, which illustrates
+many of the features of B<wrapper>.
+
+ 1 ['^(VLDB|Total) entries', '.']
+ 2 ['^(\S+)', sub {
+ my(%vinfo) = %OpenAFS::wrapper::result;
+ if ($vinfo{name}) {
+ $vinfo{rosites} = [@rosites] if (@rosites);
+ $vlist{$vinfo{name}} = \%vinfo;
+ @rosites = ();
+ %OpenAFS::wrapper::result = ();
+ }
+ }],
+ 3 ['^(\S+)', 'name' ],
+ 4 ['RWrite\:\s*(\d+)', 'rwid' ],
+ 5 ['ROnly\:\s*(\d+)', 'roid' ],
+ 6 ['Backup\:\s*(\d+)', 'bkid' ],
+ 7 ['Volume is currently (LOCKED)', 'locked' ],
+ 8 ['server (\S+) partition /vicep(\S+) RW Site', 'rwserv', 'rwpart'],
+ 9 ['server (\S+) partition /vicep(\S+) RO Site', sub {
+ push(@rosites, [$_[0], $_[1]]);
+ }],
+
+Instruction 1 matchees the header and trailer lines printed out by B<vos>, and
+terminates processing of those lines before instructions 2 and 3 have a chance
+to match it. This is a simple example of a conditional - the next two
+instructions are used only if this one doesn't match. If we wanted to consider
+additional instructions even on lines that do match this one, we could place
+them above this one, or use '+2' instead of '.', which would skip only the next
+two instructions and allow remaining ones to be processed.
+
+Instruction 2 matches the first line printed for each volume, stores away any
+information that has been collected about the previous volume, and prepares for
+the new one. Besides being a good example of use of a code reference as an
+action, this instruction also takes advantage of the fact that B<wrapper>'s
+%result array is a dynamically-scoped variable, and so can be modified by code
+referenced in parsing instructions.
+
+The remaining instructions are fairly simple. Instructions 3 through 8 use
+simple strings to add information about the volume to %result. Instruction 9
+is a bit more complicated; it uses a function to add a server/partition pair
+to the current volume's list of RO sites.
+
+=head1 COPYRIGHT
+
+The CMUCS AFStools, including this module are
+Copyright (c) 1996, 2001 Carnegie Mellon University. All rights reserved.
+For use and redistribution information, see CMUCS/CMU_copyright.pm
+
+=cut
--- /dev/null
+/*
+ * Copyright (c) 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void
+doit (const char *filename)
+{
+ int fd;
+ int ret;
+ void *buf;
+
+ fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = ftruncate (fd, 1);
+ if (ret < 0)
+ err (1, "ftruncate %s", filename);
+ buf = mmap (NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (buf == (void *) MAP_FAILED)
+ err (1, "mmap");
+ if (fchmod (fd, 0) < 0)
+ err (1, "fchmod %s, 0", filename);
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close %s", filename);
+ *((char *)buf) = 0x17;
+ ret = munmap (buf, 1);
+ if (ret < 0)
+ err (1, "munmap");
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "foo";
+
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <err.h>
+#include <netinet/in.h>
+#include <afs/param.h>
+#include <afs/stds.h>
+#include <afs/vice.h>
+#include <afs/venus.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static int
+set_acl (char *dir)
+{
+ struct ViceIoctl a_params;
+ char *foo = "1\n0\nsystem:anyuser 0\n";
+
+ a_params.in_size = strlen(foo);
+ a_params.out_size = 0;
+ a_params.in = foo;
+ a_params.out = NULL;
+
+ return pioctl (dir, VIOCSETAL, &a_params, 1);
+}
+
+static void
+doit (const char *filename)
+{
+ int fd;
+ int ret;
+ void *buf;
+
+ ret = mkdir ("bad", 0777);
+ if (ret < 0)
+ err (1, "mkdir bad");
+
+ ret = chdir ("bad");
+ if (ret < 0)
+ err (1, "chdir bad");
+
+ fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = ftruncate (fd, 1);
+ if (ret < 0)
+ err (1, "ftruncate %s", filename);
+ buf = mmap (NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (buf == (void *) MAP_FAILED)
+ err (1, "mmap");
+ ret = set_acl (".");
+ if (ret < 0)
+ err (1, "setacl failed");
+
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close %s", filename);
+ *((char *)buf) = 0x17;
+ ret = munmap (buf, 1);
+ if (ret < 0)
+ err (1, "munmap");
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "foo";
+
+
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#define _LARGEFILE64_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#include <err.h>
+
+const char *fn = "foobar";
+
+static void
+check_size(const char *fn, size_t sz, int paranoia)
+{
+ struct stat sb;
+
+ if (paranoia)
+ return;
+
+ if (stat(fn, &sb) < 0)
+ err(1, "stat");
+ if (sb.st_size != sz)
+ errx(1, "st_size mismatch %d != %d", (int)sb.st_size, (int)sz);
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd, cnt, ret;
+ int buf[1024];
+
+#ifdef O_LARGEFILE
+ fd = open(fn, O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0644);
+#else
+ fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0644);
+#endif
+ if (fd < 0)
+ err(1, "open1");
+ cnt=0;
+ while (cnt < 2097151) {
+ ret = write(fd,buf,1024);
+ if (ret != 1024)
+ errx(1, "write1 %d %d", cnt, ret);
+ cnt++;
+ }
+ ret = write(fd,buf,1024);
+ if (ret != 1023)
+ errx(1, "write1 last %d", ret);
+ if (close(fd) < 0)
+ err(1, "close1");
+
+ check_size(fn, 2147483647, 0);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+static char *
+write_random_file (int fd, size_t sz)
+{
+ char *buf;
+ int i, j;
+
+ j = sz;
+ if (j > 2048) {
+ j = 2048;
+ }
+ buf = malloc (j);
+ if (buf == NULL)
+ err (1, "malloc %u", (unsigned)sz);
+
+ for (i = 0; i < j; ++i) {
+ buf[i] = rand();
+ }
+ while (sz > 0) {
+ if (write (fd, buf, j) != j)
+ err (1, "write");
+
+ sz -= j;
+ j = sz;
+ if (j > 2048)
+ j = 2048;
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ const char *file;
+ const size_t sz;
+ char *random_buf;
+ char *read_buf1;
+ char *read_buf2;
+ int fd;
+
+ if (argc != 3)
+ errx (1, "usage: %s file size", argv[0]);
+
+ file = argv[1];
+ sz = atoi(argv[2]);
+
+ srand (time(NULL));
+
+ fd = open (file, O_RDWR | O_CREAT, 0755);
+ if (fd < 0)
+ err (1, "open %s", file);
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err (1, "lseek");
+ write_random_file(fd, sz);
+
+ close (fd);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+touch ../../replicated/foo || exit 0
+exit 1
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <err.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ int ret;
+
+ fd = open("foo", O_RDWR|O_CREAT, 0);
+ if (fd < 0)
+ err (1, "open foo");
+ ret = write (fd, "foo", 3);
+ if (ret < 0) {
+ unlink("foo");
+ err (1, "write foo");
+ }
+ ret = close (fd);
+ if (ret < 0) {
+ unlink("foo");
+ err (1, "close foo");
+ }
+ unlink("foo");
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <err.h>
+
+static void
+doit (const char *filename)
+{
+ int fd;
+ int ret;
+ struct timeval tv[2];
+ struct stat sb;
+
+ fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0)
+ err (1, "open %s", filename);
+ ret = write (fd, "hej\n", 4);
+ if(ret < 0)
+ err (1, "write %s", filename);
+ if (ret != 4)
+ errx (1, "short write to %s", filename);
+ gettimeofday (&tv[0], NULL);
+ tv[1] = tv[0];
+ ret = utimes (filename, tv);
+ if(ret < 0)
+ err (1, "utimes %s", filename);
+ ret = chmod (filename, 0644);
+ if (ret < 0)
+ err (1, "chmod %s", filename);
+ ret = chown (filename, 0, 0);
+ ret = fstat (fd, &sb);
+ if (ret < 0)
+ err (1, "fstat %s", filename);
+ if (sb.st_size != 4)
+ errx (1, "stat 1: size = %lu != 4", (unsigned long)sb.st_size);
+ ret = close (fd);
+ if (ret < 0)
+ err (1, "close %s", filename);
+ ret = stat (filename, &sb);
+ if (ret < 0)
+ err (1, "stat %s", filename);
+ if (sb.st_size != 4)
+ errx (1, "stat 1: size = %lu != 4", (unsigned long)sb.st_size);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *file = "blaha";
+
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
--- /dev/null
+#!/bin/sh
+echo hej > foo || exit 1
+if test X`cat foo` != X"hej"; then exit 1; fi
+rm foo || exit 1
--- /dev/null
+#!/bin/sh
+echo hopp > foo || exit 1
+if test X`cat foo` != "Xhopp"; then exit 1; fi
+echo hej > foo || exit 1
+if test X`cat foo` != "Xhej"; then exit 1; fi
+rm foo || exit 1
--- /dev/null
+/*
+ * Copyright (c) 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#include <err.h>
+
+const char *fn = "foobar";
+
+static void
+check_size(const char *fn, size_t sz, int paranoia)
+{
+ struct stat sb;
+
+ if (paranoia)
+ return;
+
+ if (stat(fn, &sb) < 0)
+ err(1, "stat");
+ if (sb.st_size != sz)
+ errx(1, "st_size mismatch %d != %d", (int)sb.st_size, (int)sz);
+}
+
+static void
+check_size_read(int fd, size_t sz)
+{
+ off_t old_off;
+ size_t sz2;
+ void *buf;
+
+ if ((old_off = lseek(fd, 0, SEEK_CUR)) < 0)
+ err(1, "lseek");
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ err(1, "lseek");
+ buf = malloc(sz);
+ if (buf == NULL)
+ errx(1, "malloc");
+ if ((sz2 = read(fd, buf, sz)) < 0)
+ errx(1, "read");
+ if (sz2 != sz)
+ errx(1, "end before end: sz2 (%u) != sz (%u)", (unsigned)sz2,
+ (unsigned)sz);
+ if ((sz2 = lseek(fd, 0, SEEK_END)) < 0)
+ errx(1, "lseek");
+ if (sz2 != sz)
+ errx(1, "end past end: sz2 (%u) != sz (%u)", (unsigned)sz2,
+ (unsigned)sz);
+ free(buf);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+
+ fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0644);
+ if (fd < 0)
+ err(1, "open1");
+ if (write(fd,"kaka", 4) != 4)
+ errx(1, "write1");
+ check_size(fn, 4, 1);
+ if (close(fd) < 0)
+ err(1, "close1");
+
+ check_size(fn, 4, 0);
+
+ fd = open(fn,O_RDWR|O_CREAT|O_TRUNC,644);
+ if (fd < 0)
+ err(1, "open2");
+ check_size(fn, 0, 1);
+ if (write(fd,"kaka", 4) != 4)
+ errx(1, "write2");
+ check_size(fn, 4, 1);
+ check_size_read(fd, 4);
+ if (close(fd) < 0)
+ err(1, "close2");
+ check_size(fn, 4, 1);
+
+ unlink(fn);
+
+ return 0;
+}