summaryrefslogtreecommitdiff
path: root/usr.sbin/afs
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2000-09-11 14:41:41 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2000-09-11 14:41:41 +0000
commit76a06795631625d8e65dd5fa8bf1e2a59bd7fbce (patch)
treec61de38b627eae3cd273de2c6dd1c0bc2f9554ea /usr.sbin/afs
parenta0a0fcba7412ad7cd38c8a407322cb67eb58f685 (diff)
Import of arla-0.35.7
Diffstat (limited to 'usr.sbin/afs')
-rw-r--r--usr.sbin/afs/src/.cvsignore5
-rw-r--r--usr.sbin/afs/src/.indent.pro29
-rw-r--r--usr.sbin/afs/src/ChangeLog.19998348
-rw-r--r--usr.sbin/afs/src/HACKING17
-rw-r--r--usr.sbin/afs/src/LIESMICH195
-rw-r--r--usr.sbin/afs/src/Makefile.in52
-rw-r--r--usr.sbin/afs/src/acconfig.h36
-rw-r--r--usr.sbin/afs/src/acinclude.m49
-rw-r--r--usr.sbin/afs/src/appl/Makefile.in49
-rw-r--r--usr.sbin/afs/src/appl/afsmgr/Makefile.in97
-rw-r--r--usr.sbin/afs/src/appl/afsmgr/afsaclmgr.in314
-rw-r--r--usr.sbin/afs/src/appl/afsutils/Makefile.in166
-rw-r--r--usr.sbin/afs/src/appl/afsutils/README.afsutils61
-rw-r--r--usr.sbin/afs/src/appl/afsutils/TODO.afsutils23
-rw-r--r--usr.sbin/afs/src/appl/afsutils/aklog.187
-rw-r--r--usr.sbin/afs/src/appl/afsutils/aklog.c315
-rw-r--r--usr.sbin/afs/src/appl/afsutils/klog.1196
-rw-r--r--usr.sbin/afs/src/appl/afsutils/klog.c801
-rw-r--r--usr.sbin/afs/src/appl/afsutils/klog.ctx221
-rw-r--r--usr.sbin/afs/src/appl/afsutils/klog.h80
-rw-r--r--usr.sbin/afs/src/appl/afsutils/sys.c73
-rw-r--r--usr.sbin/afs/src/appl/afsutils/tokens.195
-rw-r--r--usr.sbin/afs/src/appl/afsutils/tokens.c248
-rw-r--r--usr.sbin/afs/src/appl/afsutils/tokens.h5
-rw-r--r--usr.sbin/afs/src/appl/afsutils/unlog.160
-rw-r--r--usr.sbin/afs/src/appl/afsutils/unlog.c281
-rw-r--r--usr.sbin/afs/src/appl/afsutils/unlog.h21
-rw-r--r--usr.sbin/afs/src/appl/afsutils/up.c168
-rw-r--r--usr.sbin/afs/src/appl/amon/Makefile.in121
-rw-r--r--usr.sbin/afs/src/appl/amon/amon.c471
-rw-r--r--usr.sbin/afs/src/appl/asrvutil/Makefile.in119
-rw-r--r--usr.sbin/afs/src/appl/asrvutil/README10
-rw-r--r--usr.sbin/afs/src/appl/asrvutil/asrvutil.c334
-rw-r--r--usr.sbin/afs/src/appl/bos/Makefile.in119
-rw-r--r--usr.sbin/afs/src/appl/bos/bos.c163
-rw-r--r--usr.sbin/afs/src/appl/bos/bos_adduser.c140
-rw-r--r--usr.sbin/afs/src/appl/bos/bos_getrestart.c130
-rw-r--r--usr.sbin/afs/src/appl/bos/bos_listhosts.c142
-rw-r--r--usr.sbin/afs/src/appl/bos/bos_listusers.c135
-rw-r--r--usr.sbin/afs/src/appl/bos/bos_local.h61
-rw-r--r--usr.sbin/afs/src/appl/bos/bos_status.c200
-rw-r--r--usr.sbin/afs/src/appl/fs/Makefile.in136
-rw-r--r--usr.sbin/afs/src/appl/fs/fs.1654
-rw-r--r--usr.sbin/afs/src/appl/fs/fs.c2169
-rw-r--r--usr.sbin/afs/src/appl/fs/fs_local.h111
-rw-r--r--usr.sbin/afs/src/appl/lib/Makefile.in111
-rw-r--r--usr.sbin/afs/src/appl/lib/appl_locl.h136
-rw-r--r--usr.sbin/afs/src/appl/lib/arlalib.c580
-rw-r--r--usr.sbin/afs/src/appl/lib/arlalib.h210
-rw-r--r--usr.sbin/afs/src/appl/lib/fs_lib.c921
-rw-r--r--usr.sbin/afs/src/appl/pts/Makefile.in136
-rw-r--r--usr.sbin/afs/src/appl/pts/pts.1259
-rw-r--r--usr.sbin/afs/src/appl/pts/pts.c1526
-rw-r--r--usr.sbin/afs/src/appl/udebug/Makefile.in136
-rw-r--r--usr.sbin/afs/src/appl/udebug/udebug.161
-rw-r--r--usr.sbin/afs/src/appl/udebug/udebug.c283
-rw-r--r--usr.sbin/afs/src/appl/vos/Makefile.in144
-rw-r--r--usr.sbin/afs/src/appl/vos/vos.8392
-rw-r--r--usr.sbin/afs/src/appl/vos/vos.c166
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_common.c352
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_createentry.c164
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_createvolume.c291
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_dump.c213
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_endtrans.c170
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_examine.c327
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_listpart.c125
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_listvldb.c192
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_listvol.c132
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_local.h94
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_lock.c167
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_partinfo.c177
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_status.c154
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_syncsite.c100
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_unlock.c169
-rw-r--r--usr.sbin/afs/src/appl/vos/vos_vldbexamine.c202
-rw-r--r--usr.sbin/afs/src/arlad/.gdbinit109
-rw-r--r--usr.sbin/afs/src/arlad/CellServDB.535
-rw-r--r--usr.sbin/afs/src/arlad/Makefile.in198
-rw-r--r--usr.sbin/afs/src/arlad/SuidCells.516
-rw-r--r--usr.sbin/afs/src/arlad/ThisCell.529
-rw-r--r--usr.sbin/afs/src/arlad/aix-subr.c153
-rw-r--r--usr.sbin/afs/src/arlad/dynroot.c376
-rw-r--r--usr.sbin/afs/src/arlad/dynroot.h61
-rw-r--r--usr.sbin/afs/src/arlad/hpux-subr.c161
-rw-r--r--usr.sbin/afs/src/arlad/irix-subr.c148
-rw-r--r--usr.sbin/afs/src/arlad/solaris-subr.c164
-rw-r--r--usr.sbin/afs/src/arlad/subr.c136
-rw-r--r--usr.sbin/afs/src/arlad/sunos-subr.c148
-rw-r--r--usr.sbin/afs/src/arlad/unknown-subr.c60
-rw-r--r--usr.sbin/afs/src/arlad/xfs.c543
-rw-r--r--usr.sbin/afs/src/arlad/xfs.h74
-rw-r--r--usr.sbin/afs/src/cf/auth-modules.m427
-rw-r--r--usr.sbin/afs/src/cf/broken-glob.m422
-rw-r--r--usr.sbin/afs/src/cf/broken-snprintf.m458
-rw-r--r--usr.sbin/afs/src/cf/broken.m419
-rw-r--r--usr.sbin/afs/src/cf/bsd-func-lockmgr.m424
-rw-r--r--usr.sbin/afs/src/cf/bsd-func-lockstatus.m449
-rw-r--r--usr.sbin/afs/src/cf/bsd-func-suser.m423
-rw-r--r--usr.sbin/afs/src/cf/bsd-func-vfs-getnewfsid.m427
-rw-r--r--usr.sbin/afs/src/cf/bsd-header-vnode-if-h.m441
-rw-r--r--usr.sbin/afs/src/cf/bsd-vfs-busy.m447
-rw-r--r--usr.sbin/afs/src/cf/bsd-vfs-object-create.m428
-rw-r--r--usr.sbin/afs/src/cf/bsd-vget.m466
-rw-r--r--usr.sbin/afs/src/cf/bsd-vop-lock.m463
-rw-r--r--usr.sbin/afs/src/cf/c-attribute.m439
-rw-r--r--usr.sbin/afs/src/cf/c-function.m433
-rw-r--r--usr.sbin/afs/src/cf/check-declaration.m425
-rw-r--r--usr.sbin/afs/src/cf/check-dirsiz.m445
-rw-r--r--usr.sbin/afs/src/cf/check-getpwnam_r-posix.m424
-rw-r--r--usr.sbin/afs/src/cf/check-glibc.m422
-rw-r--r--usr.sbin/afs/src/cf/check-kafs.m447
-rw-r--r--usr.sbin/afs/src/cf/check-kerberos.m4478
-rw-r--r--usr.sbin/afs/src/cf/check-kernel-func.m411
-rw-r--r--usr.sbin/afs/src/cf/check-kernel-funcs.m415
-rw-r--r--usr.sbin/afs/src/cf/check-kernel-var.m411
-rw-r--r--usr.sbin/afs/src/cf/check-kernel-vop-t.m417
-rw-r--r--usr.sbin/afs/src/cf/check-kernel.m460
-rw-r--r--usr.sbin/afs/src/cf/check-lfs.m431
-rw-r--r--usr.sbin/afs/src/cf/check-man.m459
-rw-r--r--usr.sbin/afs/src/cf/check-type-extra.m423
-rw-r--r--usr.sbin/afs/src/cf/check-var.m420
-rw-r--r--usr.sbin/afs/src/cf/check-x.m452
-rw-r--r--usr.sbin/afs/src/cf/check-xau.m454
-rw-r--r--usr.sbin/afs/src/cf/elf-object-format.m415
-rw-r--r--usr.sbin/afs/src/cf/find-func-no-libs.m49
-rw-r--r--usr.sbin/afs/src/cf/find-func-no-libs2.m463
-rw-r--r--usr.sbin/afs/src/cf/find-func.m49
-rw-r--r--usr.sbin/afs/src/cf/find-if-not-broken.m413
-rw-r--r--usr.sbin/afs/src/cf/func-hstrerror-const.m418
-rw-r--r--usr.sbin/afs/src/cf/func-krb-get-default-tkt-root.m431
-rw-r--r--usr.sbin/afs/src/cf/func-krb-get-err-text.m428
-rw-r--r--usr.sbin/afs/src/cf/func-krb-kdctimeofday.m431
-rw-r--r--usr.sbin/afs/src/cf/func-ntohl.m438
-rw-r--r--usr.sbin/afs/src/cf/grok-type.m435
-rw-r--r--usr.sbin/afs/src/cf/have-def.m419
-rw-r--r--usr.sbin/afs/src/cf/have-kernel-struct-field.m419
-rw-r--r--usr.sbin/afs/src/cf/have-linux-kernel-type.m424
-rw-r--r--usr.sbin/afs/src/cf/have-linux-kernel-types.m414
-rw-r--r--usr.sbin/afs/src/cf/have-pragma-weak.m437
-rw-r--r--usr.sbin/afs/src/cf/have-struct-field.m419
-rw-r--r--usr.sbin/afs/src/cf/have-type.m432
-rw-r--r--usr.sbin/afs/src/cf/have-types.m414
-rw-r--r--usr.sbin/afs/src/cf/header-dirent-dir-h.m421
-rw-r--r--usr.sbin/afs/src/cf/kernel-have-def.m419
-rw-r--r--usr.sbin/afs/src/cf/kernel.m419
-rw-r--r--usr.sbin/afs/src/cf/krb-bigendian.m453
-rw-r--r--usr.sbin/afs/src/cf/krb-find-db.m489
-rw-r--r--usr.sbin/afs/src/cf/krb-func-getcwd-broken.m442
-rw-r--r--usr.sbin/afs/src/cf/krb-ipv6.m4130
-rw-r--r--usr.sbin/afs/src/cf/krb-prog-ln-s.m428
-rw-r--r--usr.sbin/afs/src/cf/krb-prog-ranlib.m48
-rw-r--r--usr.sbin/afs/src/cf/krb-prog-yacc.m48
-rw-r--r--usr.sbin/afs/src/cf/krb-struct-sockaddr-sa-len.m422
-rw-r--r--usr.sbin/afs/src/cf/krb-struct-spwd.m422
-rw-r--r--usr.sbin/afs/src/cf/krb-struct-winsize.m427
-rw-r--r--usr.sbin/afs/src/cf/krb-sys-aix.m415
-rw-r--r--usr.sbin/afs/src/cf/krb-sys-nextstep.m422
-rw-r--r--usr.sbin/afs/src/cf/krb-version.m425
-rw-r--r--usr.sbin/afs/src/cf/linux-func-d_alloc_root-two_args.m421
-rw-r--r--usr.sbin/afs/src/cf/linux-func-devfs-register-eleven-args.m419
-rw-r--r--usr.sbin/afs/src/cf/linux-func-init-mutex.m420
-rw-r--r--usr.sbin/afs/src/cf/linux-func-init-wait-queue-head.m417
-rw-r--r--usr.sbin/afs/src/cf/linux-type-wait-queue-head.m416
-rw-r--r--usr.sbin/afs/src/cf/mips-abi.m487
-rw-r--r--usr.sbin/afs/src/cf/misc.m43
-rw-r--r--usr.sbin/afs/src/cf/need-proto.m425
-rw-r--r--usr.sbin/afs/src/cf/osf-func-ubc-lookup.m424
-rw-r--r--usr.sbin/afs/src/cf/osfc2.m414
-rw-r--r--usr.sbin/afs/src/cf/prog-cc-flags.m415
-rw-r--r--usr.sbin/afs/src/cf/proto-compat.m422
-rw-r--r--usr.sbin/afs/src/cf/shared-libs.m4186
-rw-r--r--usr.sbin/afs/src/cf/test-package.m488
-rw-r--r--usr.sbin/afs/src/cf/try-compile-kernel.m410
-rw-r--r--usr.sbin/afs/src/cf/try-cpp-kernel.m410
-rw-r--r--usr.sbin/afs/src/cf/type-iovec.m423
-rw-r--r--usr.sbin/afs/src/cf/type-krb-principal.m426
-rw-r--r--usr.sbin/afs/src/cf/type-msghdr.m419
-rw-r--r--usr.sbin/afs/src/cf/wflags.m421
-rw-r--r--usr.sbin/afs/src/conf/Makefile.in59
-rw-r--r--usr.sbin/afs/src/conf/SuidCells0
-rw-r--r--usr.sbin/afs/src/conf/arla.spec.in133
-rw-r--r--usr.sbin/afs/src/conf/bos.conf21
-rw-r--r--usr.sbin/afs/src/conf/services13
-rw-r--r--usr.sbin/afs/src/config.guess1171
-rw-r--r--usr.sbin/afs/src/config.sub1256
-rw-r--r--usr.sbin/afs/src/configure.in1611
-rw-r--r--usr.sbin/afs/src/doc/Makefile.in189
-rw-r--r--usr.sbin/afs/src/doc/ack.texi145
-rw-r--r--usr.sbin/afs/src/doc/ack.texi.in35
-rw-r--r--usr.sbin/afs/src/doc/afs-basics.texi176
-rw-r--r--usr.sbin/afs/src/doc/arla.info1332
-rw-r--r--usr.sbin/afs/src/doc/arla.texi222
-rw-r--r--usr.sbin/afs/src/doc/authors.texi36
-rw-r--r--usr.sbin/afs/src/doc/debugging.texi78
-rw-r--r--usr.sbin/afs/src/doc/intro.texi89
-rw-r--r--usr.sbin/afs/src/doc/latin1.tex95
-rw-r--r--usr.sbin/afs/src/doc/milko1.fig111
-rw-r--r--usr.sbin/afs/src/doc/oddities.texi40
-rw-r--r--usr.sbin/afs/src/doc/partsofarla.texi347
-rw-r--r--usr.sbin/afs/src/doc/porting.texi142
-rw-r--r--usr.sbin/afs/src/doc/servers.texi67
-rw-r--r--usr.sbin/afs/src/doc/storage.texi150
-rw-r--r--usr.sbin/afs/src/doc/timeline.texi84
-rw-r--r--usr.sbin/afs/src/doc/tools.texi34
-rw-r--r--usr.sbin/afs/src/doc/xfs.txt380
-rw-r--r--usr.sbin/afs/src/include/Makefile.in132
-rw-r--r--usr.sbin/afs/src/install-sh250
-rw-r--r--usr.sbin/afs/src/lib/Makefile.in45
-rw-r--r--usr.sbin/afs/src/lib/acl/Makefile.in81
-rw-r--r--usr.sbin/afs/src/lib/acl/acl.h60
-rw-r--r--usr.sbin/afs/src/lib/acl/acl_files.c611
-rw-r--r--usr.sbin/afs/src/lib/acl/acl_files.doc107
-rw-r--r--usr.sbin/afs/src/lib/bufdir/Makefile.in95
-rw-r--r--usr.sbin/afs/src/lib/bufdir/afs_dir.h110
-rw-r--r--usr.sbin/afs/src/lib/bufdir/fbuf.c485
-rw-r--r--usr.sbin/afs/src/lib/bufdir/fbuf.h71
-rw-r--r--usr.sbin/afs/src/lib/bufdir/fdir.c624
-rw-r--r--usr.sbin/afs/src/lib/bufdir/fdir.h89
-rw-r--r--usr.sbin/afs/src/lib/cmd/Makefile.in122
-rw-r--r--usr.sbin/afs/src/lib/cmd/cmd.3271
-rw-r--r--usr.sbin/afs/src/lib/cmd/cmd.c1016
-rw-r--r--usr.sbin/afs/src/lib/cmd/cmd.h136
-rw-r--r--usr.sbin/afs/src/lib/cmd/frame.ctx48
-rw-r--r--usr.sbin/afs/src/lib/cmd/testc.c103
-rw-r--r--usr.sbin/afs/src/lib/cmd/testc.ctx121
-rw-r--r--usr.sbin/afs/src/lib/editline/ChangeLog93
-rw-r--r--usr.sbin/afs/src/lib/editline/Makefile.in86
-rw-r--r--usr.sbin/afs/src/lib/editline/README45
-rw-r--r--usr.sbin/afs/src/lib/editline/complete.c243
-rw-r--r--usr.sbin/afs/src/lib/editline/edit_compat.c118
-rw-r--r--usr.sbin/afs/src/lib/editline/editline.3175
-rw-r--r--usr.sbin/afs/src/lib/editline/editline.c1376
-rw-r--r--usr.sbin/afs/src/lib/editline/editline.h64
-rw-r--r--usr.sbin/afs/src/lib/editline/sysunix.c92
-rw-r--r--usr.sbin/afs/src/lib/editline/testit.c38
-rw-r--r--usr.sbin/afs/src/lib/editline/unix.h22
-rw-r--r--usr.sbin/afs/src/lib/ko/Makefile.in161
-rw-r--r--usr.sbin/afs/src/lib/ko/afsconf.c115
-rw-r--r--usr.sbin/afs/src/lib/ko/auth.c149
-rw-r--r--usr.sbin/afs/src/lib/ko/auth.h77
-rw-r--r--usr.sbin/afs/src/lib/ko/cellconfig.h82
-rw-r--r--usr.sbin/afs/src/lib/ko/kotest.c79
-rw-r--r--usr.sbin/afs/src/lib/ko/part.c103
-rw-r--r--usr.sbin/afs/src/lib/ko/part.h42
-rw-r--r--usr.sbin/afs/src/lib/sl/Makefile.in117
-rw-r--r--usr.sbin/afs/src/lib/sl/lex.l117
-rw-r--r--usr.sbin/afs/src/lib/sl/make_cmds.c240
-rw-r--r--usr.sbin/afs/src/lib/sl/make_cmds.h76
-rw-r--r--usr.sbin/afs/src/lib/sl/parse.y167
-rw-r--r--usr.sbin/afs/src/lib/sl/ss.c137
-rw-r--r--usr.sbin/afs/src/lib/sl/ss.h55
-rw-r--r--usr.sbin/afs/src/lwp/Makefile.in119
-rw-r--r--usr.sbin/afs/src/lwp/lwp_asm.c1054
-rw-r--r--usr.sbin/afs/src/lwp/lwp_asm.h229
-rw-r--r--usr.sbin/afs/src/lwp/lwp_elf.h29
-rw-r--r--usr.sbin/afs/src/lwp/process.aix22.S120
-rw-r--r--usr.sbin/afs/src/lwp/process.alpha.S205
-rw-r--r--usr.sbin/afs/src/lwp/process.hpux.S219
-rw-r--r--usr.sbin/afs/src/lwp/process.i386.S111
-rw-r--r--usr.sbin/afs/src/lwp/process.ibm032.S109
-rw-r--r--usr.sbin/afs/src/lwp/process.m68k.S125
-rw-r--r--usr.sbin/afs/src/lwp/process.mips.S213
-rw-r--r--usr.sbin/afs/src/lwp/process.patch.S80
-rw-r--r--usr.sbin/afs/src/lwp/process.ppc.S182
-rw-r--r--usr.sbin/afs/src/lwp/process.rios.S179
-rw-r--r--usr.sbin/afs/src/lwp/process.sparc.S534
-rw-r--r--usr.sbin/afs/src/lwp/process.vax.S108
-rw-r--r--usr.sbin/afs/src/make-release26
-rw-r--r--usr.sbin/afs/src/make-release.el25
-rw-r--r--usr.sbin/afs/src/milko/ChangeLog1227
-rw-r--r--usr.sbin/afs/src/milko/Makefile.in48
-rw-r--r--usr.sbin/afs/src/milko/README196
-rw-r--r--usr.sbin/afs/src/milko/appl/Makefile.in48
-rw-r--r--usr.sbin/afs/src/milko/appl/bootstrap/Makefile.in58
-rw-r--r--usr.sbin/afs/src/milko/appl/bootstrap/anti-boot-strap.sh.in48
-rw-r--r--usr.sbin/afs/src/milko/appl/bootstrap/boot-strap.sh.in149
-rw-r--r--usr.sbin/afs/src/milko/appl/perf/Makefile.in112
-rw-r--r--usr.sbin/afs/src/milko/appl/perf/perf.c680
-rw-r--r--usr.sbin/afs/src/milko/appl/sked/Makefile.in124
-rw-r--r--usr.sbin/afs/src/milko/appl/sked/sked.c793
-rw-r--r--usr.sbin/afs/src/milko/bos/Makefile.in117
-rw-r--r--usr.sbin/afs/src/milko/bos/bos_locl.h77
-rw-r--r--usr.sbin/afs/src/milko/bos/bosprocs.c162
-rw-r--r--usr.sbin/afs/src/milko/bos/bosserver.c630
-rw-r--r--usr.sbin/afs/src/milko/bos/kconf.c804
-rw-r--r--usr.sbin/afs/src/milko/bos/kconf.h210
-rw-r--r--usr.sbin/afs/src/milko/fs/Makefile.in139
-rw-r--r--usr.sbin/afs/src/milko/fs/connsec.c265
-rw-r--r--usr.sbin/afs/src/milko/fs/connsec.h52
-rw-r--r--usr.sbin/afs/src/milko/fs/fileserver.c236
-rw-r--r--usr.sbin/afs/src/milko/fs/fs_def.h57
-rw-r--r--usr.sbin/afs/src/milko/fs/fsprocs.c1639
-rw-r--r--usr.sbin/afs/src/milko/fs/fsrv_locl.h96
-rw-r--r--usr.sbin/afs/src/milko/fs/volprocs.c793
-rw-r--r--usr.sbin/afs/src/milko/include/mdebug.h75
-rw-r--r--usr.sbin/afs/src/milko/lib/Makefile.in48
-rw-r--r--usr.sbin/afs/src/milko/lib/dpart/Makefile.in103
-rw-r--r--usr.sbin/afs/src/milko/lib/dpart/dpart.c263
-rw-r--r--usr.sbin/afs/src/milko/lib/dpart/dpart.h74
-rw-r--r--usr.sbin/afs/src/milko/lib/mlog/Makefile.in103
-rw-r--r--usr.sbin/afs/src/milko/lib/mlog/mlog.c203
-rw-r--r--usr.sbin/afs/src/milko/lib/mlog/mlog.h114
-rw-r--r--usr.sbin/afs/src/milko/lib/msecurity/Makefile.in103
-rw-r--r--usr.sbin/afs/src/milko/lib/msecurity/msecurity.c161
-rw-r--r--usr.sbin/afs/src/milko/lib/msecurity/msecurity.h55
-rw-r--r--usr.sbin/afs/src/milko/lib/msecurity/netinit.c237
-rw-r--r--usr.sbin/afs/src/milko/lib/msecurity/netinit.h54
-rw-r--r--usr.sbin/afs/src/milko/lib/ropa/Makefile.in108
-rw-r--r--usr.sbin/afs/src/milko/lib/ropa/README79
-rw-r--r--usr.sbin/afs/src/milko/lib/ropa/ropa.c1267
-rw-r--r--usr.sbin/afs/src/milko/lib/ropa/ropa.h57
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/Makefile.in110
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/common.c228
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/debug.c68
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/fvol.c352
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/fvol.h54
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/glue.c240
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/mdir.c227
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/mdir.h79
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/mnode.c274
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/mnode.h113
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/salvage.c800
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/salvage.h48
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/sfvol_private.h69
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/svol.c131
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/svol.h1
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/vld.c1860
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/vld.h263
-rw-r--r--usr.sbin/afs/src/milko/lib/vld/vld_ops.h24
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/Makefile.in105
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/vdb_flat.c944
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/vol.c268
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/voldb.c507
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/voldb.h237
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/voldb_internal.h132
-rw-r--r--usr.sbin/afs/src/milko/lib/voldb/voldb_locl.h71
-rw-r--r--usr.sbin/afs/src/milko/lib/vstatus/Makefile.in105
-rw-r--r--usr.sbin/afs/src/milko/lib/vstatus/vstat.xg67
-rw-r--r--usr.sbin/afs/src/milko/lib/vstatus/vstatus.c177
-rw-r--r--usr.sbin/afs/src/milko/lib/vstatus/vstatus.h51
-rw-r--r--usr.sbin/afs/src/milko/pts/Makefile.in115
-rw-r--r--usr.sbin/afs/src/milko/pts/pr.c431
-rw-r--r--usr.sbin/afs/src/milko/pts/ptserver.c788
-rw-r--r--usr.sbin/afs/src/milko/pts/ptserver.h53
-rw-r--r--usr.sbin/afs/src/milko/vldb/Makefile.in123
-rw-r--r--usr.sbin/afs/src/milko/vldb/ubikprocs.c101
-rw-r--r--usr.sbin/afs/src/milko/vldb/vl_db.c376
-rw-r--r--usr.sbin/afs/src/milko/vldb/vldb_locl.h109
-rw-r--r--usr.sbin/afs/src/milko/vldb/vldbserver.c820
-rw-r--r--usr.sbin/afs/src/milko/vldb/vled.c454
-rw-r--r--usr.sbin/afs/src/mkinstalldirs40
-rw-r--r--usr.sbin/afs/src/rx/Makefile.in155
-rw-r--r--usr.sbin/afs/src/rx/rxdebug.175
-rw-r--r--usr.sbin/afs/src/rx/rxdebug.c670
-rw-r--r--usr.sbin/afs/src/rx/rxperf.c400
-rw-r--r--usr.sbin/afs/src/rx/test_rx_clock.c64
-rw-r--r--usr.sbin/afs/src/rxdef/Makefile.in196
-rw-r--r--usr.sbin/afs/src/rxdef/bos.xg248
-rw-r--r--usr.sbin/afs/src/rxdef/ka.xg177
-rw-r--r--usr.sbin/afs/src/rxkad/Makefile.in96
-rw-r--r--usr.sbin/afs/src/tests/Makefile.in231
-rw-r--r--usr.sbin/afs/src/tests/append-over-page.c986
-rw-r--r--usr.sbin/afs/src/tests/append16
-rw-r--r--usr.sbin/afs/src/tests/apwd.c471
-rw-r--r--usr.sbin/afs/src/tests/boot-strap-arla17
-rw-r--r--usr.sbin/afs/src/tests/build-emacs4
-rw-r--r--usr.sbin/afs/src/tests/build-emacs-j4
-rw-r--r--usr.sbin/afs/src/tests/build-gdb4
-rw-r--r--usr.sbin/afs/src/tests/checkpwd3
-rw-r--r--usr.sbin/afs/src/tests/compare-inum-mp8
-rw-r--r--usr.sbin/afs/src/tests/compare-inums4
-rw-r--r--usr.sbin/afs/src/tests/compare-with-local77
-rw-r--r--usr.sbin/afs/src/tests/copy-and-diff-gnu-mirror6
-rw-r--r--usr.sbin/afs/src/tests/creat15
-rw-r--r--usr.sbin/afs/src/tests/create-dirs.c100
-rw-r--r--usr.sbin/afs/src/tests/create-files.c123
-rw-r--r--usr.sbin/afs/src/tests/create-remove-dirs4
-rw-r--r--usr.sbin/afs/src/tests/create-remove-files4
-rw-r--r--usr.sbin/afs/src/tests/create-remove.c142
-rw-r--r--usr.sbin/afs/src/tests/create-stat.c174
-rw-r--r--usr.sbin/afs/src/tests/create-symlinks.c100
-rw-r--r--usr.sbin/afs/src/tests/dd8
-rw-r--r--usr.sbin/afs/src/tests/deep-tree6
-rw-r--r--usr.sbin/afs/src/tests/deep-tree212
-rw-r--r--usr.sbin/afs/src/tests/dir-size-mismatch10
-rw-r--r--usr.sbin/afs/src/tests/dir-tree22
-rw-r--r--usr.sbin/afs/src/tests/discon-create6
-rw-r--r--usr.sbin/afs/src/tests/discon-echo6
-rw-r--r--usr.sbin/afs/src/tests/discon-mkdir6
-rw-r--r--usr.sbin/afs/src/tests/discon-mkdir27
-rw-r--r--usr.sbin/afs/src/tests/discon-tar19
-rw-r--r--usr.sbin/afs/src/tests/discon-tar213
-rw-r--r--usr.sbin/afs/src/tests/discon-touch17
-rw-r--r--usr.sbin/afs/src/tests/discon-touch28
-rw-r--r--usr.sbin/afs/src/tests/dup2-and-unlog.c53
-rw-r--r--usr.sbin/afs/src/tests/echo-n.c20
-rw-r--r--usr.sbin/afs/src/tests/exec9
-rw-r--r--usr.sbin/afs/src/tests/exit-wo-close.c134
-rw-r--r--usr.sbin/afs/src/tests/fcachesize-dir13
-rw-r--r--usr.sbin/afs/src/tests/fcachesize-file-small13
-rw-r--r--usr.sbin/afs/src/tests/find-and-cat-netbsd5
-rw-r--r--usr.sbin/afs/src/tests/find-linux5
-rw-r--r--usr.sbin/afs/src/tests/fs-flush6
-rw-r--r--usr.sbin/afs/src/tests/fs-sa-la6
-rw-r--r--usr.sbin/afs/src/tests/ga-test.c332
-rw-r--r--usr.sbin/afs/src/tests/generic-build19
-rw-r--r--usr.sbin/afs/src/tests/getdents-and-unlink19
-rw-r--r--usr.sbin/afs/src/tests/getdents-and-unlink29
-rw-r--r--usr.sbin/afs/src/tests/getdents-and-unlink39
-rw-r--r--usr.sbin/afs/src/tests/hardlink1.c154
-rw-r--r--usr.sbin/afs/src/tests/hardlink2.c110
-rw-r--r--usr.sbin/afs/src/tests/hello-world.in8
-rw-r--r--usr.sbin/afs/src/tests/kill-softer.c198
-rw-r--r--usr.sbin/afs/src/tests/kill-softly.c168
-rw-r--r--usr.sbin/afs/src/tests/kotest4
-rw-r--r--usr.sbin/afs/src/tests/large-dir-163844
-rw-r--r--usr.sbin/afs/src/tests/large-dir-extra7
-rw-r--r--usr.sbin/afs/src/tests/large-dir.c164
-rw-r--r--usr.sbin/afs/src/tests/large-dir2.c143
-rw-r--r--usr.sbin/afs/src/tests/large-dir3.c131
-rw-r--r--usr.sbin/afs/src/tests/ls-afs5
-rw-r--r--usr.sbin/afs/src/tests/many-dirs4
-rw-r--r--usr.sbin/afs/src/tests/many-fetchs15
-rw-r--r--usr.sbin/afs/src/tests/many-files4
-rw-r--r--usr.sbin/afs/src/tests/many-files-with-content4
-rw-r--r--usr.sbin/afs/src/tests/many-stores10
-rw-r--r--usr.sbin/afs/src/tests/many-symlinks4
-rw-r--r--usr.sbin/afs/src/tests/mkdir10
-rw-r--r--usr.sbin/afs/src/tests/mkdir-lnk12
-rw-r--r--usr.sbin/afs/src/tests/mkdir17
-rw-r--r--usr.sbin/afs/src/tests/mkdir2.c89
-rw-r--r--usr.sbin/afs/src/tests/mkm-rmm13
-rw-r--r--usr.sbin/afs/src/tests/mmap-and-read.c152
-rw-r--r--usr.sbin/afs/src/tests/mmap-shared-write.c108
-rw-r--r--usr.sbin/afs/src/tests/mmap-vs-read.c175
-rw-r--r--usr.sbin/afs/src/tests/mmap-vs-read2.c175
-rw-r--r--usr.sbin/afs/src/tests/mountpoint.in12
-rw-r--r--usr.sbin/afs/src/tests/parallel15
-rw-r--r--usr.sbin/afs/src/tests/pine.c108
-rw-r--r--usr.sbin/afs/src/tests/read-vs-mmap.c175
-rw-r--r--usr.sbin/afs/src/tests/read-vs-mmap2.c138
-rw-r--r--usr.sbin/afs/src/tests/read-write.c150
-rw-r--r--usr.sbin/afs/src/tests/readdir-vs-lstat.c109
-rw-r--r--usr.sbin/afs/src/tests/readfile-wo-create3
-rw-r--r--usr.sbin/afs/src/tests/rename-under-feet.c166
-rw-r--r--usr.sbin/afs/src/tests/rename17
-rw-r--r--usr.sbin/afs/src/tests/rename27
-rw-r--r--usr.sbin/afs/src/tests/rename39
-rw-r--r--usr.sbin/afs/src/tests/rename48
-rw-r--r--usr.sbin/afs/src/tests/rename5.c114
-rw-r--r--usr.sbin/afs/src/tests/rm-rf.c150
-rw-r--r--usr.sbin/afs/src/tests/run-tests.in235
-rw-r--r--usr.sbin/afs/src/tests/setgroups4
-rw-r--r--usr.sbin/afs/src/tests/setpag4
-rw-r--r--usr.sbin/afs/src/tests/shallow-tree5
-rw-r--r--usr.sbin/afs/src/tests/strange-characters7
-rw-r--r--usr.sbin/afs/src/tests/strange-characters-c.c100
-rw-r--r--usr.sbin/afs/src/tests/strange-other-characters5
-rw-r--r--usr.sbin/afs/src/tests/symlink.c79
-rw-r--r--usr.sbin/afs/src/tests/test-gunzip-gnu-mirror14
-rw-r--r--usr.sbin/afs/src/tests/test-parallel1.c108
-rw-r--r--usr.sbin/afs/src/tests/test-parallel2.c190
-rw-r--r--usr.sbin/afs/src/tests/test-setgroups.c151
-rw-r--r--usr.sbin/afs/src/tests/test-setpag.c144
-rw-r--r--usr.sbin/afs/src/tests/touch14
-rw-r--r--usr.sbin/afs/src/tests/untar-emacs9
-rw-r--r--usr.sbin/afs/src/tests/utime-dir.c86
-rw-r--r--usr.sbin/afs/src/tests/visit-volumes6
-rw-r--r--usr.sbin/afs/src/tests/write-closed.c104
-rw-r--r--usr.sbin/afs/src/tests/write-closed2.c139
-rw-r--r--usr.sbin/afs/src/tests/write-ro-file.c77
-rw-r--r--usr.sbin/afs/src/tests/write-ucc.c110
-rw-r--r--usr.sbin/afs/src/tests/write14
-rw-r--r--usr.sbin/afs/src/tests/write26
-rw-r--r--usr.sbin/afs/src/util/Makefile.in123
-rw-r--r--usr.sbin/afs/src/util/log_log.3148
-rw-r--r--usr.sbin/afs/src/ydr/Makefile.in99
477 files changed, 84536 insertions, 0 deletions
diff --git a/usr.sbin/afs/src/.cvsignore b/usr.sbin/afs/src/.cvsignore
new file mode 100644
index 00000000000..75a58a36051
--- /dev/null
+++ b/usr.sbin/afs/src/.cvsignore
@@ -0,0 +1,5 @@
+ID
+configure
+config.h.in
+TAGS
+aclocal.m4
diff --git a/usr.sbin/afs/src/.indent.pro b/usr.sbin/afs/src/.indent.pro
new file mode 100644
index 00000000000..52b50d7c837
--- /dev/null
+++ b/usr.sbin/afs/src/.indent.pro
@@ -0,0 +1,29 @@
+-bad
+-bap
+-bbb
+-nbc
+-br
+-c40
+-cdb
+-ce
+-cli0
+-d0
+-di1
+-ndj
+-ei
+-nfc1
+-i4
+-ip
+-l78
+-lp
+-npcs
+-psl
+-sc
+-nsob
+-Tpag_t
+-Txfs_cred
+-Txfs_message_function
+-Txfs_handle
+-Txfs_cache_handle
+-Txfs_attr
+-Topaque
diff --git a/usr.sbin/afs/src/ChangeLog.1999 b/usr.sbin/afs/src/ChangeLog.1999
new file mode 100644
index 00000000000..47ab1c5e464
--- /dev/null
+++ b/usr.sbin/afs/src/ChangeLog.1999
@@ -0,0 +1,8348 @@
+1999-12-31 Love <lha@s3.kth.se>
+
+ * arlad/reconnect.c (*): try to handle the case that find_first_fs
+ failes
+
+1999-12-31 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c: add debug prints of the fids to the messages
+
+ * arlad/inter.c (getrights): static-ize
+ * arlad/fcache.c (sum_node): static-ize
+ * arlad/inter.c (cm_getattr): make sure we have a parent before
+ doing bulk status
+
+ * tests/Makefile.in (run-tests): make it work with makes that run
+ all the commands in the same shell
+ (clean): add run-tests
+
+ * arlad/messages.c: remove some double fcache_release:s
+
+1999-12-31 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (creating_nodes): remove variable
+ (unlink_lru_entry): make it more presistant and not fail
+
+1999-12-30 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (*): disable prio-stuff
+
+ * arlad/fcache.h (FCacheEntry): added cleanergen and changed type
+ of priority
+ (fcache_need_bytes,fcache_need_nodes): new prototypes
+
+ * arlad/fcache.c (current_vnodes): counter of currently created
+ vnodes
+ (needbytes): how many bytes the cleaner needs to clean away
+ (fprioritylevel): make it a bool
+ (creating_nodes): if the create_nodes is running
+ (create_nodes): merge in create_node() and create_new_entries() and
+ make create_nodes add new entires to the list instead of operating
+v on the list, also mak create_nodes a thread sleeping until we need
+ more nodes.
+ (cleaner_working): tells if the cleaner is working
+ (cleaner): make it a state machine that is waken up each time there
+ is a shortage of nodes or bytes, this repleaces
+ emergency_remove_data() and emergency_remove_nodes().
+ (fcache_wakeup_cleaner) how to wake up the cleaner
+ (fcache_need_bytes): wakeup the cleaner to get more bytes
+ (fcache_need_nodes): wakeup the cleaner to get more nodes
+ (emergency_remove_data): remove
+ (emergency_remove_nodes): remove
+ (unlink_lur_entry): call fcache_need_nodes()
+ (find_free_entry): print warning to ADEBWARN
+ (fcache_recover_state): assert find_free_entry never failes
+ (fcache_reinit): disable increseing of nodes
+ (fcache_unused): never signal lru_list since we never clean out the node
+ (read_data): use new fcache_need_bytes(), more verbose debugging
+
+1999-12-29 Love <lha@s3.kth.se>
+
+ * xfs/linux/xfs_message.c (xfs_message_installnode): remember to
+ dput the dentry when its inserted without a already existing
+ dcache-entry.
+ (gc_vnode): more debugging
+
+ * xfs/solaris/Makefile.in (xfs): added magic glue to avoid that
+ the solaris module is name xfs
+ (load,mount): new target
+
+ * xfs/linux/xfs_node.c: remove #ifdef HAVE_GET_EMPTY_INODE
+
+ * configure.in (linux): no get_empty_inode test
+
+ * cf/linux-func-get-empty-inode.m4: no more
+
+ * doc/oddities.texi: note importance that . and .. need to be
+ first, also tell about dirent.reclen
+
+ * doc/debugging.texi: note that you can cat the /proc/kmsg file on
+ linux since klogd sucks performancewise and it loosses message
+
+1999-12-28 Love <lha@s3.kth.se>
+
+ * lib/ko/ko_locl.h: no strmatch.h
+
+ * include/Makefile.in: no strmatch or strsplit
+
+1999-12-28 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/Makefile.in (vnode_if.c): not used. remove
+ (vnode_if.h): handle vnode_if.sh and vnode_if.pl
+ * configure.in (freebsd): try to handle running vnode_if.pl or
+ vnode_if.sh
+
+ * tests/large-dir2.c: don't check for directory being 2048 bytes
+ long
+ * tests/large-dir.c: don't check for directory being 2048 bytes
+ long
+
+ * arlad/bsd-subr.c (dir_remove_name): using a too large d_reclen
+ is bad because readdir() can't cope with it being larger than the
+ buffer size that's being used by opendir/readdir. so let's take
+ DIRBLKSIZ (defaulting to 1024) as a conservative estimate
+
+ * xfs/bsd/xfs_message.c (xfs_message_version): try to figure out
+ if we don't have a getfh syscall installed. new and improved.
+ now more #ifdef's.
+
+ * configure.in (nosys, sys_nosys): test for under bsd
+
+1999-12-25 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs/xfs_vnodeops.h: handle VOP_LOCK with [1,3] arguments
+ and bail out else.
+
+ * xfs/bsd/xfs_message.c (xfs_message_version): test for getfh
+ actually being filled in. In FreeBSD 3 and 4 before kern/15452
+ was applied, it might not be filled in at run-time if there's no
+ NFS.
+
+ * configure.in (freebsd): do the test for vnode_if.sh the same way
+ as in xfs/bsd/Makefile.in
+ (AC_BSD_FUNC_LOCKSTATUS): use
+
+ * xfs/bsd/bin/Makefile.in: segregate programs and scripts. use
+ INSTALL_SCRIPT for installing scripts.
+
+ * tests/build-emacs-j: cater for people with broken shells
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (cleanup_cnp): new function for
+ cleaning up a componentname. also reset HASBUF after free-ing,
+ this is needed by fbsd-current.
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_link): conditionalize calls to
+ VOP_ABORTOP (doesn't exist in fbsd-current)
+ (xfs_islocked): handle one and two-argument lockstatus
+
+ * xfs/bsd/Makefile.in (vnode_if.h): try to handle vnode_if.src in
+ fbsd-current with different arguments
+
+1999-12-16 Love <lha@s3.kth.se>
+
+ * Release 0.29.2 (in the arla-0-29-2-branch)
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (do_read_attr): always set ret_conn so it's not
+ left unitialized
+
+1999-12-16 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (xfs_message_rename): set old_entry to NULL
+
+1999-12-14 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs/xfs_node.h (xfs_do_vget): use {1,2,3}_ARGUMENT_VGET.
+ * cf/bsd-vget.m4: <sys/cdefs.h> conditionalize check for 1, 2, or
+ 3 arguments verify that at least one of them actually works
+ * cf/bsd-vop-lock.m4: conditionalize <sys/cdefs.h>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): do copy-in. never call
+ fhopen or sys_fhopen. if this function was called, that's because
+ someone didn't want the ordinary fhopen function.
+ * xfs/bsd/xfs_syscalls-common.c (fhopen_call): adapt to new
+ xfs_fhopen
+
+ * configure.in (osf): move test_KERNEL_CFLAGS
+ * configure.in (AC_CHECK_KERNEL_FUNCS): remove sys_fhopen. not
+ used anymore.
+ * configure.in (freebsd[34]): handle current version of
+ vnode_if.sh and check that we actually got a vnode_if.h generated
+ * configure.in: junk freebsd2: we don't support in anyway
+
+1999-12-14 Love <lha@s3.kth.se>
+
+ * arlad/.gdbinit (lwp_ps_internal): pritty-printing and added
+ intelism
+
+ * configure.in: testing for readline in editline, by Tino Schwarze
+ <tino.schwarze@informatik.tu-chemnitz.de>
+
+1999-12-13 Love <lha@s3.kth.se>
+
+ * milko/lib/ropa/Makefile,milko/appl/perf/Makefile
+
+ * configure.in (AC_OUTPUT): Added
+
+ * Release 0.29.1 (in the arla-0-29-1-branch)
+
+ * arlad/messages.c (VenusFid_cmp): really compare the to fids
+
+1999-12-11 Love <lha@s3.kth.se>
+
+ * lwp/plwp.c (Debug): disable hardwired debugging..
+
+ * Makefile.in (SUBDIRS): do test too
+
+ * tests/compare-inum-mp: remove right mountpoint
+
+ * tests/Makefile.in: echo-n
+
+1999-12-08 Assar Westerlund <assar@sics.se>
+
+ * arlad/bsd-subr.c (write_dirent): handle DIRENT_SIZE
+
+ * arlad/arla_local.h: <dirent.h>: needs _KERNEL, otherwise we
+ don't get DIRENT_SIZE
+
+ * configure.in: re-do editline/readline stuff
+
+ * arlad/sunos-subr.c (dir_remove_name): do a proper reclen
+ overflow check
+
+ * arlad/solaris-subr.c (dir_remove_name): do a proper reclen
+ overflow check
+
+ * arlad/irix-subr.c (dir_remove_name): do a proper reclen overflow
+ check
+
+ * arlad/hpux-subr.c (dir_remove_name): do a proper reclen overflow
+ check
+
+ * arlad/aix-subr.c (dir_remove_name): do a proper reclen overflow
+ check
+
+ * arlad/bsd-subr.c (dir_remove_name): handle last_dp == NULL (this
+ might happen for the first entry and even through we should never
+ remove `.' (which is always the first entry) it seems better not
+ to rely on this)
+
+ * arlad/bsd-subr.c (dir_remove_name): do a proper check for
+ overflow `d_reclen'
+
+ * arlad/messages.c (xfs_message_create): be more careful before
+ releasing fcache entries
+
+1999-12-08 Love <lha@s3.kth.se>
+
+ * conf/CellServDB: updated rhic
+
+ * Release 0.29
+
+1999-12-08 Assar Westerlund <assar@sics.se>
+
+ * configure.in: add missing ;; in case, from hin@stacken.kth.se
+
+1999-12-06 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (create_directory): don't update used bytes, its
+ done in adir_mkdir().
+
+Sun Dec 5 05:50:15 1999 Magnus Ahltorp <map@stacken.kth.se>
+
+ * configure.in: Make all --with-sys-guessing in one place. Use
+ $SYS/include as the include directory for linux.
+
+1999-12-05 Love <lha@s3.kth.se>
+
+ * arlad/reconnect.c (reconnect_create): fetch parent fid volume if
+ there is none.
+
+ * arlad/fcache.c (fcache_get_attr_bulk): don't care about nodes
+ without names, version 3.with brain
+ * arlad/fcache.c (fcache_get_attr_bulk): don't care about nodes
+ without names, version 2.
+
+ * arlad/inter.c (cm_lookup): no more mp_traversal
+
+ * arlad/fcache.h (*): no more mp_traversal
+
+ * arlad/fcache.c (fcache_get_attr_bulk): don't care about nodes
+ without names
+
+1999-12-05 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/Makefile.in (install): support installing in /modules
+
+ * configure.in (AC_CHECK_KERNEL_VFSSW): remove, it's not used
+ anyways.
+
+ * cf/linux-func-get-empty-inode.m4: set CFLAGS to
+ test_KERNEL_CFLAGS
+
+ * cf/linux-func-full-name-hash-8bit.m4: set CFLAGS to
+ test_KERNEL_CFLAGS
+
+ * cf/have-linux-kernel-type.m4: call AC_TRY_COMPILE_KERNEL so that
+ we use the right flags.
+
+ * cf/check-kernel-vfssw.m4: not used. remove
+
+ * lib/bufdir/fdir.c: use typedef for function point to
+ fdir_readdir
+ * lib/bufdir/fdir.h: use typedef for function point to
+ fdir_readdir
+
+ * configure.in: support KERNEL_CFLAGS being set in the shell.
+ support --with-sys on linux check for sys/dir.h and don't check
+ for sys/dir.h and dirent.h being compatible (we only include one
+ of them anyways)
+
+ * arlad/inter.c (cm_lookup): look in the volume entry to find the
+ parent of ..
+ * arlad/fcache.c (get_root_of_volume): store parent fid in the
+ volume entry
+ * arlad/volcache.h (volcacheentry): add `parent' (the .. of this
+ volume)
+
+ * arlad/messages.h (VenusFid_cmp): add prototype
+ * arlad/messages.c (VenusFid_cmp): const-ify
+
+ * arlad/volcache.h (volcacheentry): rename fid fields
+ * arlad/volcache.c (recycle_entry): don't care about finding the
+ root vnode
+
+ * arlad/*-subr.c: use common subr functions
+ * arlad/subr.c: new file
+ * arlad/Makefile.in (arlad_OBJS): add subr.o
+ (SRCS): add subr.c
+
+1999-12-03 Assar Westerlund <assar@sics.se>
+
+ * configure.in: redo the tests for readline/editline. now it
+ should only test for the functions that are needed. and if should
+ fail if any does not exist.
+
+ * tests/build-emacs-j: new test
+
+ * tests/run-tests.in (ARLA_TESTS): do `build-emacs' before
+ `untar-emacs'. add `build-emacs-j'
+
+ * lib/ko/kocell.c (readdb): love-complete skipping of white-space
+ * lib/ko/kocell.c (readdb): also try to remove trailing white
+ space
+ * lib/ko/kocell.c (readdb): change the format to be "IP-address([#
+ \t]+hostname)?"
+
+1999-12-02 Assar Westerlund <assar@sics.se>
+
+ * arlad/bsd-subr.c (write_dirent): check for volume == NULL
+
+1999-12-01 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c: add a magic cookie and version number to the
+ dump file.
+
+ * arlad/fcache.h: add a magic cookie and version number to the
+ dump file.
+
+ * arlad/volcache.h: add a magic cookie and version number to the
+ dump file.
+
+ * arlad/bsd-subr.c: simplify include-mess
+ (write_dirent): use `volume->mp'
+
+ * arlad/volcache.c: set `li'
+ (volcache_free): add at tail of lrulist
+
+ * arlad/volcache.h (volcacheentry): add a list pointer into
+ lrulist
+
+ * arlad/fcache.c: don't use realfid any longer. store the
+ information in the volume instead
+ (fcache_realfid): new function
+
+ * arlad/fcache.h (FCacheEntry): delete `realfid' (this information
+ is now stored in the volume entry instead)
+ (fcache_realfid): new function
+
+ * ydr/output.c (generate_server_switch): make ExecuteRequest of
+ the type that rx expects it to be.
+ * rx/rx.h (rx_service): correct type for `executeRequestProc'
+ * rx/rx.c (rx_NewService): correct type for `serviceProc'
+ * arlad/cmcb.c (cmcb_init): remove bad cast
+ (RXAFSCB_CallBack): print warning when we can't find the host the sent
+ us the callback
+
+ * arlad/arla_local.h: don't include both dirent.h and sys/dir.h,
+ but just in that order of preference
+
+ * arlad/afsdir_check.c (check): printf format correctness
+
+1999-12-01 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (xfs_message_mkdir): avoid to set datausedp to
+ later when we know that the node will be installed
+
+ * arlad/messages.c (xfs_message_mkdir): do some locking of the
+ parent
+
+ * lib/ko/kocell.c (readdb): pass over isspace() in hostnames, if
+ there is no hostname, replace with ip-address.
+
+ * arlad/fcache.c (fcache_get_attr_bulk): check if we want to do
+ bulkstatus, check the return value of find_first_fs()
+
+ * arlad/messages.c (*): try to set datausedp later when the node
+ is passed down to the kernel
+
+1999-11-30 Assar Westerlund <assar@sics.se>
+
+ * xfs/*/xfs_message.c: make installattr not finding the node non-fatal
+
+1999-11-28 Assar Westerlund <assar@sics.se>
+
+ * arlad/inter.c (cm_lookup): don't get provoked into doing
+ bulk-status on "." or ".."
+
+ * arlad/messages.c (xfs_message_inactivenode): reset datausedp and
+ attrusedp also.
+
+ * xfs/bsd/xfs_vnodeops-osf.c: update to changing reality
+
+ * xfs/bsd/xfs_message.c (xfs_message_installattr): sanity-check
+ tokens
+ (*): print handle in lots of the debug messages
+
+ * xfs/bsd/xfs_node-bsd.c: better and more consistent debug
+ messages
+
+1999-11-27 Love <lha@s3.kth.se>
+
+ * xfs/linux/xfs_syscalls.c (sys_afs_int): handle the case where
+ the dentry set
+ (xfs_debug_print): XDEBNODE:enable printing of node and childs
+
+ * arlad/afsdir_check.c (*): add verbose and help
+
+1999-11-27 Assar Westerlund <assar@sics.se>
+
+ * appl/afsutils/klog.c (randfilename): use
+ krb_get_default_tkt_root if existing
+
+ * appl/afsutils/klog.h: add (with gcc attributes) prototypes for
+ die et al
+
+ * configure.in: test for krb_get_default_tkt_root bsd: test for
+ cdevsw_add (it might disappear any day now in fbsd)
+ * configure.in (linux): test for inode_operations.get_block
+
+ * xfs/linux/xfs/xfs_locl.h: add <linux/smp_lock.h> define LINUX2_3
+ based on patches from <yasushi@cs.washington.edu>
+
+ * xfs/linux/xfs_inodeops.c (xfs_d_validate): add new flag argument
+ inode_operations has added a `get_block' operation
+ (xfs_readpage): lock and unlock kernel under 2.3
+
+ * xfs/linux/xfs_dev.c (xfs_print_sleep_queue): handle new type of
+ wait_queue in 2.3
+
+ * arlad/fcache.c (fcache_get_attr_bulk): check for `prefered_name'
+ being NULL. set tokens to be the tokens of the entry masking out
+ data if the data hasn't been installed in the kernel.
+
+ * xfs/bsd/xfs/xfs_common.h (xfs_devtoname_r): add prototype
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_lookup): try to handle the
+ locking protocol correctly for "." and ".."
+
+ * xfs/bsd/xfs_dev-common.c: use xfs_devtoname_r
+
+ * xfs/bsd/xfs_dev-bsd.c: use xfs_devtoname_r
+
+ * xfs/bsd/xfs_common-bsd.c (xfs_devtoname_r): new function to
+ print the name of a `dev_t'
+
+ * configure.in (bsd): test for snprintf and devtoname in the
+ kernel
+
+1999-11-26 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_symlink_common): don't rele
+ in modern FreeBSD
+
+ * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): also mask SIGVTALRM
+
+ * include/stds.h (int16, u_int16): define. From Derrick J
+ Brashear <shadow@dementia.org>
+
+ * conf/CellServDB: update for MIT cells
+
+1999-11-26 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (*): try to set datausedp when data is
+ installed, also remeber to set tokens to some (in)sane value.
+
+ * arlad/inter.c: (cm_getattr): remove datatokens it data isn't
+ used
+
+ * arlad/fcache.c (fcache_get_attr_bulk): update tokens more
+ forcefully (even new nodes can have data)
+
+ * arlad/fcache.c (fcache_get_attr_bulk): update tokens
+
+ * arlad/fcache.c (xfs_message_install_node_attr): union of
+ install{node,attr} for bulkstat
+ (bulkstat_help_func): don't exclude nodes we have attributes for,
+ we need them too in kernel, this should be made more beautifully,
+ it should be installed, but not bulkstat:ed
+ (fcache_get_attr_bulk): just install nodes when they don't exist
+ in kernel, install attributes otherwise
+
+ * arlad/messages.c (xfs_message_remove): install the nodes in
+ right order
+
+ * xfs/linux/xfs_message.c (xfs_message_installnode): invalid
+ childs when XFS_INVALID_DNLC is set.
+
+1999-11-23 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_wrap-bsd.c: adapt to fbsd -current:
+
+ s/remove_dev/destroy_dev/ DEV_MODULE now only takes three
+ arguments
+
+ * xfs/bsd/xfs/xfs_dev.h (xfs_devioctl): simplify prototype by not
+ caring for old FreeBSD
+
+ * xfs/bsd/xfs/xfs_common.h (MALLOC_DECLARE): use if defined
+ * xfs/bsd/xfs_common-bsd.c (MALLOC_DEFINE): use if defined
+
+1999-11-22 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_message.c (xfs_message_gc_nodes): remove comment
+ about osf
+
+ * arlad/xfs.h: export xfs_send_message_{,v}multiple{,list}()
+
+ * arlad/xfs.c (send_count): removed since we don't use writev any
+ longer, need to add some logarithmic stuff instead
+ (add_new_msg): new function, add a msg to a ``struct write_buf''
+ (send_msg): new function, send of a ``struct write_buf''
+ (xfs_send_message_vmultiple): rewrite in terms of add_new_msg and
+ send_msg
+ (xfs_send_message_multiple): new function
+ (xfs_send_message_multiple_list): new function, send of a list of
+ message of same size.
+ (xfs_send_message_wakeup_vmultiple): reimpement in terms of
+ xfs_send_message_vmultiple and write
+
+ * arlad/reconnect.c (*): use new adir_lookup
+
+ * arlad/messages.c (xfs_message_getdata): set datausedp when
+ getting dir
+ (fcacheentry2xfsnode): export
+
+ * arlad/inter.c (cm_getattr): implement bulkstat
+ (cm_lookup): use new adir_lookup and implement bulkstat
+
+ * arlad/fcache.h (FCacheEntry): add hits
+
+ * arlad/fcache.c (fcache_counter): add some counters
+ (emergency_remove_data): implement some more intelligent removing of data
+ (emergency_remove_node): implement some more intelligent removing of nodes
+ (unlink_lru_entry): increse number of nodes we emergency remove
+ (fcache_get/fcache_recover_state): init hits to 0
+ (update_attr_entry): break out common code
+ (do_read_attr): use update_attr_entry
+ (bulkstat_help_func): helper function for fcache_get_attr_bulk and fdir_readdir
+ (fcache_get_attr_bulk): implement bulkstat
+
+ * arlad/adir.h (adir_lookup): changed signature
+
+ * arlad/adir.c (adir_lookup): enable too pass back the entry of
+ ``dir''
+
+1999-11-21 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_cachedlookup): cast pointer to
+ correct type
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_symlink_common): simplify
+ ifdef
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_mkdir): vput should also be
+ called on NetBSD
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_link): try to DTRT when failing
+ when errors early
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_create): on {Net,Open}BSD dvp
+ should not be returned locked
+
+ * appl/afsutils/klog.c (get_afs_id): use
+ arlalib_get_viceid_servers
+
+ * appl/lib/arlalib.c (arlalib_get_viceid): new function
+
+1999-11-20 Assar Westerlund <assar@sics.se>
+
+ * Release 0.28
+
+1999-11-20 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-common.c: remove vn_share_lock and
+ vn_unshare_lock (and all calls). they're not actually used for
+ doing anything.
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lookup): don't unlock parent
+ when returning EJUSTRETURN
+ (xfs_lock, xfs_unlock): print flags when DEBUG
+
+1999-11-17 Assar Westerlund <assar@sics.se>
+
+ * rx/rx_rdwr.c (rx_ReadProc, rx_WriteProc): make generic and
+ pretty prototypes
+
+ * rx/rx_clock.c (clock_ReInit): add dummy function when we're
+ without getitimer
+ * configure.in: check for getitimer
+ * rx/rx_clock.c: add fallback code for systems without getitimer
+
+ * ydr/output.c (encode_enum): hopefully make the generated code be
+ more portable and correct without using any casts to and from int
+
+ * lib/ko/ko_locl.h: conditionalize <sys/mman.h>
+ * lib/bufdir/fbuf.c: conditionalize <sys/mman.h>
+ * arlad/arla_local.h: conditionalize <sys/mman.h>
+
+ * lwp/plwp.c (LWP_WaitProcess): make prototype compatible with the
+ lwp function
+
+ * configure.in: test for `make_dev' in kernel
+
+ * rx/rx.h: add some prototypes
+
+1999-11-17 Love <lha@s3.kth.se>
+
+ * xfs/linux/xfs_node.c (free_xfs_node): be paranoid and reset
+ tokens
+
+ * xfs/linux/xfs_message.c (xfs_message_installattr): added some
+ paranoid checks to try to catch readpage on NULL node
+ (xfs_message_installdata): remove obsolete BSD comment
+ (xfs_invalid_xnode): added comment about possible race then throwing node->data
+
+1999-11-13 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_wrap-bsd.c: add calls to make_dev and remove_dev iff
+ the kernel has a make_dev
+ (FreeBSD 4.x).
+
+ * xfs/bsd/xfs/xfs_vnodeops.h (xfs_lookup_name): what function?
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_name): not used.
+ retire.
+
+ * xfs/bsd/xfs_vnodeops-osf.c (xfs_symlink): adapt to changes in
+ xfs_symlink_common
+ (xfs_create, xfs_mkdir): use xfs_lookup_common
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_create, xfs_mkdir): use
+ `xfs_lookup_common'
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_symlink_common): use
+ xfs_lookup_common
+
+ * arlad/fcache.c (fcache_stale_entry): if the cell is unknown,
+ loop over all the entries in the cache and nuke the ones with
+ matching fid. This is a kludge to solve the problem with
+ multi-homed file servers. The problem is that the callback break
+ can come from a different IP address than the one we have been
+ talking to and then we have no idea as to what cell that belongs
+ to. The real fix is to start using the 3.4 interfaces and be
+ aware of multi-homed file servers.
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_lookup): correct tbl_lookup
+ call
+ * xfs/bsd/xfs_vnodeops-common.c (vn_share_lock, vn_unshare_lock):
+ disable
+ (xfs_lookup_common): don't do any parent unlocking. try to handle
+ . and .. special cases. we always get back a locked vnode from
+ xfs_dnlc_lookup
+ (xfs_create_common): more information in debug messages
+
+ * xfs/bsd/xfs_node-bsd.c (tbl_lookup): make common
+ (xfs_dnlc_lookup): always lock the node that is returned
+
+1999-11-08 Love <lha@s3.kth.se>
+
+ * conf/CellServDB ({arla.,}e.kth.se): Put arla.e.kth.se after
+ e.kth.se since libkafs seams to do first match.
+ (psc.edu): update from info-afs
+ (lsa.umich.edu): update from info-afs
+ (math.lsa.umich.edu): update from info-afs
+
+1999-11-07 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_message.c (xfs_message_installnode,
+ xfs_message_installdata): do vget without locking and vrele
+ (gc_vnode): unlock interlock if node is being used
+ (xfs_message_gc_nodes): don't use dead next pointer
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): don't tell vget
+ we already have an interlock. we don't.
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lookup): look at PDIRUNLOCK flag
+ to see if we should unlock
+ (xfs_create): simplify
+ (xfs_mkdir): simplify. correct debug printf
+ (xfs_inactive): remove FreeBSD 2-code
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): the fhopen syscall can be
+ called fhopen or sys_fhopen. handle both cases.
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call): we don't have any
+ memset on FreeBSD, use bzero instead
+
+ * xfs/bsd/xfs_node-bsd.c (new_xfs_node): always do vget. (this
+ will probably not work on fbsd2)
+ (tbl_lookup): new version for NetBSD 1.4K or higher. cache_lookup now
+ returns with the resulting node locked, do the same thing in
+ tbl_lookup
+
+ * configure.in (AC_CHECK_KERNEL_FUNCS): check for `sys_fhopen'
+
+1999-11-03 Love <lha@s3.kth.se>
+
+ * configure.in (AC_OUTPUT): added milko/appl/bootstrap/Makefile
+
+1999-11-03 Marcus Sundberg <mackan@stacken.kth.se>
+
+ * cf/linux-func-devfs-register-eleven-args.m4: new file
+
+ * configure.in: use AC_LINUX_FUNC_DEVFS_REGISTER_ELEVEN_ARGS
+
+ * xfs/linux/xfs_load.c (init_module): support recent devfs_register()
+
+1999-11-02 Love <lha@nutcracker.e.kth.se>
+
+ * rxdef/cb.xg: removed #if 0 def's that have been moved to
+ common.h removed \r in comment end mark.
+
+ * rxdef/vldb.xg: added a comment about VLSF and VLF
+
+1999-10-31 Assar Westerlund <assar@sics.se>
+
+ * arlad/inter.c (cm_symlink): create mount points with 0644
+
+ * arlad/fcache.c (create_new_entries): handle `n == 0'
+ (fcache_reinit): don't fail when setting it to the same number as
+ nodes that's already there
+
+1999-10-30 Assar Westerlund <assar@sics.se>
+
+ * configure.in: don't export RXKAD_LIBS use new
+ AC_FIND_FUNC_NO_LIBS2 for checking for kafs/krbafs
+
+ * cf/find-func-no-libs.m4: add yet another argument to allow
+ specify linker flags that will be added _before_ the library when
+ trying to link
+
+ * cf/find-func-no-libs2.m4: add yet another argument to allow
+ specify linker flags that will be added _before_ the library when
+ trying to link
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock): handle the
+ case of three-argument lockmgr's
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_loopup_common): remove
+ lockparent stuff
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lookup): move the BSD-specific
+ lockparent stuff here from xfs_lookup_common
+
+ * xfs/bsd/xfs/xfs_locl.h: move syscall argument macros here from
+ xfs_syscalls.h
+
+ * xfs/bsd/xfs/xfs_syscalls.h: move syscall argument stuff to
+ xfs_locl.h
+
+ * xfs/bsd/xfs_vfsops-osf.c: add some struct to xfs_fhandle_t make
+ debug printfs less informative by not printing unexisting
+ variables
+
+ * xfs/bsd/xfs-message.c (xfs_message_gc_nodes): add osf version
+
+ * xfs/bsd/xfs/xfs_locl.h (u_int16_t): add for osf
+ (xfs_setgroups_args): add a hard-coded defintion of this struct for
+ osf. It's not defined anywhere and hopefully it will not be
+ changed.
+
+1999-10-26 Love <lha@s3.kth.se>
+
+ * rxdef/common.h: Added SS_FSYNC flag, given to StoreData and
+ friends when we are supposed to fsync.
+
+1999-10-23 Love <lha@s3.kth.se>
+
+ * appl/afsmgr/afsaclmgr.in: A acl manager written i guile-gtk.
+
+1999-10-22 Love <lha@s3.kth.se>
+
+ * configure.in (AC_PATH_PROGS): Added check for guile-gtk
+ (AC_OUTPUT): Added appl/afsmgr/Makefile
+
+1999-10-22 Magnus Ahltorp <map@stacken.kth.se>
+
+ * lib/bufdir/fbuf.c, arlad/*.c: Don't close fd when fbuf is closed.
+
+1999-10-22 Love <lha@s3.kth.se>
+
+ * appl/afsutils/klog.h: remove do_help prototype
+
+ * appl/afsutils/klog.c (*): rewrote to use getarg
+
+ * tests/ga-test.c (test_simple_strings): added simple test for
+ arg_strings
+ (*): print what test failed
+
+1999-10-21 Love <lha@s3.kth.se>
+
+ * tests/ga-test.c (test_simple_integer, test_simple_string):
+ swaped functionsname to reflect what the do.
+
+ * appl/afsutils/unlog.c (save_tokens): remove variable as a
+ cleanup from Chris Wing
+ (getarg): made getarg work as expected (compat)
+
+1999-10-20 Magnus Ahltorp <map@stacken.kth.se>
+
+ * arlad/fcache.[ch], arlad/dynroot.c, arlad/reconnect.c: Added
+ length field to FCacheEntry
+
+1999-10-19 Love <lha@s3.kth.se>
+
+ * tests/{ga-test.c,Makefile.in,run-tests.in}: added basic getarg
+ tests suite.
+
+Tue Oct 19 02:44:21 1999 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_read_file): read from page owned
+ by backing store
+
+1999-10-19 Magnus Ahltorp <map@stacken.kth.se>
+
+ * lib/bufdir/fdir.c (update_fid_by_name): Don't corrupt directory
+ entry
+
+1999-10-17 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: xfs_readdir: Eliminated memory leak
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * tests/create-files.c (creat_files): remember O_WRONLY to open
+
+ * configure.in (hpux): set KERNEL_INCLUDE
+
+ * appl/fs/fs.c: revert last commit. xfs_deb.h is needed here
+
+1999-10-16 Magnus Ahltorp <map@stacken.kth.se>
+
+ * rxdef/pts.c, appl/pts/pts.c, milko/pts/pr.c,
+ milko/pts/ptserver.c: Better names for pts constants
+
+1999-10-15 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_syscalls.c: sys_afs_int: Check for NULL xnode
+
+1999-10-15 Love <lha@s3.kth.se>
+
+ * rx/Makefile.in (install): create $(includedir)/rx
+
+ * rx/rx.[ch]: a service returns a int32_t not a long
+
+1999-10-13 Love <lha@s3.kth.se>
+
+ * tests/create-files.c(usage): updated.
+
+ * tests/compare-inums: new style create-file
+
+1999-10-13 Assar Westerlund <assar@sics.se>
+
+ * appl/udebug/Makefile.in (LIB_tgetent): add
+
+ * xfs/bsd/xfs_wrap-bsd.c: use NODEV on FreeBSD 3
+
+ * xfs/bsd/xfs_vnodeops-common.c: use xfs_vfs_vn_lock
+
+ * xfs/bsd/xfs/xfs_vnodeops.h (xfs_vfs_vn_lock): new ugly macro for
+ calling vn_lock
+
+Tue Oct 12 23:22:35 1999 Magnus Ahltorp <map@stacken.kth.se>
+
+ * arlad/fcache.c: Clear attrp when clearing length.
+
+1999-10-12 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_getnode): reset data mask before
+ installing tokens
+
+ * configure.in: use LIB_tgetent when testing for el_init
+
+ * cf/find-func-no-libs.m4 (AC_FIND_FUNC_NO_LIBS): new argument
+ `extra libs'
+
+ * cf/find-func-no-libs2.m4 (AC_FIND_FUNC_NO_LIBS2): new argument
+ `extra libs'
+
+ * configure.in: use AC_BSD_FUNC_LOCKMGR
+
+ * cf/bsd-func-lockmgr.m4: new test
+
+1999-10-10 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_wrap-bsd.c: NODEV -> NOMAJ
+
+ * xfs/bsd/xfs_vfsops-netbsd.c: use xfs_checkexp
+
+ * xfs/bsd/xfs_vfsops-freebsd.c (xfs_vfsops): add `xfs_checkexp'
+ when appropriate
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_checkexp): new dummy function
+
+ * configure.in: check for debuglockmgr
+
+ * xfs/bsd/xfs/xfs_node.h (xfs_node): sort out when to use `struct
+ lock'
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_lookup): try to handle the new
+ NetBSD version of cache_lookup that has a return value that's the
+ opposite of the traditional one (but actually more logical and
+ consistent with everything else). The test for __NetBSD_Version__
+ >= 104110000 might not be optimal.
+
+ * arlad/arla_local.h: fix for building on MacOS X
+
+ * tests/create-files.c: support writing data into the files
+
+1999-10-07 Love <lha@s3.kth.se>
+
+ * arlad/xfs.h (rcvfuncs): is extern.
+
+ * configure.in (tgetent): check in ncurses too.
+
+Wed Oct 6 01:51:12 1999 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: xfs_write_file: Check if cache file is
+ NULL
+
+ * tests/read-write.c: Added.
+
+ * xfs/linux/xfs_node.c: free_xfs_node: Cleanup.
+
+ * xfs/linux/xfs_message.c: xfs_invalid_xnode: Move code around to
+ avoid scheduling between token clearing and DATA_FROM_XNODE
+ clearing. Cleanup.
+
+ * xfs/linux/xfs_inodeops.c: xfs_readdir: Merge 2.0 and 2.2 code.
+ Cleanup. xfs_readpage: Correct spelling mistake.
+
+1999-10-06 Assar Westerlund <assar@sics.se>
+
+ * (xfs_lookup_common): use xfs_vfs_unlock
+
+ * xfs/bsd/xfs/xfs_locl.h: add <sys/signalvar.h>
+
+ * xfs/bsd/xfs_wrap-bsd.c (DEV_MODULE): set major number
+
+ * xfs/bsd/xfs_node-bsd.c: handle the case of there being no
+ `cn_hash' in `struct componentname'
+
+ * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): handle another way
+ of setting signal masks
+ (SIGADDSET, used in FreeBSD 4)
+
+ * xfs/bsd/xfs_dev-bsd.c (FreeBSD, cdevsw): conditionalize some
+ fields
+
+ * lwp/process.S (RCSID): undef to avoid conflicts and possibly use
+ an assembly version (ENTRY): conditionalize
+
+ * configure.in (AC_CHECK_HEADERS): beautify. add
+ <sys/signalvar.h>
+ (struct cdevsw): test for lots of fields
+ (struct componentname): check for cn_hash
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): try to
+ approximate the weird locking some more
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_getnewvnode): lockmgr or not
+ (new_xfs_node): don't interlock
+
+ * xfs/bsd/xfs_vnodeops-bsd.c: start using lockmgr for vop_lock,
+ vop_unlock, and vop_islocked
+
+ * xfs/bsd/xfs_vfsops-freebsd.c (xfs_dead_vnodeop_entries): default
+ should be vop_defaultop
+
+ * xfs/bsd/xfs_dev-bsd.c (FreeBSD): more conditional fields
+
+ * configure.in: test for d_spare in cdevsw
+
+ * configure.in: test for d_reset in `struct cdevsw'
+
+ * xfs/linux/xfs/xfs_locl.h (xfs_iref): inline function for
+ incrementing the ref count
+
+ * xfs/linux/xfs_syscalls.c (fhopen_call): always call DPUT. add
+ some comments
+
+ * xfs/linux/xfs_inodeops.c (xfs_readpage): always call dput,
+ simplify a tiny bit use xfs_iref
+
+ * xfs/linux/xfs_message.c (xfs_message_installnode): iput the
+ xnode instead of `dentry->d_inode'. use `xfs_iref' for bumping
+ reference count
+
+ * xfs/linux/xfs_node.c: add some comments
+ (xfs_iget): don't call xfs_attr2inode, it's always done in
+ new_xfs_node
+ (xfs_node_find): simplify
+
+1999-10-05 Love <lha@s3.kth.se>
+
+ * conf/CellServDB (northstar.dartmouth.edu): changed
+
+ * appl/afsutils/sys.c (main): ask kernel if avaible.
+
+ * arlad/fcache.c (throw_data, create_file): when truncating files
+ to zero length, set status.Length == 0.
+
+1999-10-05 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs/xfs_node.h (xfs_node): start using `struct lock' iff
+ lockmgr
+
+ * arlad/bsd-subr.c (write_dirent): check that the parent isn't the
+ same
+
+1999-10-05 Love <lha@s3.kth.se>
+
+ * conf/CellServDB (urz.uni-magdeburg.de): changed db servers
+
+ * arlad/cmcb.c: s,EOPNOTSUPP,RXGEN_OPCODE,
+
+1999-10-04 Love <lha@s3.kth.se>
+
+ * appl/afsutils/sys.c: Added sys program.
+
+Mon Oct 4 01:58:56 1999 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: xfs_readdir: Don't lookup inode
+ number. Cleanup.
+
+1999-10-03 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_symlink): handle realfid
+
+ * arlad/inter.h (cm_symlink): update prototype
+
+ * arlad/inter.c (cm_symlink): return the realfid
+
+ * arlad/bsd-subr.c (write_dirent): also handle the case of `..'
+ refering to a mount-point
+
+ * tests/readdir-vs-lstat.c (verify_inodes): no need to check for
+ . or ..
+
+ * xfs/linux/Makefile.in (mount): add
+
+ * tests/readdir-vs-lstat.c (verify_inodes): probably works better
+ if chdir:ing to the directory
+
+ * tests/readdir-vs-lstat.c (main): change default "foo" -> "."
+
+ * tests/readdir-vs-lstat.c (verify_inodes): don't unlink
+
+ * tests/compare-inum-mp: new test
+
+ * tests/compare-inums: new test
+
+ * tests/run-tests.in: add compare-inums, compare-inum-mp
+
+ * tests/readdir-vs-lstat.c: only verify inode numbers
+
+1999-10-02 Love <lha@s3.kth.se>
+
+ * conf/CellServDB (dev.mit.edu): changed
+ (athena.mit.edu): changed
+
+1999-10-01 Assar Westerlund <assar@sics.se>
+
+ * tests/run-tests.in: add readdir-vs-lstat
+
+ * tests/Makefile.in: add readdir-vs-lstat
+
+ * tests/readdir-vs-lstat.c: new test program for verifying that
+ inode numbers from lstat and readdir are equal
+
+1999-09-30 Assar Westerlund <assar@sics.se>
+
+ * rx/Makefile.in (install, uninstall): move include files to `/rx'
+
+ * xfs/bsd/xfs/xfs_locl.h: <vm/vm_object.h>: add
+
+ * arlad/hpux-subr.c: DIRSIZ circus
+
+ * arlad/arla.c (args): more units
+
+ * appl/fs/fs.c: no <xfs/xfs_deb.h>
+
+ * include/Makefile.in: add parse_bytes.h
+
+ * appl/amon/amon.c: add parse_bytes.h
+
+1999-09-30 Harald Barth <haba@pdc.kth.se>
+
+ * doc/intro.texi: Documentation is for wimps /Überwimp.
+ * doc/oddities.texi
+ * doc/partsofarla.texi
+ * doc/porting.texi
+ * doc/tools.texi
+ * doc/authors.texi: Here, too.
+ * doc/arla.texi: Love said I should do this by now
+ * configure.in: Noting in if clause is no good
+
+1999-09-30 Assar Westerlund <assar@sics.se>
+
+ * lwp/make-process.o.sh.in: hpux: don't set PROCESS_S, it gets
+ included from process.S add -I$(srcdir) when running cpp/cc
+
+ * lwp/Makefile.in (make-process.o.sh): add a dependency on
+ ../config.status
+
+1999-09-29 Love <lha@s3.kth.se>
+
+ * configure.in: readline support done diffrently, again
+
+ * NEWS: remove asrvutil notice and replace it with lwp notice
+
+ * configure.in: move lwp things to the top so we can use it in
+ windows too add case cygwin in the switch statment. That isn't
+ relly correct but print a warning that we only work on NT.
+
+ * lwp/plwp.h: windwos threads glue code.
+
+ * lwp/plwp.c: Added windows threads suppport on phtread emulation
+ mode. Debugged by Magnus map@stacken.kth.se and Robert rb@abc.se
+
+1999-09-28 Harald Barth <haba@puffin.pdc.kth.se>
+
+ * doc/partsofarla.texi: nice format
+
+ * doc/debugging.texi: minor
+
+ * doc/Makefile.in: New targets: .pdf and .html files. Generated
+ from texi input. Not made as default yet.
+
+ * configure.in: Test for texi2pdf and texi2html, used in the doc
+ tree
+
+1999-09-27 Love <lha@s3.kth.se>
+
+ * arlad/unknown-subr.c (dir_remove_name): new dummy function
+
+ * rx/rx_clock.c (set_alrm_handler): use only sigaction if
+ SA_RESTART is defined
+
+ * xfs/winnt/src/xfs_vops.c (xfs_close): free ccb and fcb
+ (xfs_cleanup): opencounter--
+ (xfs_create): allocate ccb and fcb and
+ to pointer magic
+ (xfs_dirctl): figure out where to start and only show 3 files
+ (xfs_devctl): add begining of ioctl that we might use for xfs-rpc
+
+ * xfs/winnt/src/makefile: check for alternate location of NTDDK
+
+ * xfs/winnt/src/xfs_misc.c: ccb/fcb allocation/release
+
+ * xfs/winnt/inc/xfs_locl.h: CCB flags and panic string
+
+1999-09-26 Love <lha@s3.kth.se>
+
+ * xfs/winnt/inc/xfs_type.h: Add a allignment macro
+
+ * xfs/winnt/inc/xfs_locl.h: Added lot of confusion structures that
+ the book claims we need.
+
+ * xfs/winnt/src/xfs_init.c (InitFS): initilize the zones for fcb
+ and ccb
+ (DriverEntry): #if 0 out exception code since can't generate a loadable
+ modules otherwise.
+
+1999-09-26 Assar Westerlund <assar@sics.se>
+
+ * appl/amon/amon.c (GetUsedBytes): use unparse_bytes_short for
+ nicer output
+
+ * arlad/volcache.c (get_info_loop, get_info_byid,
+ get_info_byname): add an explicit `cell' argument
+ (volcache_getbyname, volcache_getbyid): set stablep correctly and also
+ set validp
+
+1999-09-26 Love <lha@s3.kth.se>
+
+ * xfs/winnt/xfs.reg: Z: to many \ in string.
+
+ * arlad/messages.c (vioc_calculate_cache): must be root.
+
+1999-09-26 Harald Barth <haba@pdc.kth.se>
+
+ * doc/debugging.texi: Spelling check and some new night excercices.
+
+ * doc/intro.texi: Mostly spelling check.
+
+ * doc/partsofarla.texi: Mostly spelling check.
+
+ * doc/porting.texi: Mostly spelling check.
+
+1999-09-25 Love <lha@s3.kth.se>
+
+ * lib/ko/ko.h (cell_is_sanep): new prototype
+
+ * lib/ko/kocell.c (cell_is_sanep): new function
+
+ * arlad/volcache.c (get_info_loop): print out the volume of the
+ strance cell that doesn't have and db-server, and assert that this
+ cell is a sane one.
+
+ * arlad/fcache.c (*): Add some comments about silly rename
+
+ * arlad/fcache.c (write_data): in case of failure, set the
+ status.Length = 0 since we truncate the buffer, otherwise the
+ assertion that
+ (sum (all-fcachenodes).status.Length) != usedbytes will fail.
+
+ * tests/Makefile(dup2-and-unlog): Added program.
+
+ * tests/dup2-and-unlog.c: xsession-errors emulation
+
+1999-09-24 Love <lha@s3.kth.se>
+
+ * appl/lib/Makefile.in (INCLUDES): Added xfs/include
+
+ * arlad/fcache.c (throw_data): make sure we call
+ cm_check_usedbytes_consistency() If we are compiling w/o assert,
+ make sure we don't count below zero.
+ (cleaner) call cm_check_usedbytes_consistency.
+ (sum_node): only use Length when calculating sum (that should be
+ equal usedbytes)
+
+ * arlad/cmcb.c (RXAFSCB_CallBack): call
+ cm_check_usedbytes_consistency()
+ (RXAFSCB_InitCallBackState): call cm_check_usedbytes_consistency()
+
+ * arlad/arla.c (args): new option --usedbytes-consistency -b
+ (main): turn on usedbytes_consistency if needed
+
+ * arlad/inter.h
+ (cm_turn_on_usedbytes_consistency,cm_check_usedbytes_consistency):
+ new prototypes.
+
+ * arlad/inter.c (cm_check_usedbytes_consistency): if we have a
+ consistent view of usedbytes
+ (*): start to use cm_check_usedbytes_consistency()
+
+ * arlad/messages.c (viocwhereis): send address to userland in
+ network order.
+
+1999-09-23 Love <lha@s3.kth.se>
+
+ * arlad/.gdbinit (lwp_ps_internal): more pretty printing
+
+ * arlad/messages.c (read_mount_point): Map the mountpoint
+ rw|rd|private
+ (vioc_afs_stat_mt_pt): now that the mountpoint is mapped private, dont
+ use a copy buffer.
+
+ * lib/bufdir/fbuf.h: (fbuf_flags): new flags
+
+ * lib/bufdir/fbuf.c:(mmap_flags): check new semantics
+ (mmap_prot): new function
+ (mmap_create): use mmap_prot
+ (malloc_flush): mmap emulation
+
+ * arlad/fcache.c (parse_mountpoint): document
+ (followmountpoint): map file PRIVATE|WRITE
+
+ * */{,*/}/*.c (*): Changed sematics of fbuf_create
+
+1999-09-23 Assar Westerlund <assar@sics.se>
+
+ * arlad/Makefile.in: add arladeb2
+
+ * arlad/arladeb2.c: new file
+
+ * arlad/arladeb.c (arla_log_method): make global
+ (arla_vwarn_with_fid, arla_warn_with_fid): move away
+
+1999-09-20 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (try_again): try to print more explicit
+ messages when waiting
+
+ * arlad/volcache.c (volcache_getname): new function for mapping id
+ -> name
+
+ * arlad/arladeb.c (arla_warnx_with_fid, arla_vwarnx_with_fid): new
+ functions
+
+ * util/log.c (log_vlog): try to handle vasprintf failing
+
+ * configure.in: support smp for FreeBSD as well
+
+1999-09-17 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (read_mount_point): break up into
+ get_mount_point and read_mount_point
+
+1999-09-17 Love <lha@s3.kth.se>
+
+ * arlad/volcache.c: Apply assar's patch to avoid dead-lock in
+ recycle_entry()
+
+ * arlad/messages.c (vioc_afs_stat_mt_pt): create a termporary
+ buffer to make sure the string ends with a '\0'.
+ (read_mount_point): more confusing comments.
+
+1999-09-16 Love <lha@s3.kth.se>
+
+ * appl/afsutils/klog.c: put krb_afslog_uid inside a KERBEROS ifdef
+
+ * configure.in (APPL_SUBDIRS): += asrvutil
+
+1999-09-14 Love <lha@s3.kth.se>
+
+ * appl/asrvutil/asrvutil.c (ANAME_SZ & co): Added some krb-compat
+
+ * lib/ko/ko_locl.h: added <sys/ioccom.h>
+
+ * arlad/fcache.c (fcache_get): make sure the new (not newest)
+ entry is unlocked when put on the lru.
+ (find_free_entry): Added comment about locking
+ (unlink_lru_entry): Added comment about locking
+
+ * arlad/.gdbinit: add random gdb sequences for your late night
+ entertainment.
+
+1999-09-13 Love <lha@s3.kth.se>
+
+ * appl/vos/vos_local.h: Iflags now defined in volumeserver.xg
+
+ * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): ignore SIGALRM
+
+1999-09-11 Magnus Ahltorp <map@stacken.kth.se>
+
+ * configure.in: Don't use fpu registers on alpha and sparc64
+
+1999-09-10 Love <lha@s3.kth.se>
+
+ * ydr/sym.h (Symbol): add u.proc.package
+
+ * ydr/parse.y (proc_decl): save what package we was created ``in''
+ (directive): add package to packagelist
+
+ * ydr/output.h (packagelist): add extern prototype.
+
+ * ydr/output.c (packagelist): used to keep track of what packages
+ we have had
+ (generate_hdr_struct): don't be suprised by a empty defintion.
+ (generate_init): create list packagelist
+ (generate_server_switch/gencase): iterate over all packages in
+ this .xg file
+
+ * ydr/parse.y (directive): estrdup package
+
+ * appl/lib/arlalib.c (arlalib_getsyncsite): seams like the
+ syncsite doesn't fill in the syncsiteaddress for some odd reson.
+
+ * arlad/services.h: added KA one of services
+
+ * rxdef/Makefile.in: add ka server stuff
+
+ * rxdef/ka.xg: (new file) partial kaserver def.
+
+ * appl/asrvutil/*: Initial import, a afs equivalent of ksrvutil.
+
+ * conf/CellServDB (e.kth.se): changed names of db servers
+
+ * conf/CellServDB (jpl.nasa.gov): new db-servers
+
+1999-09-10 Assar Westerlund <assar@sics.se>
+
+ * appl/Makefile.in (SUBDIRS): partly set conditionally
+
+ * lib/ko/koerror.c: move around includes
+
+ * include/stds.h: more ifdef
+
+ * configure.in: handle --without-krb4 set APPL_SUBDIRS to build
+ some subdirs of appl conditionally
+
+ * include/Makefile.in: add acl.h
+
+ * arlad/fcache.c: some ifdef KERBEROS
+
+ * arlad/bsd-subr.c (conv_dir): ignore fcache_fhget failing
+
+ * lib/ko/auth.c: ifdef KERBEROS
+
+ * lib/acl/acl_files.c: ifdef KERBEROS
+
+1999-09-09 Assar Westerlund <assar@sics.se>
+
+ * rxdef/cb.xg: int32 -> int32_t
+
+ * rxdef/cb.xg: add new RPCs for AFS3.5 and the data types used by
+ these
+
+ * rxdef/common.h (afs_UUID): add
+
+ * rxdef/vldb.xg: move afs_UUID to common.h
+
+ * arlad/cmcb.c: implement stubs for the 3.5 RPCs
+
+ * configure.in: always link with -lkrb et al when testing for
+ -lkafs (this breaks with shared libraries otherwise)
+
+1999-09-03 Assar Westerlund <assar@sics.se>
+
+ * appl/lib/arlalib.c (rx_initlizedp): remove, rx takes care of not
+ re-initializing
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * xfs/include/xfs/xfs_attr.h: remove obsolete comment
+
+ * xfs/solaris/xfs_syscalls.c (xfs_pioctl_call): ifdef the 32 bit
+ versions so we don't get duplicates
+
+ * xfs/include/xfs/xfs_message.h (xfs_msg_node): add more padding
+ at the end
+
+ * lwp/make-process.o.sh.in: handle all kinds of sparcs
+
+1999-09-09 Marcus Sundberg <mackan@stacken.kth.se>
+
+ * configure.in: Check for linux/devfs_fs_kernel.h
+
+ * xfs/linux/xfs/xfs_locl.h: If linux/devfs_fs_kernel.h is available,
+ use that instead of linux/devfs_fs.h
+
+1999-09-07 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (throw_data): use entry->status.Length when
+ counting usedbytes.
+
+ * arlad/fcache.c (create_file): remove superflourius
+ free_fs_server_context in case of error
+
+1999-09-06 Love <lha@s3.kth.se>
+
+ * arlad/xfs.c (xfs_send_message_gc_nodes): log the number of nodes
+ to gc
+
+ * arlad/fcache.c (do_read_attr): remeber to free context when
+ failing, add comment about fs_context
+ (write_attr): remeber to free fs_context when failing
+ (create_file): emeber to free fs_context when failing
+
+1999-09-03 Love <lha@s3.kth.se>
+
+ * conf/Makefile.in (install) At least try to set the bits rights
+ on the cachedir
+
+ * configure.in: Check for chmod
+
+ * xfs/solaris/bin/Makefile.in: Added krb_lib_flags
+
+1999-09-03 Assar Westerlund <assar@sics.se>
+
+ * lib/ko/Makefile.in (LIB_SOURCES): add afsconf and auth
+ (install): install header files
+
+ * lib/ko/{cellconfig.h,afsconf.c,auth.h,auth.c}: new files for
+ some transarc library compatability
+
+ * lib/ko/ports.c (ports_init): make sure we only execute once
+
+1999-08-30 Assar Westerlund <assar@sics.se>
+
+ * tests/Makefile.in (REALCFLAGS): add $(srcdir)/../include
+
+1999-08-30 Love <lha@s3.kth.se>
+
+ * configure.in: Added check for libkafs with AC_FIND_FUNC_NO_LIBS
+
+1999-08-29 Love <lha@s3.kth.se>
+
+ * appl/udebug/udebug.c: Host order bug noticed by Dr A V Le Blanc
+ <LeBlanc@mcc.ac.uk>
+
+ * README: Update that programs we distribute
+
+1999-08-28 Love <lha@s3.kth.se>
+
+ * conf/Makefile.in: Create the cache-dir
+
+1999-08-27 Love <lha@s3.kth.se>
+
+ * xfs/linux/xfs_message.c (xfs_message_installdata): Add code for
+ open_namei in the linux2.1+ case.
+
+ * configure.in (AC_OUTPUT): Changed to reflect new directory
+ structure for appl/
+
+ * appl/*/Makefile.in (RXKAD_LIBS): use @MILKO_RXKAD_LIBS@
+
+ * xfs/include/xfs/xfs_message.h: Ugly hack for WIN32/i386
+
+1999-08-25 Love <lha@s3.kth.se>
+
+ * xfs/winnt/src/xfs_vops.c: Added create
+
+ * xfs/winnt/xfs.reg [Dos Devices] Change place of device
+
+ * xfs/winnt/README: Added more tips and tools
+
+ * xfs/winnt/src/xfs_init.c: start using XFSLOG and xfs_debug()
+
+ * xfs/winnt/inc/xfs_locl.h: Added <stdio.h> <stdarg.h>
+
+ * xfs/winnt/src/xfs_deb.c (xfs_debug): implement
+
+ * xfs/winnt/inc/xfs_proto.h: Add prototyp for xfs_debug()
+
+ * xfs/winnt/inc/xfs_deb.h: rename things to XFSLOG since that is
+ what is realy is add XDEB things from xfs/include/xfs_debug.h,
+ should really be an include XXX
+
+ * xfs/winnt/src/xfs_vops.c (*): more sane debugging
+ (xfs_queryvol,xfs_fscontrol): added placeholder
+
+ * xfs/winnt/src/xfs_init.c: Added IRP_MJ_QUERY_VOLUME_INFORMATION,
+ IRP_MJ_FILE_SYSTEM_CONTROL more debugging
+
+ * xfs/winnt/inc/xfs_deb.h: Misc debugging constants
+
+ * xfs/winnt/inc/xfs_proto.h: Added xfs_queryvol, xfs_fscontrol
+
+ * xfs/winnt/inc/xfs_locl.h: include xfs_deb.h
+
+1999-08-22 Love <lha@flippflopp.passet.pp.se>
+
+ * appl/lib/arlalib.c: remove empty comment ad the end
+
+ * appl/lib/appl_locl.h: move <kafs.h> outside #ifdef KERBEROS
+
+ * appl/afsutils/unlog.h: change prototype of do_help
+
+ * appl/afsutils/tokens.c (*): Added nonkerberos support
+
+ * appl/afsutils/klog.c (main) moved non-global stuff to main
+ (*): Added non-kerberos support.
+
+ * appl/afsutils/TODO.afsutils (general): fixed mktemp and /ticket
+ problem
+
+ * appl/*: new style tree (one program in each dir (almost))
+
+1999-08-21 Love <lha@s3.kth.se>
+
+ * appl/fs.c (getcache_cmd): formating fix
+
+ * tests/run-tests.in: Format stuff for tests now when they are
+ reformated print date when we are done.
+
+1999-08-20 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_syscalls.c (unpag): repair linux 2.0 code
+
+ * xfs/linux/xfs_message.c (gc_vnode): try to handle linux 2.0
+
+ * xfs/linux/xfs_node.c (xfs_iget): use get_empty_inode if we have
+ it
+
+ * configure.in (AC_LINUX_FUNC_GET_EMPTY_INODE): add
+
+ * rx/Makefile.in (test_rx_clock): add dependency on $(LIB)
+
+1999-08-17 Love <lha@s3.kth.se>
+
+ * arlad/xfs.c (xfs_message_wakup): Added check for lost messages.
+ Fix the assert
+
+ * configure.in(linux): Set KERNEL_CC to CC as default
+
+1999-08-17 Simon Josefsson <jas@pdc.kth.se>
+
+ * appl/klog.c (do_timeout): Use waitpid() instead of wait4().
+
+ * xfs/irix/Makefile.in (distclean,distclean-subdirs): New targets.
+
+ * xfs/irix/bin/Makefile.in (distclean): New target.
+
+ * conf/Makefile.in (distclean): Remove Makefile.
+
+ * lwp/Makefile.in (clean): Remove process.i.
+ (distclean): Remove Makefile.
+
+ * include/Makefile.in (distclean): New target.
+
+1999-08-14 Love <lha@s3.kth.se>
+
+ * tests/find-linux: new test
+
+ * tests/run-tests.in: beatified and added test find-linux
+
+ * arlad/fcache.c (emergency_remove_node): added function
+ (cleaner): try to throw nodes when they are in kernel
+ (unlink_lru_entry): call emergency_remove_node() if we are short on nodes.
+
+1999-08-10 Assar Westerlund <assar@sics.se>
+
+ * configure.in: AC_DEFINE with three arguments to avoid having
+ garbage in acconfig.h
+
+ * acconfig.h: remove more from this supposed-to-be-empty file
+
+1999-08-09 Assar Westerlund <assar@sics.se>
+
+ * configure.in: use AC_HAVE_KERNEL_DEF instead of AC_HAVE_DEF
+
+1999-08-08 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs/xfs_locl.h: try to move up asm/current.h even more
+
+1999-08-08 Assar Westerlund <assar@sics.se>
+
+ * Release 0.27
+
+1999-08-08 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): correct call to
+ xfs_vfs_object_create
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call): return a
+ `xfs_handle_t' and not a `fh_args' in vice_ioctl->out
+
+ * xfs/bsd/xfs/xfs_common.h (memcpy): add prototype
+
+ * xfs/bsd/xfs_common-bsd.c (memcpy): implement in terms of bcopy
+ for the kernels that don't have it
+
+ * configure.in: check for memcpy in kernel
+
+ * arlad/messages.c (xfs_message_remove): always do an installnode
+ instead of an installattr sometimes. this seems to solve
+ hardlink1
+
+ * appl/Makefile.in (LIBS): gratious link with RXKAD_LIBS.
+
+ * appl/tokens.sh: retire
+
+ * appl/Makefile.in: remove SHELL_SCRIPTS. none left after
+ tokens.sh was retired
+
+ * xfs/solaris/Makefile.in (DEFS): include KERNEL_CFLAGS
+
+ * configure.in (solaris): try to handle 64-bit sparc
+
+ * configure.in (linux): add `-ffixed-8' when compiling on alpha
+ (setgroups-tests): add _LKM, should really use KERNEL_foo instead
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_pioctl): conditionalize to death
+ (for 32 bit compat foobar).
+
+ * include/kafs.h: conditionalize 32-bit guck
+
+ * appl/klog.c: merge in more patch from Chris Wing
+ <wingc@engin.umich.edu>:
+
+ 1) Somebody broke the behavior of the -tmp option. (made get_tkt
+ FALSE instead of TRUE). Fixed.
+
+ 2) mkstemp() from roken creates a unique temporary file and
+ returns the name. Previously I had used mktemp(), which returns
+ a unique name only.
+ (I originally dealt with the possible race condition by putting the
+ ticket files in a directory called /ticket, mode 1733).
+
+ The problem is that if a ticket cannot be gathered (for
+ instance, if the wrong password is entered), this temporary
+ file will stick around.
+
+ Fixed so that the ticket file is automatically destroyed if it
+ isn't made available to the user.
+
+ 3) If -setpag is used and the shell cannot be exec()ed, the AFS
+ token will stick around in a ghost PAG. Now klog makes sure to
+ remove the token in this case.
+
+ (as per the recent discussion about bloating the AFS client with large
+ numbers of dead credentials)
+
+ 4) Minor changes to move all warning messages to use warnx, diet,
+ etc., eliminating fprintf(stderr, ... )
+
+ 5) Minor changes to warning messages missing whitespace or having
+ superfluous newlines
+
+1999-08-02 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_pioctl): handle all the 32 bit
+ versions of the pioctls
+
+ * xfs/solaris/xfs_wrap.c: install the 32bit syscall
+
+ * xfs/solaris/xfs_syscalls.c (xfs_syscall32): implement a 32 bit
+ syscall (to be used when running on solaris 7 in 64bit mode)
+
+ * include/kafs.h: define ViceIoctl32 for the 32bit API in case
+ it's different. also define all the pioctl values with _32
+ appended because the sizeof the struct may be used to to derive
+ the actual value used.
+
+ * configure.in (--with-krbafs): handle both pointing at the prefix
+ and the lib itself
+ (setgroups tests): define all kernel defines and correct name of
+ sysproto macro (this should really be done with the kernel test)
+
+ * arlad/afsdir_check.c: don't include arla_local.h because that
+ would give us xfs.h which we don't want.
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_link): try to handle early
+ FreeBSD here as well
+
+ * arlad/arladeb.c: don't include arla_local.h because that would
+ give us xfs.h which we don't want.
+
+1999-08-02 Love <lha@s3.kth.se>
+
+ * conf/CellServDB (umr.edu): Uppdated
+
+1999-08-01 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (fcache_fhget): move vice_ioctl to avoid warning.
+
+ * xfs/bsd/xfs/xfs_syscalls.h (xfs_fhandle_t): define
+
+ * xfs/bsd/xfs/xfs_locl.h: glue for xfs_vfs_getvfs and
+ xfs_vfs_object_create
+
+ * xfs/bsd/xfs_vfsops-osf.c (xfs_fhlookup): use opaque
+ xfs_fhandle_t instead of (fsid,fileid,gen)
+ (xfs_fhopen): changed to new signature
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): new signature, use
+ opaque struct to pass in fh-data and typecast it to xfs_fh_args or
+ fhandle_t depending on if we have a working VPTOHP (ie getfh)
+ (xfs_fhopen): use native sys_fhopen
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call): implement a fhget if
+ we have a working VPTOFH.
+ (fhopen_call): use xfs_fhandle_t instead of fh_args.
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): use new style
+ fhlookup
+ (xfs_message_version): reenable native fhget
+
+ * xfs/solaris/xfs_syscalls.c (xfs_unpag): implement
+
+1999-07-29 Assar Westerlund <assar@sics.se>
+
+ * appl/klog.c: use krb_get_pw_in_tkt instead of krb_get_pw_in_tkt2
+ and don't use krb_get_default_principal to be compatible with CNS
+
+ * lib/acl/acl_files.c (krb_principal): removed definition. we get
+ it from stds.h
+
+ * lwp/process.S: use ENTRY instead of _ENTRY to be more consistent
+ with the definitions in <machine/asm.h>
+
+1999-07-29 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (try_again): free connections then we get a
+ RXKADEXPIRED.
+
+ * rx/rx.c (rxi_ReceivePacket): if there is an error with the
+ connection propagate that up to the user with
+ rxi_ConnectionError()
+
+1999-07-29 Assar Westerlund <assar@sics.se>
+
+ * lwp/process.S: try to be more consitent with using _C_LABEL and
+ _ENTRY
+
+ * configure.in: some more <sys/time.h>, from Harald Barth
+ <haba@pdc.kth.se>
+
+1999-07-29 Love <lha@s3.kth.se>
+
+ * conf/CellServDB: Added eng.utah.edu, anl.gov changed
+
+ * include/Makefile.in: Added parse_time.h, by Ken Raeburn
+ <raeburn@raeburn.org>
+
+ * xfs/bsd/xfs/xfs_locl.h: include xfs/xfs_syscalls.h instead of
+ sys/syscallargs.h to avoid dual inclusion by Ken Raeburn
+ <raeburn@raeburn.org>
+
+ * configure.in: added <sys/time.h> for setgroups test as suggested
+ by Ken Raeburn <raeburn@raeburn.org>
+
+1999-07-28 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (stale): throw data if we have any
+
+1999-07-28 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (sanitize_nvldbentry): added. used.
+
+ * arlad/volcache.c (volcache_getbyname, volcache_getbyid): move
+ the setting of stablep here
+
+ * arlad/messages.c (try_again): figure out if the volume
+ information is reliable
+
+ * arlad/volcache.c (cmp_nvldbentry): new function
+ (volcache_reliable): another new function
+ (*): maintain stablep
+
+ * arlad/volcache.h (volcacheentry): add last_fetch and stablep
+ (volcache_reliable): prototype
+ (VOLCACHE_OLD): 120
+
+1999-07-25 Simon Josefsson <jas@pdc.kth.se>
+
+ * tests/hardlink1.c (main): Non-ambigous errors.
+
+1999-07-25 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs/xfs_msg_locl.h: Added xfs_message_{version,gc_nodes}
+ prototypes
+
+ * xfs/linux/xfs_message.c (xfs_message_version): new func, what
+ this xfs supports
+ (xfs_message_gc_nodes): throw away nodes that isn't used
+
+ * xfs/linux/xfs_dev.c: Call new functions
+
+1999-07-25 Love <lha@s3.kth.se>
+
+ * tests/run-tests.in: -p for `fs calculate`
+
+ * appl/fs_lib.c (fs_calculate_cache): new function
+
+ * arlad/messages.c (vioc_calculate_cache): New function
+
+ * arlad/fcache.c (fcache_calculate_usage,sum_node): new functions
+ to calculate real cachesize
+
+ * include/kafs.h: added VIOC_CALCULATE_CACHE (58)
+
+ * arlad/reconnect.c (reconnect_mkdir): Dont run mkdir on the
+ child-node, its already done.
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c (error_function): let the default be the empty
+ string which makes lots of stuff much simpler
+ (generate_simple_stub): always use error_function
+
+ * arlad/fcache.c (throw_data): correct the assert to use the
+ correct variable
+ (try_next_fs): return TRUE for ARLA_VNOVOL (suggested by Jeffrey
+ Hutzelman <jhutz+@cmu.edu>)
+ (read_attr): don't free server context if do_read_attr fails
+ (read_data): increment `usedbytes' when we have actually gotten the
+ data
+ (fcache_get_data): don't free server context if do_read_attr fails
+
+1999-07-24 Love <lha@s3.kth.se>
+
+ * arlad/*-subr.c: use fcache_get_fbuf and fdir_readdir instead of
+ adir_readdir to avoid racecondition
+
+ * arlad/adir.c (get_fbuf_from_fcache): remove and use
+ fcache_get_fbuf instead.
+
+ * arlad/fcache.[ch] (fcache_get_fbuf): new function
+
+ * arlad/xfs.[ch]: Move a lot of xfs related stuff here. Document
+ and clarify how each function is (almost) suppose to work,
+ REMEMBER the comments are only there to confuse you.
+
+ * arlad/messages.[ch]: move a lot of xfs related stuff from
+ message.[ch] to xfs.[ch]
+
+ * arlad/kernel.c (version_thread): don't wait, just exit
+
+ * appl/vos_dump.c (dump_volume): use conv_to_arla_errno for
+ afs-errors
+
+ * xfs/include/xfs/xfs_message.h: Add
+ xfs_message_{version,gc_nodes} messsages
+
+ * xfs/bsd/xfs/xfs_msg_locl.h: Added xfs_message_{version,gc_nodes}
+ prototypes
+
+ * xfs/bsd/xfs_message.c (xfs_message_version): new func, what this
+ xfs supports
+ (xfs_message_gc_nodes): throw away nodes that isn't used, XXX
+ osf,smp
+
+ * arlad/fcache.c (fcache_fhopen,fcache_fhget): check if we have
+ native fopen
+ (throw_data): don't assert on wrong length, file might be broken
+ from and faulty StoreData.
+ (cleaner): run xfs_send_message_gc_nodes() to try to gc nodes that
+ is ref:ed by xfs.
+ (emergency_remove_data): use xfs_send_message_gc_nodes() to throw
+ any lot of nodes that is ref:ed by xfs
+ (read_data): use conv_to_arla_errno() for afs-errors
+ (write_data): open file RW so we can truncate if it we get an
+ error while storing the file
+ (truncate_file): use conv_to_arla_errno() for afs-errors
+
+ * lib/bufdir/fbuf.c (mmap_copy{rx2fd,fd2rx}): use
+ conv_to_arla_errno to fetch afs special error (VDISKFULL & co)
+ from rx_Write()
+
+ * arlad/reconnect.c (reconnect_putattr): use conv_to_arla_errno to
+ fetch afs special error (VDISKFULL & co) from rx_Write()
+
+ * arlad/messages.h (xfs_message_{send,sleep}): export
+
+ * arlad/messages.c (*): Add gc node stuff
+ (xfs_message_{send,sleep}): export
+ (xfs_message_rpc): move to xfs.[ch]
+
+ * arlad/kernel.c (kernel_interface): create version_thread
+ (version_thread): start probing on what xfs can do. (XXX do
+ earlier ?)
+
+ * arlad/arla_local.h: Added "xfs.h"
+
+ * arlad/Makefile.in: Added xfs.[cho]
+
+ * arlad/xfs.[ch]: xfs related stuff, like version-control and
+ xfs_send_message_gc_nodes().
+
+ * configure.in: AC_CHECK_KERNEL_FUNCS(vgonel)
+
+1999-07-23 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (xfs_message_rmdir): only do sillyrename when
+ linkcount == 2, add comments.
+ (xfs_message_remove): only set it silly when linkcount == 1 (ie
+ last reference to file)
+
+ * arlad/fcache.c
+ (do_read_attr,write_data,write_attr,fcache_get_data): don't read
+ attr if its a silly rename.
+
+1999-07-20 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (fcache_get): reset flags.silly
+ (fcache_recover_state): set flags.silly == FALSE
+ (fcache_reobtain_callbacks): check for flags.silly
+ (fcache_giveup_all_callbacks): check for flags.silly
+
+ * arlad/reconnect.c (do_replay): ftruncate the log_file
+
+ * arlad/messages.c (xfs_message_remove): Only insert limbo entry
+ into kernel when its there, add comment.
+
+ * arlad/inter.c (cm_symlink): the caller of create_symlink is
+ resonsible of setting flags.kernelp.
+
+ * arlad/fcache.c (create_symlink): move out settign of
+ flags.kernelp, since the entry might be a mountpoint and the
+ child_entry is never pushed to the kernel.
+
+ * arlad/inter.c (cm_lookup): make sure ret is set to a correct
+ value.
+
+ * appl/fs.c (getcache_cmd): use getarg, enable printing of bytes
+ and kbytes.
+
+ * appl/amon.c (GetUsedBytes): change names to reflect new
+ fs_getfilecachestats
+
+ * appl/fs.c (getcache_cmd): use new fs_getfilecachestats() that
+ uses bytes instead of kbytes
+
+ * appl/fs_lib.c (fs_getfilecachestats): change signature, pass
+ bytes instead of kbytes.
+
+ * arlad/messages.c (viocgetcacheparams): pass on
+ fcache_{high,used}bytes unchanged to userland.
+
+1999-07-20 Assar Westerlund <assar@sics.se>
+
+ * arlad/inter.h (cm_lookup): update prototype
+
+ * arlad/inter.c (cm_lookup): new flags for following mount points
+
+ * arlad/messages.c: new version of cm_lookup, change callers
+ (xfs_message_remove): set tokens correctly
+
+1999-07-20 Artur Grabowski <art@stacken.kth.se>
+
+ * configure.in: test for machine/endian.h
+
+ * rxkad/rxk_crpt.c: add a special test for endianness to allow
+ static config.h on many architectures. (don't ask)
+
+ * xfs/bsd/xfs_common-bsd.c: make it build without XFS_DEBUG.
+
+1999-07-20 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs/xfs_locl.h: add test for {sys_,}setgroups_args
+
+ * xfs/bsd/xfs_syscalls-common.c (xfs_setgroups): use
+ xfs_setgroups_args and SCARG
+
+ * configure.in: test for {,sys_}setgroups_args
+
+ * cf/have-def.m4: New macro
+
+1999-07-20 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_vfsops.c: handle d_alloc_root with one and two
+ arguments
+
+ * configure.in: use AC_LINUX_FUNC_D_ALLOC_ROOT_TWO_ARGS
+
+ * cf/linux-func-d_alloc_root-two_args.m4: new test
+
+ * xfs/solaris/xfs_syscalls.c (xfs_setgroups): port the linux patch
+ to prohibit setting the pag with setgroups
+
+ * xfs/bsd/xfs_syscalls-common.c (xfs_setgroups): port the linux
+ patch to prohibit setting the pag with setgroups
+
+ * xfs/linux/xfs_syscalls.c (xfs_setgroups): always leave from the
+ PAG. prevent it from installing fake PAGs. From Chris Wing
+ <wingc@engin.umich.edu>
+
+ * arlad/fcache.c (create_symlink): remove bogus increate of
+ `usedbytes'
+
+1999-07-20 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_extra_file_name): terminate string
+ properly
+
+1999-07-19 Assar Westerlund <assar@sics.se>
+
+ * tests/hardlink1.c: more testing
+
+ * xfs/linux/xfs_inodeops.c (xfs_getattr): new function for return
+ the attributes for a file or directory. installed in all the
+ instances of `struct inode_operations'. This requires the patch
+ adding the getattr operation to inode_operations.
+
+ * xfs/linux/xfs/xfs_locl.h: <asm/current.h>: conditionalize
+
+ * configure.in: check for asm/current.h check for {updatepage,
+ revalidate, and getattr} in `struct inode_operations'
+
+ * NEWS: mention new cache file names
+
+ * arlad/messages.c (token_for_cell): copy out the ticket
+
+1999-07-19 Simon Josefsson <jas@pdc.kth.se>
+
+ * appl/fs.c (copyacl_cmd):
+ (afs_copyacl): New functions.
+ (afs_setacl): Garbage collect empty rights. Don't segfault on
+ empty acl.
+
+1999-07-19 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_extra_file_name): add the @ at the end
+ instead
+
+1999-07-15 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (voicckserv): s,0,cell_name2num
+ (cell_getthiscell());,
+
+1999-07-15 Assar Westerlund <assar@sics.se>
+
+ * appl/klog.c (main): use kname_parse instead of krb_parse_name
+
+1999-07-14 Assar Westerlund <assar@sics.se>
+
+ * appl/appl_locl.h: <sys/wait.h>
+
+ * lib/acl/acl_files.c: some functions to handle other kerberos
+ libraries
+
+ * appl/tokens.c (krb_kdctimeofday): check for
+
+ * appl/klog.c: fallback for KRB_TICKET_GRANTING_TICKET
+
+ * configure.in: check for sys/wait.h
+
+ * configure.in: AC_FUNC_KRB_KDCTIMEOFDAY: add
+
+ * tests/Makefile.in: add create-{symlinks,dirs}
+
+ * arlad/fcache.c: make the cache directory two-level
+
+ * arlad/fcache.h (fcache_dir_name): new prototype
+
+ * tests/many-dirs: use create-dirs
+
+ * tests/many-symlinks: use create-symlinks
+
+ * tests/create-symlinks.c: new file
+
+ * tests/create-dirs.c: new file
+
+ * tests/many-files: use create-files
+
+ * tests/create-files.c: new program for creating lots of files
+
+ * tests/Makefile.in: add create-files
+
+ * tests/read-vs-mmap2.c (mmap_file): needed cast
+
+ * tests/read-vs-mmap.c (mmap_file): needed cast
+
+ * appl/fs.c (afs_whereis): remove htonl - address is already in
+ network byte order
+
+1999-07-13 Love <lha@s3.kth.se>
+
+ * xfs/winnt/*: Added dead code.
+
+ * arlad/bsd-subr.c (dir_remove_name): Add assertions. Only merge
+ with previous dirent, if there is enough space in the dirent.
+
+ * appl/klog.c: start to use diet{,x}
+ (randfilename): rewrite, umich compat on ticketfile
+
+ * appl/{README.afsutils,TODO.afsutils}: Note by Chris Wing
+ <wingc@engin.umich.edu>
+
+ * appl/klog.[ch1]: Added klog by Chris Wing
+ <wingc@engin.umich.edu>
+
+ * appl/unlog.[ch1]: Added unlog by Chris Wing
+ <wingc@engin.umich.edu>
+
+ * appl/appl_locl.h: Added <kafs.h>, <parse_time.h>
+
+ * appl/amon.c: removed <kafs.h>
+
+1999-07-12 Magnus Ahltorp <map@stacken.kth.se>
+
+ * appl, lib/ko: Move partition name conversion to libko
+
+1999-07-06 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_link): only vput on OpenBSD and
+ NetBSD :-(
+
+1999-07-06 Love <lha@s3.kth.se>
+
+ * arlad/volcache.c (get_info_loop): check for dynroot volume
+
+ * arlad/fcache.c (read_attr): check for dynroot
+ (getroot): check for dynroot
+ (fcache_get_data): check for dynroot
+
+ * arlad/arla.c: (args): -dynroot, -D for dynroot
+
+ * arlad/arla_local.h: <dynroot.h>
+
+ * arlad/Makefile.in (SOURCE,HEADER,OBJECT) += dynroot.?
+
+ * arla/dynroot.[ch]: dynamic root, new files.
+
+ * lib/ko/ko.h (cell_foreach,cell_get_version): export
+
+ * lib/ko/kocell.c (celldb_version): version of in-memory
+ (cellno): dont use the 0 cell
+ (add_cell): assert on cell == 0
+ (cell_init): add dynroot cell
+ (cell_foreach): make a iterator function
+ (cell_get_version): return version of the db
+ (add_special_dynroot_cell): add dynrootcell to the celldb
+
+1999-07-04 Love <lha@s3.kth.se>
+
+ * tests/fs-flush: test to flush
+
+1999-07-04 Assar Westerlund <assar@sics.se>
+
+ * tests/run-tests.in (ARLA_TESTS): add mkdir2
+
+ * tests/Makefile.in (mkdir2): add
+
+ * tests/mkdir2.c: new test
+
+ * tests/run-tests.in (ARLA_TESTS): add hardlink2
+
+ * tests/hardlink2.c: new test
+
+ * tests/Makefile.in (hardlink2): add
+
+ * arlad/messages.c (xfs_message_remove): fall back to conv_dir if
+ dir_remove_name fails. decrement the linkcount to zero if it was
+ one before so that hardlink1 succeeds. generally clean-up.
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * tests/test-gunzip-gnu-mirror: replace spaces in the case-pattern
+ with * (how do you quote in a case-pattern?)
+
+ * tests/run-tests.in (ARLA_TESTS): add test-gunzip-gnu-mirror
+
+ * tests/test-gunzip-gnu-mirror: new test
+
+1999-07-01 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla_local.h: add <sys/mount.h>
+
+ * configure.in (NetBSD): figure out PMAP_NEW in the same way as
+ UVM
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_link): VOP_UNLOCK ->
+ xfs_vfs_unlock
+
+ * configure.in (NetBSD): fix test syntax, hopefully.
+
+ * arlad/fcache.c (fcache_fhopen, fcache_fhget): try to handle
+ getfh and fhopen syscalls
+
+ * configure.in (VERSION): bump to 0.27pre
+ (getfh, fhopen): check for
+
+1999-06-29 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_remove): install attributes for
+ the dead none so that if there are more links to it they will get
+ the correct link count
+
+ * tests/Makefile.in: add hardlink1
+
+ * tests/hardlink1.c: new test
+
+ * tests/run-tests.in (ARLA_TESTS): add hardlink1
+
+ * xfs/linux/xfs_node.c (new_xfs_node): always update the inode
+ attributes
+
+ * appl/fs.c (afs_print_sysname): transarc-compatible quoting.
+ From Simon Josefsson <jas@pdc.kth.se>
+
+ * arlad/messages.c (token_for_cell): return the viceId instead.
+ From Chris Wing <wingc@engin.umich.edu>
+
+1999-06-29 Assar Westerlund <assar@sics.se>
+
+ * Release 0.26
+
+ * configure.in (VERSION): bump
+
+ * configure.in (irix): set IP in a more robust way
+
+ * xfs/linux/xfs_inodeops.c (xfs_print_lock): punt on printing
+ `waking' since it's different types on different architectures
+
+1999-06-28 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-osf.c: implement xfs_mmap, and (crude)
+ xfs_getpage
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): ugly hack to
+ prevent panics on OSF/1
+
+1999-06-26 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_dev.c (xfs_message_rpc): remove unused variable
+
+ * xfs/linux/xfs_inodeops.c: removed som printf warnings
+
+1999-06-24 Assar Westerlund <assar@sics.se>
+
+ * lib/bufdir/fbuf.h: <rx/rx.h>: add
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/bin/arla.init.in: new sysv-style init file from Marko
+ Asplund <aspa@hip.fi>
+
+ * arlad/messages.c (xfs_message_remove): remove the entry from the
+ converted directory but without moving anything around (with
+ dir_remove_name). also install it with XFS_DATA_R. this should
+ fix the problem with large-dir-extra
+
+ * arlad/solaris-subr.c (dir_remove_name): implement
+
+ * arlad/sunos-subr.c (dir_remove_name): implement
+
+ * arlad/irix-subr.c (dir_remove_name): implement
+
+ * arlad/hpux-subr.c (dir_remove_name): implement
+
+ * arlad/aix-subr.c (dir_remove_name): implement
+
+ * arlad/solaris-subr.c (dir_remove_name): some more paranoia
+
+ * arlad/subr.h (dir_remove_name): new prototype
+
+1999-06-22 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_wrap-osf.c (xfs_configure): check for errors
+
+1999-06-20 Assar Westerlund <assar@sics.se>
+
+ * lib/bufdir/fdir.c (fdir_readdir): initialize `len'. start using
+ fbuf_len and fbuf_buf
+
+ * configure.in: comment out test for mode_t and nlink_t
+
+ * lib/bufdir/fbuf.c (mmap_copyfd2rx): correct arguments to mmap
+
+ * arlad/fcache.c (find_first_fs): don't segv when e->volume is not
+ set
+ (write_data): new copyfd2rx
+
+ * lib/bufdir/fbuf.c (copyfd2rx): also include offset
+
+ * arlad/adir.c: remove all unsued variables
+
+ * arlad/adir.c: start using fdir
+
+ * arlad/inter.c: new signature for adir_lookup_fcacheentry
+
+ * arlad/adir.h (adir_lookup_fcacheentry): new parameter `dir'
+
+ * arlad/Makefile.in: link with bufdir instead of our own copy of
+ fbuf
+
+ * include/Makefile.in (LOCL_HEADERS): add fbuf.h
+
+ * tests/test-setgroups.c, tests/test-setpag.c (NGROUPS): define to
+ NGROUPS_MAX if not def
+
+ * tests/large-dir3.c: remove extra paranoid test
+
+ * lwp/process.S: update comment for .register stuff on solaris 7
+
+ * arlad/messages.c (xfs_message_create, xfs_message_mkdir): don't
+ send down (owner,group) group attributes
+
+ * appl/vos_common.c: get rid of some stupid ctype warnings
+
+ * configure.in (mode_t, nlink_t): test for
+ (const, endianness): also test for
+
+ * arlad/fcache.c (create_directory): use the kludge of throwing
+ away data if we for turn out to get a new directory with initial
+ data. this is to make milko happy and should really be solved
+ there instead.
+
+1999-06-19 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: write the PID to /var/run/arlad.pid make
+ fork-logic simpler
+
+1999-06-17 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_read_common): actually call
+ xfs_vop_read
+
+1999-06-16 Assar Westerlund <assar@sics.se>
+
+ * xfs/rhapsody/xfs_node.c (xfs_attr2vattr, vattr2xfs_attr): it's
+ not ts_* but tv_*
+
+ * xfs/rhapsody/xfs_message.c (xfs_message_installdata): the
+ standard `tmp' -> `message->cache_name'
+
+ * xfs/solaris/xfs_vnodeops.c (do_fsync): copy attributes
+
+ * xfs/solaris/xfs_node.c (vattr2xfs_attr): only copy the
+ interesting bits from va_mode
+
+1999-06-13 Assar Westerlund <assar@sics.se>
+
+ * appl/vos_dump.c: patch from Alexandra Ellwood <lxs@MIT.EDU> to
+ work around a rhapsody gcc bug (variables and typenames in the
+ same namespace)
+
+ * arlad/arla.c (miain): complain if we can't create the cache
+ directory or it doesn't exist
+
+1999-06-11 Assar Westerlund <assar@sics.se>
+
+ * util/ip.[ch]: zaped
+
+1999-06-10 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_syscalls-common.c: remove some more ifdefs
+
+ * xfs/bsd/xfs/xfs_locl.h: add xfs_proc_to_ruid
+
+1999-06-09 Assar Westerlund <assar@sics.se>
+
+ * include/Makefile.in (LOCL_HEADERS): removed unexisting headers
+
+ * ydr/main.c (main): use efopen and remove temporary files and
+ give sensible error messages for popen failing
+
+1999-06-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-common.c: use
+ xfs_vop_{read,write,access,getattr}
+
+ * xfs/bsd/xfs/xfs_locl.h: add xfs_vop_{read,write,access,getattr}
+
+ * xfs/bsd/xfs_syscalls-wrap-bsd.c: add support for NetBSD a.out
+ emulation
+
+ * configure.in: check for aout_sysent to keep old pre-ELF NetBSD
+ programs happy
+
+1999-06-08 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_wrap-bsd.c (xfs_mod): dont have a special case for
+ MOD_DISPATCH since we need the major number befor exiting.
+
+1999-06-08 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (viocsettok): return ENOENT if the cell doesn't
+ exist
+
+ * xfs/bsd/bin/startarla.in: after thinking about it, it doesn't
+ make very much sense to send kldload options that isn't supported
+ on any machine other than mine
+
+1999-06-07 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/getcwd.c: add <sys/types.h>. Patch from Derrick J
+ Brashear <shadow@dementia.org>
+
+1999-06-04 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/bin/startarla.in: send -p to kldload
+
+1999-06-03 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): FILE_UNUSE the `struct
+ file'. This might solve arlad getting hung in `closef' on NetBSD
+
+ * xfs/bsd/xfs_wrap-bsd.c (xfs_modload): make it compile
+
+ * xfs/bsd/xfs/xfs_dev.h (xfs_is_xfs_dev): add prototype
+
+ * xfs/bsd/xfs_wrap-osf.c (xfs_is_xfs_dev): new function
+
+ * xfs/bsd/xfs_wrap-bsd.c (xfs_is_xfs_dev): new function
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): use
+ xfs_is_xfs_dev instead of xfs_isdevopen
+
+ * xfs/bsd/xfs_dev-osf.c (xfs_func_is_devopen): remove
+
+ * xfs/bsd/xfs_dev-bsd.c (xfs_func_is_devopen): remove
+
+1999-06-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_wrap-bsd.c (xfs_mod): expand call to DISPATCH, since
+ we want to get the assigned major number before exiting
+
+1999-05-31 Love <lha@s3.kth.se>
+
+ * util/eefile.c (eefopen) Fail if mkstemp fails
+
+1999-05-30 Love <lha@s3.kth.se>
+
+ * Release 0.25
+
+1999-05-30 Assar Westerlund <assar@sics.se>
+
+ * tests/run-tests.in (ARLA_TESTS): add discon-tar{1,2} and remove
+ setgroups (it needs to be run as root)
+
+ * tests/test-setgroups.c (main): kludgy tests to handle the case
+ of the PAG being in slots (0 and 1) or (1 and 2)
+
+ * configure.in: add test for .register on solaris as
+
+ * HACKING: new file
+
+ * rx/Makefile.in: add test_rx_clock
+
+ * rx/test_rx_clock.c: new test program
+
+ * tests/build-gdb: use gdb-4.18 instead
+
+ * arlad/reconnect.c: only update the fids in the kernel if they
+ are there
+
+ * tests/run-tests.in: warm fuzzy at the end
+
+ * tests/run-tests.in: add more discon*
+
+ * arlad/reconnect.c (reconnect_putattr): comment out some code.
+ handle directories correctly.
+
+ * arlad/messages.c (xfs_message_mkdir): try to invent attributes
+ when creating directories
+
+ * arlad/fcache.c (write_attr): handle disconnected mode
+ (create_file, create_directory): allocate fake FIDs from 1000 and 1001
+ with an increment of two.
+
+ * xfs/solaris/xfs/xfs_locl.h: add sys/syscall.h
+
+ * xfs/irix/xfs_syscalls.c: junk unused code
+
+ * tests/run-tests.in: recognize --version and --help
+
+ * lwp/process.S: upgrade solaris 7 sparcv9 .register declarations
+ to the (apparently) correct syntax. now we only need an autoconf
+ test.
+
+ * arlad/kernel.c: err format fixes
+
+ * arlad/afsdir_check.c: err format fixes
+
+1999-05-30 Love <lha@s3.kth.se>
+
+ * doc/partsofarla.texi: @xref in a () should be a @pxref
+
+ * tests/boot-strap-arla: New test
+
+ * conf/CellServDB: Added arla.e.kth.se
+
+ * configure.in (CONFIG_FILES)+= milko/bos/Makefile
+
+ * rxdef/bos.xg: Added partial bos def.
+
+ * rxdef/Makefile.in: Add libbos{server,client}.a
+
+ * arlad/service.h: Added bos service id
+
+ * lib/ko/koerror.c: Prefixed all entries with appropiate prefixes.
+ Added bos errorcodes.
+
+ * appl/fs.c: fs strerror to easy find the errorcode
+
+1999-05-29 Assar Westerlund <assar@sics.se>
+
+ * tests/run-tests.in (ARLA_TESTS): add new tests
+
+ * tests/discon-{create,echo,mkdir}: new tests
+
+ * arlad/volcache.c (volcache_set_rootvolume): assert there being a
+ volname
+ (VOLCACHE_SIZE): make prime
+
+ * arlad/reconnect.c (fid_translate): make global
+ (recon_hashtabdel, recon_hashtabadd): remove
+ (reconnect_mkdir): remove bad error check
+
+ * arlad/messages.c (xfs_message_putattr): write disconnected
+ changes to the log
+ (xfs_message_create): try to invent attributes when creating
+ disconnected files
+ (xfs_message_mkdir): log disconnected changes
+ (viocconnect): remove ARLACACHEDIR
+
+ * arlad/fcache.c (recon_hashtabadd, recon_hashtabdel): add
+ handle the case of entry->volume == NULL in more places
+ (init_fs_server_context): new function
+ (find_first_fs): don't care about connected_mode
+ (fcache_reobtain_callbacks): get volume entries here. is this right?
+ (write_attr, create_directory, create_symlink, create_link,
+ remove_file, remove_directory, rename_file, do_read_data, getacl,
+ setacl, getvolstat, setvolstat): check connected_mode
+ (create_file): initialize more attributes
+
+ * arlad/discon_log.h: add more prototypes
+
+ * arlad/conn.c (internal_get): don't check connected_mode here,
+ it's done elsewhere.
+
+ * configure.in: AC_HAVE_STRUCT_FIELD: fix uses
+
+ * tests/mountpoint.in: run fs from objdir
+
+ * tests/run-tests.in (MILKO_TESTS): add deep-tree2
+
+1999-05-28 Assar Westerlund <assar@sics.se>
+
+ * configure.in (KRB_LIB_FLAGS): set
+
+ * tests/Makefile.in: need to link against libkrb as well...
+
+ * tests/run-tests.in: add new test: setgroups setpag
+
+ * tests/Makefile.in: add setgroups and setpag
+
+ * tests/setpag*, tests/setgroups*: add new tests
+
+ * xfs/solaris/xfs_syscalls.c (store_pag): always get a new `struct
+ ucred'
+
+ * xfs/bsd/xfs_syscalls-common.c (store_pag): always get a new
+ `struct ucred'
+
+1999-05-28 Love <lha@s3.kth.se>
+
+ * lib/ko/kocell.c: add cell_setthiscell
+
+ * appl/vos_createentry.c: added cell, and corrected noauth, use cell in
+ arlalib_getconnbyname, return a sane error
+
+ * appl/vos_vldbexamine.c: Added, a examine that only probes the
+ vldbserver (to be removed by when vldblist works).
+
+1999-05-27 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs/xfs_syscalls.h: new prototypes
+
+ * xfs/solaris/xfs_wrap.c: install/remove setgroups wrapper
+
+ * xfs/solaris/xfs_syscalls.c: add setgroups wrapper
+
+ * lib/acl/acl.h: add atypes.h to make stds.h happy
+
+ * configure.in: fix the hstrerror tests
+
+ * xfs/bsd/xfs_syscalls-common.c (store_pag): store the correct
+ values
+
+ * xfs/bsd/xfs/xfs_syscalls.h (xfs_setgroups, old_setgroups_func):
+ add
+
+ * xfs/bsd/xfs_syscalls-wrap-osf.c: save and restore setgroups
+ system call
+
+ * xfs/bsd/xfs_syscalls-wrap-freebsd.c: save and restore setgroups
+ system call
+
+ * xfs/bsd/xfs_syscalls-wrap-bsd.c: save and restore setgroups
+ system call
+
+ * xfs/bsd/xfs_syscalls-common.c (store_pag): new function
+ (xfs_setgroups): wrapper around setgroups that preserves the PAG
+
+ * xfs/linux/xfs_syscalls.c (xfs_setgroups): a wrapper around
+ setgroups that preserves the PAG
+
+1999-05-25 Love <lha@s3.kth.se>
+
+ * lib/ko/ko.h: Added <netinet/in.h>
+
+1999-05-22 Assar Westerlund <assar@sics.se>
+
+ * INSTALL: note that if you change your prefix your kerberos/afs
+ libraries may have problems.
+
+1999-05-22 Marcus Sundberg <mackan@stacken.kth.se>
+
+ * xfs/linux/bin/startarla.in: Do insmod before creating missing
+ device node - makes devfs happy.
+
+1999-05-19 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_dev-bsd.c (xfs_devioctl): reorder defines
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): udev2dev for
+ freebsd
+
+ * configure.in: AC_CHECK_KERNEL_FUNCS check for udev2dev
+
+1999-05-19 Johan Danielsson <joda@pdc.kth.se>
+
+ * configure.in: fix test for -mno-fp-regs on NetBSD/alpha
+
+ * lib/bufdir/fbuf.c: sys/errno.h -> errno.h
+
+1999-05-18 Love <lha@s3.kth.se>
+
+ * configure.in: CONFIG_FILES += milko/lib/msecurity
+
+1999-05-17 Love <lha@s3.kth.se>
+
+ * milko/*: Added filbunke - nnp-server-class fileserver
+
+ * include/Makefile.in: Added afs_dir.h
+
+ * appl/vos_createentry.c (vos_createentry): zero out newentry
+
+Mon May 17 14:13:33 1999 Johan Danielsson <joda@pdc.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c: only include vm/vnode_pager.h if
+ it's present
+
+1999-05-16 Assar Westerlund <assar@sics.se>
+
+ * configure.in (AC_LINUX_FUNC_INIT_WAITQUEUE_HEAD): add
+
+ * cf/linux-func-init-wait-queue-head.m4: new file
+
+ * lwp/lwp.h (LWP_NewRock, LWP_GetRock): add prototypes
+
+ * rx/rx_clock.c: handle the case of the itimer expiring
+
+ * acconfig.h (__EXTENSIONS__): conditionalize. (it gets
+ automatically defined on Irix and needs to be defined on Solaris)
+
+ * appl/vos.c: move cmds to avoid a forward declaration
+
+ * cf/linux-type-wait-queue-head.m4: try compiling instead of
+ greping in linux/wait.h
+
+ * arlad/fcache.c (fcache_extra_file_name): change the name for the
+ converted directory to be @%04X
+
+ * arlad/reconnect.c: adjusted the length of the filenames, based
+ on a patch from Niklas Hallqvist <niklas@appli.se>.
+ (copy_cached_file): simplify
+
+1999-05-15 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_print_lock): make it work on 2.3.2
+ and 2.2 by printing less information. From Hee-Seok Heo
+ <hsheo@postech.ac.kr>
+
+ * xfs/linux/xfs_dev.c: patch from Hee-Seok Heo
+ <hsheo@postech.ac.kr> for 2.3.2 plus autoconf-junk by myself.
+
+ * configure.in: test for wait_quque_head_t and init_MUTEX.
+
+ * acconfig.h: cut down a lot
+
+ * aclocal.m4: dead
+
+ * configure.in: moved most of the tests to cf. removed duplicate
+ tests updated to autoconf 2.13 separated linux and bsd kernel
+ tests
+
+ * lwp/Makefile.in (install): work around make rewriting the vpath
+ file name
+
+ * xfs/bsd/xfs_vfsops-osf.c: use xfs_suser
+
+ * xfs/bsd/xfs_vfsops-bsd.c: use xfs_suser
+
+ * xfs/bsd/xfs_syscalls-common.c: use xfs_suser
+
+ * xfs/bsd/xfs_common-osf.c (xfs_suser): add
+
+ * xfs/bsd/xfs_common-bsd.c (xfs_suser): add
+
+ * lwp/rw.c (main): correct cast
+
+ * arlad/fcache.h (FCacheEntry): kill invalid_le
+
+ * Release 0.24
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): handle one and two
+ argument suser
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call, xfs_debug): handle
+ one and two argument suser
+
+ * configure.in: test for suser taking two arguments
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * lwp/process.S (__sparcv9): add commented-out .register
+ declarations. these are apparently needed if you have a recent as
+ but I've currently no way of testing it.
+
+1999-05-12 Assar Westerlund <assar@sics.se>
+
+ * rx/rx.c (rxi_ReceivePacket): long should be u_int32_t
+
+ * rx/rx.h: do the obvious short -> u_int16_t, long -> u_int32_t
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * lwp/make-process.o.sh.in: use AS from configure
+
+ * configure.in: allow setting AS
+
+ * xfs/linux/xfs_inodeops.c: merge 2.2.7-fix from map
+
+ * lwp/Makefile.in (install): solaris make seems very good at
+ rewriting vpath file names. try to work around it.
+
+ * include/Makefile.in (install): solaris make seems very good at
+ rewriting vpath file names. try to work around it.
+
+1999-05-06 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c (newwalk): renamed to walk.
+
+1995-05-04 Assar Westerlund <assar@sics.se>
+
+ * rx/rx_clock.c (clock_ReInit): count microseconds also
+
+ * arlad/fcache.c (getroot): find out the local cell the equality
+ way. also made more robust, more informative, and more
+ consistent. welcome to the new getroot.
+
+ * lib/ko/kocell.c: make all cells be equal (and no cells more
+ equal that others)
+
+ * arlad/arla.c (main): call clock_ReInit after forking
+
+ * rx/rx_clock.c (clock_ReInit): add
+
+1999-04-12 Assar Westerlund <assar@sics.se>
+
+ * arlad/Makefile.in (LDFLAGS): set
+
+ * configure.in: LDFLAGS: substitute
+
+1999-04-06 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (viocsetvolstat): Do not change volumename,
+ motd or offlinemsg
+
+ * arlad/fcache.c (fcache_get): Added check if we missed
+ volume. Note that we should really either nuke the entry or check
+ for e->volume == NULL everywhere.
+
+1999-03-29 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (try_again) If we don't have EDQUOT use ENOSPC
+
+1999-03-28 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.23
+
+Sat Mar 27 05:16:49 1999 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (vioc_get_cellstatus): reverse issuid test
+
+ * configure.in (freebsd[34]): build KLD if kernel is ELF
+
+ * xfs/bsd/xfs_syscalls-wrap-osf.c (rename sys_xfspioctl ->
+ xfspioctl)
+
+ * xfs/bsd/xfs_syscalls-wrap-freebsd.c (rename sys_xfspioctl ->
+ xfspioctl)
+
+ * xfs/bsd/xfs_syscalls-wrap-bsd.c (rename sys_xfspioctl ->
+ xfspioctl)
+
+ * xfs/bsd/xfs_syscalls-common.c (rename sys_xfspioctl ->
+ xfspioctl)
+
+ * xfs/bsd/xfs/xfs_syscalls.h (rename sys_xfspioctl -> xfspioctl)
+
+1999-03-27 Robert Burgess <rb@stacken.kth.se>
+
+ * Removed Solaris umount_xfs (the umount command that comes with
+ Solaris works better)
+
+ * xfs/solaris/xfs_syscalls.c (fhopen_call): Changed in_size check
+
+Wed Mar 24 23:31:09 1999 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: always do fork_late
+
+Thu Mar 4 02:40:46 1999 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c: revert back extra changes
+
+ * ydr/output.c (generate_multi): do the right thing with the macro
+ arguments
+
+ * rxdef/ubik.xg: remove bogus struct keywords
+
+ * rx/rx_user.c (rxi_GetUDPSocket): fix typos
+
+1999-03-20 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs/xfs_node.h: Added test for LK_SHARED
+
+ * xfs/bsd/xfs_message.c (xfs_message_installnode): lock node when
+ doing vget
+ (xfs_message_installdata): lock node when doing vget
+
+
+1999-03-19 Love <lha@s3.kth.se>
+
+ * Snapshot 1999-03-19
+
+ * arlad/volcache.h (volume_make_uptodate): new function
+
+ * arlad/volcache.c (volume_make_uptodate): new function
+
+ * arlad/messages.c (try_again): ARLA_VMOVED and ARLA_VNOVOL
+ invalidates volcache
+ (*): new useage of try_again()
+
+ * arlad/fcache.c (find_first_fs): make sure the volume is uptodate
+ (try_next_fs): ARLA_VMOVED and ARLA_VNOVOL are errornous and will break
+ the search for next fileserver (they mean that we should update
+ our vldb info)
+
+ * lib/ko/koerror.c: Added <rx/rx.h>, <fs_errors.h> and fileserver
+ converted errors.
+
+ * arlad/messages.c (viocflushvolume): when flushing the volume,
+ flush the volume from the volcache at the same time
+
+ * ydr/parse.y: use create_type
+
+ * ydr/types.c (create_type): New function
+
+ * xfs/bsd/xfs/xfs_node.h: If LK_EXCLUSIVE isn't defined make sure
+ we define it to 1, its used for compat with old vget() that
+ doesn't use lockmgr locking-style
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): return a locked
+ vnode
+
+ * xfs/bsd/xfs_message.c: (xfs_message_install{node,root}): do
+ vrele() instead of vput() since we never locks the vnode in the
+ vget
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): Get a lock on
+ when returning it
+
+1999-03-16 Love <lha@s3.kth.se>
+
+ * include/Makefile.in: Break out generated headers and files that
+ comes with the dist
+
+Sun Mar 14 20:03:10 1999 Assar Westerlund <assar@sics.se>
+
+ * appl/vos_local.h: update prototypes
+
+ * appl/vos_listvldb.c (vos_listvldb_iter): complain if
+ find_db_cell_and_host fails
+
+ * appl/vos_examine.c (printvolstat): complain if
+ find_db_cell_and_host fails
+
+ * appl/vos_common.c (get_vlentry): write a comment to make Magnus
+ happy. assume host != NULL.
+ (new_vlentry): check and complain if find_db_cell_and_host fails
+ (find_db_cell_and_host): comment and remove casts
+
+ * rxkad/rxk_clnt.c (client_GetResponse): handle versions >=
+ RXKAD_VERSION and always generate a version 2 response
+
+1999-03-12 Love <lha@s3.kth.se>
+
+ * Snapshot 1999-03-12
+
+ * ydr/parse.y: (TPOINTER): set symbol to NULL
+
+ * arlad/fcache.c (find_first_fs): set num_conns to 0 for
+ DISCONNECTED case
+ (do_read_attr): check if disconnected and have bits
+
+1999-03-11 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c (setacl): flush bits in kernel to make it
+ update acl
+
+1999-03-10 Assar Westerlund <assar@sics.se>
+
+ * rxdef/*.xg: include <config.h> and <roken.h>. They are needed
+ when building with !gcc
+
+ * xfs/bsd/xfs/xfs_vfsops.h (xfs_fhopen): correct prototype
+
+ * xfs/bsd/xfs/xfs_syscalls.h (xfs_pioctl_call): correct prototype
+
+ * xfs/bsd/xfs_syscalls-common.c (lookup_node): printf format fix
+
+1999-03-06 Love <lha@s3.kth.se>
+
+ * appl/vos_syncsite.c (vos_syncsite): Added arguments (-cell and
+ -no-resolve)
+
+ * rxdef/volumeserver.xg (AFSVolCreateVolume): name is string
+
+ * appl/vos_local.h: Added prototypes
+
+ * appl/vos_listvldb.c (vos_listvldb_iter): use
+ find_db_cell_and_host
+
+ * appl/vos_examine.c (vos_examine): use find_db_cell_and_host
+
+ * appl/vos_common.c (getvolumetype): document
+ (new_vlentry): New function
+ (find_db_cell_and_host): new function
+
+ * appl/fs.c(apropos_cmd): use sl apropos
+
+ * appl/Makefile.in: Added vos_createvolume.c vos_endtrans.c to vos
+
+ * appl/vos_{createvolume,endtrans}.c: New files
+
+Thu Mar 4 02:40:46 1999 Assar Westerlund <assar@sics.se>
+
+ * appl/vos_listvldb.c (vos_listvldb_iter): const-ify
+
+ * appl/vos_examine.c (printvolstat): use get_vlentry
+
+ * appl/vos_common.c (get_vlentry): use arlalib_authflags_t
+
+ * appl/vos_common.c (get_vlentry): new function
+
+ * appl/vos_dump.c: new file
+
+ * ydr/types.c (define_struct): handle already declared structures
+ (set_struct_body_sym): new function
+
+ * ydr/parse.y: handle forward declaration of struct and redundant
+ struct keywords
+
+ * ydr/output.c (generating_multi): fix macro call code
+
+ * ydr/lex.l: match the final newline on the #line-lines from cpp
+ so that we don't increment the lineno when we should not.
+
+ * ydr: patches from Derrick J Brashear <shadow@dementia.org> for
+ generating rx-multi macros
+
+1999-03-04 Love <lha@s3.kth.se>
+
+ * appl/*: started to use arlalib_getauthflag arlalib_authflags_t
+ for unified -noauth and -local
+
+ * appl/vos_listvldb.c: New file
+
+ * appl/vos_local.h: Added prototypes for vos_listvldb() and
+ vos_listvldb_iter()
+
+ * appl/vos.c (cmds): added listvldb
+
+ * appl/Makefile.in (vos): vos_listvldb
+
+Thu Mar 4 02:40:46 1999 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-netbsd.c (xfs_vfsops): add vfs_checkexp
+ conditionally
+
+ * configure.in: check for vfsops.vfs_checkexp
+
+ * rx/rx_pkt.c (rxi_ReadPacket): ignore errors from recvmsg
+ silently.
+ (osi_NetSend): sendmsg can return ECONNREFUSED on linux. ignore it.
+
+ * rx/rx_user.c (rxi_GetUDPSocket): set SO_BSDCOMPAT. clean-up
+
+ * include/Makefile.in (install): install stds.h
+
+Wed Mar 3 13:10:15 1999 Marcus Sundberg <mackan@stacken.kth.se>
+
+ * xfs/linux/getcwd.c: removed redundant fcntl.h so it works on glibc 2.1
+
+Wed Mar 3 00:49:00 1999 Marcus Sundberg <mackan@stacken.kth.se>
+
+ * configure.in, xfs/linux/xfs_load.c, xfs/linux/xfs/xfs_locl.h:
+ Linux devfs support
+
+Tue Mar 2 08:50:27 1999 Assar Westerlund <assar@sics.se>
+
+ * rxdef/*.xg: more RPCs
+
+ * rx/Makefile.in (install): install header files
+
+ * lwp/Makefile.in (install): install include files from srcdir
+
+ * lib/ko/Makefile.in: add vlmisc
+
+ * arlad/volcache.c (vldb2vldbN): move to vlmisc.c
+ (get_info_loop): less warnings
+
+ * appl/arlalib.c: let all the functions take a cell argument
+
+ * appl/appl_locl.h: add rx header files
+
+ * appl/Makefile.in: vos: re-organize
+
+ * lib/ko/vlmisc.c: new file
+
+ * lib/acl/Makefile.in (INCLUDES): use include directory in srcdir
+ (Makefile): add
+ * appl/vos.c: clean-up
+
+ * ydr/output.c (print_varray): correct code
+ (init_generate): let all the files include the appropriate header
+ files
+ (print_type): make `string<>' generate `char *'
+ (encode_string): allocate memory dynamically with string<>
+
+ * arlad/volcache.c (recycle_entry): don't assume that num_ptr and
+ name_ptr are parallel
+ (add_clone): add a parameter for the suffix_type
+ (get_info_common): if there's no read-write volume, add the read-only
+ volume with the vanilla name
+
+ * arlad/fcache.c (find_first_fs): do not believe volumeId[type] to
+ be valid
+ (find_volume): more paranoid checks for if the volumes really exist.
+
+ * arlad/conn.c (pinger): re-structure the code
+
+ * rx/rx_user.c (rxi_getUDPSocket): remove code for looping around
+ bind and for checking the port number
+
+ * rx/Makefile.in (install): install headers
+
+ * lwp/Makefile.in (install): install headers
+
+Sun Feb 28 00:44:51 1999 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c (init_generate): add inclusion of foo.{s,c}s.h in
+ foo.{c,s}s.c
+ (generate_server_stub): use prefix when writing the prototype.
+
+ * configure.in: freebsd34: nuke DIAGNOSTIC test
+
+ * xfs/bsd/xfs_vnodeops-bsd.c: call zfreei instead of zfree
+
+ * ydr/output.c: always generate includs for atypes.h and rx.h in
+ stubs
+
+ * ydr/main.c (main): return an error if parse_errors is true.
+
+ * ydr/lex.l: recognize `proc'
+ (error_message): set a flag when an error has occured.
+
+ * ydr/lex.h (error_message): update prototype
+
+ * ydr/parse.y: add prefix
+
+ * ydr/lex.l: add prefix
+
+ * lwp/Makefile.in (install): install lwp.h
+
+ * ydr/Makefile.in (install): install ydr
+
+ * ydr/output.c (generating): remove roken.h and arlad/fs_errors.h
+
+ * rxdef/*.xg: arlad/fs_errors.h -> fs_errors.h
+
+ * lwp/Makefile.in (clean): remove test programs.
+
+ * include/Makefile.in: install some headers
+
+ * ydr/parse.y (param_type): default to IN
+ (memberdecl2): handle string without size
+
+Sat Feb 27 20:11:28 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * xfs/bsd/xfs_dev-common.c (xfs_uprintf_device): don't print junk
+
+Sat Feb 27 12:01:35 1999 Assar Westerlund <assar@sics.se>
+
+ * util/eefile.c, util/eefile.h: new files
+
+ * ydr: Install patches from Derrick J Brashear
+ <shadow@dementia.org> for running several instances simultaneously.
+
+1999-02-26 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-common.c: (xfs_rename_common): Don't remove
+ "tname". Arlad changes the fid if it exist (linux does this today)
+
+ * configure.in: welcome back test for mnt_syncer
+
+ * xfs/bsd/xfs_node-bsd.c: (free_all_xfs_nodes): check if we don't
+ unmount and then skip mnt_syncer
+
+ * xfs/bsd/xfs_node-osf.c: (free_all_xfs_nodes): third dummy
+ argument
+
+ * xfs/bsd/xfs_dev-common.c (xfs_devclose_common): pass on to
+ free_all_xfs_nodes that we dont unmount
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_unmount_common): pass on to
+ free_all_xfs_nodes that we unmount
+
+1999-02-25 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (xfs_message_rename): flush new dir from DNLC
+ cache
+
+1999-02-22 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_dev-common.c:(xfs_devclose_common): Removed dead
+ mnt_syncer code.
+
+ * acconfig.h: HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_fseek):
+ HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS
+
+ * configure.in: check for vop_fsync_args.a_flags
+
+ * Release 0.22
+
+ * arlad/fs_errors.h: catch VRESTARTING
+
+ * arlad/messages.c: catch VRESTARTING.
+
+ * xfs/bsd/bin/startarla.in: test for kld
+
+Sun Feb 21 04:31:22 1999 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_message.c (xfs_message_installnode): Try a
+ requested entry first, then try any entry. Delete old alias from
+ alias chain before adding it.
+
+Sat Feb 13 02:32:37 1999 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_syscalls-common.c (sys_xfspioctl): use
+ `xfs_proc_to_cred'
+
+ * util/Makefile.in: add heaptest
+ (check): new target
+
+ * util/heaptest.c, util/util-tester.c: improve batchability a
+ little bit
+
+ * util/Makefile.in (libutil_SRCS, libutil_OBJS): removed prio and
+ timeprio
+
+ * util/prio.[ch], util/timeprio.[ch]: removed
+
+ * util/mem.[ch]: removed.
+
+ * xfs/linux/getcwd.c: handle both `struct stat' and `struct
+ new_stat'
+
+ * acconfig.h (HAVE_STRUCT_NEW_STAT): add
+
+ * configure.in: remove old BSD kernel functions not being called
+ any longer. test for `struct new_stat' for linux
+
+ * xfs/linux/getcwd.c: handle the case without getcwd
+
+ * xfs/linux/getcwd.c: try to get the current directory by any of
+ these ways:
+ a. the getcwd syscall
+ b. /proc/self/cwd (only on 2.1)
+ c. by tracing the directory structure backwards and comparing
+ inode numbers
+
+ also make sure that buf == NULL works everywhere
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock): re-organize
+ the code so that we handle the case of there not being any flag
+ argument (with one argument vop_lock)
+
+ * xfs/bsd/xfs/xfs_vnodeops.h (xfs_fsync_common, xfs_close_common):
+ update prototypes
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_fsync_common,
+ xfs_close_common): add `proc' argument
+
+ * xfs/bsd/xfs_vnodeops-osf.c (xfs_fsync, xfs_close): adapt to
+ changing *-common functions
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_fsync, xfs_close): adapt to
+ changing *-common functions
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked):
+ re-introduce counted locking but only when flags & LK_TYPE_MASK,
+ otherwise the assymetry comes back to bite us.
+
+ * xfs/bsd/Makefile.in (unload): add support for kld
+
+ * configure.in (freebsd): generate vnode_if.[ch] and -I. to be
+ able to find them
+
+Sat Feb 6 03:22:56 1999 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs/xfs_vnodeops.h (xfs_fsync_common, xfs_close_common):
+ update prototypes
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_fsync_common,
+ xfs_close_common): add `proc' argument
+
+ * xfs/bsd/xfs_vnodeops-osf.c (xfs_fsync, xfs_close): adapt to
+ changing *-common functions
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_fsync, xfs_close): adapt to
+ changing *-common functions
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked):
+ re-introduce counted locking but only when flags & LK_TYPE_MASK,
+ otherwise the assymetry comes back to bite us.
+
+ * xfs/bsd/Makefile.in (unload): add support for kld
+
+ * configure.in (freebsd): generate vnode_if.[ch] and -I. to be
+ able to find them
+
+ * xfs/bsd/xfs_syscalls-common.c (xfs_debug): move the super-user
+ test to the setting of the debug level. I don't quite remember
+ why I did this but I can see no harm in letting any user find out
+ the current debug level?
+
+ * tests/run-tests.in: add --help
+
+ * arlad/volcache.c (vldb2vldbN): constize and only copy the safe
+ number of servers
+
+ * arlad/fcache.c: remove old code
+
+ * arlad/inter.c: always set Result.error to make things simpler.
+
+1999-02-05 Love <lha@s3.kth.se>
+
+ * arlad/volcache.c (vldb2vldbN): Added bounce checking
+ (get_info_loop): dont loop if old serve returns RXGEN_OPCODE
+
+1999-02-05 Love <lha@s3.kth.se>
+
+ * arlad/volcache.c (vldb2vldbN): New function
+ (get_info_loop): Added fallback-code for old server
+
+ * arlad/volcache.c (ConnCacheEntry): Added field flags.old
+
+ * arlad/conn.c (new_connection): reset flags.old
+
+ * arlad/arla_local.h: Added rxgencon.h
+
+ * appl/fs.c (connect_cmd): return 0;
+ (newcell_cmd): rewrote and started to use getarg
+ (getmaxfprio): return 0
+
+ * arlad/messages.c (viocgetwscell): len strlen(cellname)+1 as
+ suggested by Chuck Lever <cel@monkey.org>
+
+Mon Feb 1 05:53:52 1999 Assar Westerlund <assar@sics.se>
+
+ * lwp/plwp.c: include config.h
+ (LWP_CreateProcess): call thr_yield if there's one
+ (Create_Process_Part2): fix call to pthread_attr_setstacksize
+
+ * acconfig.h: define __EXTENSIONS__ to make solaris' header files
+ happy.
+
+ * configure.in: check for thr_yield
+
+ * lwp/plwp.[ch]: new files with lwp-over-pthreads
+
+ * lwp/rw.c: new file with test code
+
+ * lwp/preempt.h: more prototypes
+
+ * lwp/Makefile.in: support building with lwp-over-pthreads
+
+ * include/Makefile.in (lwp.h): link in the correct file for
+ LWP/pthreads
+
+ * appl/Makefile.in: handle linking with pthreads
+
+ * arlad/Makefile.in: handle linking with pthreads
+
+ * INSTALL: document --with-pthreads
+
+ * configure.in (--with-pthreads): add code from Derrick J Brashear
+ <shadow@dementia.org> for using pthreads
+
+Sun Jan 31 20:48:57 1999 Assar Westerlund <assar@sics.se>
+
+ * configure.in (irix): always add -DR4000 to cflags, otherwise it
+ seems to break.
+
+ * xfs/irix/xfs/xfs_syscalls.h: use correct include files
+
+ * xfs/irix/xfs/xfs_node.h: port to Irix 6.4
+
+ * xfs/irix/xfs/xfs_fs.h: port to Irix 6.4
+
+ * xfs/irix/xfs_vnodeops.c: port to Irix 6.4
+
+ * xfs/irix/xfs_vfsops.c: port to Irix 6.4
+
+ * xfs/irix/xfs_syscalls.c: use `curprocp' instead of `u'. that
+ makes it work under 6.4 as well
+
+ * xfs/irix/xfs_node.c: port to Irix 6.4
+
+ * xfs/irix/xfs_message.c (xfs_message_installdata): VOP_LOOKUP is
+ called differently under irix 6.4
+
+ * xfs/irix/Makefile.in (LDFLAGS): always add -32
+ (MOD): write in current directory and not source directory
+
+ * configure.in (irix): correct and portabilize irix6.4-test
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_map): always cast len to
+ unsigned long in the debug output
+
+ * xfs/bsd/xfs_vfsops-osf.c (xfs_root): send both proc and cred to
+ xfs_root_common
+
+ * configure.in (irix): define IRIX_64 if running on Irix 6.4 or
+ above.
+
+ * tests/dir-size-mismatch: use find | xargs rm to remove the
+ files, it was overflowing the argument size.
+
+ * xfs/solaris/xfs/xfs_dev.h (intptr_t): define if there's none
+
+ * acconfig.h (HAVE_INTPTR_T): add
+
+ * configure.in: bump version to 0.22pre remove duplicate test for
+ syslog test for `intptr_t'
+
+Sun Jan 31 17:51:34 1999 Assar Westerlund <assar@sics.se>
+
+ * Release 0.21
+
+ * configure.in (freebsd34): add -I. to kernel flags to find the
+ generated vnode_if.h
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked):
+ more debug output
+
+Sat Jan 30 17:42:00 1999 Assar Westerlund <assar@sics.se>
+
+ * tests/copy-and-diff-gnu-mirror: use correct fd. From Simon
+ Josefsson <jas@pdc.kth.se>
+
+1999-01-28 Love <lha@s3.kth.se>
+
+ * arlad/arla.c(arla_cp): Added copy command.
+
+1999-01-24 Love <lha@s3.kth.se>
+
+ * conf/Makefile.in(install): Install a empty SuidCells if there is no.
+
+ * tests/run-tests.in: Print out that the test FAILED while running
+
+ * xfs/bsd/Makefile.in: (xfs_vopdefs.h): Make the link even if
+ 'mkdir xfs' fails, and test if xfs is a dir
+
+ * configure.in (freebsd[34]*) Add support for freebsd4, default to
+ kld on freebsd4, add output from test
+
+Tue Jan 19 20:31:50 1999 Assar Westerlund <assar@sics.se>
+
+ * configure.in (irix): check for IP and cpu and add them to
+ KERNEL_CFLAGS
+
+ * xfs/irix/Makefile.in: use KERNEL_CFLAGS for figuring out CPU and
+ such
+
+Sat Jan 16 18:55:17 1999 Love <lha@stacken.kth.se>
+
+ * configure.in: check if VOP_LOCK takes one argument (NetBSD1.3.x)
+
+ * xfs/bsd/xfs_vnodeops-bsd.c: Check if VOP_LOCK takes one argument
+
+Tue Jan 12 01:16:12 1999 Assar Westerlund <assar@sics.se>
+
+ * xfs/include/xfs/xfs_message.h (CACHEHANDLESIZE): bump to 80
+ (needed on Solaris 7 in 64bit mode)
+
+ * lwp/process.S: add even more ifdef's to handle sparc v9
+
+ * lwp/make-process.o.sh.in: use CC and AS from environment.
+ remove foo.c when we're done.
+
+ * lwp/lwp.c (REGSIZE): on a sparc v9 the registers are also 8
+ bytes
+
+ * lwp/lwp.h (lwp_context): try to use the correct amount for sparc
+ v9
+
+ * rx/rx_user.c (rxi_Listener): use `rx_maxSocketNumber' when
+ selecting to avoid having to send the rather large FD_SETSIZE
+
+ * rx/rx_pkt.h (rx_GetLong, rx_PutLong): use `u_int32_t' instead of
+ `long'
+
+ * tests/build-gdb: change path for gdb.
+
+ * tests/build-emacs: change path for emacs. GNU has reorganized
+ their ftp server and moved all programs into subdirectories.
+
+Sun Jan 10 07:25:51 1999 Assar Westerlund <assar@sics.se>
+
+ * arlad/fprio.c (fprio_readin): don't print a warning if the file
+ cannot be opened.
+
+ * xfs/linux/xfs_dev.c (xfs_message_rpc): also check for strange
+ positive return values.
+
+ * xfs/bsd/xfs_wrap-bsd.c (SYSCALL_MODULE): replace index with
+ pointer
+ (xfs_load): update prototype
+
+ * xfs/bsd/xfs_vfsops-bsd.c (vfs_object_create): use the correct
+ number of arguments
+
+ * INSTALL (--enable-kld): add
+
+ * configure.in (freebsd3): change test for kernel object format
+ (vfs_object_create): add test for number of arguments
+
+ * xfs/bsd/xfs_vfsops-freebsd.c: preliminary support for syscall
+ KLD module
+
+ * xfs/bsd/xfs/xfs_vfsops.h (xfs_root_common): update prototype
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): take a `proc' as
+ argument. call vget instead of vref.
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_root): call new style
+ xfs_root_common update comments
+
+ * xfs/bsd/xfs_syscalls-freebsd.c: preliminary support for syscall
+ KLD module
+
+ * xfs/bsd/xfs_wrap-bsd.c: preliminary support for syscall KLD
+ module
+
+ * arlad/messages.c (CELLSTATUS_{PRIMARY,SETUID}): use defines
+ (vioc_gcpags): implement no-op
+
+ * arlad/inter.c (cm_getattr): real_fid is always set.
+
+ * appl/fs_lib.c (fs_gcpags): send in a correct (and empty) params
+ structure
+
+ * appl/fs.c (gc_cmd): correct argc and string in printf
+ (all): add XDEBNODE
+
+ * configure.in (freebsd): use sysctl to get the name of the kernel
+ reorder the include files in the kernel compilation tests, it was
+ failing on FreeBSD-current
+
+1999-01-05 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_vfsops.c: Do xfs_d_init() when building too to
+ prevent dangling pointers
+
+ * xfs/linux/xfs_message.c: Hopefully more correct invalidation of
+ dentries
+
+Tue Jan 5 00:07:51 1999 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-openbsd.c (vfs_register, vfs_unregister):
+ define and use
+
+ * include/kafs.h: add cell status flags
+
+1999-01-03 Love <lha@s3.kth.se>
+
+ * arlad/fcache.c
+ (throw_entry,fcache_reobtain_callbacks,fcache_giveup_all_callbacks):
+ if the fileserver is `down' don't give up callbacks
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_getnewvnode): Set field vnlock to 0
+ (new_xfs_node): Use HAVE_LK_INTERLOCK
+
+ * xfs/include/xfs/xfs_message.h: XFS_MSG_ADVLOCK confusion
+
+ * xfs/bsd/xfs/xfs_node.h: Added locks confusion
+
+ * lib/ko/kocell.c: Implement clue-code for
+ cell_{is,set}suid{,by_{num,name}} and $SYSCONFDIR/SuidCells
+
+ * lib/ko/ko.h (cell_issuid): new function
+ (cell_issuid_by_name): new function
+ (cell_issuid_by_num): new function
+ (cell_setsuid_by_num): new function
+ (struct cell_entry): Added field suid_cell
+
+ * arlad/messages.c: added rpc messages advlock
+ (vioc_get_cellsstatus): implement
+ (vioc_get_cells): implement
+
+ * appl/fs_local.h: afs_listcells()
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_invalid): dummyify since is
+ break free 2.2.x
+ (xfs_print): write
+ (xfs_advlock): comment out comfusing code
+
+ * arlad/fcache.c (update_entry): suid-flags cleaner
+
+ * appl/fs.c:suidcells: New command, show all cells with suid cells
+ marked. afs_listcells(): Rewritten
+
+
+ * appl/fs_lib.c: fs_getcells(): New function fs_getcellstatus():
+ New function
+
+ * appl/alralib.c(hfs_getcells): New function fs_getcellstatus():
+ New function
+
+ * xfs/bsd/xfs_vfsops-freebsd.c(xfs_init (<3.0)): reset ptr's
+ (vfs_register): set ptr before calling function
+
+ * conf/CellServDB(stacken.kth.se): dog.stacken.kth.se ->
+ fishburger.stacken.kth.se
+
+1999-01-03 Assar Westerlund <assar@sics.se>
+
+ * arlad/reconnect.c: add some more O_BINARY
+
+ * arlad/messages.c: add some more O_BINARY
+
+ * arlad/fcache.c: add some more O_BINARY
+
+ * util/date_rfc822.c (date_time2rfc822): update from rfc822 to
+ rfc1123 section 5.2.14
+
+ * rx/rx_pkt.h (RX_FIRSTBUFFERSIZE): always define it to 1468
+ (RX_CBUFFERSIZE): always define it to 1024
+
+ * xfs/bsd/xfs_syscalls-freebsd.c: use `sysent' instead of
+ `aout_sysvec'
+
+1999-01-02 Magnus Ahltorp <map@stacken.kth.se>
+
+ * Changed getcwd.so to libgetcwd.so.
+
+Thu Dec 31 12:13:10 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter): actually set nameiop to
+ CREATE. (when did this disappear?)
+
+Thu Dec 31 13:04:23 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (volcache_getbyid): use correct hash table
+
+ * arlad/volcache.c (recycle_entry): don't clear entire entry
+ (volcache_getbyname, volcache_getbyname): restructure
+
+ * xfs/linux/xfs_message.c (xfs_message_installnode): nuke benign
+ warning
+
+Wed Dec 30 11:56:04 1998 Assar Westerlund <assar@sics.se>
+
+ * tests/untar-emacs: esthetically corect on fd 3
+
+ * configure.in (freebsd3): always try to guess the kernel object
+ format, also print it out to give the user the change to see if
+ the guess was wrong. also, warn when building LKMs with a !aout
+ kernel (maybe we should just switch to KLDs in that case).
+
+ * arlad/volcache.c (recycle_entry): hopefully work around
+ refcount-bug
+
+Tue Dec 29 03:01:57 1998 Assar Westerlund <assar@sics.se>
+
+ * tests/generic-build: get rid of warning messages from tar
+
+ * configure.in (full_name_hash): more politically correct test.
+
+ * configure.in: --with-sys: actually use the value.
+
+ * arlad/messages.c (vioc_afs_sysname): send 4 bytes length and
+ then string
+ * appl/fs_lib.c (fs_get_sysname): change to expect 4 bytes before
+ sysname string
+
+ * arlad/arla.c (krb_get_err_text): fallback version. Should
+ probably be somewhere else. kroken?
+
+ * configure.in: test for krb_get_err_text
+
+ * configure.in: HAVE_BROKEN_FULL_NAME_HASH ->
+ HAVE_FULL_NAME_HASH_8BIT
+
+ * xfs/linux/xfs/xfs_locl.h: conditionalize on replacing
+ full_name_hash
+
+ * configure.in: test for broken full_name_hash
+
+1998-12-28 Love <lha@s3.kth.se>
+
+ * xfs/bsd/bin/Makefile.in(startarla): Build startarla via
+ startarla.new as suggested by Ken Raeburn <raeburn@raeburn.org>
+
+ * rx/Makefile.in(INCLUDE): typo, fix by Ken Raeburn
+ <raeburn@raeburn.org>
+
+ * Snapshot 0.21pre
+
+Mon Dec 28 01:16:36 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-freebsd.c (xfs_init): kludge that might make
+ it work with kld modules
+
+ * aclocal.m4: KERNEL_CFLAGS -> test_KERNEL_CFLAGS
+
+ * configure.in: support for building kld modules. more tests
+
+ * xfs/bsd/Makefile.in: support building a kld module
+
+ * xfs/bsd/xfs_vfsops-freebsd.c (xfs_init): try with
+ vfs_add_vnodeops
+
+ * xfs/bsd/xfs_vfsops-netbsd.c (xfs_init): vfs_opv_init depending
+ on NetBSD-version
+
+ * configure.in: check for vfs_opv_init include <sys/module.h> in
+ some tests
+
+ * xfs/bsd/xfs_wrap-bsd.c: update and conditionalize KLD_MODULE
+
+ * arlad/messages.c (all_powerful_p): new function. use it.
+ (vioc_afs_sysname): fix reading of sysname
+
+ * configure.in: new files to test for
+ (freebsd3): try to make kld work
+
+ * xfs/bsd/xfs_vfsops-netbsd.c: try without having a special vfs
+ for xfs dead vnodes
+
+ * xfs/bsd/xfs_vfsops-netbsd.c: HAVE_VFS_ATTACH ->
+ HAVE_KERNEL_VFS_ATTACH
+
+ * xfs/bsd/xfs_vfsops-freebsd.c (xfs_stat_filesys): add
+
+ * xfs/bsd/xfs_vfsops-openbsd.c (xfs_stat_filesys): add
+
+ * xfs/bsd/xfs_vfsops-netbsd.c (xfs_stat_filesys): add
+ (xfs_install_filesys): try xfs first
+ (xfs_uninstall_filesys): dito
+
+ * xfs/bsd/xfs_wrap-bsd.c (xfs_unload): try unloading filesystem
+ first
+ (xfs_may_unload): remove
+
+ * xfs/bsd/xfs_vfsops-netbsd.c (vfs_attach): check for vfs_init
+ being NULL
+
+ * include/Makefile.in (HEADERS): add heap.h
+
+ * util/heap.c, util/heap.h: new files
+
+ * util/Makefile.in: add heap.[ch]
+
+ * arlad/fcache.c (add_to_invalidate): go backwards
+
+ * util/list.h (listhead, listtail, listprev, listnext, listdata,
+ listemptyp, listnextp): made into inline functions
+
+ * arlad/inter.c (cm_close): don't overwrite the error code.
+
+ * arlad/fcache.c (fcache_update_length): assert against usedbytes
+ wrapping around
+
+ * arlad/fcache.c (create_file, create_directory): don't touch
+ dir_entry->status.Length
+
+ * arlad/fcache.c (create_symlink): update usedbytes
+
+ * INSTALL: linux: add map's warning message about updating
+ getcwd.so
+
+ * arlad/reconnect.c (reconnect_putdata): adapt to new semantics of
+ copyfd2rx
+
+ * arlad/fcache.c (read_data): adapt to new semantics of copyrx2fd
+ and copyfd2rx
+
+ * arlad/fbuf.c: *_copyfd2rx, *_copyrx2fd: don't close the fd some
+ comments
+
+ * arlad/fcache.c: assert that all closes are succesful.
+
+ * arlad/adir.c: assert that all closes are succesful.
+
+1998-12-24 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.20
+
+1998-12-23 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/getcwd.c (getcwd): If we fail with ENOSYS, fall back
+ on the old getcwd. From <allbery@ece.cmu.edu>
+
+ * lib/ko/kocell.c (newcell): no dbnum
+ (readcellservdb): init dbnum
+
+ * arlad/messages.c (vioc_new_cell): new function
+ (vioc_get_cell): fix bugs
+
+ * lib/ko/ko.h: sync with kocell.c
+
+ * lib/ko/kocell.c: re-organize and write some new functions
+
+ * appl/fs.c: newcell: implement
+
+ * appl/fs_lib.c (fs_newcell): implement
+
+ * xfs/bsd/xfs_vfsops.c: move all xfs initialization code into
+ xfs_vfsops-*bsd.c
+
+ * configure.in (*bsd): use xfs_vfsops-*bsd.c
+
+1998-12-22 Love <lha@s3.kth.se>
+
+ * */*/*: Moved xfs's include files to xfs/
+
+1998-12-21 Assar Westerlund <assar@sics.se>
+
+ * arlad/cred.c (print_cred): print uid correctly
+
+ * arlad/fcache.c (find_next_fs): made global
+ (*): hopefully use try_next_fs properly
+
+Sun Dec 20 17:52:17 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_message.c (xfs_message_installnode): vget and vput
+ the parent node to prevent it from being recycled
+ (xfs_message_installdata): vget and vput the vnode.
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_symlink_common): vput the
+ just created symlink...
+
+ * arlad/messages.c (try_again): also translate error codes
+ (*): realfid always contains the correct fid
+
+ * arlad/fcache.c (try_next_fs): some more error codes
+
+ * arlad/fs_errors.h: add some more error codes
+
+ * arlad/fs_errors.h (VNOVOL, ARLA_VNOVOL): add
+
+ * arlad/fcache.c (findconn): remove
+ (try_next_fs): figure out if it's worth trying the next fs from the
+ error code. call it.
+ (fcache_get): always set realfid
+
+1998-12-19 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: Prevent xfs_lookup from returning
+ errno values below -1000 in 2.1 kernels. They would otherwise be
+ dereferenced in other parts of the kernel.
+
+ * arlad/fcache.c: Check for rw flag when looking for backup volume
+
+ * arlad/reconnect.c: Use find_first_fs instead of find_conn
+
+Sat Dec 19 01:34:23 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/fs.c: move around some more
+ (apropos_cmd): implement
+
+ * conf/CellServDB (transarc.com): updated cell entry
+
+ * arlad/volcache.c (get_info_loop): call VL_GetEntryByNameN
+ instead of VL_GetEntryByName
+
+ * arlad/fs_errors.h (conv_to_arla_errno): add unused. this also
+ requires <roken.h>
+
+ * arlad/fcache.c (fs_server_context): MAXNSERVERS -> NMAXNSERVERS
+
+ * arlad/volcache.h (volcacheentry): use nvldbentry
+
+1998-12-16 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/bin/startarla.in: start arlad with -z switch
+
+1998-12-15 Assar Westerlund <assar@sics.se>
+
+ * Release 0.19
+
+ * xfs/solaris/xfs_dev.c (xfs_message_rpc): bzero the xfs_link's.
+ why is this necessary?
+
+ * xfs/solaris/xfs_node.c (xfs_dnlc_enter): handle the case of no
+ NC_NAMLEN
+
+ * xfs/solaris/xfs_syscalls.c (xfs_debug): new function
+ (xfs_pioctl_call): call xfs_debug
+
+ * xfs/irix/xfs_dev.c (xfs_message_wakeup_data): fix call to
+ MUTEX_LOCK
+
+ * arlad/fcache.c (find_next_fs): simplify
+ (free_fs_server_context): simplify
+
+ * tests: introduce and use AFSROOT
+
+ * arlad/fcache.c (find_first_fs): only sort valid entries.
+ estimate rtt:s before sorting.
+ * arlad/volcache.c (get_info_loop): only sort valid entries.
+ estimate rtt:s before sorting.
+ * arlad/conn.c (conn_rtt_cmp): don't handle NULL pointers
+
+ * arlad/conn.h (conncacheentry): add rtt
+ (RTT_FUZZ): add
+
+1998-12-14 Love <lha@s3.kth.se>
+
+ * xfs/unknown/xfs_deb.h: dummy
+
+Sun Dec 13 10:55:10 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.18
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked):
+ add a large comment describing the sad state of affairs and remove
+ all commented out code from the functions
+
+ * ydr/parse.y: add syntax: error-function <function>
+
+ * configure.in (AC_C_INLINE): test for
+
+ * arlad/fcache.c (find_first_fs, find_next_fs): update to sort
+ filservers by rtt (+ random fuzz)
+ (free_fs_server_context): new function
+
+ * arlad/volcache.c (get_info_loop): get all db-servers and sort
+ them by rtt + random fuzz.
+
+ * arlad/conn.c (conn_rtt_cmp): comparison function for rtt of two
+ entries. adds a random fuzz to load balance.
+
+ * arlad/conn.h (conn_rtt_cmp): function for comparing two entries
+ for rtt
+
+Sun Dec 13 10:47:21 1998 Magnus Ahltorp <map@stacken.kth.se>
+
+ * appl/fs.c: Added fs rmm.
+
+ * arlad/messages.c: Change to new symlink creation
+ sematics. VIOC_AFS_DELETE_MT_PT added. VIOC_AFS_STAT_MT_PT code
+ rewritten.
+
+ * arlad/inter.c: Do followmountpoint in cm_symlink in order to
+ install correct information into xfs
+
+ * arlad/fcache.c: Don't to fcache_update_length when doing
+ directory operations. Put more paranoia into fcache_update_length
+
+ * arlad/adir.c: Change to unsigned char in hash function
+
+ * xfs/linux/xfs_message.c: Invalidate cache when directory is
+ installed.
+
+ * tests/*: New tests.
+
+Sat Dec 12 11:52:22 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/Makefile.in (SYS): set from configure
+
+ * configure.in (--with-sys): add
+
+ * arlad/volcache.c (get_info_loop): try to return better errors.
+ also handle the case of an non-existing volume better.
+
+ * arlad/fcache.c (followmountpoint): update some comments and move
+ some code.
+
+ * arlad/fcache.c (followmountpoint): more comments.
+
+ * arlad/fcache.c (followmountpoint): restructure and split up.
+ also return better errors.
+
+ * arlad/messages.c (vioc_arladebug): new function
+
+ * arlad/volcache.c (volcache_getby*): return ETIMEDOUT instead of
+ ENODEV
+
+ * arlad/fcache.c (followmountpoint): don't nuke the error code
+
+ * arlad/conn.c (pinger): ping one host per loop. print debug
+ information correctly
+ (conn_dead): print port number/services correctly.
+
+ * appl/fs.c (checkservers_cmd): try to give better error messages
+ for non-existing cells
+
+ * tests/Makefile.in (SRC_TESTS): add ls-afs
+
+ * tests/ls-afs: new test
+
+ * appl/arlalib.h (fserr): update prototype
+
+ * appl/fs_lib.c (fserr): const-ize, print to stderr
+ (fs_checkservers): copy cell name correctly. return correct return
+ value
+
+ * appl/fs.c (checkservers): fixes
+
+ * appl/arlalib.h: add prototype for fs_checkservers
+
+ * appl/fs_lib.c (fs_checkservers): random fixups move around
+ #ifdef's
+
+ * arlad/messages.c (viocckserv): some fixes
+
+ * arlad/conn.h (conn_probe): add prototype
+
+ * arlad/conn.c (pinger): run `conn_free' instead of just
+ decrementing the refcount when done with a connection. if
+ somebody else killed it while we're using it, it should get
+ recycled.
+ (conn_probe): new function
+ (host_down): implement CKSERV_DONTPING and some other random stuff
+
+ * xfs/linux/xfs_inodeops.c (xfs_write_file): return `i_blocks' in
+ units of `I_BLOCKS_UNIT'
+
+ * xfs/linux/xfs_node.c (xfs_attr2inode): return `i_blocks' in
+ units of `I_BLOCKS_UNIT'
+
+ * xfs/linux/xfs_locl.h (I_BLOCKS_UNIT): add
+
+ * configure.in (VERSION): bump
+
+1998-12-08 Love <lha@s3.kth.se>
+
+ * tests/run-tests.in: new file, do it in shellscript instead
+ of the makefile.
+
+ * lib/roken/getarg.[ch]: Made arg_printusage() understand style.
+
+ * */{,*/}*.c: Made world aware of that arg_printusage() took
+ a style argument.
+
+ * fs/fs_lib.c: stub for VIOCCKSERV
+
+ * fs/fs.c: checkservers
+
+ * arlad/conn.[ch]: conn_downhosts
+
+ * arlad/messages.c: Non working viocckserv()
+
+ * include/kafs.h: Flags for VIOCCKSERV
+
+Tue Dec 8 00:49:26 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.17.1
+
+Tue Dec 8 00:47:49 1998 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/*: Fix memory leak.
+
+1998-12-06 Love <lha@s3.kth.se>
+
+ * tests/find-and-cat-netbsd: cat netbsd 1.3.2
+
+Sun Dec 6 20:00:25 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.17
+
+ * appl/amon.c (main): no options to XtAppInitialize
+
+ * configure.in (VERSION): bump
+
+ * INSTALL: add --without-x
+
+ * appl/Makefile.in (AMON_LIBS): add more libraries
+
+ * appl/fs_lib.c (debug): new helper function
+ (arla_debug): new function
+
+ * appl/fs_local.h (arla_debug): add prototype
+
+ * appl/fs.c (arladebug_cmd): new function
+ (xfsdebug_cmd): fix parsing and unparsing of flags
+
+ * appl/Makefile.in (fs): add arladeb.c
+
+ * xfs/bsd/xfs_deb.c (xfsdeb): no XDEBANY
+
+ * xfs/linux/xfs_syscalls.h: remove xfs_syscall debug stuff
+
+ * xfs/linux/xfs_syscalls.c (handle_xfs_syscall): remove
+
+ * xfs/include/xfs_debug.h (XDEBANY): remove
+
+ * include/kafs.h (VIOC_ARLADEBUG): add
+
+ * configure.in (VERSION): bump
+
+1998-12-06 Love <lha@s3.kth.se>
+
+ * arlad/messages.c (viocaviator): New funtion
+ (xfs_message_pioctl): Add VIOC_AVIATOR case
+
+ * appl/fs_lib.c (fs_getaviatorstats)new function
+
+ * appl/arlalib.h (fs_getaviatorstats)new function
+
+ * arlad/kernel.[ch]: added kernel_usedworkers() and
+ kernel_highworkers()
+
+ * include/kafs.h: added VIOC_AVIATOR
+
+ * appl/amon.c: Break out stripChart and add workers
+
+ * configure.in: Check for X.
+
+ * appl/amon.c: New, monitor number of vnodes and kbytes used i cache.
+
+Sun Dec 6 00:02:42 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arladeb.h (arla_deb_units): export new prototypes
+ * arlad/arladeb.c (arla_deb_units): define in order. define all
+ and almost-all properly
+ (arla_log_set_level_num, arla_log_get_level_num): new functions
+
+ * xfs/linux/setdebug.c: removed
+
+ * xfs/linux/Makefile.in: removed setdebug
+
+ * arlad/discon_log.c (log_head): initialize to zero by default
+
+ * arlad/reconnect.c: static-ize some
+
+ * arlad/darla.h: add prototypes
+
+ * arlad/arla_local.h: include reconnect.h
+
+ * arlad/reconnect.h: new file
+
+ * appl/vos.c (main): initports -> ports_init
+
+ * appl/pts.c (main): initports -> ports_init
+
+ * lib/ko/ports.c (ports_num2name): new function
+ (initports): renamed to ports_init. changed all callers
+
+ * arlad/volcache.c (vl_probe): new function
+
+ * arlad/messages.c (try_again): print a warning and sleep while
+ waiting for a busy volume
+ (viocgetacl, viocsetacl, viocgetvolstat, viocsetvolstat): call
+ try_again
+
+ * arlad/fcache.c (fs_probe): new function
+ (invalidator): new debug messages
+
+ * arlad/cred.c (cred_expire): print a message telling the user
+ that credentials have expired
+
+ * arlad/conn.h (ConnCacheEntry): add `probe', `probe_le',
+ `probe_next', `ntries'
+ (conn_get): new parameter `probe'
+
+ * arlad/conn.c: probe servers that were marked as down.
+ (re_probe, add_to_probe_list, pinger): new functions
+ (conn_init): start a pinger thread
+ (new_connection, add_connection, internal_get, conn_get): new
+ parameter `probe' (a function that probes the service)
+ (conn_dead): print message when loosing connection to a server
+ (conn_alive): print message when a server comes up again
+
+ * arlad/arla_local.h: add <pwd.h>
+
+ * arlad/arla.c (main): init rx before conn. initports ->
+ ports_init
+
+ * xfs/irix/Makefile.in (CFLAGS): update with more magic flags
+
+ * util/list.c (listempty): explicit cast to shut up SGI cc
+
+ * tests/copy-and-diff-gnu-mirror: use find and cmp instead of diff
+ -r
+
+ * arlad/discon_log.c (write_log_ent): add type to `index'
+
+ * xfs/linux/xfs_message.c (xfs_message_installnode): use
+ xfs_full_name_hash instead of full_name_hash
+
+ * xfs/linux/xfs_inodeops.c (xfs_readdir): use xfs_full_name_hash
+ instead of full_name_hash
+
+ * xfs/linux/xfs_locl.h (xfs_full_name_hash): work-around for
+ broken full_name_in_hash in 2.1.131
+
+ * xfs/linux/xfs_vfsops.c (xfs_delete_inode): correct type in debug
+ output
+
+Sat Dec 5 00:35:05 1998 Assar Westerlund <assar@sics.se>
+
+ * tests/Makefile.in (SRC_TESTS): add build-gdb
+
+ * tests/build-emacs: use generic-build
+
+ * tests/build-gdb: new test
+
+ * tests/generic-build: new file
+
+ * tests/strange-characters: new test
+
+ * tests/read-vs-mmap.c, read-vs-mmap2.c, mmap-and-read.c: include
+ <time.h>
+
+ * tests/Makefile.in: add copy-and-diff-gnu-mirror
+ (check): generate more unique directory names so that several tests
+ can be run in the same directory at the same time
+
+ * tests/copy-and-diff-gnu-mirror: new test
+
+ * arlad/kernel.c (worker): move `data' up front to make sure it's
+ more suitably aligned. how should this really be done?
+
+ * lwp/make-process.o.sh.in (irix): needs -n32 to as.
+
+ * arlad/discon_log.h: clean-up
+
+ * arlad/discon.h: clean-up
+
+ * arlad/reconnect.c (reconnect_create): remove C++-comment
+
+ * arlad/discon_log.c (update_log_ent): fix strange comment
+ look-a-likes
+
+ * arlad/messages.c (afsstatus2xfs_attr): use ClientModTime instead
+ of ServerModTime
+
+ * arlad/adir.c: spell-checking and updating of comments
+
+ * arlad/fcache.c (find_next_fs): destroy previous connection.
+ change all callers.
+
+ * arlad/fcache.c: call conn_dead at all the appropriate places
+
+ * arlad/volcache.c (get_info_loop): mark conns as dead
+
+ * arlad/conn.c (create_new_connections): init `parent'
+ (recycle_conn): remove one reference to `parent'
+ (internal_get): new function. handle setting of parent.
+ (conn_get): only return live servers
+ (conn_dead, conn_alive): new functions
+
+ * arlad/conn.h (ConnCacheEntry): `parent' points to a
+ security-cred-free instance
+ (conn_dead, conn_alive): new functions
+
+ * arlad/fcache.c (find_next_fs, find_first_fs): fill the daily
+ quota for comments.
+
+ * arlad/fcache.c (find_next_fs): remember how far we got
+ (getacl, setacl, getvolstat, setvolstat): always call fcache_release
+
+1998-12-05 Love <lha@s3.kth.se>
+
+ * arlad/arla.c: New option, --fork-late,-f that daemonify,
+ when everything is setup and running.
+
+1998-12-03 Love <lha@s3.kth.se>
+
+ * Cleaned up disconnected code (no warnings).
+
+Wed Dec 2 05:04:04 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (viocgetcell): update to use `cell_dbservers'
+
+ * arlad/fcache.c (find_first_fs, find_next_fs): new functions.
+ use them.
+ (findconn): dead. reconnect code probably doesn't work
+
+ * arlad/volcache.c (get_info_loop): new function to try all db
+ servers. use it.
+
+ * lib/ko/ko.h (cell_dbservers): new prototype
+
+ * lib/ko/kocell.c (cell_dbservers): new function to list all DB
+ servers
+ (cell_listdbserver, cell_finddbserver): removed
+
+ * ydr/output.c (print_array, print_varray): fix printf types
+
+Wed Dec 2 09:26:55 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.16
+
+Wed Dec 2 00:10:05 1998 Assar Westerlund <assar@sics.se>
+
+ * tests/large-dir.c, tests/large-dir-16384: new files
+
+ * tests/Makefile.in (TEST_PROGRAMS): add large-dir
+
+ * tests/large-dir.c (creat_files): fix types
+
+ * tests/mmap-and-read.c (generate_random_file): generate digits in
+ the different pages
+
+ * configure.in: vm/vm_object.h, vm/vm_pager.h, vm/vnode_pager.h:
+ check for
+
+ * util/hash.c (_add): add braces to make it do what I mean
+
+ * util/hash.h (hashtabaddreplace): new prototype
+
+ * util/hash.c (hashtabadd): renamed hashtabaddreplace
+ (hashtabadd): don't replace existing entry
+
+ * arlad/afs_dir.h (MAXPAGES): update comment
+
+ * arlad/afsdir_check.c: handle large directories
+
+ * arlad/adir.c (getpage): new function. use it.
+ (is_page_empty): new function
+ handle large directories
+
+ * tests/large-dir.c (creat_files): better close the files
+
+ * xfs/bsd/xfs_message.c (xfs_message_installattr,
+ xfs_message_installdata): set pager size
+
+ * xfs/bsd/xfs_locl.h: include vm/vm.h and vm/vm_extern.h
+
+ * configure.in: VERSION: bump to 0.15
+ vm/vm.h, vm/vm_extern.h: check for
+
+ * arlad/reconnect.c: don't inlcude discon_fix.h
+
+ * arlad/discon_fix.h: remove. not used anymore.
+
+ * arlad/discon_log.c: don't inlcude discon_fix.h
+
+ * arlad/arla_local.h: remove discon_fix.h
+
+ * arlad/discon_log.h: replace vattr by xfs_attr and moved two
+ definitions here from discon_fix.h
+
+1998-11-23 Love <lha@s3.kth.se>
+
+ * Release 0.15
+
+Sun Nov 22 00:35:33 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/inter.c (cm_open): set result to zero if succesful
+
+ * arlad/fs_errors.h: new file
+
+ * arlad/messages.c (try_again): new function
+ (xfs_message_*): rewritten to use a loop and call try_again to handle
+ expiring kerberos credentials and busy volumes
+
+ * arlad/kernel.c (WORKER_STACKSIZE): increase
+
+ * tests/untar-emacs: progress to fd 3
+
+ * tests/Makefile.in (check): give the tests a fd to stderr
+
+ * tests/Makefile.in: add read-vs-mmap2
+
+ * tests/read-vs-mmap2.c: new file
+
+ * tests/Makefile.in (SRC_TESTS): add rename2
+ (check): write output of failing tests into temporary files. run
+ scripts with $(SHELL) -x
+
+ * tests/Makefile.in: add mmap-and-read
+
+ * arlad/inter.c (cm_mkdir): ReleaseSharedLock -> ReleaseWriteLock
+
+ * arlad/fcache.h (fcache_update_length); add prototype
+
+ * arlad/fcache.c (fcache_update_length): new function. use it.
+
+ * arlad/adir.c: call fcache_update_length at appropriate places
+
+ * configure.in: don't test for <sys/dirent.h> test for
+ vfs_object_create and vnode_pager_setsize
+
+ * tests/read-vs-mmap.c: new file
+
+ * tests/hello-world.in: new file
+
+ * tests/Makefile.in: hello-world, read-vs-mmap: add
+
+ * arlad/fbuf.c (fbuf_buf): new function
+
+ * arlad/fbuf.h (fbuf_buf): add prototype
+
+ * arlad/fbuf.h: (fbuf_len): add prototype
+
+ * arlad/fbuf.c (fbuf_len): add
+
+ * tests/untar-emacs: add . in loop
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_getpages): report the error
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): call vfs_object_create
+ if there's one.
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_write_comon): call
+ `vnode_pager_setsize' if there's one
+
+1998-11-18 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c(xfs_{get,put}pages): use
+ vnode_pager_generic_{put,get}pages if they exist.
+
+Tue Nov 17 04:10:59 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/bin/startarla.in: create /afs
+
+ * arlad/bsd-subr.c (write_dirent): use _GENERIC_DIRSIZ
+
+ * arlad/arla_local.h: only include <sys/dir.h> if there's no
+ <dirent.h>
+
+1998-11-15 Love <lha@s3.kth.se>
+
+ * arlad/inter.c(cm_rename): Check in new_name already exist, and
+ delete it in that case, this should not happen. Suggested by
+ Chuck Lever <chuckl@netscape.com>. Relly a problem between
+ implementations of rename i bsd and linux xfs.
+
+1998-11-14 Love <lha@s3.kth.se>
+
+ * arlad/inter.c(cm_rename): use adir_lookup_fcacheentry()
+
+ * arlad/adir.[ch]: New function adir_lookup_fcacheentry()
+
+Fri Nov 13 05:31:27 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (get_info_common): check for dfs fileset
+
+ * rxdef/vldb.xg (VLF_DFSFILE_SET): added
+
+Tue Nov 10 05:08:27 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_get): handle the case of the entry
+ appearing while we were out looking for a free entry to put it in.
+
+ * arlad/adir.c (adir_lookup): centry shouldn't be static
+
+1998-11-08 Love <lha@s3.kth.se>
+
+ * ydr/output.c: dont ydr the OUT arguments in server stub if
+ function fails, ie returns != 0.
+
+Sat Nov 7 17:22:58 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: new argument --workers
+
+ * arlad/kernel.c (kernel_interface): dynamic number of worker
+ threads
+
+ * arlad/{discon_fix.h,darla.h,discon_log.c,discon.h,discon_log.h,darla.c,reconnect.c}: new files (from wwshen)
+
+ * include/kafs.h (CONNMODE_PARCONNECTED): new
+
+ * arlad/messages.c (xfs_message_create): preliminary disconn
+ support
+ (viocconnectmode): create and replay log on transitions between
+ DISCONNECTED and CONNECTED
+
+ * arlad/fcache.h: some new prototypes
+
+ * arlad/cmcb.c (cmcb_init): not being able to create security
+ objects is a fatal error
+
+ * arlad/fcache.c (throw_entry): signal threads waiting on fee
+ nodes
+ (unlink_lru_entry): if there are no nodes, sleep until they appear.
+ don't reuse nodes being used.
+ (findconn): made global. handle disconnected mode
+ (find_entry): remove bogus assert
+ (fcache_unused): new function
+ (fcache_giveup_all_callbacks): new function
+ (fcache_reobtain_callbacks): new function
+ (do_read_attr): more asserts
+ (read_data): more asserts
+ (write_data): try to handle disconnected mode
+ (truncate_file): try to handle disconnected mode
+ (create_file): dito
+ (fcache_get): can't set volume if disconnected
+
+ * arlad/adir.c (adir_lookup): remove static variables. add more
+ asserts
+ (adir_readdir): handle the case of broken pgcount in athena.mit.edu
+
+ * arlad/kernel.c: create NUM_WORKERS worker threads to handle
+ messages from xfs
+
+ * arlad/volcache.c (get_info): handle the case of getting back a
+ different name (seems to happen with DFS-servers). move out some
+ common code.
+
+1998-11-07 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_dead_lookup): add
+
+ * arlad/volcache.c: separate out the _byid and _byname functions.
+
+1998-11-07 Love <lha@s3.kth.se>
+
+ * appl/fs.c: Patches from Andrzej Filinski <andrzej@daimi.aau.dk>
+
+1998-11-04 Love <lha@s3.kth.se>
+
+ * arlad/fbuf.c (malloc_create): Do lseek(fd, 0, SEEK_SET) before
+ reading in the file.
+
+ * doc/oddities.texi: Added.
+
+1998-11-02 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): Fix for FreeBSD3.0
+
+ * util/list.[ch] (listnextp): New function.
+
+ * ydr/main.c: Call generate_tcpdump_patches().
+
+ * ydr/parse.y: Call generate_printfunction{,_prototype} and
+ generate_tcpdump_stub
+
+ * ydr/output.h: Random prototypes for below functions.
+
+ * ydr/output.c: Introduces concept of printing ydr structures,
+ added random comment (in generated and !generated code).
+ (td_file): where tcpdump patches ends up.
+ (encode_*): Changed sematics for *_MEM, now do goto fail; instead
+ of return
+ (print_*): Implemented random functions and stubs for the rest.
+ (display_type): entrypoint for printing functions
+
+Mon Nov 2 05:11:25 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (throw_data): check that the length of the cache
+ file agress with the status
+
+ * arlad/arladeb.c (arla_deb_units): add `almost-all'
+
+ * xfs/bsd/xfs_vnodeops-osf.c (xfs_create): don't print va_rawmode,
+ there's no such field in 4.0
+
+ * xfs/bsd/xfs_vfsops-osf.c (xfs_root): moved the code to
+ xfs_root_common
+
+ * xfs/bsd/xfs_vfsops.h (xfs_root_common, make_dead_vnode): add
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): new function
+
+ * xfs/bsd/xfs_vfsops-bsd.c (make_dead_vnode): set v_data in newly
+ created node
+ (xfs_root): moved the code to xfs_root_common
+ (xfs_install_filesys): use vfs_register if available
+
+ * arlad/fcache.c (write_data): make sure `usedbytes' and
+ entry->status.Length is updated correctly even if we fail to write
+ the data to the server
+
+ * aclocal.m4 (AC_C___ATTRIBUTE__): update to discover that the
+ support for __attribute__ in gcc 2.6.3 is not enough for us
+
+Mon Nov 2 05:53:25 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.14.1
+
+1998-11-02 Love <lha@s3.kth.se>
+
+ * README: Note about ultrix.
+
+ * lib/acl/acl.h: Added stds.h, patch from Max
+ <davros@cyclone.Stanford.EDU>
+
+Mon Nov 2 02:38:52 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.14
+
+1998-11-02 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_{get,put}pages): Disable since
+ it doesn't work.
+
+1998-10-31 Love <lha@s3.kth.se>
+
+ * configure.in (FreeBSD3.0): Ugly hack to check if we have
+ DIAGNOSTIC in kernel.
+
+ * xfs/bsd/xfs_vnodeops-common.c: FreeBSD3.0
+ (xfs_rename-common): Removed common
+
+
+Sat Oct 31 15:00:55 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * xfs/bsd/xfs_syscalls-common.c: make xfs_is_pag static
+
+ * xfs/bsd/xfs_node-osf.c (vattr2xfs_attr): va_mode is u_short, not
+ mode_t
+
+Sat Oct 31 03:42:23 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_d_delete): make sure we have an
+ xfs_node to delete
+
+ * xfs/solaris/bin/Makefile.in (check): add
+
+ * arlad/inter.c (cm_rename): swap order of adir_creat and
+ adir_remove
+
+Wed Oct 28 04:00:05 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_syscalls-freebsd.c (xfs_syscall): fix typo
+
+ * configure.in: vfsops: test for vfs_uninit and vfs_oidp struct
+ proc.p_retval: improve test vfs_register: test for
+
+Sun Oct 25 20:36:37 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * arlad/arla.c: implement simple `wc' command
+
+ * rx/rx_clock.c: STARTVALUE for UXP/V
+
+ * lwp/make-process.o.sh.in: UXP/V
+
+ * lwp/lwp.c: set regsize to 8 for UXP/V
+
+ * lwp/process-vpp.s: LWP context switch for Fujitsu UXP/V
+
+1998-10-25 Assar Westerlund <assar@sics.se>
+
+ * configure.in (freebsd3): set VFS_LKM
+
+Sun Oct 25 09:48:25 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad: Added viocgetcacheparms
+
+ * xfs/linux: Use filehandles in installdata. SMP fixes.
+
+Sat Oct 24 02:11:00 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux: Added filehandle support
+
+1998-10-24 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): revert second
+ part of last change.
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): fall back to
+ looking up cached by names if fhlookup fails. do not reinstall
+ the same node.
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_unmount_common): conditionalize
+ on HAVE_KERNEL_DOFORCE
+
+ * xfs/bsd/Makefile.in (DEFS): remove DIAGNOSTICS. defining this
+ when it's defined in the kernel build would be a good idea but we
+ currently have no way of knowing when that's the case.
+
+ * arlad/adir.c (adir_lookup, adir_changefid): fcache_release
+ properly
+
+ * configure.in (doforce): check for
+
+ * aclocal.m4 (AC_CHECK_KERNEL_VAR): new macro
+
+ * xfs/bsd/bin/mount_xfs.c: handle two argument getvfsbyname
+
+ * configure.in: getvfsbyname: check for two argument version
+
+1998-10-23 Love <lha@natt.e.kth.se>
+
+ * rxkad/rxkad_locl.h: #ifndef assert
+
+ * appl/pts.c: Implemented: createuser, creategroup, delete, remove,
+ rename, chown, setfields
+ (pr_name2id): Bugfixed
+ (prdebug): Added debugging variable, and added some output code.
+ (main): Added cvs style debugging switch.
+
+ * lib/ko/koerror.c: Added prerrors.
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_readdir): Cookies are off_t in NetBSD
+
+1998-10-21 Love <lha@s3.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_readdir): No need to save cookies
+ for netbsd.
+
+ * ydr/output.c (encode_string): Check length of size-less TSTRING
+ when decoding.
+
+Wed Oct 21 22:41:29 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_cnp_init): init cn_proc
+
+Mon Oct 19 01:47:22 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call, remote_pioctl):
+ re-order code so that we always vrele vp
+
+ * arlad/adir.c (adir_lookup): don't release the centry if
+ fcache_get fails
+
+ * arlad/messages.c (viocvenuslog): only print rx stats if RX_DEBUG
+
+ * xfs/bsd/xfs_msg_locl.h: new prototype
+
+ * xfs/bsd/xfs_message.c (xfs_message_updatefid): new function
+
+ * xfs/include/xfs_message.h (XFS_MESSAGE_UPDATEFID): new message
+
+ * xfs/bsd/xfs_dev-common.c (xfs_message_receive): handle
+ XFS_MSG_UPDATEFID
+
+ * arlad/messages.c (update_kernelfid): new function
+ (xfs_message_pioctl): moved most of the operations into functions of
+ their own
+
+ * arlad/adir.h: new prototypes
+
+ * arlad/adir.c (find_entry): new function
+ (find_by_name): use find_entry
+ (update_fid_by_name): new function
+ (adir_changefid): new function
+ (adir_emptyp): new function
+
+1998-10-19 Assar Westerlund <assar@sics.se>
+
+ * lwp/make-process.o.sh.in (irix): needs -n32 add -I../include to
+ find config.h
+
+ * lwp/process.S (hopefully) improve some of the conditional stuff.
+
+Sun Oct 18 11:00:58 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_mkdir): conditionalize vput
+
+ * xfs/irix/xfs_vnodeops.c (xfs_write): merge solaris fix for
+ updating mtime and size
+ (xfs_creat): merge solaris fix for truncating file
+ (xfs_map): try to implement
+
+Sun Oct 18 00:03:12 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_symlink): fix call to
+ xfs_symlink_common
+
+ * arlad/cred.h (cred_add_krb4): updated prototype
+
+ * arlad/cred.c (cred_add_krb4): add `uid'
+
+Sun Oct 18 00:02:36 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * xfs/bsd/xfs_node-osf.c (vattr2xfs_attr): cast VNOVAL to correct
+ type
+ (xfs_cnp_init): fix hash calculation
+
+ * xfs/bsd/xfs_vnodeops-*.c: don't pass cnp to various common
+ vnode-ops
+
+Sat Oct 17 12:37:54 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common,
+ xfs_create_common): disable my create optimization
+
+ * xfs/bsd/xfs_node-bsd.c (new_xfs_node): fix interlock stuff
+
+ * arlad/adir.c (adir_lookup): disable cache
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): only purge
+ cache if XFS_INVALID_DNLC is set
+
+ * arlad/messages.c: set installdata.flag
+
+ * xfs/include/xfs_message.h (installdata): add a flag
+
+Sat Oct 17 11:47:48 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (token_for_cell): return uid
+ (xfs_message_pioctl VIOCSETTOK): remember uid
+
+ * arlad/cred.c (cred_add): add `uid'
+
+ * arlad/cred.h (CredCacheEntry): add uid
+
+ * xfs/irix/xfs_vnodeops.c (xfs_readdir): look at the abi and
+ convert to irix5_dirent if needed
+
+ * xfs/bsd/xfs_vnodeops-common.c: remove bsd-specific code
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lookup, xfs_remove, xfs_rmdir,
+ xfs_link, xfs_symlink): move the freeing of the namei buffer here
+ from common
+
+ * xfs/bsd/xfs_vfsops-osf.c (make_dead_vnode): fix prototype
+
+ * xfs/bsd/xfs_syscalls-common.c: include <sys/ioccom.h> or
+ <sys/ioctl.h>
+
+ * xfs/bsd/xfs_node-osf.c (xfs_dnlc_enter): do the negative cache
+ check
+
+ * xfs/bsd/xfs_vnodeops-common.c: VOP_UNLOCK -> xfs_vfs_unlock
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter): make sure there's no
+ entry already in the DNLC
+
+ * xfs/bsd/xfs_message.c (xfs_message_installnode): removed cache
+ checking code
+
+ * arlad/fcache.c (read_data): if copyrx2fd fails, bail out
+
+Fri Oct 16 16:46:57 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * xfs/bsd/xfs_locl.h: #define cn_nameiop ni_nameiop
+
+1998-10-16 Love <lha@s3.kth.se>
+
+ * appl/fs*.[ch]: Added code to gc pags (compat).
+
+ * include/kafs.h: Added VIOC_GCPAGS
+
+1998-10-15 Love <lha@s3.kth.se>
+
+ * INSTALL,configure.in: --enable-knfs
+
+ * xfs/bsd/xfs_vnodeops.c(xfs_readdir): Added cookie creation code.
+
+Wed Oct 14 05:41:34 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops.h: update prototypes
+
+ * xfs/bsd/xfs_vnodeops-osf.c (xfs_mkdir, xfs_readdir): adapt to
+ new versions of -common functions
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): do not enter
+ negative entries if creating
+ (xfs_mkdir_common): remove the OS-specific code
+ (xfs_readdir): set `eofflag'
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_create): make sure to call
+ VOP_LOOKUP with cn_nameiop == LOOKUP
+ (xfs_mkdir): do the post mkdir lookup
+ (xfs_readdir): set eofflag
+
+ * xfs/bsd/xfs_vfsops-bsd.c: replace printf with XFSDEB
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call): check suser
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter_name): init more fields
+ in `cn'
+
+ * xfs/bsd/xfs_message.c (xfs_message_installnode): make sure we
+ get rid of any negative entries before adding the new entry. Is
+ this really needed?
+ (xfs_message_installdata): remove old stuff
+
+ * xfs/bsd/xfs_locl.h (xfs_proc_to_cred): new macro
+
+ * xfs/bsd/Makefile.in (unload): fix for non-OSF1
+
+ * xfs/bsd/bin/mount_locl.h (__progname): remove
+
+ * xfs/bsd/xfs_vfsops.h (xfs_fhlookup): update prototype
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): take `gen' and check it
+
+ * lib/ko/gensysname.c (sysnames): remove all bsd entries
+
+ * TODO: I think we do this (at least on some OSes)
+
+ * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): sigmask seems to be
+ defined on more systems than __sigmask. are there any with only
+ __sigmask?
+
+ * xfs/bsd/xfs_common.h: s/define/endif/
+
+Thu Oct 15 05:29:19 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/Makefile.in: use KERNEL_LD
+
+ * xfs/bsd/xfs_locl.h: <vm/vm_zone.h>
+
+ * configure.in (KERNEL_LD): set
+ <vm/vm_zone.h>: check for
+
+ * xfs/bsd/xfs_vnodeops-bsd.c: free pathnames with zfree if there's
+ a zfreei.
+
+ * aclocal.m4 (AC_KERNEL): allow ac_kernel_ld to be already set
+ (AC_HAVE_KERNEL_FUNC): use KERNEL_CLAGS. should probably call
+ AC_TRY_COMPILE_KERNEL directly
+
+ * xfs/bsd/xfs_vnodeops-common.c: free pathnames with zfree if
+ there's a zfreei.
+
+ * configure.in (freebsd3): add
+ (vfc_mountroot in struct vfsconf): check for
+ (zfreei, vfs_cache_lookup): check for
+
+ * xfs/irix/xfs_vfsops.c (xfs_root): don't VN_HOLD
+ (make_dead_vnode): use vn_alloc
+
+ * xfs/bsd/xfs_vfsops-bsd.c: move around and reorganize the code
+
+ * xfs/bsd/xfs_wrap-bsd.c: handle different versions of MOD_DEV
+
+ * xfs/bsd/xfs_syscalls.h: re-organize SCARG & syscallarg
+
+ * configure.in: add -I. before testing for VOP_LOCK & c:o
+
+ * configure.in (freebsd): use /bin/sh and not $SHELL
+
+ * acconfig.h (HAVE_STRUCT_PROC_P_RETVAL): add
+
+ * configure.in (freebsd): generate vnode_if.[ch]
+ (struct proc): look for `p_retval'
+
+ * xfs/bsd/xfs_wrap-bsd.c: replace printf by XFSDEB
+ (xfs_mod): handle MOD_DISPATCH
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_cachedlookup): new function
+ (xfs_eopnotsupp): always return EOPNOTSUPP. use instead of
+ vn_default_error
+
+ * xfs/bsd/xfs_syscalls.h (xfs_setpag_call, xfs_pioctl_call): add
+
+ * xfs/bsd/xfs_syscalls-freebsd.c (xfs_syscall): move here. handle
+ 3.0 returning values
+ (xfs_install_syscalls): try AFS_SYSCALL first, then first free lkm
+ slot
+
+ * xfs/bsd/xfs_syscalls-common.c (xfs_syscall): remove
+
+ * xfs/bsd/xfs_syscalls-osf.c (xfs_syscall): move here
+ (xfs_install_syscalls): try AFS_SYSCALL first, then AFS_SYSCALL2, and
+ then first free lkm slot
+
+ * xfs/bsd/xfs_syscalls-bsd.c (xfs_syscall): move here
+ (xfs_install_syscalls): try AFS_SYSCALL first, then first free lkm
+ slot
+
+ * xfs/bsd/xfs_locl.h: <sys/filedesc.h>: move <sys/fctnl.h>:
+ include
+
+ * xfs/bsd/xfs_dev-bsd.c (xfs_dev): modern FreeBSD has poll instead
+ of select
+
+Sun Oct 11 16:15:04 1998 Johan Danielsson <joda@stp.pdc.kth.se>
+
+ * xfs/bsd/xfs_vnodeops-{osf,bsd}.c (xfs_create): move some code from
+ xfs_create_common here
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_create_common): remove
+ architecture dependent code (specifically the call to VOP_LOOKUP)
+
+ * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): use __sigaddset if
+ defined
+
+Sat Oct 10 21:05:13 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/ko/gensysname.c: add generic bsd handler
+
+ * configure.in, lib/ko/ko_locl.h: sys/utsname.h
+
+1998-10-09 Love <lha@s3.kth.se>
+
+ * ydr/output.c: (sizeof_type) TOPAQUE has a size (1).
+
+Thu Oct 8 14:39:48 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * xfs/bsd/xfs_node-osf.c (new_xfs_node): move call to insmntque to
+ after initializing the vnode
+ (so it will automagically create a VM object)
+
+ * xfs/bsd/xfs_vfsops.h: xfs_fhlookup takes generation number iff
+ OSF/1
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): pass generation
+ number to xfs_fhlookup iff OSF/1
+
+ * xfs/bsd/xfs_vfsops-osf.c: implement xfs_fhlookup, and xfs_fhopen
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): init OSF/1
+ f_fsid
+
+ * xfs/bsd/xfs_dev-osf.c (xfs_install_device): try to install
+ device with major 64
+
+ * xfs/bsd/xfs_syscalls-osf.c: try to install syscall at slot 232
+
+ * xfs/bsd/xfs_syscalls-common.c: fixes for OSF/1
+
+ * xfs/bsd/xfs_dev-common.c (xfs_devclose_common): cleanup,
+ (xfs_message_rpc): use xfs_curproc()
+
+ * xfs/bsd/xfs_locl.h: xfs_curproc()
+
+ * arlad/bsd-subr.c (conv_dir): check return value from
+ fcache_fhget
+
+ * xfs/bsd/bin/mount_xfs.c: call set_progname, add `-F' option to
+ set mountflags (used by OSF/1 mount)
+
+Wed Oct 7 21:28:14 1998 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * lib/ko/gensysname.c: Add Digital UNIX/Alpha
+
+Wed Oct 7 05:01:53 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_follow_link): handle both two and
+ three argument versions
+
+ * acconfig.h: HAVE_FOLLOW_LINK_THREE_ARGS: add
+
+ * configure.in (linux): try looking in /proc/ksyms before
+ /proc/cpuinfo
+ (follow_link): test for number of arguments
+
+1998-10-05 Assar Westerlund <assar@sics.se>
+
+ * Release 0.13
+
+ * NEWS: updated
+
+ * configure.in: bump to 0.13
+
+ * arlad/irix-subr.c: use the correct size macro
+
+ * INSTALL: add --disable-dynamic-afs and --enable-smp
+
+ * xfs/irix/Makefile.in (unload): add
+
+ * configure.in (linux): fall back on testing on /proc/cpuinfo
+ (--enable-smp): add
+
+ * configure.in (linux): do the smp test against the include-files
+ instead of /proc
+
+ * configure.in (linux): test for smp by looking in /proc/ksyms
+ instead of /proc/cpuinfo
+
+1998-10-04 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (stale): set sentenced iff already locked.
+ changed all callers.
+
+ * util/log.c (log_vprint_syslog): fflush
+
+ * xfs/irix: much improved. most stuff (except getdents) seems to
+ work.
+
+Sun Oct 4 03:44:53 1998 Magnus Ahltorp <map@stacken.kth.se>
+
+ * acconfig.h configure.in: Check for read_super arguments.
+
+ * xfs/linux/xfs_load.c: Fix read_super argument confusion.
+
+1998-10-03 Love <lha@e.kth.se>
+
+ * xfs/bsd/xfs_node-bsd.c(new_xfs_node): Broke out the
+ getnewvnode() code.
+ (xfs_getnewvnode): new function, creates xnode too.
+
+ * xfs/bsd/xfs_vfsops-{bsd.c,common.c}: Added strange knfs code.
+
+Fri Oct 2 06:39:15 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (get_info): remove bogus `we didn't get what we
+ asked for'-warning
+
+ * xfs/linux/xfs_inodeops.c (xfs_readdir, xfs_follow_link): do
+ xfs_free
+
+ * xfs/linux/xfs_dev.c (xfs_devread): do free
+
+ * xfs/linux/xfs_common.c (xfs_alloc): debugging for xfs_allocs -
+ xfs_frees
+
+ * xfs/linux/xdeb.h (XDEBMEM): add
+
+ * ydr/symbol.c (printsymbol): unused
+
+ * lwp/iomgr.c (IOMGR): correct printf format string
+
+ * include/bits.c: some unused to get rid of warnings
+
+ * arlad/messages.c (xfs_message_rpc): mark as unused to get rid of
+ a warning
+
+ * acconfig.h (_GNU_SOURCE): define it
+
+Wed Sep 30 06:39:08 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/irix/xfs_dev.c (xfs_install_device): initialize the queues
+
+ * xfs/irix/xfs_vfsops.c (xfs_mount): remove cdevsw check
+
+Wed Sep 30 01:10:31 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.12
+
+ * arlad/fcache.c (create_node): new function
+ (fcache_get): call create_node if there is no cache node.
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked):
+ don't use vop_nolock/vop_nounlock/vop_noislocked
+
+Tue Sep 29 04:07:14 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (recycle_entry): release the filecache entry
+
+ * arlad/fcache.c (fcache_get): assert that find_free_entry
+ succeeded
+
+Mon Sep 28 00:51:45 1998 Assar Westerlund <assar@sics.se>
+
+ * acconfig.h (HAVE_KERNEL_VFS_GETVFS): add
+
+Sun Sep 27 11:55:55 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_may_uninstall_filesys): new
+ (xfs_fhlookup): use vfs_getvfs
+
+ * configure.in (vfs_getvfs): check for
+ (linux): check for __SMP__
+
+Sun Sep 27 11:55:54 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.11
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_islocked): faking always having
+ it locked is better.
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): bump v_writecount if
+ opening for wrinting
+
+Sun Sep 27 11:29:46 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/Makefile.in: use KERNEL_CFLAGS
+
+ * configure.in (linux): set KERNEL_CFLAGS
+ use AC_HAVE_KERNEL_STRUCT_FIELD
+
+ * aclocal.m4 (AC_HAVE_KERNEL_STRUCT_FIELD): new macro
+
+Sun Sep 27 07:33:18 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/adir.c (add_to_page): set flag
+
+Sat Sep 26 19:45:37 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.10
+
+Sat Sep 26 19:28:00 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/adir.c (adir_lookup): correct centry logic
+
+ * lwp/Makefile.in (REALCFLAGS): add DEBUG
+
+ * arlad/fbuf.c (mmap_copyrx2fd, mmap_copyfd2rx, malloc_copyrx2fd,
+ malloc_copyfd2rx): handle len == 0 properly
+
+ * arlad/arla.c: use fcache_release
+
+ * arlad/adir.c (adir_lookup): verify datap of cached directory
+
+ * arlad/fcache.c (find_entry_nolock): new function
+ (fcache_stale_entry): if entry is locked, sentence it
+ (read_data): always call copyrx2fd
+ (write_data): always call copyfd2rx
+ (fcache_release): new function. change all callers.
+
+ * arlad/fcache.h (FCacheEntry): new flag `sentenced'
+ (fcache_release): new function
+
+Wed Sep 23 03:31:48 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_common.c (memcpy): define in terms of bcopy
+ because gcc generates references to it and solaris doesn't have
+ any in the kernel
+
+Sun Sep 20 06:18:09 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/sunos-subr.c (conv_dir): `handle' should be `cache_name'
+
+ * arlad/irix-subr.c (conv_dir): `handle' should be `cache_name'
+
+ * arlad/hpux-subr.c (conv_dir): `handle' should be `cache_name'
+
+ * arlad/linux-subr.c (conv_dir): `handle' should be `cache_name'
+
+Thu Sep 17 00:26:08 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c: conditionalize all tests of RXKADEXPIRED on
+ KERBEROS
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): use cache
+ handle
+
+ * xfs/bsd/xfs_syscalls-common.c: use xfs_fh_args
+
+ * xfs/bsd/xfs_syscalls.h (xfs_fh_args): define
+
+ * xfs/bsd/xfs_vfsops.h (xfs_fhlookup): add prototype
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): new function
+ (xfs_fhopen): use `xfs_fhlookup'
+
+1998-09-15 Love <lha@s3.kth.se>
+
+ * xfs/linux/xfs_locl.h: Checked for HAVE_LINUX_MODVERSIONS_H
+ and appied patch from Aaron M. Ucko <amu@mit.edu>.
+
+ * configure.in: - Added check for <linux/modversions.h>
+ - Applied patch from (Dima Ruban) <dima@best.net>
+
+Mon Sep 14 03:14:13 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_read, xfs_write): complain if
+ not VREG
+
+ * xfs/solaris/xfs_message.c (xfs_message_installdata): only purge
+ the name cache if this file had data before.
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): removed bogus
+ NCHNAMLEN test
+
+ * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter): check for NCHNAMLEN.
+ apparently freebsd-3.0 doesn't have any limit on the length of
+ file names in the dnlc.
+
+ * conf/arla.conf: bump {high,low}_bytes
+
+ * arlad/messages.c (xfs_message_mkdir): do an installdata of the
+ new directory
+
+ * arlad/inter.c (cm_getattr): should be no need to set the tokens
+ here explicitly
+
+ * arlad/adir.c: removed lots of magic, clean-up.
+ (adir_lookup): add a one-entry cache of directories
+ (adir_readdir): return entries in order stored in directory instead of
+ hash table order (. and .. are always the two first entries)
+
+1998-09-13 Johan Danielsson <root@chowder.pdc.kth.se>
+
+ * configure.in: use AC_ELF_OBJECT_FORMAT, add -D_LKM to CFLAGS
+ when checking for vfssw, (NetBSD) try to figure out KERNEL_CFLAGS
+ in a more intelligent way, and make sure we have -mno-fp-regs on
+ alpha
+
+Sat Sep 12 23:34:14 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_setattr): clear tokens before
+ rpc
+ (xfs_link): arguments in correct order. call lookup correctly
+ (xfs_map): verify that the attributes are there. fake handling the
+ MAP_SHARED, PROT_WRITE-case
+
+ * xfs/solaris/xfs_syscalls.c: solaris' uprintf doesn't understand
+ %p
+
+ * arlad/messages.c (xfs_message_putattr): install the new
+ attributes
+
+ * arlad/fcache.c (truncate_file): send (size, 0, size) to
+ StartRXAFS_StoreData.
+
+1998-09-12 Love <lha@s3.kth.se>
+
+ * ydr/output.c: Added missing adding of total_len for strings.
+ Added RCSID to the generated files.
+
+Sat Sep 12 03:01:36 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops.h (xfs_mount_common): new prototype
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): const-ize
+ user_path
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): more debugging
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call, fhopen_call): new
+ prototypes
+
+ * xfs/bsd/xfs_syscalls-freebsd.c (xfs_syscallent): correct number
+ of arguments
+
+ * xfs/bsd/xfs_syscalls-bsd.c (xfs_syscallent): correct number of
+ arguments
+
+ * arlad/fcache.c (fcache_fhget): check fhopen_working
+
+Fri Sep 11 04:27:35 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * milko/{ptserver.c,pr.c}: First version of ptserver
+
+Wed Sep 9 22:15:09 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_syscalls.h (SCARG): better definition
+
+ * xfs/bsd/xfs_syscalls-common.c: now even compiles
+
+ * xfs/bsd/xfs_message.c (xfs_messge_installdata): don't use
+ non-existing variable `tmp'
+
+ * rx: compilable without RXDEBUG
+
+ * arlad/messages.c: remove unused variables
+
+ * lib/ko/gensysname.c: add freebsd2.2
+
+ * arlad/arla.c (arla_rx_status): conditionalize on RXDEBUG
+
+ * arlad/Makefile.in (REALCFLAGS): add RXDEBUG
+
+Tue Sep 8 01:21:25 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/adir.c: new fcache_open_file
+
+ * xfs/bsd/xfs_vfsops.h (xfs_fhopen): prototype
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): new function
+
+ * xfs/bsd/xfs_syscalls-common.c (fhget_call, fhopen_call): new
+ functions
+ (pioctl_call): restructure
+
+ * xfs/solaris/bin/umount_xfs.c: include <config.h>
+ add ID
+
+ * xfs/solaris/bin/mount_xfs.c: include <config.h>
+ add ID
+
+ * xfs/solaris/bin/test-fhopen.c: new file
+
+ * xfs/solaris/bin/Makefile.in (test-fhopen): add
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_space): implement for cmd ==
+ F_FREESP, fl->l_len == 0
+
+ * xfs/solaris/xfs_vfsops.c (xfs_fhlookup, xfs_fhopen): new
+ functions
+
+ * xfs/solaris/xfs_syscalls.h (xfs_fh_args): add
+
+ * xfs/solaris/xfs_syscalls.c (fhget_call, fhopen_call): new
+ functions
+ (pioctl_call): restructure
+
+ * xfs/solaris/xfs_message.c (xfs_message_installdata): update to
+ new message. use xfs_fhlookup
+
+ * xfs/solaris/xfs_deb.h (XDEBLKM, XDEBSYS): define
+
+ * xfs/sunos/xfs_message.c (xfs_message_installdata): update to new
+ message
+
+ * xfs/rhapsody/xfs_message.c (xfs_message_installdata): update to
+ new message
+
+ * xfs/linux/xfs_message.c (xfs_message_installdata): update to new
+ message
+
+ * xfs/irix/xfs_message.c (xfs_message_installdata): update to new
+ message
+
+ * xfs/include/xfs_message.h (CACHEHANDLESIZE): make fsid_t +
+ fhandle_t in size
+ (xfs_message_installdata): add cache_name
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): update to new
+ message
+
+ * xfs/aix/xfs_message.c (xfs_message_installdata): update to new
+ message
+
+ * include/kafs.h (VIOC_FHGET, VIOCE_FHOPEN): define
+
+ * arlad/inter.h (cm_open): update prototype
+
+ * arlad/inter.c (cm_open): return cache_name and cache_handle
+
+ * arlad/arla.c: update to new fcache_open_file
+
+ * arlad/fcache.h (FCacheEntry): 32-ize. replace `inode' with
+ index and cache-handle
+
+ * arlad/fcache.c (fhopen, fcache_fhget): new functions
+ (fcache_create_file): new function. use.
+ (fcache_open_file): use fhopen if it's working
+ (fcache_open_file): remove mode argument. change all callers.
+ (find_entry): handle the case of being called from volcache before the
+ fcache is initialized.
+ (read_data, write_data): only call copyrx2fd/copyfd2rx if sizefs > 0
+
+ * arlad/subr.h (conv_dir): update prototype
+
+ * arlad/*-subr.c (conv_dir): return cache_name and handle.
+
+ * arlad/Makefile.in (KAFS_LIBS): set
+ (LIBS): add KAFS_LIBS
+
+1998-09-06 Love <lha@s3.kth.se>
+
+ * output.c: - Added bounce checking for memencoding.
+ - Got rid of fail: label error message.
+
+ * rx/rx.h: Added sys/param.h to get rid of warning.
+
+Fri Aug 28 22:49:22 1998 Assar Westerlund <assar@sics.se>
+
+ * util/strutil.h (strupr, strlwr): remove prototypes
+
+ * util/strutil.c (strupr, strlwr): remove (they're already in
+ libroken)
+
+Mon Aug 24 02:48:19 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_create): truncate the file if
+ needed
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_create): existing file is no
+ error
+ (xfs_write): update mtime and size from cache vnode
+
+Tue Aug 11 18:34:33 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * arlad/arla.c (read_conffile): use parse_units
+
+Tue Aug 4 02:19:06 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_vfsops): conditionalize vfc_name
+
+ * configure.in: check for `vfs_name' in `struct vfsops'
+
+Fri Jul 31 00:15:38 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.9
+
+ * xfs/solaris: compiler warning cleanup
+
+Thu Jul 30 23:04:46 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in (netbsd): comments are `dnl' and not `/*' :-)
+
+ * configure.in: --with-krb{4,5}: better values for include and lib
+ directory
+
+ * xfs/linux/xfs_inodeops.c (xfs_write_file): set the f_pos of the
+ cached file before calling its write
+
+Wed Jul 29 22:35:31 1998 Assar Westerlund <assar@sics.se>
+
+ * TODO: optimistically remove the items that I think have been
+ fixed
+
+ * arlad/fcache.c (unlink_lru_entry): don't remove entries with
+ refcount > 0
+ (followmountpoint): set refcount on the root of the new volume, not on
+ the mount point in the old one.
+
+ * arlad/inter.c (cm_lookup): fix the handling of `..' over mount
+ points.
+
+ * arlad/volcache.c (recycle_entry): decrement the refcounts of all
+ fcacheentries pointing to the root of any of the volumes of `e'
+
+ * arlad/volcache.h (volcacheentry): remove `mount_point'
+
+ * INSTALL: removed mknod from BSD installation instructions
+
+ * xfs/bsd/bin/xfs_makedev: new file
+
+ * xfs/bsd/bin/startarla.in: use xfs_makedev
+
+ * xfs/bsd/bin/Makefile.in: install xfs_makedev
+
+ * xfs/bsd/xfs_wrap-bsd.c: made it into a LKM_DEV.
+
+ * xfs/bsd/xfs_dev-bsd.c (xfs_install_device, xfs_uninstall_device,
+ xfs_stat_device): removed all code for adding the device to the
+ cdevsw.
+
+ * xfs/bsd/Makefile.in (load): use -p xfs_makedev
+
+ * arlad/adir.c (adir_remove, adir_creat): assert the directory
+ having data
+
+ * arlad/inter.c (cm_create, cm_mkdir, cm_symlink, cm_link,
+ cm_remove, cm_rmdir, cm_rename): make sure we have the data of the
+ directory
+
+ * arlad/fbuf.c (malloc_truncate): call ftruncate
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): handle two
+ argument vfs_getnewfsid
+
+ * configure.in: test for two argument vfs_getnewfsid
+
+Tue Jul 28 23:36:47 1998 Assar Westerlund <assar@sics.se>
+
+ * lwp/process.S: Applied patch for NetBSD/alpha from John Davison
+ <davisoja@clarkson.edu>
+
+ * ydr/output.c: try to handle error returns from rx_Read and
+ rx_Write
+
+ * lib/ko/kocell.c: check memory allocation and clean-up
+
+ * appl/fs.c (afs_listquota): don't divide by zero
+
+ * arlad/fcache.c (followmountpoint): close fd if fbuf_create fails
+
+1998-07-28 Love <lha@e.kth.se>
+
+ * xfs/bsd/xfs_vfsops-osf.c(xfs_install_fs): Be paranoid about the size
+ of the private data of struct vnode.
+
+ * xfs/bsd/xfs_dev-common.c: (xfs_message_rpc):No code for sigwaitmask
+
+1998-07-24 Love <lha@e.kth.se>
+
+ * xfs/bsd/xfs_vfsops-osf.c: (xfs_root): Added uid check for osf.
+
+ * appl/fs.c: Added VIOCNOP.
+
+Fri Jul 24 19:15:45 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/messages.c: Added VIOCGETCELL, VIOCWHEREIS, VIOCNOP,
+ VIOCUNPAG and VIOC_AFS_STAT_MT_PT.
+
+Fri Jul 24 09:53:19 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in (int32, u_int32): test for
+
+ * arlad/messages.c (xfs_message_create): try installing data for
+ the new file.
+
+ * arlad/arla.c (temp_sysname): const-ize
+
+Fri Jul 24 06:49:32 1998 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: Merged in patch from
+ Aaron M. Ucko <amu@mit.edu>.
+
+ * xfs/linux: Made things work better on 2.0 and i386.
+
+1998-07-24 Love <lha@e.kth.se>
+
+ * appl/fs.c: fixed small bug in fs lsm.
+
+Thu Jul 23 03:55:12 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): use
+ vfs_getnewfsid is there's one. From Dan Winship <danw@MIT.EDU>
+
+ * xfs/bsd/xfs_vfsops-bsd.c: use `struct vnodeopv_desc',
+ vfs_attach, and vfs_detach when applicable. From Dan Winship
+ <danw@MIT.EDU>
+
+ * configure.in: more tests for modern NetBSD. From Dan Winship
+ <danw@MIT.EDU>
+
+ * arlad/inter.c (expand_sys): new function for expanding @sys
+ (cm_lookup): expand @sys anywhere in the name
+
+ * xfs/bsd/xfs_vnodeops-common.c (xfs_inactive_common): handle the
+ case of an already clean vnode.
+
+ * xfs/bsd/xfs_node-bsd.c (free_xfs_node): remove bogus comment
+
+ * arlad/fcache.c (create_{file,symlink,directory}): update the
+ acccache and anonacess
+
+ * arlad/volcache.c: rename recover_state -> volcache_recover_state
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_islocked): return 0 as a
+ fallback
+
+ * xfs/bsd/xfs_vnodeops.h (xfs_vfs_readlock, xfs_vfs_writelock,
+ xfs_vfs_unlock): new macros for encapsulating the locking
+
+ * xfs/bsd/xfs_vfsops-osf.c (xfs_root): remove ifdef __osf__
+
+ * xfs/bsd/xfs_vfsops-bsd.c (xfs_root): remove ifdef __osf__
+
+Wed Jul 22 05:00:08 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.h (create_symlink): update prototype
+
+ * arlad/fcache.c: keep better track of the number of used bytes
+ (usedbytes)
+
+ * rxdef/fs.xg (Symlink): correct
+
+ * arlad/fcache.c (fcache_file_name): cast `inode' to unsigned
+
+ * lib/ko/gensysname.c: restructured, cleaned up and added new
+ sysnames
+
+ * util/strmatch.c: const-ize
+
+ * arlad/adir.c: replace magic numbers with expressions based on
+ constants from afs_dir.h
+
+ * arlad/arla.c (main): set the sysname from arla_getsysname
+
+Tue Jul 21 04:55:00 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/adir.c (adir_remove): eliminate trailing empty pages
+
+ * arlad/adir.c (adir_remove): use the actual size of the converted
+ directory instead of that from status
+
+ * arlad/adir.c (adir_lookup, adir_readdir): use the actual size of
+ the converted directory instead of that from status
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_revoke): implement
+
+ * configure.in (vop_revoke, genfs_revoke): check for
+
+ * configure.in (vop_noislocked, genfs_nolock, genfs_nounlock,
+ genfs_noislocked): check for
+
+ * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked):
+ try to use default operations
+
+Mon Jul 20 04:51:11 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: openbsd2.3: remove
+ more kernel tests
+
+ * lwp/lwp.h (lwp_context): add linkRegister and conditionRegister
+ for powerpc
+
+ * xfs/bsd: restructured
+
+ * arlad/arla.c (connected_levels): fix misspelling
+
+Mon Jul 20 01:49:28 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.8
+
+Sun Jul 19 10:41:44 1998 Mattias Amnefelt <mattiasa@stacken.kth.se>
+
+ * appl/vos.c: added support for busy volumes
+
+Fri Jul 17 18:21:10 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * configure.in, xfs/linux/Makefile.in, xfs/linux/getcwd.c: Added
+ getcwd shared library to make getcwd work better in 2.1.
+
+Fri Jul 17 03:10:48 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_recover_state): make sure the volume of
+ the entry we read back actually exists, otherwise just ignore it.
+
+Thu Jul 16 02:06:28 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: selinfo.si_pid test removed
+
+ * lib/ko/gensysname.c (printsysname): arla_getsysname should
+ return a const string
+
+ * lib/ko/ko.h (arla_getsysname): const-ize
+
+ * arlad/volcache.c (volcache_getbyname, volcache_getbyid):
+ restructure tail so that refcount is return whenn e != NULL
+
+ * xfs/openbsd2.3/xfs_vnodeops.c (xfs_lookup): set *vpp to NULL at
+ the beginning
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_lookup_common): set *vpp to NULL at
+ the beginning
+
+1998-07-15 Love <lha@s3.kth.se>
+
+ * lib/ko/gensysname.c: Added generation of a sysname function.
+
+Tue Jul 14 16:35:31 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/bin/mount_xfs.c: conditionalize on autoconf symbols
+ instead of on __FreeBSD__
+
+ * configure.in (getvfsbyname,vfsisloadable,vfsload): check for
+ them
+
+1998-07-14 Love <lha@s3.kth.se>
+
+ * arlad/services.h: Added VOTE_SERVICE and DISK_SERVICE
+
+ * appl/udebug.c: Added the udebug program.
+
+ * appl/vos.c: Added command syncsite (only work on local cell)
+
+ * appl/arlalib.[ch]: arlalib_getsyncsite() does not work,
+ I can't see why it shouldn't work thou.
+
+ * appl/appl_locl.h: added <err.h> and <ubib*>
+
+ * appl/Makefile: Added udebug
+
+ * rxdef/ubik.xg: Added
+
+ * xfs/bsd/bin/mount_xfs.c: Added patch from Alec Wolman
+ <wolman@cs.washington.edu> to add the right argument to mount
+ for FreeBSD
+
+Mon Jul 13 20:50:09 1998 Assar Westerlund <assar@sics.se>
+
+ * lwp/make-process.o.sh.in (aix): for some odd reason the aix
+ assembler is happier if we always say we have a RIOS
+
+ * ydr/Makefile.in: compat with stupid makes
+
+ * xfs/sunos/Makefile.in: compat with stupid makes
+
+ * xfs/linux/Makefile.in: compat with stupid makes
+
+ * util/Makefile.in: compat with stupid makes
+
+ * rxdef/Makefile.in: compat with stupid makes
+
+ * lwp/process.S: rhapsody fixes
+
+ * arlad/volcache.c (recycle_entry): only decrement fe->refcount
+ if we found the node.
+
+ * arlad/kernel.c (process_message): remove `proc_msg: byte = %d'
+
+ * arlad/fcache.c (count): rename to inode_count
+ (fcache_stale_entry): always call stale
+ (fcache_find): check if find_entry succeeded
+
+ * arlad/conn.c (conn_get): check securityindex and cred, otherwise
+ we could end up not having any connection for (0,0) and loose when
+ we get a callback
+
+ * arlad/arla.c (newwalk): patches from Alec Wolman
+ <wolman@cs.washington.edu>
+
+ * arlad/Makefile.in: compat with stupid makes
+
+ * lib/Makefile.in: compat with stupid makes
+
+ * appl/Makefile.in: compat with stupid makes
+
+ * THANKS: Alec Wolman <wolman@cs.washington.edu>
+
+ * Makefile.in: compat with stupid makes
+
+ * configure.in (KERNEL_INCLUDE): include -I
+ (rhapsody): add
+ some more field tests
+
+ * config.{guess,sub}: rhapsody
+
+ * xfs/rhapsody: Rhapsody port from Alexandra Ellwood <lxs@MIT.EDU>
+
+Thu Jul 9 16:14:50 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_write_file): 2.0-fix
+
+Mon Jul 13 06:35:55 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux: Locking corrected and locking debugging added
+
+ * xfs/linux: Changed to new lookup method
+
+Sun Jul 12 16:39:05 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * xfs/bsd/*: Merge OSF/1 changes.
+
+ * xfs/bsd/xfs_dev.h: make xfs_devopen static, and add prototype
+ for xfs_func_is_devopen that does the comparison
+
+ * xfs/bsd/xfs_deb.h: unsigned int
+
+ * xfs/bsd/xfs_deb.c: unsigned int
+
+ * xfs/bsd/xfs_common.c: use xfs_malloc
+
+ * configure.in: Add support for OSF/1.
+
+ * xfs/bsd/bin/{mount_xfs,umount_xfs}.c: use <mount_locl.h>
+
+ * xfs/bsd/bin/mount_locl.h: common include file for mount/umount
+
+ * xfs/bsd/bin/mntopts.h: remove __P from the single prototype (to
+ avoid having to add a definition for __P) -- all compilers (gcc
+ and DEC CC knows prototypes anyway).
+
+ * xfs/bsd/bin/Makefile.in: some fixes for OSF/1: conditionally
+ build `startarla', and add include and link paths for roken.
+
+ * rxkad/rxk_crpt.c: __alpha is LE
+
+Thu Jul 9 22:18:25 MET DST 1998 Mattias Amnefelt <mattiasa@stacken.kth.se>
+
+ * appl/Makefile.in: Changed so we use libroken included in
+ arla insead of the one which comes with kth-krb.
+
+1998-07-08 Love <lha@e.kth.se>
+
+ * xfs/bsd/{xfs_vfsops.c,xfs_wrap.c} Check if we can unload
+ before we even try, since on NetBSD you can unload a
+ mounted filesystem, that will crash in next sync.
+
+Wed Jul 8 01:44:15 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (creat_nodes): use IOMGR_Select instead of
+ LWP_DispatchProcess to give the iomgr thread the chance to run
+
+ * xfs/aix/xfs_syscalls.c (xfs_setpag_call): generate the pag
+ correctly
+
+1998-07-07 Love <lha@e.kth.se>
+
+ * util/{time,}prio.[ch], util-tester.c: Added.
+
+Tue Jul 7 02:41:05 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_vfsops.c: Use print_aliases() and
+ set xfsp->root to NULL when unmounting
+
+ * xfs/linux/xfs_common.[ch]: Added print_aliases()
+
+Mon Jul 6 19:56:34 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_dev.c: obvious xfs_vfs_busy fix
+
+Mon Jul 6 12:59:51 1998 Mattias Amnefelt <mattiasa@sundance.stacken.kth.se>
+
+ * appl/vos.c: correct parsing of partition names
+
+ * appl/appl_locl.h: #include <ctype.h>
+
+Mon Jul 6 12:29:04 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * xfs/bsd/Makefile.in: Get KERNEL_CFLAGS from configure.
+
+ * xfs/bsd/xfs_dev.c: Add wrapper for vfs_busy.
+
+ * xfs/bsd/xfs_vnodeops.c: Add wrapper for VOP_LOCK/VOP_UNLOCK.
+
+ * configure.in: Add KERNEL_CFLAGS for *BSD and OSF/1. Test for
+ three valued vfs_busy, and two valued VOP_LOCK.
+
+ * aclocal.m4: AC_TRY_COMPILE_KERNEL, that adds KERNEL_CFLAGS to
+ CFLAGS during test.
+
+Sun Jul 5 20:26:02 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_find): new function add invalidating and
+ vnode creating threads
+
+ * arlad/fcache.h (FCacheEntry): rename `listentry' -> `lru_le'.
+ add `invalid_le'
+ (fcache_find): add prototype
+
+ * util/list.c (listaddbefore, listaddafter): new functions
+
+Sun Jul 5 03:28:44 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: new option `--cache-dir'
+
+Sun Jul 5 04:28:02 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_vfsops.c: Fix 2.1 {put,delete}_inode weirdness
+
+ * xfs/linux/xfs_message.c: Fix callback handling
+
+Sun Jul 5 04:24:14 1998 Magnus Ahltorp <magnus@dike.aladdin.se>
+
+ * xfs/linux/xfs_inodeops.c: Clear vm maps when closing file.
+
+Sat Jul 4 16:21:44 1998 Magnus Ahltorp <magnus@dike.aladdin.se>
+
+ * xfs/linux/xfs_inodeops.c: 2.0 fixes
+
+Sat Jul 4 05:53:01 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/*: Big rewrite of different things. Works somewhat
+ (writes sometimes do the wrong thing) on 2.1, 2.0 is untested.
+ The file system may now be mounted before arlad is started.
+
+Fri Jul 3 19:38:22 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla_local.h: this ugliness seems required
+
+Wed Jul 1 21:34:42 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_get): remove the old entry from the free
+ list before adding the new one.
+
+Sat Jun 27 12:46:20 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_syscalls.c (sys_afs): correct check for
+ copy_{from,to}_user. Always return -errno.
+
+ * xfs/linux/xfs_common.h (copy_to_user, copy_from_user): these
+ functions should return the number of uncopied bytes.
+
+ * configure.in: remove uid_t size test
+
+ * xfs/include/xfs_message.h: use __kernel_foo_t
+
+ * xfs/include/xfs_attr.h: define __kernel_foo_t if they are not
+ already defined and use them.
+
+ * xfs/bsd/xfs_node.c (vattr2xfs_attr): cast to `mode_t' otherwise
+ it breaks on modern NetBSD
+
+Thu Jun 25 06:04:01 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/adir.c (add_to_page): don't index off the end of the page.
+
+1998-06-24 Love Hornquist-Astrand <root@junkyard.stacken.kth.se>
+
+ * doc/partsofarla.texi: Added info about libkafs and pioctl()
+
+Mon Jun 22 17:34:53 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * xfs/solaris/xfs_vfsops.c: debug panic patch from:
+ John Hawkinson <jhawk@bbnplanet.com>
+
+1998-06-22 Love <lha@e.kth.se>
+
+ * Added doc/*.texi
+
+1998-06-21 Love <lha@e.kth.se>
+
+ * lib/sl/sl.[ch]: Added SL_BADCOMMAND
+
+ * appl/{fs,vos}.c: Fixes for sl.
+
+ * configure.in: Added patch for afslib from:
+ Mark Eichin <eichin@kitten.gen.ma.us>
+
+Fri Jun 19 20:43:42 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/fs.c (connect_cmd): correct comparison against `dis'
+
+Wed Jun 17 17:08:39 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.7.2
+
+Sat Jun 13 03:32:39 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/vos.c (printpartinfo): use bogus field
+
+1998-06-09 Love <lha@e.kth.se>
+
+ * lwp/make-process.o.sh.in: The new magic way of building process.o
+
+Tue Jun 9 10:11:03 1998 Magnus Ahltorp <map@stacken.kth.se>
+
+ * Release 0.7.1
+
+ * major bug fixes
+
+Mon Jun 8 18:07:12 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * Release 0.7
+
+1998-06-08 Love <lha@e.kth.se>
+
+ * arlad/fcache.c: Try to do sane things with callback->ExpirationTime.
+ (Assume that ExpirationTime is a relative time)
+
+ * util/log.c(log_vprint_file): Print date when logging to file/stderr.
+
+Mon Jun 8 15:14:10 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/openbsd2.3/xfs_syscalls.c: merge in
+ xfs/bsd/xfs_syscalls.c:1.26->1.27
+
+ * xfs/bsd/xfs_syscalls.c (xfs_setpag_call): only copy the required
+ gids and return the new cred
+
+Sun Jun 7 10:57:18 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: add irix
+
+Sun Jun 7 07:23:07 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * xfs/{solaris,aix,sunos}/xfs_messages.c
+ (xfs_message_invalidroot): clear tokens when invalidating
+
+ * arlad/fcache.c (fcache_init): set fprioritylevel at init
+
+Sun Jun 7 07:19:35 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * acconfig.h, configure.in, lib/roken/roken.h:
+ Autodetect linux htonl weirdness
+
+Thu Jun 4 00:12:37 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: new option `--recover' or `-z' for recovering
+ (not) stored state
+
+ * arlad/fcache.c (fcache_init): new parameter `recover'
+
+ * arlad/volcache.c (volcache_init): new parameter `recover'
+
+Wed Jun 3 23:41:42 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (do_read_attr): make sure we don't return -1
+
+Tue Jun 2 19:16:15 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_locl.h: include <linux/modversions.h> to get
+ versioned names of exported kernel symbols
+
+Tue May 26 22:54:33 1998 Assar Westerlund <assar@sics.se>
+
+ * acconfig.h (VFS_NEED_PROCP): remove
+
+ * configure.in (openbsd2.3): remove old junk
+
+Mon May 25 04:16:26 1998 Artur Grabowski <art@stacken.kth.se>
+
+ * arlad/messages.c: fix reading of links when only having
+ 'l' rights
+
+ * xfs/*bsd*/xfs_vnodeops.c: change size and mtime of files when
+ writing to them.
+
+Mon May 25 00:58:17 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.6
+
+ * lwp/Makefile.in: more uglyness for process.S
+
+ * util/Makefile.in: link mmaptime_test with libroken
+
+1998-05-24 Love <lha@e.kth.se>
+
+ * util/mmaptime_test.c: Added
+
+ * arlad/messages.c(vioc_fpriostatus): FPRIO_{GET,SET}MAX
+
+ * arlad/fcache.c(restore_state): Set priority too.
+ (do_read_attr): Check for disconnected mode, if we got
+ attr just return, otherwise return ENETDOWN.
+ (read_data): Check for disconnected mode.
+ (fcache_get): Check for disconnected mode.
+ (uptodatep): Check for connected logging mode.
+
+ * arlad/conn.c(conn_free): When in disconnected mode conn
+ sets to NULL.
+
+ * appl/{arlalib.h,fs.c,fs_lib.c,fs_local.h}: Added
+ {set,get}maxfprio.
+
+Sat May 23 07:24:22 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/appl_locl.h: include <sys/param.h>
+
+ * arlad/aix-subr.c: new file
+
+ * arlad/linux-subr.c (conv_dir): got rid of stupid warning
+
+ * arlad/arla.c (arla_cat): check return values from fcache*
+
+ * configure.in: check for h_errno, h_errlist, and h_nerr
+
+ * aclocal.m4: add check-declaration and check-var
+
+Fri May 22 21:34:30 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (fcache_get): check return value from
+ volcache_getbyid.
+
+Wed May 20 02:56:14 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: add `--port'
+
+ * getarg.c: fix some of the getarg bugs
+
+Tue May 19 17:18:31 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux: Fixed varous pointer conversions.
+ Moved glibc support to the correct place.
+ Added random code for debug control syscall.
+
+1998-05-18 Love <lha@e.kth.se>
+
+ * lwp/process.S: Add linux alpha support
+
+ * xfs/bsd/xfs_syscalls.c: Log to XDEBSYS instead of XDEBMSG
+
+ * include/kafs.h: Added new PIOCTL (50) for VIOC_FPRIOSTATUS
+ Added defines and structs for FPRIOSTATUS.
+
+ * conf/arla.conf: Added fpriority, default to 100
+
+ * arlad/messages.c: Added vioc_fpriostatus
+
+ * arlad/inter.c:(log_operation) dont log operations when in
+ connected mode.
+
+ * arlad/fcache.c: Added fprioritylevel and made use of it in
+ emergency_remove_file() and in cleaner thread.
+
+ * arla/arla_local.h: Added new state of connected_mode,
+ CONNECTEDLOG
+
+ * arlad/arla.c: Added fpriority to the conf file
+
+ * appl/fs.c: (getarg) Added {add,remove,get}removepriority,
+ and version.
+ (connect) changed fs_connect syntax
+ ({get,set}crypt) changed fs_*crypt syntax
+ ({set,get,remove}prio) added calls
+ (fserr) moved to fs_lib.c and changed syntax
+ (fsversion) print version of fs.c and fs_lib.c
+ (afs_getfid) moved to fs_lib
+
+ * appl/arlalib.h: Added fs_* prototypes
+
+Sat May 16 11:41:19 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux: Merged in Linux 2.1 support
+
+Sat May 16 06:44:16 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_vnodeops.c: fix use of VOP_RWLOCK and
+ VOP_RWUNLOCK
+
+ * xfs/aix/bin: add umount_xfs and mount_xfs.
+
+ * xfs/aix/xfs_vfsops.c (xfs_mount): find the device path
+
+ * xfs/aix/xfs_dev.c: init `event_word' to EVENT_NULL
+
+ * xfs/aix/xfs_deb.h: Use uprintf instead of printf to make it
+ possible to see the messages.
+
+Tue May 12 17:29:39 1998 Assar Westerlund <assar@sics.se>
+
+ * lwp/process.S: grammar fix
+
+Sun May 10 02:25:47 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: Fixed create, mkdir, rmdir, rename
+ in 2.1 branch
+
+ * xfs/linux/{xfs_message.c,xfs_inodeops.c}:
+ Addded more correct handling of dcache in 2.1 branch
+
+Sat May 9 11:41:10 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_vnodeops.c: replace VN_HOLD/VN_RELE by
+ VOP_RWLOCk/VOP_RWUNLOCK before calling VOP-funktions in ufs.
+
+ * configure.in: aix
+
+ * xfs/solaris/xfs_message.c (xfs_message_installdata): replace
+ printf by XFSDEB. Extra ASSERT for rb.
+
+Thu May 7 04:00:30 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/aix: new directory
+
+1998-05-06 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_message.c: try to purge the dnlc once in a while
+
+ * xfs/solaris/xfs_node.c (vattr2xfs_attr): check for AT_TYPE
+ (vattr2xfs_attr, xfs_attr2vattr): correct panic string
+
+Tue May 5 10:45:15 1998 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c (encode_string): zero-terminate string when
+ decoding.
+
+1998-05-05 Love <lha@s3.kth.se>
+
+ * configure.in: Check for dbm.
+
+ * arla/arla.c: Added flushfid command in -t mode.
+
+ * milko/bufcache.{c,h}: Added experimental bufcache.
+
+Sun May 3 04:29:01 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/solaris/xfs_vnodeops.c: return ENOSYS instead of EINVAL.
+ implement some trivial vnodeops
+
+ * xfs/solaris/xfs_vfsops.c: return ENOSYS instead of EINVAL for
+ non-implemented vfs-operations
+
+Sat May 2 03:00:35 1998 Assar Westerlund <assar@sics.se>
+
+ * **/Makefile.in: add `DESTDIR' and `uninstall:'
+
+ * arlad/fcache.c: got rid of some stupid warnings
+ updated to new volcache root volume stuff
+
+ * arlad/volcache.c: renamed volcache_rootvolume ->
+ volcache_get_rootvolume
+ (volcache_set_rootvolume): new function
+
+ * arlad/cred.c (cred_add): remove any old entry before adding the
+ new one.
+
+ * arlad/messages.c: try to handle expiring credentials in lots of
+ places
+ (viocgettok): remember to free the cred.
+
+ * arlad/fcache.c (read_data): handle the case of the file not
+ fitting in the cache.
+ (getroot): print the errors correctly
+ (getacl, setacl, getvolumestatus, setvolumestatus): don't destroy the
+ error code
+
+ * arlad/fbuf.c: rename all arguments fbuf -> f to avoid namespace
+ invasion.
+
+ * arlad/bsd-subr.c (conv_dir): get rid of a stupid varning
+
+ * arlad/cred.c (cred_expire): new function
+
+ * arlad/messages.c: try to handle expiring credentials.
+
+Fri May 1 22:20:23 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: call AC_C___ATTRIBUTE__
+
+ * aclocal.m4 (AC_C___ATTRIBUTE__): new macro for testing for
+ `__attribute__'
+ (AC_C___FUNCTION__, AC_FUNC_NTOHL): conservative default when
+ cross-compiling
+
+1998-04-30 Love <lha@s3.kth.se>
+
+ * ydr/output.c: No #define FOO_BAR_SIZE 0
+
+ * conf/services.h: No more errormessages...
+
+ * arlad/{fcache.c, arlad.c}: Added --root-vol=root.afs
+
+ * milko/* Added random stuff.
+
+Mon Apr 27 22:11:55 1998 Assar Westerlund <assar@sics.se>
+
+ * ydr/lex.l: parse more types of #line-lines.
+ renamed all tokens to T_FOO
+
+ * lwp/lwp.h: <sys/types.h> and <sys/select.h>
+
+ * lwp/Makefile.in: rs6000.
+ try harder preprocessing process.S
+
+ * appl/Makefile.in: add AIX_EXTRA_KAFS
+
+ * configure.in: aix
+
+ * aclocal.m4: AC_KRB_SYS_AIX added
+
+Sun Apr 19 15:36:35 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/Makefile.in (vop_defs.h): generate list of vops. From
+ "Per Boussard, ERA/T/ED" <per@era-t.ericsson.se>
+
+ * xfs/bsd/xfs_locl.h: include vop_defs.h
+
+Sun Apr 19 08:09:43 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/openbsd2.3/xfs_vfsops.c (xfs_mount): set `f_files' correctly
+
+ * xfs/bsd/xfs_vfsops.c (xfs_mount): set `f_files' correctly
+
+Wed Apr 15 04:52:27 1998 Robert Burgess <rb@abc.se>
+
+ * Release 0.5
+
+ * xfs/solaris/xfs_node.c: set blksize/nblocks
+
+Tue Apr 14 23:59:08 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_load.c: Changed major number to the newly
+ allocated 103
+
+Tue Apr 7 05:32:26 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * arlad/fcache.c: Added VIOCSETAL support
+
+ * arlad/messages.c: Moved some checks here from xfs_syscalls.c
+
+Mon Apr 6 05:19:44 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_vfsops.c: Added xfs_statfs
+
+ * xfs/linux/xfs_syscalls.c: Merged in new syscall style from bsd
+
+ * arlad/messages.c: Free opaque after use
+
+Sun Apr 5 12:50:56 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_node.c (xfs_dnlc_lookup): print debug output
+ correctly.
+
+ * arlad/cred.c (cred_delete): new function
+
+Sun Apr 5 05:49:27 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * arlad/fcache.c: Added VIOCGETVOLSTAT/VOLCSETVOLSTAT support
+
+Sun Apr 5 05:31:52 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (truncate_file): decrement usedbytes iff the data
+ was cached.
+
+ * arlad/adir.c (adir_mkdir): zero out hash table.
+
+ * arlad/afsdir_check.c: use arla_log
+
+ * arlad/Makefile.in (afsdir_check): link with arladeb.o
+
+Sun Apr 5 01:25:00 1998 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c (gendeclare): handle strings
+
+Sat Apr 4 20:39:18 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: add a --disable-mmap
+
+ * aclocal.m4 (AC_HAVE_GETCONF): call AC_CHECK_PROG properly
+
+Sat Apr 4 14:00:06 1998 Assar Westerlund <assar@sics.se>
+
+ * appl/Makefile.in: link with RXKAD and KAFS in the correct order
+
+Fri Apr 3 09:19:53 1998 Love H-Astrand <lha@ksk.sala.se>
+
+ * lib/ko/port.[ch]: Moved and added more ports.
+
+Fri Apr 3 05:30:19 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/ko/koerror.c: const-ize
+
+ * arlad/arla.c: new option `-n'
+
+ * arlad/*.c: rationalize and use new debug levels and functions
+
+ * util/log.c: change LOG_DEBUG -> LOG_INFO
+
+ * util/log.h: add __attribute__
+
+ * arlad/arladeb.c: add new debug levels.
+ add arla_{v,}{err,warn}{,x}
+
+Thu Apr 2 05:07:29 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: use AC_STRUCT_SOCKADDR_HAS_SA_LEN
+
+ * aclocal.m4 (AC_STRUCT_SOCKADDR_HAS_SA_LEN): added
+
+ * rx/rx_user.c (GetIFInfo): rewrite so that it actually works.
+
+Tue Mar 31 07:52:39 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_lookup): better debug output for
+ negative caching
+
+ * xfs/bsd/xfs_message.c (xfs_message_installnode): purge the name
+ cache
+ (xfs_message_installdata): purge the name cache iff it's a directory
+
+Mon Mar 30 17:45:45 1998 Love Hörnquist-Åstrand <lha@stacken.kth.se>
+
+ * Added autoconf test for glibc.
+ From: Brad Keryan <keryan@andrew.cmu.edu>
+
+Mon Mar 30 12:01:50 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: added mkdir and rmdir
+
+ * xfs/linux/xfs_inodeops.c: xfs_readdir checks for inode numbers
+ in the name cache
+
+Mon Mar 30 00:27:22 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * aclocal.m4: Autoconf test for getconf, and getconf LFS_{C,LD}FLAGS
+
+Sun Mar 29 14:25:28 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux: Merged in access control from bsd.
+
+ * xfs/linux: Fixed various things. Should work much better.
+
+Sun Mar 29 03:21:39 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c: new option `connected-mode' for setting initial
+ connected mode
+
+ * arlad/fcache.c (do_read_attr, read_data): set anonaccess
+
+ * configure.in: remove test for winsock.h. added test for recvmsg
+ and sendmsg.
+
+ * rx/rx_mach.h: cygwin doesn't have SIOCGIFCONF. From Dan Winship
+ <danw@MIT.EDU>
+
+ * arlad/*.c: Use O_BINARY. From Dan Winship <danw@mit.edu>
+
+Sat Mar 28 10:34:30 1998 assar westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_common.c (install): use DESTDIR
+
+ * arlad/bsd-subr.c (write_dirent): conditionalize on
+ HAVE_STRUCT_DIRENT_D_TYPE
+
+ * configure.in: check for `d_type' in `struct dirent'
+
+Sat Mar 28 10:15:29 1998 Assar Westerlund <assar@sics.se>
+
+ * aclocal.m4 (AC_HAVE_STRUCT_FIELD): added
+
+1998-03-28 Love Hörnquist-Åstrand <lha@s3.kth.se>
+
+ * *: USE_MMAPTIME
+
+ * configure.in: Added --enable-mmaptime
+
+ * arlad/{messages,arlad}.c: Added no kerberos fix from
+ Dan Winship <danw@mit.edu>
+
+1998-03-27 Love Hornquist-Astrand <lha@ksk.sala.se>
+
+ * util/mmaptime.[ch]: Added (not working yet)
+
+Fri Mar 27 03:41:45 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c (newwalk): handle symlink followed by more path
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_lookup): enter negative entires in
+ name cache when arlad returns ENOENT
+
+ * xfs/bsd/xfs_node.c (xfs_dnlc_lookup): change signature to be
+ more compatible with cache_lookup
+
+ * arlad/arla.c (arla_cat): release lock
+
+Thu Mar 26 02:21:48 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.4
+
+ * lwp/process.S: rhapsody/powerpc
+
+ * lwp/Makefile.in: Add powerpc and rhapsody.
+
+ * **/Makefile.in: Use KRB_INC_FLAGS
+
+ * configure.in, aclocal.m4: Test for krb v5. From <lxs@mit.edu>
+
+Wed Mar 25 04:26:56 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_dev.c (xfs_devwrite): return the correct value.
+ also check for bogus size == 0
+
+ * xfs/{linux,sunos,solaris}: update to new style xfs_message.h
+
+ * xfs/bsd/xfs_msg_locl.h: new file
+
+ * xfs/bsd/xfs_wrap.c: do DISPATCH the `correct' way
+
+ * xfs/bsd/xfs_message.c: add `struct proc *p' to xfs_message_*
+
+ * xfs/bsd/xfs_node.c (new_xfs_node): now takes a `struct proc *p'
+
+ * xfs/bsd/xfs_dev.c: add `struct proc *p' to xfs_message_*
+
+ * xfs/bsd/xfs_dev.h: add prototypes for xfs_message_*
+
+ * arlad/messages.c: made all xfs_message_* functions static
+
+ * arlad/messages.h: add proto for xfs_message_receive
+
+ * xfs/include/xfs_message.h: Removed all the prototypes.
+
+ * xfs/bsd/xfs_vnodeops.c: s/EINVAL/EOPNOTSUPP/
+
+ * xfs/bsd/xfs_dev.c (xfs_message_wakeup_data): correct debug
+ output
+
+ * arlad/messages.c(afsrights2xfsrights): change arguments.
+
+ * xfs/linux/xfs_load.c (init_module): don't print
+ xfs_message_installnode, it's static now.
+
+Tue Mar 24 00:24:18 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vfsops.c (xfs_mount): copy in the arguments. From
+ Karl Ramm <kcr@mit.edu>.
+
+Tue Mar 24 19:53:50 1998 Robert Burgess <rb@stacken.kth.se>
+
+ * arlad/fcache.c: Added VIOCGETAL support
+
+Tue Mar 24 02:03:43 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_dev.c (xfs_devwrite): fix?
+
+ * arlad/kernel.c: also collect statistics on the number of
+ messages per read
+
+ * arlad/messages.c: more stats
+
+ * arlad/messages.c: count the number of send/recd messages
+
+ * xfs/include/xfs_message.h (XFS_MSG_COUNT): added
+
+ * arlad/*-subr.c (conv_dir): use `fcache_extra_file_name' and do
+ locking correctly.
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_seek): return 0.
+
+ * Makefile.in (configure): ignore errors
+
+ * arlad/arla.c (main): don't malloc and free device_file
+
+ * appl/fs.c: added `getcrypt' and `setcrypt'
+
+ * xfs/bsd/xfs_syscalls.c (xfs_pioctl_call): add
+ VIOC_[GS]ETRXKCRYPT
+
+ * include/kafs.h (VIOC_[GS]ETRXKCRYPT): added
+
+ * arlad/bsd-subr.c (write_dirent): set `d_type'
+
+Sun Mar 22 19:25:18 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.3
+
+ * configure.in: don't clobber CFLAGS
+
+ * xfs/bsd/xfs_syscalls.c (xfs_pioctl_call): use
+ `a_followSymlinks'. Call `suser' instead of == 0
+
+ * arlad/solaris-subr.c: handle the weirdness in the solaris dirent
+ format
+
+ * arlad/afsdir_check.c (check): removed bogus code
+
+ * xfs/solaris: major rewriting and fixing.
+
+Sun Mar 22 02:47:59 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * appl/fs.c,arlad/messages.c,xfs/{bsd,openbsd2.3,linux}:
+ Added VIOCCONNECTMODE
+
+Sat Mar 21 15:20:52 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (read_data, write_data, truncate_file): kill the
+ call if an error occurs.
+
+ * configure.in: tweak CFLAGS and -I/usr/athena
+
+ * arlad/conn.c (conn_get): connected_mode test
+
+ * arlad/volcache.c (volume_uptodatep): look at connected_mode
+
+ * arlad/fcache.c (uptodatep): look at `connected_mode'
+
+ * arlad/arla.c: new option `--debug'
+
+ * arlad/arladeb.c (arla_log_set_level, arla_log_get_level,
+ arla_log_print_levels): new functions
+
+ * arlad/kernel.c (process_message): handle multiple messages
+
+ * xfs/{sunos,solaris,linux}/xfs_dev.c: merge in changes from bsd
+
+ * arlad/messages.c(xfs_send_message_wakeup_multiple): new
+ function. use it.
+
+ * lwp/iomgr.c: re-wrote the handling of fd_set's
+
+ * xfs/bsd/xfs_dev.c (xfs_devread, xfs_devwrite): implement
+ multiple messages per read/write
+
+Sat Mar 21 06:45:42 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * doc/* : added a few docs about Arla.
+
+Fri Mar 20 08:19:36 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * xfs/{openbsd2.3,bsd}/xfs_vfsops.c (xfs_unmount): fix unmounting.
+
+Fri Mar 20 04:30:33 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_fetch_rights): new function used by
+ `xfs_access'
+ (xfs_read, xfs_write, xfs_readdir, xfs_readlink): vop_lock and
+ vop_unlock
+
+Thu Mar 19 22:31:20 1998 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c (init_generate): change path of rx.h
+
+ * xfs/bsd/xfs_vnodeops.c(xfs_fsync): send correct flags to
+ do_fsync
+
+ * arlad/fbuf.c (mmap_copyrx2fd, malloc_copyrx2fd): check result of
+ ftruncate
+
+ * arlad: moved kerberos includes to arla_local.h
+
+ * include/Makefile.in: remove stds.h, kafs.h add rxkad.h service.h
+
+ * **/Makefile.in: remove unused INCLUDES
+
+Thu Mar 19 12:27:47 1998 Love Hörnquist-Åstrand <lha@s3.kth.se>
+
+ * app/fs/fs.c:
+ (fserr): Implemented and changed on all used use on all places.
+ (afs_getfid): Added VIOCGETFID
+ (quit_cmd): use return instead of exit();
+
+Wed Mar 18 21:52:31 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (create_directory): create the directory locally
+ instead of fetching it from the file server
+
+ * arlad/adir.c (dir_mkdir): new function
+
+ * arlad/fcache.c (stale): don't bother if the callback is already
+ dropped
+
+Wed Mar 18 10:58:44 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_vfsops.c: Added xfs_write_inode
+
+ * xfs/linux/xfs_inodeops.c: Added permission checking and write support
+
+Wed Mar 18 03:11:51 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * xfs/{openbsd2.3,bsd}/{xfs_fs.h,xfs_node.c}: xfs_has_pag implemented.
+
+ * xfs/{openbsd2.3,bsd}/xfs_node.c (new_xfs_node): set anonrights.
+
+ * xfs/openbsd2.3/xfs_vfsops.c: small fix to {un,}installation.
+
+ * xfs/{openbsd2.3,bsd}/xfs_vnodeops.c
+ (xfs_access): implement correctly
+
+ * xfs/{openbsd2.3,bsd}/xfs_node.h: add an anonrights field to
+ xfs_node.
+
+ * xfs/{openbsd2.3,bsd}/xfs_message.c
+ (xfs_message_installattr, xfs_message_installdata): set anonrights.
+
+ * xfs/include/xfs_message.h: add anonrights, change id from u_int
+ to pag_t, add masks for rights.
+
+ * arlad/messages.c
+ (afsrights2xfsrights): implement.
+ (fcacheentry2xfsnode): add handling of access rights.
+ (most functions): access rights handling with changed cm_attr.
+
+ * arlad/inter.c
+ (getrights): correct implementation.
+ (checkright): correct implementation.
+ (cm_getattr): handling of access rights.
+
+ * arlad/fcache.c
+ (create_new_entries): initialize acccache.
+ (recover_state): Do not recover rights.
+ (findaccess): pag 0 doesn't mean that it's unauthorized.
+
+ * ChangeLog: updated.
+
+Tue Mar 17 06:05:26 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * lwp/iomgr.c: some speed optimizations on selecting.
+
+Tue Mar 17 03:09:56 1998 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * Make arlad /dev/xfs0 working again.
+
+ * lib/ko/koerror.c: Fallback on strerror().
+
+ * xfs/bsd/{xfs_dev.c,xfs_vnodeops.c,xfs_locl.h}: Started to
+ use #ifdef HAVE_VOP_FOO for everything.
+
+ * xfs/bsd/xfs_dev.c: NetBSD 1.3 and OpenBSD 2.2 doesn't have
+ vop_{get,put}pages_desc.
+
+Tue Mar 17 01:24:55 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/*: moved xfs/*.h to .
+
+ * xfs/bsd/xfs_vnodeops.c: fixed vop_t
+
+ * xfs/solaris/Makefile.in: renamed xfs.mod -> xfs
+
+ * lwp/Makefile.in: check if the compiler is gcc not if it's called
+ gcc
+
+ * **: renames lots of `errno' to `error'
+
+ * xfs/linux/Makefile.in: include KRB_INC_DIR last
+
+Mon Mar 16 21:38:06 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * lwp/process.S: close a comment and let lwp work on ppc. (reported
+ to work)
+
+Mon Mar 16 20:55:52 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: Fixed bug in xfs_readdir
+
+Mon Mar 16 02:54:53 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.2
+
+ * NEWS, THANKS: new files.
+
+ * include/Makefile.in: add parse_units.h and resolve.h
+
+Sun Mar 15 00:56:47 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (volume_uptodatep): new function
+ (recover_state): don't mark recovered volumes as valid
+
+ * xfs/sunos/xfs_vnodeops.c (xfs_inactive): use the flag field on
+ the inactivenode message
+
+ * xfs/solaris/xfs_vnodeops.c (xfs_inactive): use the flag field on
+ the inactivenode message
+
+ * xfs/openbsd2.3/xfs_vnodeops.c (xfs_reclaim): use the flag field
+ on the inactivenode message
+
+ * xfs/linux/xfs_vfsops.c (xfs_put_inode): set flag in inactivenode
+ message
+
+ * xfs/include/xfs_message.h (xfs_message_inactivenode): new `flag'
+ field
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_close): only call `do_fsync' if the
+ file was oppened for writing and was actually changed.
+ (xfs_inactive): send an inactivenode message
+ (xfs_reclaim): use the correct flag on the inactivenode message
+
+ * arlad/messages.c (xfs_message_inactive): look at the flags
+ (xfs_message_create & c:o): use the correct realfid
+
+ * arlad/inter.c: update to new FCacheEntry
+
+ * arlad/fcache.c (throw_entry): only give up a callback if we have
+ any.
+ (recover_state): init `count'
+ (fcache_stale_entry): call stale iff flags.kernelp
+ (fcache_get_data): don't get data if the shows that it hasn't changed.
+
+ * arlad/fcache.h (FCacheEntry): remove `nreaders' and `nwriters'.
+ add `flags.kernelp'
+
+ * arlad/adir.c (create_new_page): return page1
+ (add_to_page): only loop till ENTRIESPERPAGE - 2
+ (adir_creat): don't use status.Length, it might already have been
+ increased by the file server. more and more correct checks.
+
+ * appl/vos.c (printvolstat): const-ized
+
+ * appl/arlalib.h: const-ized
+
+ * appl/arlalib.c: const-ized
+
+Sat Mar 14 14:39:25 1998 Assar Westerlund <assar@sics.se>
+
+ * include/Makefile.in: add err.h
+
+ * rx/rx_pkt.[ch]: don't assume sizeof(void) == 1
+
+Sat Mar 14 14:08:02 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/cmcb.c (RXAFSCB_CallBack): remove warning message
+
+ * arlad/{ports,arla,messages}.c: no \n to arla_log
+
+ * rxkad/rxk_locl.c (rxkad_check_packet): kludge around.
+
+ * README: update installation instructions
+
+ * arlad/arla.c: add options for rxkad_level and device.
+
+Sat Mar 14 13:56:55 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/Makefile.in: Added libko dependencies in arlad
+
+Fri Mar 13 05:06:37 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_readlink): call `set_fs'
+
+ * xfs/bsd/xfs_vnodeops.c (do_fsync): reset the XFS_DATA_DIRTY flag
+ (xfs_remove): remove the name from the dnlc
+ (xfs_mmap, xfs_bmap, xfs_getpages, xfs_putpages): dummy functions
+
+ * xfs/bsd/xfs_message.c: spell-check the printfs
+
+ * util/fnameutil.[ch]: rename {base,dir}name to copy_\1name
+
+ * rxdef/pts.xg: fix broken declarations
+
+ * include/Makefile.in: add getarg.h
+
+ * arlad/volcache.h (volcacheentry): add `validp'
+
+ * arlad/volcache.c: change `freelist' to be a `lrulist'
+ (recover_state, volcache_store_state): new functions
+ (volcache_invalidate): new function
+
+ * arlad/inter.c (cm_init,cm_store_state,log_operation): new
+ functions
+ (*): call log_operation
+ (*): const-ized some arguments
+
+ * arlad/fcache.h: update prototypes
+
+ * arlad/fcache.c (fcache_store_state,recover_state): new functions
+ (fcache_init): don't create cachedir. try to recover state.
+ (*): return ENETDOWN if findconn fails
+ (do_read_attr): throw data if DataVersion has changed
+ (truncate_file): use O_CREAT
+ (create_file): create a empty cache file
+ (*): const-ized some arguments
+ (fcache_get_data): DTRT
+
+ * arlad/cmcb.c (RXAFSCB_CallBack): handle volume callbacks.
+
+ * arlad/arladeb.h: add ADEBVOLCACHE and ADEBCM
+
+ * arlad/arla.c (newwalk): return int. change callers. handle
+ signals by storing state
+ (main): use getarg. chdir to cachedir before initializing
+
+ * configure.in: fix sys/dir.h and dirent.h test.
+ call AC_KRB_VERSION
+
+ * aclocal.m4 (AC_KRB_VERSION): new macro
+
+ * TODO: update
+
+Thu Mar 12 15:22:50 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * configure.in,aclocal.m4,acconfig.h,lib/roken/resolve.c:
+ Added HAVE__RES
+
+ * configure.in, aclocal.m4: Added tests for krb-libs,and includes.
+
+Thu Mar 5 22:20:54 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: More correct error handling
+ and -Wall pleasing.
+
+Thu Mar 7 05:50:10 1998 Love Hörnquist-Åstrand <lha@s3.kth.se>
+
+ * rxdef/pts.xg: Added broken xg def.
+
+Wed Mar 4 03:23:19 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arla/*.c: Added arla_log and started to used.
+
+ * util/log.c: Added log_vlog.
+
+ * arlad/messages.c: Moved vicofluchvolume outsize #ifdef KERBEROS
+ and added stub for VIOCGETAL.
+
+Tue Mar 3 21:16:06 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: fixes memoryleak and xfs_readdir()
+ on linux != sparc. from amu@mit.edu (Aaron M. Ucko)
+
+Tue Mar 3 00:00:55 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/inter.c (cm_lookup): const-ized parameters
+
+ * xfs/{sunos,solaris}/{,bin/}Makefile.in: set exec_prefix
+ (install): removed '-m 444'
+
+ * rxdef/volumeserver.xg: remove stds.h
+
+ * lib/{ko,tl}/Makefile.in (install): removed '-m 444'
+
+ * arlad/arla.c (newwalk): follow symlinks
+ (main): try harder getting kerberos credentials
+
+ * appl/appl_locl.h: include <atypes.h>
+
+Mon Mar 2 13:32:42 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * appl/vos.c: Vos exa now uses libko/kocell.
+
+ * lib/ko/kocell.c: Moved from arlad/cell.c, and turned
+ arlad/cell.c to a dummy.
+
+ * configure.in,include/stds.h.in: Added autoconf test
+ for krb_principal
+
+ * Made a bunch of links to include/ from all .h files
+ to make the compile lines more sane.
+
+ * arla/{fcache.c,volcache.c} Added use of libkoerror.
+
+Mon Mar 2 01:00:09 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * arlad/bsd-subr.c: Horrible hack for DEC Unix.
+
+Sun Mar 1 06:42:00 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.1
+
+ * arlad/fcache.c (do_read_attr): invalidate data if we have it
+ cached and DataVersion has changed.
+
+ * xfs/bsd/xfs_node.c (new_xfs_node): postpone vget-ing
+
+ * xfs/bsd/bin/Makefile.in: set PROGS and clean properly
+
+ * xfs/bsd/xfs_message.c (xfs_message_isntallnode): more debug
+
+ * xfs/bsd/Makefile.in (doclean): clean properly
+ (CFLAGS): remove Wall (it is set by configure)
+
+ * rx/rx.h: remove stupid includes
+
+ * conf/Makefile.in: don't overwrite existing configuration files
+
+ * configure.in: remove unused tests
+
+ * xfs/bsd/xfs_message.c (xfs_message_installdata): don't
+ VOP_UNLOCK unlocked vnode.
+
+ * util/list.c: more paranoia
+
+ * arlad/bsd-subr.c (conv_dir): free buf
+
+ * arlad/adir.c (adir_readdir): do `.' and `..'-magic correctly.
+
+Fri Feb 27 23:37:39 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c: better error reports when rx calls fail.
+
+Fri Feb 27 07:09:08 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * arlad/*-subr.c: truncate files when opening a dircache file.
+
+Fri Feb 27 04:56:58 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * arlad/arladeb.h: ADEBFCACHE added
+
+ * arlad/fcache.c: don't break dead xfs-callbacks.
+
+ * arlad/adir.c: put '.' and '..' in front of a readdir. Some systems
+ seem to like it that way.
+
+Thu Feb 26 01:30:44 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/fcache.c,messages.c: VIOC_FLUSHVOLUME
+
+ * Now semiworking (no good parsing) vos listvol, it was a feature
+ in ydr.
+
+ * ydr/output.c:
+ - long -> int32 fix
+ - Fix for use of temporary variables.
+
+Mon Feb 23 06:38:18 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/bsd/xfs_syscalls.c: Merged in changes from obsd23.
+
+ * lib/roken/roken.h: ssize_t added.
+
+ * lib/roken/roken.h: sunos select fix.
+
+ * lib/roken/roken.h,acconfig.h, configure.in: sunos select fix.
+
+ * VIOC_VENUSLOG: Almost.
+
+Mon Feb 23 01:17:43 1998 Artur Grabowski <art@stacken.kth.se>
+
+ * xfs/openbsd2.3: (xfs_pioctl) cleanup and VIOCSETCACHE
+
+ * arlad/messages.c, fcache.c: VIOCSETCACHE
+
+Mon Feb 23 02:10:51 1998 Assar Westerlund <assar@sics.se>
+
+ * Release 0.0
+
+ * arlad/arla.c (main): try to get tokens for the local cell.
+
+ * appl/appl_locl.h: include rxkad.h iff KERBEROS
+
+ * arlad/fcache.c (read_data): make sure we never go over
+ `highbytes'
+
+ * lwp/Makefile.in: add hpux
+
+ * configure.in: add hpux
+
+ * rx/rx_pkt.c(rxi_ReadPacket): fix from <per@era-t.ericsson.se>
+ for handling strange packets.
+
+ * rxdef/vldb.xg: MAXNAMELEN -> VLDB_MAXNAMELEN
+
+ * rx/rx_locl.h: include <atypes.h>
+
+ * lib/ko/ko.h: include <atypes.h>
+
+ * arlad/messages.c: always include <kafs.h>
+
+ * arlad/arla.c: made `conf_params' static to make it initable.
+
+ * arlad/Makefile.in: coompatible with stupid make
+
+ * appl/Makefile.in: use KAFS_LIBS
+
+ * configure.in: set KAFS_LIBS
+
+ * arlad/arla.c: allow setting of low and high-water marks.
+
+ * configure.in: test if strtok_r needs a prototype
+
+ * rxdef/Makefile.in: remove new junk files
+
+ * ydr/main.c: changed the way of running cpp :-(
+
+Mon Feb 23 05:55:54 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * xfs/openbsd2.3: (xfs_pioctl) cleanup and VIOCSETCACHE
+
+ * arlad/messages.c, fcache.c: VIOCSETCACHE
+
+ * appl/fs.c: setcachesize implmeneted.
+
+ * arlad/arla.c: Added reading of a configuration file.
+
+Sun Feb 22 20:51:47 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/bsd/xfs_vnodeops.c(xfs_link): Added OpenBSD and NetBSD
+ compability
+
+ * configure.in, include/stds.h, rxkad/rxkad.h: Added test for
+ {,u_}int32, and added those for rxkad.
+
+ * appl/vos.c: Fixing listpart, but the total is still wrong.
+
+ * appl/vos.c: Added libko to parts of vos.c
+
+ * lib/ko: Added libko, vlserver, volserver and rxkad errorcodes
+ and messages.
+
+Sun Feb 22 15:59:30 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (print_entry): print every volume only once.
+
+Sun Feb 22 15:23:31 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * lwp/iomgr.c (struct IoRequest): add `next' pointer instead of
+ bogus use of `result'.
+
+ * lwp/lwp.c: Include <string.h>, replace "0x%x" with "%p".
+
+ * rx/*: Use rx_locl.h
+ - replace bcopy with memcpy
+ - remove `register'
+ - change long -> int32
+ - don't depend on sizeof(whatever) being correct
+
+ * rx/rx_user.c: Clean up osi_Panic.
+
+ * rx/rx_pkt.c: Cleanup rx_Slow{Read,Write}Packet.
+
+ * appl/vos.c: htonl(vlentry.serverNumber)
+
+Sun Feb 22 06:10:55 1998 Assar Westerlund <assar@sics.se>
+
+ * ydr/lex.l (yywrap): conditionalize
+
+Sun Feb 22 01:11:17 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_pioctl): implement VIOCGETTOK
+
+ * xfs/bsd/xfs_syscalls.c (xfs_pioctl_call): implement `VIOCGETTOK'
+
+ * rxkad: updated to a more modern version.
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_link, xfs_rename): implement
+
+ * arlad/messages.c (xfs_message_link, xfs_message_rename):
+ implement
+
+ * arlad/inter.c (cm_link, cm_rename): new functions
+
+ * arlad/fcache.c (create_link, rename_file): new functions
+ all functions are now careful not to use any OUT parameters from
+ rpc's that fail.
+
+ * xfs/bsd/xfs_node.c (xfs_node_find): cleaner
+
+ * arlad/fbuf.c: re-did the fbuf-interface
+
+ * arlad/bsd-subr.c (write_dirent): do special for ".." iff
+ flags.mountp
+
+ * arlad/volcache.c (recycle_entry): removed a bogus `hashtabdel'
+
+ * rx/rx_pkt.c (rxi_ReadPacket): case `RX_HEADER_SIZE' to int when
+ comparing again `nbytes', otherwise we lose :-(
+
+ * xfs/bsd/xfs_node.c (xfs_node_find): a dead vnode might still be
+ on the mount-list, check for that.
+
+Sat Feb 21 23:14:47 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * arlad/adir.c(adir_remove): Use length when deleting a entry
+ in a afsdir.
+
+ * arlad/fcache.c: Return ENOMEM when not finding a cred for the
+ new cell (this should never fail, we should allways be able to find a
+ rx_null cred.)
+
+ * xfs/bsd/xfs_vnodeops.c: Define xfs_vop_t for Open|NetBSD for
+ typecasting --> getting less errors.
+
+ * arlad/fcache.c: Use CRED_ANY when we hit a remote cell,
+ and doesn't find a "native" cred.
+
+Sat Feb 21 18:14:47 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/messages.c (xfs_message_symlink): new function
+
+ * arlad/inter.c (cm_symlink): new function
+
+ * arlad/fcache.c (create_symlink): new function
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_symlink): implement
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_lookup): more SAVENAME voodoo
+ (xfs_remove, xfs_rmdir, xfs_abortop): implement functions
+
+ * arlad/messages.c (xfs_message_mkdir, xfs_message_rmdir): new
+ functions
+
+ * arlad/inter.c (cm_mkdir, cm_rmdir): new functions
+
+ * arlad/fcache.c (create_directory, remove_file,
+ remove_directory): new files
+
+ * arlad/afsdir_check.c: more paranoid tests
+
+ * arlad/adir.c: squash some almost fence-post bugs.
+
+ * xfs/include/xfs_message.h (xfs_message_remove): added cred
+
+ * arlad/afs_dir.h: start using sized types
+
+ * arlad/messages.c (xfs_message_create): convert and push down the
+ updated directory
+
+ * arlad/inter.c (cm_create): create the file in the local cached
+ copy of the directory.
+
+ * arlad/fbuf.c: re-organized.
+ (truncatefilebuffer): new function
+
+ * arlad/adir.c (adir_lookup): test to see that `dir' is a
+ directory.
+ (adir_readdir): dito
+ (adir_creat): new function for adding an entry to a directory.
+ (aidr_remove): new function for removing an entry from a directory.
+
+ * arald/afsdir_check.c: new program
+
+Sat Feb 21 16:00:00 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * arlad/arla.c, rx/r.c: Added rx-status.
+
+Fri Feb 20 09:32:52 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c: return better error codes than ENODEV (except in
+ two cases)
+
+Thu Feb 19 23:17:25 1998 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * xfs/bsd/xfs_syscalls.c, arlad/messages.c: Added VIOC_GET_WS_CELL.
+
+ * xfs/include/xfs_messages.h: Added handle to pioctl msg.
+
+Thu Feb 19 02:47:52 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/bsd/syscalls.c, arlad/message.c: VIOC_FILE_CELL_NAME.
+
+ * xfs/bsd/xfs_vnodeops.c(xfs_mkdir): Send right message and
+ save us a panic
+
+ * include/kafs.h: Added more pioctl calls.
+
+ * appl/vos.c: Added to option to query a specific server in vos exa
+ and added options -host, -cell and -noauth.
+
+ * arlad/arla.c: begining for sysname in -t mode.
+
+ * arlad/cell.c: Ask diffrent vldb-server each time.
+
+Thu Feb 19 06:05:43 1998 Assar Westerlund <assar@sics.se>
+
+ * include/kafs.h: added
+
+ * arlad/fcache.c: re-wrote
+
+ * arlad/volcache.c: re-wrote
+
+ * arlad/messages.c (VIOC_AFS_SYSNAME): remove
+ (afsstatus2xfs_attr): fix
+ (xfs_message_*): updated
+
+ * arlad/inter.c (getrights, checkright): commented out, I didn't
+ bother to fix them now.
+ (cm_lookup): add test for `@sys'
+ (cm_remove, cm_link): commented out
+
+ * arlad/fbuf.c: remove #undef HAVE_MMAP and make the code compile.
+
+ * arlad/conn.c: re-wrote
+
+ * arlad/cred.c: re-wrote
+
+ * arlad/cmcb.c (RXAFSCB_InitCallBackState): do something
+
+ * arlad/cell.c: rename all functions to cell_
+ (cell_num2name): new function
+ fix fopen format strings
+ removed all locks (sorry Love)
+
+ * arlad/arla.c: Use `tmpce'
+ (arla_{conn,vol,cred,fcache}_status): new functions
+
+ * arlad/adir.c (adir_lookup): update to new fcache-interface. use
+ CredCacheEntry. don't handle @sys
+ (adir_readdir): update to new fcache-interface. use CredCacheEntry
+
+ * ydr/output.c: add copyright
+ (gen1): make TIN arguments `const'
+
+ * xfs/bsd/Makefile.in (CFLAGS): add `-Wno-unused'
+
+ * xfs/bsd/xfs_node.c (xfs_attr2vattr): set `va_blocksize' to a
+ reasonable value.
+
+ * util/hash.c (hashtabnew): check malloc return value at correct
+ place.
+
+ * arlad/Makefile.in: more includes link with libraries in correct
+ order
+
+ * makesnap: don't hardcode cvsbin and CVSROOT
+
+Thu Feb 12 01:38:21 1998 Assar Westerlund <assar@sics.se>
+
+ * ydr/output.c: include rx.h
+
+ * ydr/main.c: does it have to be this hairy to run a simple cpp
+ portably?
+
+ * xfs/solaris/xfs_node.c (new_xfs_node): use correct set of
+ attributes
+
+ * xfs/include/xfs_message.h: moved xfs_msg_node and related
+ defintions here from xfs/*/xfs/xfs_node.h
+
+ * lwp/q.c: renamed {ins,rem}que to lwp_\1
+
+ * arlad/irix-subr.c: new file
+
+ * aclocal.m4: stolen BASH_CHECK_DEV_FD from bash
+
+ * configure.in: Add testing for /dev/fd.
+ correct gcc test.
+ stub support for irix.
+
+Wed Feb 11 02:18:51 1998 Assar Westerlund <assar@sics.se>
+
+ * lib/roken/{snprintf.c,mini_inetd.c,getarg.c}: merged in newer
+ code.
+
+ * configure.in: moved util and ydr from subdirs to AC_OUTPUT
+
+1998-02-10 Per Andersson <ppan@joker.cntw.com>
+
+ * INSTALL: Changed sunos(4) instructions to match current version
+
+Tue Feb 10 02:52:51 1998 Assar Westerlund <assar@sics.se>
+
+ * lwp: renamed process.s -> process.S
+
+ * aclocal.m4(AC_GROK_TYPE): test for ktypes.h
+
+ * xfs/sunos/Makefile.in: rewrote and vpath-ed.
+
+ * xfs/sunos: updated to changes elsewhere.
+
+ * arlad/arla_local.h: use <dirent.h> xor <sys/dir.h>
+
+ * arlad/afs_dir.h: rename PAGESIZE -> AFS_PAGESIZE
+
+ * include/bits.c: test for ktypes.h
+
+ * configure.in: test for ktypes.h
+
+ * include/{bits.c,Makefile.in}: generate atypes.h
+
+ * xfs/solaris: new directory
+
+ * arlad/solaris-subr.c: new file
+
+ * ydr/lex.l: handle more kinds of #-lines
+
+ * rxkad/Makefile.in: work-around for stupid solaris make
+
+ * rxdef/Makefile.in: remove BSD/GNU-special and use explicit rules
+ instead.
+
+ * rx/Makefile.in: work-around for stupid solaris make
+
+ * lwp/iomgr.c: add <fcntl.h>
+
+ * lwp/Makefile.in: more magic for preprocessing and assembling
+ process.s
+
+ * arlad/sunos-subr.c (fcacheentry2xfsnode, conv_dir): update to
+ new signatures
+
+ * arlad/conn.c (markasdown): don't initialize `d' in declaration
+
+ * Makefile.in: add include to SUBDIRS
+
+ * configure.in: replace @CANONICAL_HOST@
+ add solaris
+ check for -lsocket, -lnsl and -lresolv
+ generate Makefile in include
+
+Tue Feb 3 16:16:42 1998 Love Hörnquist-Åstrand <lha@e.kth.se>
+
+ * util/hash.c(hashjpw): Some typecasting to save the world.
+
+ * lib/roken/snprint.c: Removed #if 0
+
+ * configure.in: Added check for gcc and -Wall
+
+Fri Jan 30 19:58:51 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/{conn.c,fcache.c,volcache.c}: Fixed conn locking.
+
+Wed Jan 28 05:43:44 1998 Artur Grabowski <art@stacken.kth.se>
+
+ * Cleaned up most of the warnings in arlad, lwp, rx* and some other
+ small things.
+
+ * lwp: ANSI-prototypes.
+
+ * rx: ANSI-prototypes. Indentation, cleanup
+
+Wed Jan 28 01:00:00 1998 Niklas Hallqvist <nh@stacken.kth.se>
+
+ * BSDmake compatibility
+
+ * Build from local libsl
+
+Thu Jan 22 22:13:57 1998 Magnus Holmberg <mho@stacken.kth.se>
+
+ * xfs/include/xfs_message.h: Argh! Whoever came up with the bright
+ idea of having userland xfs_message_receive() and kernel
+ xfs_message_receive() have the same name and share the same
+ prototype?
+
+ * xfs/include/xfs_message.h, configure.in, acconfig.h:
+ Gross hack to support both old and new VFS.
+
+Wed Jan 21 12:52:44 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs_inodeops.c (xfs_close): use XFS_{READ,WRITE}
+
+ * xfs/bsd/xfs_vnodeops.c (xfs_close): use XFS_{READ,WRITE}.
+ always call cm_close, independent of the dirty flag. arlad needs
+ to now how many processes have this file open.
+
+ * arlad/inter.c(cm_close): use XFS_READ & c:o
+
+ * xfs/include/xfs_message.h: introduced flags:
+ XFS_{READ,WRITE,...}
+
+Wed Jan 21 03:54:15 1998 Magnus Holmberg <mho@stacken.kth.se>
+
+ * xfs/openbsd2.3:
+ VFS Lite2 changes.
+ Merged from .../xfs/bsd.
+ -Wall.
+
+Mon Jan 19 03:30:53 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/*-subr.c, arlad/messages.c: Merged xfs_attr stuff into messages.c
+
+ * Changed linux xfs to use xfs_attr and changed everything to include
+ xfs/include/xfs_message.h
+
+Mon Jan 19 04:46:36 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/include/xfs_message.h: add ID. remove old junk
+
+ * xfs/include/xfs_attr.h (XA_SET_*): Use correct field name.
+ (xfs_file_type): fix typo
+
+ * xfs/bsd/xfs_node.c (vattr2xfs_attr, xfs_attr2vattr): new
+ functions
+
+Sun Jan 18 12:19:26 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/bsd/Makefile.in (MODULE): use `mv -f'
+ (unload): correct symbol is `xfs_mod'
+
+ * arlad/fcache.c (writefile): don't send the length of data in the
+ stream.
+
+Sun Jan 18 23:57:11 1998 Love H-Åstrand <lha@foo.ksk.sala.se>
+
+ * xfs/bsd/bin/startarla.in: a startscript, using autoconf.
+
+ * xfs/bsd/xfs_dev.c(xfs_devclose): Make sure we dont unmount a
+ not mounted filesystem.
+
+Sun Jan 18 12:19:26 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/conn.c (getconnection): restructured. Make all
+ unauthenticated connections with cred == 0. Try to add an
+ unauthenticated connection at the same time as a authenticated
+ one. This is used when receiving and breaking callbacks.
+
+ * arlad/conn.h (ConnCacheEntry): add `securityclass'
+
+ * xfs/bsd/bin/mount_xfs.c: DTRT with __progname and err*
+
+ * xfs/bsd/Makefile.in (unload): use modunload
+
+ * arlad/*-subr.c: no need to specify cachedir.
+
+ * arlad/fcache.c: allow specification of cachedir
+
+ * arlad/arla.c (main): specify cachedir when calling initfcache
+
+ * Makefile.in: clean and simplify
+
+ * xfs/bsd/xfs_dev.c: use = instead of bcopy
+
+Sun Jan 18 15:14:58 CET 1998 Love H-Åstrand <lha@foo.ksk.sala.se>
+
+ * Added configure option --with-arlacachedir
+
+Sun Jan 18 01:20:45 1998 Love H-Åstrand <lha@foo.ksk.sala.se>
+
+ * arla/cafe-au-lait.c: Added new file.
+
+ * Added target install and made arla/cell.c use prefix for
+ CellServDB and ThisCell.
+
+ * xfs/bsd/xfs_dev.c(xfs_uninstall_device): Fixed unload bug for
+ net|open-bsd
+
+ * xfs/bsd/xfs_vfs_ops.c: Fixed kernel panic for net|openbsd,
+ it may work now. Tried to fix it for freebsd too.
+
+Thu Jan 15 23:24:52 1998 Magnus Holmberg <mho@stacken.kth.se>
+
+ * xfs/openbsd2.3/xfs_vnodeops.c: Fixed arguments to vnode
+ functions to match new vfs.
+
+Thu Jan 15 06:10:37 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: test for symorder. use xfs/bsd
+
+ * xfs/bsd: new unified bsd xfs-module
+
+Thu Jan 15 01:14:35 1998 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * xfs/openbsd/xfs_vnodeops.c: Added use of XFS_ANONYMOUSID when we
+ dont have a cred. Setting pag_t.pag to 0 is a bad idea, since we
+ use uid when the user doesn't have a pag...
+
+Thu Jan 15 00:52:16 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_vfsops.c: Made xfs_put_inode tell arla when an
+ inode goes inactive
+
+ * arlad/fcache.c: Hopefully more correct locking
+
+Tue Jan 13 23:10:03 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c (openfile): changed to return error and fd as
+ parameter.
+
+ * arlad/Makefile.in: use @LIB_readline@
+
+ * configure.in: stolen editline-tests from krb4
+
+ * aclocal.m4: stolen AC_FIND_FUNC_NO_LIBS from krb4
+
+ * arlad/arla.c: junked lots of old code.
+ wrote a new simple command-line mode for `-t'.
+
+ * arlad/cmcb.c (RXAFSCB_Probe, RXAFSCB_InitCallBackState,
+ RXAFSCB_CallBack): print the IP-address
+
+ * arlad/Makefile.in: renamed arla -> arlad.
+ link with sl and related libraries
+
+ * configure.in: make sure we have a working version of autoconf
+ don't create any xfs-makefiles if we have a unsupported OS
+
+1998-01-13 Per Andersson <ppan@joker.cntw.com>
+
+ * Arladaemons name changed to 'arlad' in INSTALL
+
+Tue Jan 13 19:23:10 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * Added sl and editline
+
+ * Added pag support for net/open-bsd
+
+ * Added libroken
+
+Mon Jan 12 23:12:15 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/messages.c,xfs/{linux,openbsd,freebsd}:
+ Moved to pag authentication, added set sysname,
+ added set pag in linux
+
+Mon Jan 12 00:59:55 1998 Magnus Ahltorp <magnus@dike.aladdin.se>
+
+ * xfs/linux/xfs_syscalls.c: Added set pag.
+
+Sun Jan 11 05:14:44 1998 Assar Westerlund <assar@sics.se>
+
+ * rxkad/rxk_crpt.c: resurrect bswap and conditionalize it on
+ EFF_NTOHL
+
+ * configure.in: use AC_FUNC_NTOHL
+
+ * aclocal.m4 (AC_FUNC_NTOHL): new macro
+
+ * ydr: added support for the 'multi' keyword
+
+Sun Jan 11 00:19:46 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/openbsd/xfs_locl.h: Added prototype for xfs_get_pag and
+ added som include files (removed those include files all over)
+
+ * xfs/openbsd/xfs_vfsops.c: Added the type of fs to the
+ mp->mnt_stat struct
+
+ * xfs/openbsd/xfs_syscalls.c: Added pag support
+
+ * xfs/openbsd/xdeb.h: Added XDEBSYS
+
+ * xfs/openbsd/xfs_dev.c(xfs_devclose): Lock the mointpoint when
+ freeing the xfsnodes
+
+Sat Jan 10 04:21:31 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/{bsd,linux,sunos}-subr.c (conv_dir): don't ReleaseReadLock
+
+ * arlad/fcache.c: allow reuse of the cache files
+
+ * arlad/messages.c (xfs_message_getroot): use `cm_getattr'
+
+ * arlad/inter.c (cm_getattr): return real_fid as a parameter.
+
+ * arla/thash.[ch], arla/vlstr.h: removed.
+
+ * ydr/output.c (generate_server_switch): write prototype to header
+ file.
+
+ * lwp/Makefile.in: add mips/irix
+
+ * arlad/volcache.c: clean-up:
+ cell -> int32_t
+ const-ize
+
+ * arlad/ports.c (initports): use the official IANA names and
+ enable the code.
+
+ * arlad/{linux,sunos,bsd}-subr.c (write_dirent): const-ize
+
+ * arlad/conn.c: all cells are int32_t
+
+ * arlad/cell.c: all cells are int32_t
+
+ * arlad/cmcb.c: clean-up
+
+ * arlad/adir.c (afs_lookup): return int. removed old code.
+ clean-up.
+
+ * lwp/Makefile.in: fix ranlib
+
+ * arlad/cell.c: restructured a tiny bit and added some (void)
+
+ * arlad/fcache.c (getroot): return error code. changed all callers.
+
+ * arlad/kernel.c: `struct fd_set' should be `fd_set'
+
+ * include/config.h.in: removed
+
+ * xfs/openbsd2.3/xfs_vfsops.c (xfs_mount): replaced VOP_UNLOCK by
+ vput
+
+ * xfs/openbsd/xfs_vfsops.c (xfs_mount): do vput instead of
+ VOP_UNLOCK.
+
+Fri Jan 9 21:32:54 1998 Assar Westerlund <assar@sics.se>
+
+ * configure.in: test for header files used by fs
+
+Fri Jan 9 20:55:05 1998 Robert Burgess <rb@bobby.stacken.kth.se>
+
+ * appl/fs.{c,h}: added
+
+Fri Jan 9 18:29:28 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs/*/xfs/xfs_node.h: define xfs_attr
+
+ * xfs/linux/xfs/attr.h: xfs_attr must be a type and not a struct.
+
+ * bin/umount_xfs.c: does not work. replaced with the
+ openbsd-version.
+
+ * arlad/kernel.c: new file with generic kernel interface code.
+
+ * arlad/{bsd,sunos,linux}-subr.c: OS-specific functions
+
+ * arlad/messages.c: new file with the generic message code.
+
+ * conf/CellServDB: A recent version.
+
+Fri Jan 9 17:23:08 1998 Love H-Astrand <lha@ksk.sala.se>
+
+ * Added milko/aefs: Added Äckligt fs, and cleaned up
+
+ * configure: Removed
+
+Fri Jan 9 17:25:21 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/linux-messages.c: getattr and creds fixed
+
+Fri Jan 9 13:53:50 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * xfs/openbsd: cleanup
+
+ * xfs/openbsd: add flags to free_all_xfs_nodes to allow forced unmount
+
+Fri Jan 9 12:17:20 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * Made the definite move of mount_xfs and other binaries into
+ xfs/@sys/bin
+
+Fri Jan 9 05:23:13 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/adir.c: Moved pointer dereference to after initialization
+ of the pointer
+
+1998-01-08 Per Andersson <ppan@joker.cntw.com>
+
+ * Added very preliminary installation instructions in ./INSTALL
+
+Thu Jan 8 11:05:40 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/fbuf.c: Truncate file before close
+
+ * arlad/inter.c, arlad/fcache.c: Made cm_lookup handle EACCES
+
+Thu Jan 8 03:28:55 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/fcache.c: changed getfile and getattr to return an error
+ code. fixed all callers.
+
+ * lwp/preempt.c: ifdef SA_NODEFER
+
+ * ydr/lex.l: always print error messages with `error_message'.
+ use global `filename'.
+ be careful when setting `filename' from cpp-lines
+
+ * ydr/types.h: add TINOUT
+
+ * ydr/parse.y: add INOUT and int
+
+ * ydr/output.c (encode_symbol): add default catch-all.
+ add handling of INOUT.
+ rename `result' -> `_result'
+
+ * ydr/lex.l: add INOUT
+
+ * rxdef/Makefile.in (CLIENTLIB, SERVERLIB): run ranlib.
+ (clean): remove more files.
+
+ * rx/rx_queue.h: renamed _Q() to _RX_QUEUE(): it conflicts with _Q
+ from <ctype.h>
+
+ * configure, include/config.h.in: regenerated
+
+ * configure.in: remove rxgen
+
+ * rxdef/Makefile.in: add more file types to ydr rule
+
+ * lwp/preempt.c, lwp/iomgr.c: use RETSIGTYPE
+
+ * arlad/volcache.c: use `u_int32_t' for volumes.
+
+ * arlad/fcache.c (writefile): fix sprintf call.
+
+ * configure.in: add AC_TYPE_SIGNAL
+
+ * arlad/msg.c: removed
+
+Wed Jan 7 19:54:57 1998 Love H-Astrand <lha@ksk.sala.se>
+
+ * arlad/*.xg, arlad/common.h: Removed them, then live in rxdef/ now
+
+Wed Jan 7 10:00:25 1998 Magnus Ahltorp <magnus@dike.aladdin.se>
+
+ * xfs/linux/Makefile: removed
+
+ * xfs/linux/Makefile.in: Added
+
+Wed Jan 7 07:40:02 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * xfs: mount_xfs and umount_xfs moved from openbsd to xfs/bin
+
+ * xfs/bin: new mount_xfs with argument parsing and correct syntax
+
+Wed Jan 7 05:31:16 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * xfs/openbsd/mount_xfs.c: mount_xfs mow mounts with fstype "xfs"
+ and not from command-line
+
+Tue Jan 6 07:03:38 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * appl/vos.c: new command-interface for vos
+
+Tue Jan 6 05:22:13 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/inter.c(cm_setattr): Using error from writeattr()
+
+ * arlad/fcache.c(writeattr): Using the error we got back from
+ RXAFSStoreStatus()
+
+ * xfs/openbsd/Makefile.in: Added -e to modload
+
+Tue Jan 6 05:06:40 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/adir.c: Added @sys support
+
+ * arlad/linux-messages.c: Added putdata, putattr, create,
+ pioctl. Cleaned up a lot.
+
+ * xfs/linux/xfs_syscalls.c: First real version
+
+ * xfs/linux/xfs_inodeops.c: Added open, read, readdir, readlink,
+ followlink
+
+ * xfs/linux/xfs_dev.c: Added xfs_message_wakeup_data
+
+Tue Jan 6 04:16:53 1998 Artur Grabowski <art@squit.stacken.kth.se>
+
+ * fixed xfs/openbsd/umount_xfs and compilation problems with mount
+ and umount
+
+Mon Jan 5 17:30:41 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/openbsd/mod.c: Dont need the diffence between net and open,
+ use modload -e
+
+ * arlad/fcache.c: Fixed bug that made arla write the old length of
+ the file
+
+ * xfs/openbsd/xfs_node.c: Fixed long filename, and added a one
+ entry cache for them.
+
+ * xfs/openbsd/xfs_dev.c: Added some really ugly workarounds for
+ differences between *BSD
+
+Mon Jan 5 05:10:41 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/openbsd/mount_xfs.c: More errorchecking and removed compat
+ junk
+
+Sun Jan 4 22:30:37 1998 Love Hörnquist-Åstrand <lha@stacken.kth.se>
+
+ * */*/*: Removed all (?) reference to u_long cred and started to
+ use pag_t cred. Dont know how much vill break.
+
+ * xfs/openbsd/xfs/xfs_message.h: added xfs_cred and pag_t
+
+Sat Jan 3 21:51:56 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_syscalls.c: Added
+
+ * xfs/linux/xfs_inodeops.c: Released inode after use
+
+Sat Jan 3 20:24:37 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_cache.c: Added
+
+ * xfs/linux/xfs_node.c: Added cache purging in
+ free_all_xfs_nodes()
+
+ * xfs/linux/xfs_common.h: Cleaned up and changed syntax for xfs_free
+
+ * xfs/linux/xfs_common.c, xfs/linux/xfs_dev.c,
+ xfs/linux/xfs_node.c: Changed syntax for xfs_free
+
+ * xfs/linux/xfs_inodeops.c, xfs/linux/xfs_message.c: Changed to xfs_cache
+
+ * xfs/linux/xfs_vfsops.c: Added xfs_put_inode
+
+Sat Jan 3 08:37:08 1998 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/bsd-messages.c(xfs_message_create): New function
+
+ * arlad/inter.c(cm_close): Fixed flags semantics
+
+ * arlad/fcache.c(writefile): Fix AFSStoreStatus mask
+
+ * xfs/openbsd/xfs/xfs_message.h: Added flag to struct
+ xfs_message_putdata, so we know what to do.
+
+ * arlad/bsd-messages.c: Implemented xfs_message_putdata()
+
+ * xfs/openbsd/xfs_vnodeops.c(xfs_close, xfs_fsync): Added writesupport
+
+Sat Jan 3 05:27:51 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs_message.c: merge in changes from ../openbsd
+
+ * xfs_vnodeops.c (xfs_read): panic if cache vnode == NULL
+
+ * arlad/bsd-messages.c (xfs_message_getnode,xfs_message_getattr):
+ mask XFS_DATA_MASK from `msg.node.tokens'
+
+Sat Jan 3 00:55:46 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/inter.c: Changed cm_getattr to check for the correct rights
+
+ * xfs/linux/xfs_inodeops.c: Fixed return value from xfs_lookup
+
+Fri Jan 2 23:34:22 1998 Love Hörnquist-Åstrand <e96_lho@e.kth.se>
+
+ * xfs/openbsd/xfs_message.c(xfs_message_invalidnode): Fixed tokens
+ in xfsnode
+
+Fri Jan 2 20:46:03 1998 Assar Westerlund <assar@sics.se>
+
+ * xfs_vnodeops.c: mrege in changes from ../openbsd
+
+ * arlad/bsd-messages.c (vattr2afsstorestatus): remove mask
+
+Fri Jan 2 20:47:20 1998 Love Hörnquist-Åstrand <e96_lho@e.kth.se>
+
+ * xfs/openbsd/xfs_vnodeops.c: Fixed xfs_write()
+
+ * arlad/bsd-messages.c: Added vattr2afsstorestatus() and cleaned up
+
+ * arlad/arla_local.h: Added vattr2afsstorestatus() defines
+
+Fri Jan 2 12:47:20 1998 Love Hörnquist-Åstrand <e96_lho@e.kth.se>
+
+ * xfs/openbsd/xfs_vnodeops.c: putattr support working when ATTR
+ not opened RW
+
+ * arlad/inter.c (cm_setattr): Return error message if writeattr fail
+
+ * arlad/fcache.h: Fixed writeattr call
+
+ * arlad/fcache.c: Adding support for chmod
+
+ * arlad/arla_local.h: Added {fs,vldb}.cs.c to get prototypes,
+ and fixed the error that was discoved
+
+Fri Jan 2 04:27:06 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/cmcb.c (RXAFSCB_CallBack): handle the case of there not
+ being enough callbacks.
+
+Fri Jan 2 03:42:43 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * arlad/linux-messages.c: Made getnode and getroot work
+
+ * xfs/linux/xfs_inodeops.c: Added xfs_lookup
+
+ * xfs/linux/xfs_message.c: Fixed inode number bug
+
+Thu Jan 1 22:53:15 1998 Assar Westerlund <assar@sics.se>
+
+ * rx/Makefile.in: removed all xdr*
+
+ * rx/rx_misc.c: remove xdr.h and use malloc/free instead of
+ mem_alloc/mem_free
+
+ * ydr/Makefile.in: bsd-make compatible
+
+Thu Jan 1 19:13:40 1998 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_dev.c: Fixed some inits.
+
+Thu Jan 1 17:31:08 1998 Assar Westerlund <assar@sics.se>
+
+ * arlad/arla.c (main): fix call to conv_dir
+
+Wed Dec 31 18:17:15 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * milko/ss2fs/file.c: Bugfixes, not done
+
+ * milko/mutil/dirpage.c: Moved to here
+
+ * milko/mutil/fdrxop.c: Added file
+
+Wed Dec 31 13:11:01 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * milko/ss2fs/ss2dir.c: Added file
+
+Wed Dec 31 00:30:07 1997 Assar Westerlund <assar@sics.se>
+
+ * xfs/xfs_message.h (xfs_message_wakeup_data): added
+
+ * xfs_dev.c (xfs_message_wakeup_data): copied from ../openbsd
+
+ * Makefile.in: removed duplicate ydr
+
+ * rx/rx_pkt.c (rxi_ReadPcket): use a sensible length test.
+
+ * rx/rx_null.h: prototypize
+ rxnull_New{Server,Client}SecurityObject
+
+ * xfs/xfs_message.h (xfs_message_pioctl): add `outsize' add some
+ prototypes
+
+ * arlad/cred.h: only include <des.h> and <krb.h> iff KERBEROS
+
+ * arlad/conn.c (getconnection): ifdef KERBEROS for krbdata
+
+ * arlad/bsd-messages.c (xfs_message_pioctl): (VIOCSETTOK,
+ VIOCUNLOG): ifdef KERBEROS
+
+ * arlad/arla.c (get_cred): ifdef KERBEROS.
+
+ * arlad/Makefile.in: use autoconf'd RXKAD_LIBS
+
+ * configure.in: set RXKAD_LIBS
+
+ * util/fnameutil.c (dirname): return "." for local files.
+
+ * ydr/output.c (init_generate): include the same set of headers in
+ all generated .c-files.
+
+ * lwp/Makefile.in: separate cpu vs OS definitions
+
+Tue Dec 30 22:08:55 1997 Magnus Ahltorp <map@lroken.stacken.kth.se>
+
+ * xfs/linux/xfs_inodeops.c: Added
+
+ * xfs/linux/xfs_node.c: Inode values now based on xfs_node
+ pointer. Some more functions ported.
+
+ * xfs/linux/xfs_message.c: Initial linux port
+
+Tue Dec 30 21:11:01 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * milko/ss2fs/file.c: Added even more junk
+
+ * rxdef/Makefile.in: Removed that common.h link, using -I
+
+Mon Dec 29 17:23:25 1997 Assar Westerlund <assar@sics.se>
+
+ * util/fnameutil.c (dirname): new function
+
+Fri Dec 26 22:54:12 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * configure.in: Added ufs01fs & co
+
+ * milko/ss2fs: Added
+
+ * milko/ufs01fs: Added
+
+ * milko: Cleaned up and started to migrate in ss2fs
+
+Wed Dec 24 03:25:51 1997 Magnus Ahltorp <map@hefaistos.abc.se>
+
+ * xfs/linux: Added nfs like allocation of inodes
+
+ * xfs/linux/xfs/attr.h, arlad/linux-messages.c: Added xfs_attr
+
+Mon Dec 22 12:38:26 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * ydr/lex.l: We now recognise {u_,}int{16,32}_t
+
+Sun Dec 21 10:30:42 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * Makefile.in: Added rxdef
+
+Fri Dec 19 05:08:24 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/openbsd/xfs_dev.c: Added wakedup_data function in xfs end
+
+ * arlad/fcache.c: Added sysname
+
+ * xfs/openbsd/xfs/xfs_message.h: Added wakedup_data function and
+ struct
+
+ * xfs/openbsd/xfs_syscalls.c: Started adding of sysname
+
+ * arlad/volcache.c: Added VOLCACHEADDDYNAMIC
+
+Wed Dec 17 08:39:02 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * TODO: Fixed getcwd() ?
+
+ * arlad/bsd-messages.c: Added error checking and fixed error msg
+
+ * arlad/arla_local.h: Added debuggingmacro
+
+ * Makefile.in: Changed to ydr
+
+ * arlad/fcache.c: getcwd & ydr
+
+ * arlad/bsd-messages.c: Working pwd, there is still bugs in
+ there...
+
+1997-12-10 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * arlad/inter.c: Made tokens support more sane
+
+ * xfs/openbsd/*: Added support for NetBSD
+
+Tue Dec 9 03:38:52 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/inter.c: cm_open(): Not quite ready yet.
+
+ * arlad/inter.c: Added test för datausedp;
+
+Mon Dec 8 20:52:09 1997 Assar Westerlund <assar@sics.se>
+
+ * arlad/bsd-messages.c (afsstatus2vattr): use VNOVAL
+ (xfs_message_getnode): cleanup
+
+ * configure.in: test for more header files.
+
+ * ydr: new version.
+
+Thu Dec 4 14:51:05 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * TODO: Added vos and rxdef
+
+Sat Nov 29 02:18:57 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * appl/vos.c: listvol does not work, yet
+
+ * appl/vos.c: Almost working, just lacking CellServDB parsing
+
+ * appl/arlalib.c: Added more junk
+
+Fri Nov 28 17:00:17 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * appl/vos.c: More working code
+
+ * appl/arlalib.c: First version
+
+Tue Nov 25 20:45:20 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * rxgen/main.c: Fixed configure test for CPP
+
+Wed Nov 19 13:03:58 1997 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * milko/dirpage.c: Added
+
+ * milko/inodedb.c: Added
+
+ * milko/diskio.c: Made more usable
+
+Tue Nov 18 23:54:11 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * configure.in: Fixed bug that turned off kerberos default
+
+Tue Nov 18 06:13:17 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * Added support for different include and lib paths in kerberos.
+ Clean up configure.
+
+Sat Nov 15 15:31:24 1997 Love H-Astrand <lha@jenny.ksk.sala.se>
+
+ * lwp/lwp.c: Added support for posix signals, added RCSID()
+
+ * lwp/preempt.c: Added support for posix signals
+
+ * lwp/lwp.h: Added check for posix-signals
+
+ * acconfig.h: Added check for posix-signals
+
+ * configure.in: Added check for sys/ioccom.h
+
+ * arla/Makefile.in: Added @CFLAGS@
+
+Sat Nov 15 11:41:33 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * configure.in, Makefile.in: Added support for conditional
+ build of rxkad
+
+Fri Nov 14 09:36:20 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * configure.in: Cleaned up and added messages
+
+Fri Nov 14 08:54:26 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * configure.in: Added support for --with-krb4.
+
+ * acconfig.h: Removed superfluous #define KERBEROS
+
+Thu Nov 13 05:42:30 1997 Artur Grabowski <art@stacken.kth.se>
+
+ * xfs/openbsd/xfs_node.c: Fixed the removing of vnodes from the
+ list of all vnodes in the fs. :)
+
+Wed Nov 12 22:00:28 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/volcache.c: Added gc
+
+Wed Nov 12 04:40:46 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/conn.c: Added gc
+
+ * arlad/bsd-messages.c: Added check for invalid rpc calls
+
+ * arlad/cred.c: Made a cred_remove() remove all connection in the
+ connection cache too.
+
+ * arlad/bsd-messages.c: Cleaned up the code.
+
+ * arlad/conn.c: Added support to remove a connection from the
+ connection cache, we still dont gc.
+
+ * util/hash.c: Added hashtabcleantab()
+
+Mon Nov 10 01:11:38 1997 Assar Westerlund <assar@sics.se>
+
+ * added lots of copyrights.
+
+ * lib/rxkad: updated
+
+ * acconfig.h: -DKERBEROS
+
+ * xfs/freebsd/xfs/xfs_message.h: added pioctl
+
+Sun Nov 9 19:16:25 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/cred.h: Cleanup, added support to clean tokens based on
+ uid.
+
+ * xfs/openbsd/xfs_syscalls.c: Added support for VIOCUNLOG
+
+ * xfs/openbsd/xfs/xfs_message.h: Added uid to struct
+ xfs_message_pioctl, in some magic way we should support PAGs too.
+
+ * arlad/bsd-messages.c: Added support for VIOCUNLOG
+
+Sun Nov 9 17:25:27 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * xfs/openbsd/xfs/xfs_message.h: Added xfs_message_pioctl
+
+ * xfs/openbsd/kafs.h: Added
+
+ * xfs/openbsd/xfs_syscalls.c: Added VIOCSETTOK
+
+ * arlad/bsd-messages.c: Working cred
+
+Sat Nov 8 19:58:46 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/cred.c: Added putkrb4cred()
+
+Fri Nov 7 20:57:09 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * rx/rx_user.c: Removed rx warning messages
+
+ * arlad/conn.c: After 24h hacking, working rxkad !
+
+Thu Nov 6 22:28:33 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/arla.c: Added kerberos support, not working, yet.
+
+ * arlad/Makefile.in: Added support for rxkad, assume krb4 world
+
+ * Makefile.in: Added rxkad
+
+ * arlad/cred.h: Fixed.
+
+ * arlad/cred.c: Fixed some more
+
+Thu Nov 6 18:05:59 1997 Artur Grabowski <art@bobby.stacken.kth.se>
+
+ * arlad/bsd-kernel.c: fixed exit on error from device.
+
+Thu Nov 6 17:34:27 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/arla.c: Init credcache
+
+ * arlad/conn.c: Added support for rxkad
+
+Thu Nov 6 17:34:27 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * arlad/cred.h: Made it buildable and spell checked.
+
+ * arlad/cred.c: Made it buildable.
+
+Thu Nov 6 17:31:09 1997 Artur Grabowski <art@bobby.stacken.kth.se>
+
+ * xfs/openbsd/xfs_vfsops.c: fixed the releasing of vnodes.
+
+ * xfs/openbsd/xfs_vnodeops.c: cleaned up.
+
+ * Learned to use ChangeLog. (hopefully)
+
+Thu Nov 6 02:38:20 1997 Love Hornquist-Astrand <lha@foo.ksk.sala.se>
+
+ * arlad/cred.h: Added
+
+ * arlad/cred.c: Added
+
+ * milko/diskio.c: Started to read the inode instead of makeing up data.
+
+ * milko/build_a_inode.c: more features
+
+Tue Nov 4 03:03:03 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * rxkad/*.[ch]: s/int32/int32_t/g
+
+ * configure.in: Added some more tests.
+
+ * rxkad/Makefile.in: Living in a krb4 work, assar will shot me.
+
+ * aclocal.m4: Added checks for types (int32 & co)
+
+Sun Nov 2 17:24:22 1997 Assar Westerlund <assar@sics.se>
+
+ * xfs_vnodeops.c (xfs_data_valid): set `msg.tokens'
+ (xfs_lookup): copy name to `msg' correctly
+
+ * xfs_vfsops.c (xfs_root): set `msg.cred'
+
+ * xfs_node.c (free_xfs_node): reset data
+
+ * xfs_message.c (xfs_message_installdata): unlock the cache vnode
+ after lookup
+
+ * xfs_dev.c (xfs_message_rpc): copy back from temporary memory to
+ `message'
+
+ * arlad/inter.c (cm_open): set enty->tokens correctly
+
+ * arlad/Makefile.in: use `test -h' instead of `test -L'
+
+Sat Nov 1 02:06:18 1997 Love H-Astrand <lha@ksk.sala.se>
+
+ * arlad/Makefile.in: Fixed so we can build in another directory
+ then src
+
+ * aclocal.m4: Added
+
+Thu Oct 30 01:46:51 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * configure.in: Fixed linux include stuff
+
+ * arlad/linux*: Added linux specific files
+
+ * configure.in: Added milko.
+
+ * milko/Makefile.in: Fixed for merging into arla-tree
+
+Wed Oct 29 22:52:15 1997 Assar Westerlund <assar@sics.se>
+
+ * arlad/volcache.c (findvolname, findvolid): check for getvolname
+ returning an error
+
+Sun Oct 26 17:59:11 1997 Magnus Ahltorp <map@wakko.stacken.kth.se>
+
+ * xfs/linux/xfs_common.c: Linuxified
+
+Sat Oct 25 19:01:45 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * lwp/lwp.c: Ansified
+
+ * lwp/iomgr.c: Ansified
+
+Sat Oct 25 17:05:21 1997 Assar Westerlund <assar@sics.se>
+
+ * xfs/freebsd: use mp->mnt_vnodelist instead of xfsp->nodes
+
+ * xfs/freebsd/Makefile.in: new autoconf'ed makefile
+
+Sat Oct 25 15:53:31 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * lwp/Makefile.in: Grrrr gcc -E är dum.
+
+ * Makefile.in: Added rx and rxgenbuilding
+
+ * lwp/Makefine.in: Added support for multippel processors
+
+Sat Oct 25 15:48:38 1997 Assar Westerlund <assar@sics.se>
+
+ * xfs/linux/xfs: new files
+
+Sat Oct 25 14:23:45 1997 Love Hornquist-Astrand <lha@stacken.kth.se>
+
+ * configure.in: Removed some configure.in's
+
+Sat Oct 25 14:15:11 1997 Magnus Ahltorp <map@wakko.stacken.kth.se>
+
+ * xfs/linux/xfs_dev.c: Merged in the real file and adopted it to
+ Linux
+
+Sat Oct 25 05:46:29 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/xfs_dev.c: Moved device stuff here
+
+ * xfs/linux/super.c: Working filesystem
+
+Fri Oct 24 18:33:36 1997 Magnus Ahltorp <map@stacken.kth.se>
+
+ * xfs/linux/super.c: Almost working empty filesystem.
+
+Fri Oct 24 17:20:40 1997 Assar Westerlund <assar@sics.se>
+
+ * rx/Makefile.in: replaced junk makefile with a new one
+
+ * arlad/Makefile.in: much clean-up and improvements
+
+ * Makefile.in: much clean-up and improvements
+
+ * configure.in: much clean-up and improvements
+
+ * xfs/Makefile.in: stub makefile
+
+ * lib/util/ip.[ch]: resurrected
+
+ * lib/lwp/q.c: resurrected
+
+
diff --git a/usr.sbin/afs/src/HACKING b/usr.sbin/afs/src/HACKING
new file mode 100644
index 00000000000..50367e549ff
--- /dev/null
+++ b/usr.sbin/afs/src/HACKING
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $Id: HACKING,v 1.1 2000/09/11 14:40:28 art Exp $
+#
+# * Configuration stuff
+#
+# Arla uses GNU autoconf for configuration. If you want to modify
+# configure.in (or acconfig.h) you'll need autoconf 2.13 and automake
+# 1.4 or later. To re-create the configuration files, run these
+# commands:
+
+aclocal -I cf
+autoheader
+autoconf
+
+# aclocal creates a file `aclocal.m4' from all the tests in the `cf'
+# directory. autoheader will create `include/config.h.in' and autoconf
+# the `configure' script.
diff --git a/usr.sbin/afs/src/LIESMICH b/usr.sbin/afs/src/LIESMICH
new file mode 100644
index 00000000000..092cbc8c31e
--- /dev/null
+++ b/usr.sbin/afs/src/LIESMICH
@@ -0,0 +1,195 @@
+LIESMICH für arla-0.34 ($Name: $)
+$Id: LIESMICH,v 1.1 2000/09/11 14:40:29 art Exp $
+
+Für alle, die zuerst 'mal lieber auf Deutsch lesen. Die Lektüre von
+README wird aber trotzdem empfohlen.
+
+1. Was ist Arla?
+
+Arla ist eine freie Implementation des AFS Cacheverwalters.
+
+2. Wo finde ich diese Datei?
+
+Diese Datei ist enthalten in
+ftp://ftp.stacken.kth.se/pub/arla/arla-0.34.tar.gz
+(d.h. /afs/stacken.kth.se/ftp/pub/arla/arla-0.34.tar.gz).
+
+3. Was ist AFS?
+
+AFS ist ein weltweit verbreitetes Dateisystem. Lesen Sie
+<http://www.transarc.com/afs/transarc.com/public/www/Product/AFS/FAQ/faq.html>
+für mehr Informationen.
+
+4. Was ist in Arla enthalten?
+
+Kerneltreiber (mit verschieden guter Unterstützung)
+für folgende Operativsysteme:
+
+- FreeBSD 3.x, 4.,x und 5.x
+- OpenBSD 2.2-2.7
+- NetBSD 1.2, 1.3, 1.4 und 1.5
+- Linux 2.0.x, 2.1.x, 2.2.x, 2.3.x, 2.4.x
+- SunOS 4
+- Solaris 2.5, 2.6, 7 und 8
+- AIX 4.x
+- IRIX 6.x
+- Digital Unix 4.0, 5.0 (OSF/1)
+- Darwin (MacOS DP3)
+
+Nur auf Anwenderniveau:
+- Ultrix 4.4
+
+Der Cacheverwalter (arlad) der sowohl im "user-level" als auch mit
+den Kerneltreibern angewendet werden kann. Im "user-level" Modus
+ist er sehr gut zu portieren und ist (mit den Cygwin32 Bibliotheken)
+sogar unter Windows NT gefahren.
+
+Einige einfache Programme (amon, fs, klog, tokens, vos, udebug, und pts).
+
+Einen experimentellen AFS server, Milko genannt.
+
+5. Auf welchem Niveau befindet sich Arla?
+
+Dies ist noch vor den berühmten griechischen Buchstaben.
+
+Doch funktioniert das meiste. Dateien können gelesen und geschrieben
+werden, mit oder ohne Identitätskontrolle. Es ist noch nicht so stabil
+und schnell wie wir wünschen. Der Cache funktioniert nur für ganze
+Dateien, aber das reicht wohl fürs Erste.
+
+6. Was brauche ich um Arla anzuwenden?
+
+Mit einem der oben genannten Systeme sollte es Ihnen möglich sein das
+AFS Dateiensystem zu montieren (und vielleicht auch Ihrem Kernel einen
+Panic zu verpassen).
+
+Die Anwenderprogramme dürften auf fast jedem Unixdialekt compilieren
+und funktionieren.
+
+Wenn sie die Identitätskontrolle anwenden wollen brauchen Sie auch
+Kerberos V4. Wir empfehlen wärmstens die von
+<http://www.pdc.kth.se/kth-krb/>.
+
+Ab OpenBSD 2.3 ist kth-krb schon dabei. Doch muß die Zeile 'AFS=yes'
+in /etc/mk.conf hinzugefügt und libkafs und afslog neu compiliert
+werden (sind unter /usr/src/kerberosIV/{kafs,afslog} zu finden).
+
+Hier haben wir einen Abschnitt über MIT-Kerberos (eigentlich nur für
+unsere amerikanischen Anwender) ausgelassen (ist im README zu lesen).
+
+Falls Sie kein Kerberos Anwender sind sollte es Ihnen möglich sein die
+Funktion zu testen, doch wo ist dann der Witz der Sache? Wir testen
+Arla auch nicht ohne Kerberos.
+
+7. Wie installiere ich Arla?
+
+Das steht in der Datei INSTALL (bis jetzt nur auf Englisch).
+
+8. Was mache ich wenn ich einen Fehler finde?
+
+Schreiben Sie einen so detaillierten Rapport wie möglich (auf Englisch)
+an <arla-drinkers@stacken.kth.se>. Patches sind auch willkommen.
+
+Falls Sie einen "Bug" finden und keine Ahnung haben was da denn falsch
+gelaufen sein könnte, versuchen Sie es noch einmal mit
+`arlad -n -z --debug=almost-all' und legen sie den produzierten Text
+dem Email bei. Sie können auch das Debugniveau eines laufenden arlad
+(als root) mit `fs arladebug <debug-level>' ändern. Das gleiche gilt
+für den Kerneltreiber mit `fs xfsdebug <debug-level>'. Das Ergebnis
+landet in Ihrem syslog (/var/log/messages, /var/adm/messages oder so
+ähnlich).
+
+Falls arlad abstürzt, wenden sie bitte gdb an um dem core mit `bt'
+einen Backtrace zu entziehen. Auch können Werte der Variabeln nützlich
+sein. Falls kein core produziert wird kann arlad unter gdb (mit -n -z)
+gestartet werden.
+
+Im Falle eines Kernelabsturtzes, versuchen Sie mit den Mitteln Ihres
+Betriebssystems einen Dump zu erzeugen und den Debugger
+anzuwenden. Die Dokumentation Ihres Betriebssystems hilft Ihnen
+hoffentlich weiter.
+
+Ohne diese Information können wir Ihnen nicht helfen.
+
+9. Wie kann ich die Menge der Debuginformation steuern?
+
+Sowohl arlad als auch xfs (der Kerneltreiber) haben Variabeln mit
+denen die Art der Debuginformation (und damit die Menge) kontrolliert
+werden kann.
+
+Arlad anwendet `--debug' und nach dem Start `fs arladebug'. Für
+den Kerneltreiber wendet man `fs xfsdebug' an.
+
+10. Wie schwierig ist es Arla auf ein neues Betriebssystem zu
+ portieren?
+
+Nicht sehr. Im user-level sind die Unterschiede gering zwischen
+verschiedenen Betriebssystemen. Für den Kernel kann man mit einem
+anderen ähnlichen System (in xfs/SYSTEM) anfangen. Falls Sie sich für
+so etwas interessieren oder sogar Arla auf einem oben nicht genannten
+Betriebssystem laufen haben, schicken Sie ein Email an
+<arla-drinkers@stacken.kth.se>.
+
+11. Bekannte Probleme.
+
+OpenBSD hat auf einigen Architekturen Probleme mit mmap. In diesen
+Fällen kann auf configure mit `--disable-mmap' ausgewichen werden. Wir
+haben das auf sun4m bemerkt.
+
+Falls Sie Probleme mit dem Cache bemerken, entfernen sie den cache
+(normalerweise `/usr/arla/cache') und starten Sie dann arlad neu.
+
+Mit Digitals cc Program brauchen Sie wahrscheinlich -std1 (d.h. CC als
+"cc -std1" definieren wenn sie configure anwenden).
+
+Solaris hat keine Memcpy-funktion im Kernel, gcc generiert aber
+manchmal trotzdem solche Anrufe. Falls das passiert, verwenden sie
+entweder Suns Compilator oder schreiben Sie die memcpy Anrufe m.H. von
+bcopy um.
+
+12. Wie kann ich behilflich sein?
+
+Mit Quellkod. Bugreports und Patches sind immer willkommen.
+
+13. Gibt es Emaillisten?
+
+arla-drinkers@stacken.kth.se Allgemeine Diskussion.
+arla-announce@stacken.kth.se Nur Neuigkeiten.
+
+Senden Sie eine Email an <LIST>-request@stacken.kth.se um Mitglied zu
+werden.
+
+14. Gibt es eine Webpage?
+
+Ja, http://www.stacken.kth.se/projekt/arla/
+
+15. Wie ist die Lage mit Copyrights für Arla?
+
+lwp und rx haben Copyright von IBM. Wir danken Derrick J Brashear
+<shadow@dementia.org> und Jim Doyle <jrd@bu.edu> die es möglich
+gemacht haben sie anzuwenden.
+
+Die rxkad Implementation ist von Björn Grönvall <bg@sics.se> und ist auch
+in kth-krb enthalten.
+
+Editline ist von Simmule Turner und Rich Salz.
+
+Der Kod für den nicht angeschlossenen Modus ist von Wuwei Shen.
+
+Der Kod um all das zusammenzuhalten ist von uns selbst.
+
+<arla-drinkers@stacken.kth.se>
+
+16. Was ist seit * passiert?
+
+Steht in NEWS und ChangeLog.
+
+17. Und was bedeutet `arla'?
+
+- Arla ist ein schwedisches Wort für `früh'. Der größte Teil von
+Arla wurde am frühen Morgen verfaßt.
+
+- Arla is auch der Name des grössten schwedischen Produzenten für
+Milchprodukte. Sie produzieren unter anderem `fil' (schwed. filmjölk
+ist eine Art Sauermilch). `Fil' ist auch das schwedische Wort für
+Datei.
diff --git a/usr.sbin/afs/src/Makefile.in b/usr.sbin/afs/src/Makefile.in
new file mode 100644
index 00000000000..d29b747d62f
--- /dev/null
+++ b/usr.sbin/afs/src/Makefile.in
@@ -0,0 +1,52 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:29 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+SUBDIRS = include lib util ydr lwp rx rxdef lib/ko lib/bufdir \
+ @RXKAD@ xfs arlad conf appl tests doc
+
+all:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+clean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+realclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+distclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+mostlyclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+install:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+uninstall:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+Makefile: Makefile.in config.status
+ $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
+
+.PHONY: all clean realclean distclean mostlyclean install uninstall
diff --git a/usr.sbin/afs/src/acconfig.h b/usr.sbin/afs/src/acconfig.h
new file mode 100644
index 00000000000..7bc6a5ca8c6
--- /dev/null
+++ b/usr.sbin/afs/src/acconfig.h
@@ -0,0 +1,36 @@
+@BOTTOM@
+
+/* RCSID */
+#define RCSID(msg) \
+static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
+
+/* Maximum values on all known systems */
+#define MaxHostNameLen (64+4)
+#define MaxPathLen (1024+4)
+
+/* we always have stds.h */
+#define HAVE_STDS_H
+
+/*
+ * Defintions that are ugly but needed to get all the symbols used
+ */
+
+/*
+ * Defining this enables lots of useful (and used) extensions on
+ * glibc-based systems such as Linux
+ */
+
+#define _GNU_SOURCE
+
+/*
+ * Defining this enables us to get the definition of `sigset_t' and
+ * other importatnt definitions on Solaris.
+ */
+
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
diff --git a/usr.sbin/afs/src/acinclude.m4 b/usr.sbin/afs/src/acinclude.m4
new file mode 100644
index 00000000000..aa7af6adae6
--- /dev/null
+++ b/usr.sbin/afs/src/acinclude.m4
@@ -0,0 +1,9 @@
+dnl $Id: acinclude.m4,v 1.1 2000/09/11 14:40:29 art Exp $
+dnl
+dnl Only put things that for some reason can't live in the `cf'
+dnl directory in this file.
+dnl
+
+dnl $xId: misc.m4,v 1.1 1997/12/14 15:59:04 joda Exp $
+dnl
+define(upcase,`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`)dnl
diff --git a/usr.sbin/afs/src/appl/Makefile.in b/usr.sbin/afs/src/appl/Makefile.in
new file mode 100644
index 00000000000..4bc98c0e020
--- /dev/null
+++ b/usr.sbin/afs/src/appl/Makefile.in
@@ -0,0 +1,49 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:30 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+SUBDIRS = lib @APPL_SUBDIRS@ pts udebug vos bos
+
+all:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+clean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+realclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+distclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+mostlyclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+install:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+uninstall:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+Makefile: Makefile.in ../config.status
+ cd .. ; CONFIG_FILES=appl/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all clean realclean distclean mostlyclean install uninstall
diff --git a/usr.sbin/afs/src/appl/afsmgr/Makefile.in b/usr.sbin/afs/src/appl/afsmgr/Makefile.in
new file mode 100644
index 00000000000..aac547858f7
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsmgr/Makefile.in
@@ -0,0 +1,97 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:33 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = afsaclmgr
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES =
+DEFINES =
+REALCFLAGS =
+RXKAD_LIBS =
+KERNEL_INCLUDE =
+LIB_tgetent =
+READLINE_lib =
+KAFS_LIBS =
+LIBS =
+LIBDEPENDS =
+PROGS = afsaclmgr
+UDEBUG_SRCS =
+SRCS =
+UDEBUG_OBJS =
+HDRS =
+
+GUILE_GTK = @GUILE_GTK@
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+afsaclmgr: afsaclmgr.in
+ sed -e "s!%GUILE_GTK%!$(GUILE_GTK)!" $(srcdir)/afsaclmgr.in > $@
+ chmod +x $@
+
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+udebug: $(UDEBUG_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(UDEBUG_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/afsmgr/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/afsmgr/afsaclmgr.in b/usr.sbin/afs/src/appl/afsmgr/afsaclmgr.in
new file mode 100644
index 00000000000..e65ee2e8f82
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsmgr/afsaclmgr.in
@@ -0,0 +1,314 @@
+#! %GUILE_GTK% -s
+-*-scheme-*-
+!#
+
+;;
+;; A AFS ACL/PTS manager
+;;
+
+;;
+;; $Id: afsaclmgr.in,v 1.1 2000/09/11 14:40:33 art Exp $
+;;
+
+(use-modules (gtk gtk))
+(use-modules (ice-9 popen))
+
+;;
+;;
+;;
+
+(define name-window #f)
+
+(define (acl-new-name path main-window)
+ (if name-window
+ (gtk-widget-destroy name-window))
+ (set! name-window (gtk-window-new 'dialog))
+ (let ((main-panel (gtk-vbox-new #f 3))
+ (text-box (gtk-entry-new-with-max-length 40))
+ (ok-button (gtk-button-new-with-label "Ok"))
+ (cancel-button (gtk-button-new-with-label "Cancel")))
+ (define (name-close-window)
+ (gtk-widget-destroy name-window)
+ (set! name-window #f))
+
+ (gtk-window-set-title name-window "New Name")
+ (gtk-container-add name-window main-panel)
+
+ (gtk-signal-connect cancel-button
+ "clicked"
+ name-close-window)
+
+ (gtk-signal-connect ok-button
+ "clicked"
+ (lambda ()
+ (let ((user (gtk-entry-get-text text-box)))
+ (name-close-window)
+ (display path) (newline)
+ (display user) (newline)
+ (acl-magic-window path user "rl" main-window))))
+
+ (gtk-box-pack-start main-panel text-box #t #t 0)
+ (gtk-box-pack-start main-panel ok-button #f #f 0)
+ (gtk-box-pack-end main-panel cancel-button #f #f 0)
+
+ (gtk-widget-show-all name-window)))
+
+;;
+;;
+;;
+
+(define acl-titles #("Name" "R" "L" "I" "D" "W" "K" "A"))
+
+(define acl-window #f)
+
+(define (acl-magic-window path user rights main-window)
+ (if acl-window
+ (gtk-widget-destroy acl-window))
+ (set! acl-window (gtk-window-new 'dialog))
+ (let ((main-panel (gtk-vbox-new #f 3))
+ (button-panel (gtk-hbox-new #f 2))
+ (status-bar (gtk-statusbar-new))
+ (acl-foo (gtk-clist-new-with-titles acl-titles))
+ (ok-button (gtk-button-new-with-label "Ok"))
+ (cancel-button (gtk-button-new-with-label "Cancel")))
+ (define (clicked-func row col event)
+ (let ((user '(#f))
+ (ace '(#f)))
+ (gtk-clist-get-text acl-foo row 0 user)
+ (gtk-clist-get-text acl-foo row col ace)
+ (cond ((eq? col 0) '())
+ ((string=? (car ace) "X") (set! ace (list " ")))
+ ((string=? (car ace) " ") (set! ace (list "X")))
+ (else (die-in-horror)))
+ (gtk-clist-set-text acl-foo row col (car ace))))
+ (define (map-acl-to-X user clist acl)
+ (gtk-clist-append
+ acl-foo
+ (cons user
+ (map
+ (lambda (x)
+ (if (member x (string->list acl))
+ "X"
+ " "))
+ (string->list "rlidwka")))))
+ (define (acl-close-window)
+ (gtk-widget-destroy acl-window)
+ (set! acl-window #f))
+
+ (gtk-window-set-title acl-window "ACL")
+ (gtk-container-add acl-window main-panel)
+
+ (for-each
+ (lambda (col size)
+ (gtk-clist-set-column-width acl-foo col size))
+ '(0 1 2 3 4 5 6 7)
+ '(200 10 10 10 10 10 10 10))
+
+
+ (map-acl-to-X user acl-foo rights)
+
+ (gtk-signal-connect
+ acl-foo
+ "unselect-row"
+ clicked-func)
+
+ (gtk-signal-connect acl-foo "select-row" clicked-func)
+
+ (gtk-box-pack-start button-panel ok-button #t #t 0)
+ (gtk-box-pack-end button-panel cancel-button #t #t 0)
+
+ (gtk-signal-connect
+ ok-button "clicked"
+ (lambda ()
+ (define (get-text col text)
+ (let ((dummy '(#f)))
+ (gtk-clist-get-text acl-foo 0 col dummy)
+ (if (and (car dummy)
+ (string=? (car dummy) "X"))
+ text
+ "")))
+ (begin
+ (acl-set
+ path
+ user
+ (let ((ace (apply string
+ (map get-text
+ '(1 2 3 4 5 6 7)
+ '("r" "l" "i" "d" "w" "k" "a")))))
+ (if (string=? ace "")
+ "none"
+ ace))))
+ (acl-update-clist path main-window)
+ (acl-close-window)))
+
+ (gtk-signal-connect cancel-button
+ "clicked"
+ acl-close-window)
+
+
+ (gtk-box-pack-start main-panel acl-foo #t #t 0)
+ (gtk-box-pack-start main-panel button-panel #t #t 0)
+ (gtk-box-pack-end main-panel status-bar #f #f 0)
+
+ (gtk-widget-show-all acl-window)))
+
+
+(define acl-error-rx (make-regexp "^fs: Invalid argument; it is possible"))
+(define acl-split-rx (make-regexp "^ +([^ ]+) +([rlidwka]+)"))
+
+;;
+;; Get acl for given path.
+;;
+;; If path not in afs, #f is returned
+;;
+
+(define (read-to-char port ch)
+ (let ((next (read-char port)))
+ (cond ((eof-object? next) next)
+ ((equal? next ch) "")
+ (else (string next (read-to-char port ch))))))
+
+(define (acl-list path)
+ (define (parse-output pipe)
+ (let ((first (read-to-char pipe #\newline)))
+ (if (or (eof-object? first)
+ (regexp-exec acl-error-rx first))
+ #f
+ (let ((second (read-to-char pipe #\newline)))
+ (if (not (eof-object? first))
+ (let foo ((str (read-to-char pipe #\newline)))
+ (if (eof-object? str)
+ '()
+ (let* ((acl (regexp-exec acl-split-rx str))
+ (arg1 (vector-ref acl 2))
+ (arg2 (vector-ref acl 3))
+ (bar1 (substring str (car arg1) (cdr arg1)))
+ (bar2 (substring str (car arg2) (cdr arg2))))
+ (cons (list bar1 bar2)
+ (foo (read-to-char pipe #\newline)))))))))))
+ (let* ((pipe (open-input-pipe
+ (string "/usr/afsws/bin/fs la " path " 2>&1")))
+ (ret (parse-output pipe)))
+ (close-port pipe)
+ ret))
+
+;;
+;; Set `acl´ for `name´ on `path´.
+;;
+
+(define (acl-set path name acl)
+ (define (parse-output pipe)
+ (let ((first (read-to-char pipe #\newline)))
+ (not (or (eof-object? first)
+ (regexp-exec acl-error-rx first)))))
+ (let* ((pipe (open-input-pipe
+ (string "/usr/afsws/bin/fs sa " path " "
+ name " " acl " 2>&1")))
+ (ret (parse-output pipe)))
+ (close-port pipe)
+ ret))
+
+;;
+;; Update the `clist' for to reflect `path'
+;;
+
+(define (acl-update-clist path clist)
+ (let ((acl (acl-list path)))
+ (if acl
+ (begin
+ (gtk-clist-clear clist)
+ (for-each
+ (lambda (x)
+ (gtk-clist-append
+ clist
+ (vector (car x) (cadr x))))
+ acl)))))
+
+;;
+;; Main
+;;
+
+(define user-selected #f)
+(define acl-selected #f)
+
+(define main-titles #("user" "acl"))
+
+(let ((window (gtk-window-new 'toplevel))
+ (main-panel (gtk-vbox-new #f 2))
+ (button-panel (gtk-hbox-new #f 5))
+ (scrolled-window (gtk-scrolled-window-new))
+ (clist (gtk-clist-new-with-titles main-titles))
+ (add-button (gtk-button-new-with-label "Add"))
+ (modify-button (gtk-button-new-with-label "Modify"))
+ (refresh-button (gtk-button-new-with-label "Refresh"))
+ (delete-button (gtk-button-new-with-label "Delete"))
+ (quit-button (gtk-button-new-with-label "Quit")))
+
+ (define (reset-selection)
+ (set! user-selected #f)
+ (set! acl-selected #f))
+
+
+ (gtk-window-set-title window "AFS ACLManager")
+
+ (gtk-widget-set-usize clist 400 200)
+ (gtk-clist-set-column-width clist 0 200)
+
+ (acl-update-clist "." clist)
+
+ (gtk-container-add window main-panel)
+
+ (gtk-box-pack-start main-panel scrolled-window #t #t 0)
+ (gtk-box-pack-end main-panel button-panel #f #f 0)
+
+ (gtk-box-pack-start button-panel add-button #t #t 0)
+ (gtk-box-pack-start button-panel modify-button #t #t 0)
+ (gtk-box-pack-start button-panel refresh-button #t #t 0)
+ (gtk-box-pack-start button-panel delete-button #t #t 0)
+ (gtk-box-pack-end button-panel quit-button #t #t 0)
+
+ (gtk-container-add scrolled-window clist)
+
+ (gtk-signal-connect delete-button "clicked"
+ (lambda ()
+ (if user-selected
+ (begin
+ (acl-set "." user-selected "none")
+ (reset-selection)
+ (acl-update-clist "." clist)))))
+
+ (gtk-signal-connect refresh-button "clicked"
+ (lambda ()
+ (acl-update-clist "." clist)))
+
+ (gtk-signal-connect clist "select-row"
+ (lambda (row col event)
+ (let ((dummy '(#f)))
+ (gtk-clist-get-text clist row 0 dummy)
+ (set! user-selected (car dummy))
+ (gtk-clist-get-text clist row 1 dummy)
+ (set! acl-selected (car dummy)))))
+
+ (gtk-signal-connect add-button "clicked"
+ (lambda ()
+ (acl-new-name "." clist)))
+
+ (gtk-signal-connect modify-button "clicked"
+ (lambda ()
+ (if user-selected
+ (begin
+ (acl-magic-window
+ "." user-selected acl-selected
+ clist)
+ (reset-selection)
+ (acl-update-clist "." clist)))))
+
+ (gtk-signal-connect quit-button "clicked"
+ (lambda ()
+ (gtk-widget-destroy window)
+ (quit)))
+
+ (gtk-widget-show-all window)
+ (gtk-standalone-main window))
+
+(quit)
diff --git a/usr.sbin/afs/src/appl/afsutils/Makefile.in b/usr.sbin/afs/src/appl/afsutils/Makefile.in
new file mode 100644
index 00000000000..ed5960e7772
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/Makefile.in
@@ -0,0 +1,166 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:33 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+mandir = @mandir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = aklog klog tokens unlog up
+MANPAGES = tokens.1 unlog.1 aklog.1 klog.1
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I$(srcdir)/../../lib/cmd \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../lib/cmd -lcmd \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/roken \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = aklog klog sys tokens unlog up
+AKLOG_SRCS = aklog.c
+KLOG_SRCS = klog.c
+SYS_SRCS = sys.c
+TOKENS_SRCS = tokens.c
+UNLOG_SRCS = unlog.c
+UP_SRCS = up.c
+SRCS = $(AKLOG_SRCS) \
+ $(KLOG_SRCS) \
+ $(SYS_SRCS) \
+ $(TOKENS_SRCS) \
+ $(UNLOG_SRCS) \
+ $(UP_SRCS)
+AKLOG_OBJS = aklog.o
+KLOG_OBJS = klog.o
+SYS_OBJS = sys.o
+TOKENS_OBJS = tokens.o
+UNLOG_OBJS = unlog.o
+UP_OBJS = up.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir) ; \
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir) ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+
+aklog: $(AKLOG_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(AKLOG_OBJS) $(LIBS)
+
+klog: $(KLOG_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(KLOG_OBJS) $(LIBS)
+
+sys: $(SYS_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(SYS_OBJS) $(LIBS)
+
+tokens: $(TOKENS_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(TOKENS_OBJS) $(LIBS)
+
+unlog: $(UNLOG_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(UNLOG_OBJS) $(LIBS)
+
+up: $(UP_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(UP_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/afsutils/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/afsutils/README.afsutils b/usr.sbin/afs/src/appl/afsutils/README.afsutils
new file mode 100644
index 00000000000..00321f13db8
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/README.afsutils
@@ -0,0 +1,61 @@
+These are re-implementations of the traditional user utilities 'klog',
+'tokens', and 'unlog' from AFS. The code is mostly written from scratch
+with the appropriate bits of glue and insight taken from KTH-KRB.
+
+The main goal in writing these programs was to achieve maximum
+compatibility with the original programs by the same name (minus any truly
+stupid bugs or security holes). In many cases, I believe users will find
+themselves in a heterogeneous environment where Arla will be used
+alongside the official AFS client on different machines, but with the same
+shared user accounts.
+
+It is not reasonable to expect such users to be forced to learn different
+syntax for the same commands on both platforms. Indeed, even small
+semantic differences quickly annoy users, and mercilessly cause scripts to
+break.
+
+While it is possible to do much of what these programs can do by using
+script wrappers on the programs from KTH-KRB, it is not possible to get
+100% of the features.
+
+These features include:
+
+[ klog ]
+ - looking up the correct ViceId for the stored token, so that the
+ output of 'tokens' is more meaningful for those with access to
+ several AFS accounts
+
+ - a new -timeout option, so that authentication won't hang forever
+ if the network is down
+
+ - support for the -pipe and -setpag options from the original klog
+
+[ tokens ]
+ - the return code of the program can be used from a script to find
+ out if any (valid) tokens are present
+
+ - the output format is identical to the original 'tokens' by
+ default
+
+[ unlog ]
+ - you can now unlog yourself from one or more cells only, leaving
+ the rest of your tokens intact
+
+
+appl/klog.c
+appl/klog.h
+appl/tokens.c
+appl/tokens.h
+appl/unlog.c
+appl/unlog.h
+doc/README.afsutils
+doc/TODO.afsutils
+man/klog.1
+man/tokens.1
+man/unlog.1
+
+
+Enjoy,
+
+Chris Wing
+wingc@engin.umich.edu
diff --git a/usr.sbin/afs/src/appl/afsutils/TODO.afsutils b/usr.sbin/afs/src/appl/afsutils/TODO.afsutils
new file mode 100644
index 00000000000..54abb86bad8
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/TODO.afsutils
@@ -0,0 +1,23 @@
+[general]
+ - man pages don't format right on >80 column terminal
+
+ - check to see if these programs break any scripts written for
+ official AFS utilities
+
+ - (tokens, unlog) Is 128 bytes always enough to hold a token?
+
+[klog]
+ - deal properly with cells where the realm name differs from the
+ name of cell
+
+ - make -servers option actually try to get a TGT/token from
+ listed servers
+
+ ( fixing the above problems will require hacking in the Kerberos
+ library, not Arla )
+
+ - it might be nice to make klog still work even if the AFS
+ client isn't there (and still get a Kerberos TGT, etc.)
+
+[unlog]
+ - new pioctl to remove one token at a time?
diff --git a/usr.sbin/afs/src/appl/afsutils/aklog.1 b/usr.sbin/afs/src/appl/afsutils/aklog.1
new file mode 100644
index 00000000000..ffd5a20cf34
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/aklog.1
@@ -0,0 +1,87 @@
+.\" $Id: aklog.1,v 1.1 2000/09/11 14:40:33 art Exp $
+.Dd Aug 06, 2000
+.Dt AKLOG SECTION
+.Os Arla
+.Sh NAME
+.Nm aklog
+.Nd
+Fetches tokens from your ticket-file.
+.Sh SYNOPSIS
+.Nm
+.Op Fl cell Ar <cell name>
+.Op Fl createuser Ar <cell name>
+.Op Fl debug Ar <cell name>
+.Op Fl help Ar <cell name>
+.Op Fl hosts Ar <cell name>
+.Op Fl krbrealm Ar <cell name>
+.Op Fl noprdb Ar <cell name>
+.Op Fl path Ar <cell name>
+.Op Fl quiet Ar <cell name>
+.Op Fl unlog Ar <cell name>
+.Op Fl version Ar <cell name>
+.Op Fl zsubs Ar <cell name>
+.Ar <cell or path>
+.Sh DESCRIPTION
+Supported options:
+.Bl -tag -width Ds
+.It Fl cell Ar <cell name>
+cell to authenticate to
+.It Fl createuser Ar <cell name>
+create PTS user in remote cell
+.It Fl debug Ar <cell name>
+print debugging information
+.It Fl help Ar <cell name>
+print help
+.It Fl hosts Ar <cell name>
+print host address information (unimplemented)
+.It Fl krbrealm Ar <cell name>
+kerberos realm for cell
+.It Fl noprdb Ar <cell name>
+don't try to determine AFS ID
+.It Fl path Ar <cell name>
+AFS path to authenticate to
+.It Fl quiet Ar <cell name>
+fail silently if no ticket cache
+.It Fl unlog Ar <cell name>
+discard tokens
+.It Fl version Ar <cell name>
+print version
+.It Fl zsubs Ar <cell name>
+update zephyr subscriptions (unimplemented)
+.El
+.Sh ENVIRONMENT
+.Nm
+will look at the enviroment varibel
+.Ev AFSCELL
+for the default cellname.
+If will also use
+.Ev HOME
+to find the file ~/.TheseCells
+.Sh FILES
+.Nm
+will look for the files
+.Pa ThisCell ,
+.Pa TheseCells ,
+and
+.Pa CellServDB
+in the directories
+.Pa /usr/arla/etc
+and
+.Pa /usr/vice/etc
+.Sh DIAGNOSTICS
+For debugging you can use the flag
+.Ar Fl d
+for debugging.
+.Pp
+.Bd -literal
+datan# aklog -d
+aklog: get_afs_id for lha in cell e.kth.se using pts-db
+aklog: get_afs_id for lha@e.kth.se in cell stacken.kth.se using pts-db
+aklog: get_afs_id for lha@e.kth.se in cell nada.kth.se using pts-db
+aklog: get_afs_id for lha@e.kth.se in cell pdc.kth.se using pts-db
+.Ed
+.Sh SEE ALSO
+.Xr tokens 1 ,
+.Xr unlog 1 ,
+.Xr aklog ,
+.Xr klog 1
diff --git a/usr.sbin/afs/src/appl/afsutils/aklog.c b/usr.sbin/afs/src/appl/afsutils/aklog.c
new file mode 100644
index 00000000000..1e31fb94a86
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/aklog.c
@@ -0,0 +1,315 @@
+/*
+ * 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.
+ */
+
+/*
+ * allbery@ece.cmu.edu 2000-05-13
+ * Lifted from kth-krb, bodged parts of klog.c into it. The result is that
+ * it gets the AFS token for your Kerberos principal, not your user ID.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: aklog.c,v 1.1 2000/09/11 14:40:33 art Exp $");
+
+#include "appl_locl.h"
+#include "kafs.h"
+
+#ifndef KERBEROS
+
+int
+main(int argc, char **argv)
+{
+ errx (1, "Kerberos support isn't compiled in");
+ return 1;
+}
+
+#else
+
+#ifndef HAVE_KRB_AFSLOG_UID
+static int
+krb_afslog_uid (const char *cell, const char *realm, uid_t afsid)
+{
+ return k_afslog_uid(cell, realm, afsid);
+}
+#endif
+
+static int debug = 0;
+
+static void __attribute__((format (printf, 1, 2)))
+DEBUG (const char *fmt, ...)
+{
+ va_list ap;
+ if (debug) {
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+ }
+}
+
+static char krb_name[ANAME_SZ];
+static char krb_instance[INST_SZ];
+static char krb_realm[REALM_SZ];
+static char name_inst[ANAME_SZ+INST_SZ+2];
+static char *arg_cell = NULL;
+static int arg_createuser = 0;
+static int arg_debug = 0;
+static int arg_help = 0;
+static int arg_hosts = 0;
+static char *arg_realm = NULL;
+static int arg_noprdb = 0;
+static char *arg_path = NULL;
+static int arg_quiet = 0;
+static int arg_unlog = 0;
+static int arg_version = 0;
+static int arg_zsubs = 0;
+
+/*
+ * Figure out the AFS ID of a user name
+ */
+
+static u_int32_t
+get_afs_id (const char *username, const char *cell, int dontuseafs_p)
+{
+ int32_t returned_id;
+ int ret;
+ struct passwd *pwd;
+
+ DEBUG ("get_afs_id for %s in cell %s %susing pts-db", username, cell,
+ dontuseafs_p ? "not ": "");
+
+ if (dontuseafs_p == 0) {
+ ret = arlalib_get_viceid (username, cell, &returned_id);
+ if (ret == 0)
+ return returned_id;
+ DEBUG ("arlalib_get_viceid failed with: %s (%d).",
+ koerr_gettext(ret), ret);
+ }
+
+ /*
+ * If we failed to talk to any server, try various stupid means of
+ * guessing the AFS ID
+ */
+
+ pwd = getpwnam(krb_name);
+ if(pwd == NULL) {
+ returned_id = getuid();
+ warnx ("Couldn't get AFS ID for %s%s, using current UID (%d)",
+ username, cell, returned_id);
+ } else {
+ returned_id = pwd->pw_uid;
+ warnx ("Couldn't get AFS ID for %s@%s, using %d "
+ "from /etc/passwd",
+ username, cell, returned_id);
+ }
+ return (returned_id);
+}
+
+static int
+createuser (const char *username, const char *remotecell)
+{
+ char cmd[1024];
+
+ snprintf (cmd, sizeof(cmd), "pts createuser %s -cell %s",
+ username, remotecell);
+ DEBUG("Executing %s", cmd);
+ return system(cmd);
+}
+
+static void
+get_tokens (const char **cells,
+ const char *localcell,
+ const char *realm)
+{
+ u_int32_t afsid;
+ int rc;
+
+ while (*cells) {
+ char *username;
+ /*
+ * If the `*cells' isn't local cell, try the username
+ * `username@localcell'
+ */
+ if (strcasecmp (localcell, *cells) != 0)
+ asprintf (&username, "%s@%s", name_inst, localcell);
+ else
+ username = name_inst;
+
+ afsid = get_afs_id (username, *cells, arg_noprdb);
+ rc = krb_afslog_uid(*cells, realm, afsid);
+ if (rc)
+ warnx ("Failed getting tokens for cell %s.", *cells);
+
+ /* If not localcell, create user (if wanted) and free username) */
+ if (name_inst != username) {
+ if (arg_createuser && createuser(username, *cells))
+ warnx ("Failed creating user in cell %s", *cells);
+ free (username);
+ }
+ cells++;
+ }
+}
+
+
+struct getargs args[] = {
+ {"cell", 0, arg_string, &arg_cell,
+ "cell to authenticate to", "cell name", arg_optional},
+ {"createuser", 0, arg_flag, &arg_createuser,
+ "create PTS user in remote cell", NULL, arg_optional},
+ {"debug", 0, arg_flag, &arg_debug,
+ "print debugging information", NULL, arg_optional},
+ {"help", 0, arg_flag, &arg_help,
+ "print help", NULL, arg_optional},
+ {"hosts", 0, arg_flag, &arg_hosts,
+ "print host address information (unimplemented)", NULL, arg_optional},
+ {"krbrealm", 0, arg_string, &arg_realm,
+ "kerberos realm for cell", "kerberos realm", arg_optional},
+ {"noprdb", 0, arg_flag, &arg_noprdb,
+ "don't try to determine AFS ID", NULL, arg_optional},
+ {"path", 0, arg_string, &arg_path,
+ "AFS path to authenticate to", "path", arg_optional},
+ {"quiet", 0, arg_flag, &arg_quiet,
+ "fail silently if no ticket cache", NULL, arg_optional},
+ {"unlog", 0, arg_flag, &arg_unlog,
+ "discard tokens", NULL, arg_optional},
+ {"version", 0, arg_flag, &arg_version,
+ "print version", NULL, arg_optional},
+ {"zsubs", 0, arg_flag, &arg_zsubs,
+ "update zephyr subscriptions (unimplemented)"},
+ {NULL, 0, arg_end, NULL, NULL},
+};
+
+static void
+usage (int exit_code)
+{
+ arg_printusage (args, NULL, "<cell or path>", ARG_AFSSTYLE|ARG_USEFIRST);
+ exit (exit_code);
+}
+
+/*
+ *
+ */
+
+int
+main (int argc, char **argv)
+{
+ const char *cell = NULL;
+ char cellbuf[64];
+ const char *localcell;
+ int optind = 0;
+ int rc;
+
+ rc = getarg(args, argc, argv, &optind, ARG_AFSSTYLE|ARG_USEFIRST);
+ if(rc && *argv[optind] == '-') {
+ warnx ("Bad argument: %s", argv[optind]);
+ usage (1);
+ }
+
+ if(arg_help)
+ usage (0);
+
+ if(arg_version)
+ errx (0, "part of %s-%s", PACKAGE, VERSION);
+
+ if (arg_debug)
+ debug = 1;
+
+ if(!k_hasafs())
+ errx (1, "AFS support is not loaded.");
+
+ ports_init();
+ cell_init(0);
+ localcell = cell_getthiscell();
+
+ /*
+ * get the realm and name of the user
+ */
+
+ if (krb_get_default_principal(krb_name, krb_instance, krb_realm)) {
+ if (!arg_quiet)
+ warnx ("Could not even figure out who you are");
+ exit (1);
+ }
+ snprintf(name_inst, sizeof(name_inst),
+ "%s%s%s",
+ krb_name, *krb_instance ? "." : "", krb_instance);
+
+ if (arg_cell)
+ cell = cell_expand_cell(arg_cell);
+
+ if (arg_unlog) {
+ rc = k_unlog();
+ exit (rc);
+ }
+ if (arg_hosts)
+ warnx ("Argument -hosts is not implemented.");
+ if (arg_zsubs)
+ warnx ("Argument -zsubs is not implemented.");
+
+ if (rc && argv[optind]) {
+ if (strcmp(argv[optind], ".") == 0
+ || strcmp(argv[optind], "..") == 0
+ || strchr(argv[optind], '/')) {
+ DEBUG ("I guess that \"%s\" is a filename.", argv[optind]);
+ arg_path = argv[optind];
+ } else {
+ cell = cell_expand_cell(argv[optind]);
+ DEBUG ("I guess that %s is cell %s.", argv[optind], cell);
+ }
+ }
+
+ if (arg_path) {
+ if (k_afs_cell_of_file(arg_path, cellbuf, sizeof(cellbuf)))
+ errx (1, "No cell found for file \"%s\".", arg_path);
+ cell = cellbuf;
+ }
+
+ /*
+ * If not given an argument, use TheseCells to fetch tokens,
+ * If given argument, do as the user tells us.
+ */
+
+ if (cell == NULL && arg_realm == NULL && arg_path == NULL) {
+ const char **cells = cell_thesecells ();
+ get_tokens (cells, localcell, NULL);
+ } else {
+ const char *cells[2] = { NULL, NULL };
+ cells[0] = cell;
+ get_tokens (cells, localcell, arg_realm);
+ }
+
+ return 0;
+}
+
+#endif /* KERBEROS */
diff --git a/usr.sbin/afs/src/appl/afsutils/klog.1 b/usr.sbin/afs/src/appl/afsutils/klog.1
new file mode 100644
index 00000000000..b47351fb3ad
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/klog.1
@@ -0,0 +1,196 @@
+.\" $Id: klog.1,v 1.1 2000/09/11 14:40:33 art Exp $
+.\"
+.Dd July 7, 1999
+.Dt KLOG 1
+.Os "The Arla Project"
+.Sh NAME
+.Nm klog
+.Nd
+A program to get AFS tokens and possibly other things
+.Sh SYNOPSIS
+.Nm
+.Op Fl principal Ar Kerberos principal
+.Op Fl cell Ar AFS cell
+.Op Fl lifetime Ar token lifetime in hrs:min:sec
+.Op Fl tmp
+.Op Fl setpag
+.Op Fl pipe
+.Op Fl password Ar Kerberos password
+.Op Fl realm Ar Kerberos realm (optional)
+.Op Fl servers Ar AFS kaservers to contact
+.Op Fl silent
+.Op Fl timeout Ar network timeout
+.Op Fl help
+.Op Ar user@cell
+.Sh DESCRIPTION
+The
+.Nm
+command obtains AFS tokens and possibly a Kerberos ticket granting ticket
+as well. By default it only gets an AFS token for the named principal and
+cell.
+.Pp
+This command can be invoked more than once to acquire AFS tokens in
+multiple cells. There is no way at present to write Kerberos TGTs for
+different realms into the same ticket file.
+.Pp
+If
+.Nm
+is successful in getting a token and you already have a token for the same
+cell in your current PAG, it will be overwritten by the new token. An
+existing token will not be erased if a new token cannot be acquired.
+.Pp
+You can specify part or whole of a Kerberos principal on the command line;
+for instance:
+.Pp
+.Nm
+username
+.Pp
+or
+.Nm
+username@cell.name
+.Pp
+or just
+.Nm
+@cell.name
+.Pp
+If neither is specified, the default is your current user name and the
+local AFS cell.
+.Pp
+The following flags are supported:
+.Bl -tag -width xxxx
+.It Fl principal
+Principal to get tokens for. If not specified,
+.Nm
+tries to use your user name, which is guessed from $USER or from the UID
+that
+.Nm
+is run as.
+.It Fl lifetime
+Lifetime for the Kerberos TGT and/or AFS token. This can be specified as:
+.Pp
+.Nm
+.Fl lifetime hours
+.Pp
+or
+.Nm
+.Fl lifetime hours:minutes
+.Pp
+or
+.Nm
+.Fl lifetime hours:minutes:seconds
+.Pp
+If this option is not specified, the default lifetime of 720 hours (30
+days) is used; however, the administrators of your cell may have chosen a
+lesser maximum lifetime.
+.Pp
+Please note that in Kerberos 4, only 255 discrete lifetimes are possible
+spanning the range from 5 minutes to 30 days. The lifetime that you
+specify will be rounded up to the next possible lifetime.
+.It Fl cell
+AFS cell to get tokens for. If not specified,
+.Nm
+guesses your local cell.
+.It Fl password
+You can specify the Kerberos password on the command line. This is a
+really, really, really, bad idea on most systems out there, since any user
+can use the \fBps\fP command to examine the command line of any running
+process.
+.Pp
+You should not use this option.
+.It Fl realm
+Most AFS cells are set up in such a way that the Kerberos realm name is
+the same as the cell name (except in upper case). If the name of your AFS
+cell differs from your Kerberos realm, however,
+.Nm
+may not be able to automatically fetch your tokens without specifying the
+correct realm name with this option.
+.It Fl servers
+You can list one or more kaservers to contact directly here.
+.Nm
+will attempt to contact each of them until it finds one that works.
+.It Fl timeout
+You can specify the number of seconds that
+.Nm
+will wait for a network operation to complete. (there are 3 network
+operations peformed by
+.Nm
+- the AFS ID is looked up from the dbserver, the Kerberos 4 TGT must be
+obtained, and the AFS token must be fetched.
+.Pp
+If you do not use this option,
+.Nm
+will wait forever if necessary.
+.Pp
+.It Fl silent
+This causes
+.Nm
+not to write to the standard error channel. By default, error messages are
+sent to stderr.
+.It Fl pipe
+If this flag is given, then
+.Nm
+will not write to the standard output, and will only accept a password
+written to the standard input. Error messages will still be printed to
+standard error unless the \fB-silent\fP option is also specified.
+.Pp
+Because it does not attempt to verify that the TTY is safe, this should
+only be used from scripts.
+.It Fl setpag
+Stores the AFS token in a new PAG, and then
+\fBexec()\fPs a shell. The environment variable KRBTKFILE is set to point
+to a unique name in /ticket, so that the Kerberos TGT gathered (if any) is
+written to a safe place. The shell is chosen via \fBgetpwnam()\fP called
+with the principal's name; if that fails, then \fBgetpwuid()\fP is tried
+with your current UID; if this fails,
+.Nm
+attempts to execute /bin/sh.
+.It Fl tmp
+Actually get a Kerberos TGT and writes it to /tmp (or the file specified
+in the KRBTKFILE environment variable). By default, only an AFS token is
+acquired.
+.Pp
+This is a poor choice of name, as in reality writing Kerberos tickets to
+/tmp is a bad idea and often a security risk. This name is only here for
+compatibility with other AFS implementations. (\fB-tgt\fP would have been
+a better choice of name)
+.Pp
+.It Fl help
+Prints out a help message.
+.Sh EXIT STATUS
+.Nm
+returns with exit status 0 (true) if and only if a Kerberos 4 TGT was
+successfully acquired and an AFS token was successfully stored. In all
+other cases, the return value is non-zero.
+.Pp
+It is possible to call
+.Nm
+from scripts or other programs for automated authentication with the
+.Fl pipe
+option, although discretion and caution is advised when doing
+so.
+.Sh NOTES
+By default,
+.Nm
+tries to look up your Kerberos principal in the kaserver's database to
+figure out the proper AFSId to use. As far as I know, this only affects
+the output of the \fBtokens\fP program.
+.Pp
+The minimum token lifetime is 5 minutes.
+.El
+.Sh SEE ALSO
+.Xr kauth 1 ,
+.Xr kinit 1 ,
+.Xr aklog 1 ,
+.Xr kauthd 8 ,
+.Xr kf 1 ,
+.Xr unlog 1 ,
+.Xr tokens 1
+.Sh BUGS
+The
+.Fl servers
+option only affects where the AFS ID is looked up, not
+which servers are actually contacted to get the TGT or token.
+.Pp
+.Nm
+should automatically deal with the case where the Kerberos realm is not
+the same as the AFS cell name.
diff --git a/usr.sbin/afs/src/appl/afsutils/klog.c b/usr.sbin/afs/src/appl/afsutils/klog.c
new file mode 100644
index 00000000000..9bf800b8d15
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/klog.c
@@ -0,0 +1,801 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ klog.c - a version of 'klog' for Arla
+
+ Written by Chris Wing - wingc@engin.umich.edu
+ based on examples of AFS code: pts.c (Arla) and kauth.c (KTH-KRB)
+
+ Hacked to use getarg by Love Hörnquist-Åstrand <lha@stacken.kth.se>
+
+ Hacked to use getarg and still work properly by Chris Wing
+
+ This is a reimplementation of klog from AFS. The following new features
+ have been added:
+ -timeout Number of seconds to wait for Kerberos operations
+ to finish. By default, we will wait forever.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: klog.c,v 1.1 2000/09/11 14:40:33 art Exp $");
+
+#include "appl_locl.h"
+#include "klog.h"
+#include "kafs.h"
+
+/*
+ * State variables
+ */
+
+/* Lifetime in seconds. Default token lifetime is 720 hours (30 days) */
+static int lifetime = 720 * 60 * 60;
+
+/*
+ * arguments passed to program
+ */
+
+static char *arg_principal = NULL;
+static char *arg_cell = NULL;
+static char *arg_realm = NULL;
+static char *arg_password = NULL;
+static getarg_strings arg_servers;
+static char *arg_lifetime = NULL;
+static int arg_timeout = 0;
+static int arg_pipe = 0;
+static int arg_setpag = 0;
+static int arg_silent = 0;
+static int arg_getkrbtgt = 0;
+static int arg_version = 0;
+static int arg_help = 0;
+static char *arg_kname = NULL;
+
+/* AFS ID */
+static int afsid = 0;
+
+/* Password */
+static char *password = NULL;
+
+/* Did the attempted network command time out? */
+static int timed_out = 0;
+
+#ifdef KERBEROS
+
+/* Do we have a ticket file lying around we'd like to get rid of? */
+static int have_useless_ticket_file = 0;
+
+/* Kerberos ticket file */
+static char *tkfile = NULL;
+
+#endif
+
+/* Did we get a token that will sit around unused if not destroyed? */
+static int have_useless_token = 0;
+
+/*
+ * Erase passwords from memory and remove tokens and tickets that
+ * shouldn't be left laying around.
+ */
+
+static void
+final_cleanup (void)
+{
+ /* Make sure to clear out the password in this process's memory image
+ before exiting */
+ if(password)
+ memset(password, 0, PASSWD_MAX);
+
+ /* Destroy any useless tokens that we acquired */
+ if(have_useless_token)
+ k_unlog();
+
+#ifdef KERBEROS
+ /* Destroy any temporary ticket files lying around. */
+ if(have_useless_ticket_file)
+ dest_tkt();
+#endif
+}
+
+/* Death function that erases password before exiting */
+
+void
+die (int retcode)
+{
+ final_cleanup ();
+
+ exit(retcode);
+}
+
+/* Die, print out an error message, and interpret errno
+ Remember that *err*() from roken prints out a trailing newline. */
+
+void
+diet (int retcode, char *fmt, ...)
+{
+ va_list ap;
+
+ final_cleanup ();
+
+ va_start(ap, fmt);
+ verr (retcode, fmt, ap);
+ va_end(ap);
+}
+
+/* Die and print out an error message. Do not interpret errno. */
+
+void
+dietx (int retcode, char *fmt, ...)
+{
+ va_list ap;
+
+ final_cleanup ();
+
+ va_start(ap, fmt);
+ verrx (retcode, fmt, ap);
+ va_end(ap);
+}
+
+
+/*
+ * Figure out the AFS ID of a user name
+ */
+
+int
+get_afs_id(void)
+{
+ int32_t returned_id;
+
+ arlalib_get_token_id_servers (arg_principal,
+ arg_cell,
+ arg_servers.num_strings,
+ arg_servers.strings,
+ &returned_id);
+ return returned_id;
+}
+
+#ifndef KRB_TICKET_GRANTING_TICKET
+#define KRB_TICKET_GRANTING_TICKET "krbtgt"
+#endif
+
+/* Get a Kerberos 4 TGT */
+
+int
+get_k4_ticket(void)
+{
+ int rc;
+
+ int krb_lifetime;
+
+ /* The minimum lifetime is 5 minutes */
+ if(lifetime < 5 * 60)
+ krb_lifetime = 1;
+#ifdef KERBEROS
+ else
+ krb_lifetime = krb_time_to_life(0, lifetime);
+#endif
+
+ /* If a ridiculously high lifetime is given to krb_time_to_life,
+ 0 may be returned as a result... */
+ if( (krb_lifetime > 255) || (krb_lifetime == 0) )
+ krb_lifetime = 255;
+
+#ifdef KERBEROS
+ rc = krb_get_pw_in_tkt(arg_principal, "", arg_realm,
+ KRB_TICKET_GRANTING_TICKET, arg_realm,
+ krb_lifetime, password);
+ if(rc)
+ warnx("Unable to authenticate to Kerberos: %s",
+ krb_get_err_text(rc));
+#else
+ warnx ("No kerberos included");
+ return (1);
+#endif /* KERBEROS */
+
+ return(rc);
+}
+
+
+/* Get an AFS token */
+
+int get_afs_token(void)
+{
+ int rc;
+
+ /* FIXME: This will happily store a token for one cell with the
+ name of another cell, and this makes Arla
+ misbehave :( */
+
+#ifdef KERBEROS
+#ifdef HAVE_KRB_AFSLOG_UID
+ rc = krb_afslog_uid(arg_cell, arg_realm, afsid);
+#else
+ rc = k_afslog_uid(arg_cell, arg_realm, afsid);
+#endif
+ if(rc)
+ warnx("Unable to get an AFS token: %s", krb_get_err_text(rc));
+#else
+ warnx ("Unable to get an AFS token since there is no kerberos");
+ return (1);
+#endif
+
+ return(rc);
+}
+
+
+/*
+ * Generalized machinery for performing a timeout on an arbitrary
+ * function returning an integer. Fun, eh?
+ */
+
+int
+do_timeout (int (*function)(void) )
+{
+ int pipearr[2];
+ int reader, writer;
+ pid_t pid;
+ int status;
+
+ timed_out = 0;
+
+ /* Don't bother with all this jibba jabba if we don't want to timeout */
+ if(arg_timeout == 0)
+ return (function());
+
+ if(pipe(pipearr) == -1)
+ diet (1, "do_timeout(): Can't make a pipe");
+
+ reader = pipearr[0];
+ writer = pipearr[1];
+
+ /* :) */
+ fflush(stdout);
+ fflush(stderr);
+
+ pid = fork();
+
+ if(pid == -1)
+ diet (1, "do_timeout: Can't fork");
+
+ if(pid) {
+ /* parent's thread of execution */
+
+ fd_set readfds;
+ struct timeval tv;
+ int retval;
+ int result;
+ ssize_t len;
+
+ close(writer);
+
+ /* this is how you set up a select call */
+ FD_ZERO(&readfds);
+ FD_SET(reader, &readfds);
+
+ /* Wait as many as timeout seconds. */
+ tv.tv_sec = arg_timeout;
+ tv.tv_usec = 0;
+
+ retval = select(reader+1, &readfds, NULL, NULL, &tv);
+
+ /* Kill the child process in any case */
+ kill(pid, SIGKILL);
+
+ if(!retval) {
+ timed_out = 1;
+ } else {
+ /* okay, what happened */
+
+ len = read(reader, &result, sizeof(int));
+ }
+
+ /* no matter what, we must wait on the child or else we will
+ accumulate zombies */
+ waitpid(pid, &status, 0);
+
+ /* close the other end of the pipe */
+ close(reader);
+
+ if(timed_out)
+ return(1);
+ else
+ return(result);
+
+ /* PARENT ENDS HERE */
+
+ } else {
+ /* child's thread of execution */
+ int retval;
+ ssize_t len;
+
+ close(reader);
+
+ retval = function();
+
+ len = write(writer, &retval, sizeof(int));
+
+ /* Destroy the copy of the password in the child's memory image */
+ memset(password, 0, PASSWD_MAX);
+
+ exit(0);
+
+ /* CHILD ENDS HERE */
+ }
+}
+
+/*
+ * randfilename()
+ * Return a "random" file name, for use, e.g., as a ticket file
+ * use umich compat basename of ticket.
+ */
+
+static const char *tktbasename[] = {
+ KLOG_TKT_ROOT,
+#if defined(HAVE_KRB_GET_DEFAULT_TKT_ROOT)
+ "",
+#elif defined(TKT_ROOT)
+ TKT_ROOT,
+#endif
+ NULL
+};
+
+char *
+randfilename(void)
+{
+ const char *base, **basepath;
+ char *filename;
+ int fd;
+
+ for (basepath = tktbasename; (base = *basepath) != NULL; ++basepath) {
+#if defined(HAVE_KRB_GET_DEFAULT_TKT_ROOT)
+ base = krb_get_default_tkt_root ();
+#endif
+ asprintf (&filename, "%s_%u_XXXXXX", base, (unsigned)getuid());
+ if (filename == NULL)
+ dietx (1, "out of memory");
+
+ fd = mkstemp(filename);
+ if (fd >= 0) {
+ close(fd);
+ return filename;
+ }
+ free (filename);
+ }
+ dietx (1, "could not create ticket file");
+}
+
+struct getargs args[] = {
+ { "principal", 0, arg_string, &arg_principal,
+ "principal to obtain token for",
+ "user name", arg_optional},
+ { "password", 0, arg_string, &arg_password,
+ "password to use (NOT RECOMENDED TO USE)",
+ "AFS password", arg_optional},
+ { "servers", 0, arg_strings, &arg_servers,
+ "list of servers to contact",
+ "AFS dbservers", arg_optional},
+ { "lifetime", 0, arg_string, &arg_lifetime,
+ "lifetime given in hh[:mm[:ss]]",
+ "hh:mm:ss", arg_optional},
+ { "pipe", 0, arg_flag, &arg_pipe,
+ "read password from stdin and close stdout",
+ NULL, arg_optional},
+ { "timeout", 0, arg_integer, &arg_timeout,
+ "network timeout given in seconds (default is forever)",
+ "seconds", arg_optional},
+ { "setpag", 0, arg_flag, &arg_setpag,
+ "store token in new PAG and spawn a shell",
+ NULL, arg_optional},
+ { "silent", 0, arg_flag, &arg_silent,
+ "close stderr",
+ NULL, arg_optional},
+ { "tmp", 0, arg_flag, &arg_getkrbtgt,
+ "get a Kerberos TGT (possibly overwriting any current one)",
+ NULL, arg_optional},
+ { "cell", 0, arg_string, &arg_cell,
+ "cell where to obtain token",
+ "cell name", arg_optional},
+ { "realm", 0, arg_string, &arg_realm,
+ "Kerberos realm to get TGT in (default same as AFS cell)",
+ "Kerberos realm", arg_optional},
+ { "help", 0, arg_flag, &arg_help, "help",
+ NULL, arg_optional},
+ { "version", 0, arg_flag, &arg_version, "print version",
+ NULL, arg_optional},
+ { NULL, 0, arg_generic_string, &arg_kname, "Kerberos identity",
+ "user@cell", arg_optional},
+ { NULL, 0, arg_end, NULL, NULL }
+};
+
+/*
+ *
+ */
+
+static void
+do_help (int exitval)
+{
+ arg_printusage(args, NULL, NULL, ARG_AFSSTYLE);
+ exit(exitval);
+}
+
+/*
+ * If we dont have kerberos support, bail out.
+ */
+
+#ifndef KERBEROS
+
+int
+main(int argc, char **argv)
+{
+ errx (1, "Kerberos support isn't compiled in");
+ return 1;
+}
+#else
+
+/*
+ * The core of this evil
+ */
+
+int
+main(int argc, char **argv)
+{
+ char prompt[PW_PROMPT_MAX];
+ int rc;
+ int optind = 0;
+
+ char pwbuf[PASSWD_MAX];
+
+ /* for Rx - Arlalib stuff */
+ ports_init();
+ cell_init(0); /* XXX */
+
+ rc = getarg(args, argc, argv, &optind, ARG_AFSSTYLE);
+ if(rc) {
+ warnx ("Bad argument: %s", argv[optind]);
+ do_help(1);
+ }
+
+ if (arg_help)
+ do_help(0);
+
+ if (arg_version)
+ dietx (0, "part of %s-%s", PACKAGE, VERSION);
+
+ if (arg_password)
+ warnx ("WARNING: The use of -password is STRONGLY DISCOURAGED");
+
+ /* manually parse a string of the form user@cell, we used to use
+ kname_parse(), but this no longer works properly as of krb4-1.0 */
+ if (arg_kname) {
+ char *at = strchr(arg_kname, '@');
+ char *tmp_principal = arg_kname;
+ char *tmp_cell;
+
+ if(at) {
+ *at = '\0';
+
+ tmp_principal = arg_kname;
+ at++;
+ tmp_cell = at;
+
+ if(*tmp_cell != '\0')
+ arg_cell = tmp_cell;
+ }
+
+ if(*tmp_principal != '\0')
+ arg_principal = tmp_principal;
+ }
+
+ if (arg_lifetime) {
+ int h = 0, m = 0, s = 0;
+ int matched;
+
+ matched = sscanf(arg_lifetime, "%u:%u:%u", &h, &m, &s);
+
+ if(matched < 1 || matched > 3)
+ dietx (1, "Bad argument for -lifetime: %s", arg_lifetime);
+
+ lifetime = h * 3600 + m * 60 + s;
+ }
+
+ /* Simplest way to prevent any output from this command */
+ if(arg_pipe)
+ freopen("/dev/null", "r+", stdout);
+
+ /* Simplest way to prevent any output from this command */
+ if(arg_silent)
+ freopen("/dev/null", "r+", stderr);
+
+ if(!k_hasafs())
+ dietx (1, "Hmm, your machine doesn't seem to have kernel support "
+ "for AFS");
+
+ /* Try to get a new PAG, but don't abort if we can't */
+ if(arg_setpag) {
+ if (k_setpag() == -1)
+ warnx ("Couldn't get new PAG");
+ }
+
+ /* Figure out the AFS cell to use */
+ if (arg_cell == NULL) {
+ arg_cell = (char *)cell_getthiscell();
+
+ if (arg_cell == NULL)
+ dietx (1, "Can't find local cell!");
+ }
+
+ /* FIXME: Figure out a way to automatically deal with setups where the
+ Kerberos realm is not just an uppercase version of the
+ AFS cell
+
+ if libkafs exported kafs_realm_of_cell(), we could use that.
+
+ libkafs now does, but that isn't enough. kafs_realm_of_cell
+ is currently implemented by looking up the first entry in
+ CellServDB for the given cell, doing an inverse DNS lookup,
+ and then using the domain name of the resulting host name as
+ the Kerberos realm (subject to remapping via krb.realms)
+
+ This is bad, because (a) it requires a resolver call, which
+ can hang for an arbitrary amount of time, and (b) it
+ requires playing silly games with krb.realms and hoping that
+ the inverse DNS entry for the first server for a cell will
+ not change.
+
+ libkafs should recognize a file called "CellRealms", or
+ something like that, which yields a correct mapping between
+ a given AFS cell and a Kerberos realm; otherwise it should
+ just uppercase the cell name and be done with it.
+
+ For now, give the user the option to specify a specific
+ realm to use via -realm. */
+
+ if(arg_realm == NULL) {
+ char *p;
+
+ arg_realm = estrdup(arg_cell);
+
+ /* convert name to upper case */
+ p = arg_realm;
+ while(*p != '\0') {
+ *p = toupper(*p);
+ p++;
+ }
+ }
+
+ /* Figure out the Kerberos principal we are going to use */
+ if (arg_principal == NULL) {
+ struct passwd *pwd = getpwuid (getuid ());
+
+ if (pwd == NULL)
+ dietx (1, "Could not get default principal");
+
+ arg_principal = pwd->pw_name;
+ }
+
+ /* Figure out the db server we are going to contact */
+ if (arg_servers.num_strings == 0) {
+ arg_servers.strings = emalloc (sizeof(char *));
+ arg_servers.strings[0] = (char *)cell_findnamedbbyname (arg_cell);
+
+ if(arg_servers.strings[0] == NULL)
+ dietx (1, "Can't find any db server for cell %s", arg_cell);
+
+ arg_servers.num_strings = 1;
+ }
+
+ /*
+ * Get the password
+ */
+
+ if(arg_password == NULL) {
+ password = pwbuf;
+
+ if(arg_pipe) {
+ if (fgets (pwbuf, sizeof(pwbuf), stdin) == NULL)
+ dietx (1, "EOF reading password");
+ if (pwbuf[strlen(pwbuf) - 1] != '\n')
+ dietx (1, "too long password");
+ pwbuf[strlen(pwbuf) - 1] = '\0';
+ } else {
+ snprintf(prompt, PW_PROMPT_MAX,
+ "%s@%s's Password:", arg_principal, arg_cell);
+
+ if (des_read_pw_string(password, PW_PROMPT_MAX-1, prompt, 0))
+ dietx (1, "Unable to login because can't read password "
+ "from terminal.");
+
+ }
+ } else {
+ /* Truncate user-specified password to PASSWD_MAX */
+ /* This also lets us use memset() to clear it later */
+
+ strlcpy(pwbuf, arg_password, PASSWD_MAX);
+
+ password = pwbuf;
+
+ {
+ /* Have to clear out this copy of the password too from the
+ memory image */
+
+ /*
+ * FIXME: we should also erase the copy in argv[].
+ * Is it safe to overwrite bits of argv, and is there
+ * any nice way to do this from the getarg()
+ * framework?
+ */
+ int pwlen;
+ pwlen=strlen(arg_password);
+ memset(arg_password, 0, pwlen);
+ }
+ }
+
+ /* A familiar AFS warning message */
+ if (password == NULL || *password == '\0')
+ dietx (1, "Unable to login because zero length password is illegal.");
+
+ /*
+ * Create a secure random ticket file if we are running with -setpag,
+ * because we can set the environment variable in the child shell.
+ */
+
+ if(arg_setpag) {
+ tkfile = randfilename();
+ have_useless_ticket_file = 1;
+ } else {
+ if (arg_getkrbtgt) {
+ tkfile = getenv("KRBTKFILE");
+ if(tkfile == NULL) {
+ /* the insecure default ticket file :( */
+ tkfile = TKT_FILE;
+ }
+ } else {
+ /* Create a unique temporary file to get the temporary TGT */
+ tkfile = randfilename();
+ have_useless_ticket_file = 1;
+ }
+ }
+
+ setenv ("KRBTKFILE", tkfile, 1);
+ krb_set_tkt_string (tkfile);
+
+ /* Get the Kerberos TGT */
+ rc = do_timeout (get_k4_ticket);
+ if(timed_out)
+ dietx (1, "Timed out trying to get Kerberos ticket for %s@%s",
+ arg_principal, arg_realm);
+
+ /* get_k4_ticket() will already have printed out an error message. */
+ if(rc)
+ die(rc);
+
+ /* We can now clear the password from the memory image */
+ memset(password, 0, PASSWD_MAX);
+
+ /* Only keep this ticket file around if we were invoked as -tmp; this way,
+ the user will still be able to get a Kerberos TGT even if he/she cannot
+ obtain a token */
+ if(arg_getkrbtgt)
+ have_useless_ticket_file = 0;
+ else
+ have_useless_ticket_file = 1;
+
+ /*
+ * Figure out the AFS ID to store with the token.
+ * Moved this after the TGT-gathering stage because it may want to
+ * get a ticket to talk to the dbserver?
+ */
+
+ afsid = do_timeout (get_afs_id);
+ if(timed_out)
+ warnx("Timed out trying to get AFS ID for %s@%s",
+ arg_principal, arg_cell);
+
+ /* Get the AFS token */
+ rc = do_timeout (get_afs_token);
+ if(timed_out)
+ dietx (1, "Timed out trying to get AFS token for %s@%s",
+ arg_principal, arg_realm);
+
+ /* get_afs_token() will already have printed out an error message. */
+ if(rc)
+ die(rc);
+
+ /* Destroy the temporary Kerberos TGT if we didn't need it */
+ if(!arg_getkrbtgt) {
+ dest_tkt();
+
+ /* Avoid calling dest_tkt() twice-- may be security risk */
+ have_useless_ticket_file = 0;
+ }
+
+ /*
+ * Exec a shell if the user specified -setpag, because otherwise the
+ * new PAG will magically disappear when the program exits
+ */
+
+ if(arg_setpag) {
+ /*
+ * Get the default shell of the PRINCIPAL we are kloging as.
+ * This is the only thing that makes sense, as we are going to
+ * be opening up a session for this principal.
+ * Perhaps we should also change to this principal's home
+ * directory, as the shell will fail if the command was run in
+ * a restricted directory owned by a different AFS principal
+ */
+
+ struct passwd *pwd;
+ char *shell;
+
+ pwd = getpwnam(arg_principal);
+ if(pwd == NULL) {
+ pwd = getpwuid(getuid());
+ if(pwd == NULL) {
+
+ shell = getenv("SHELL");
+ if (shell == NULL) {
+ warnx ("Can't get default shell for user %s, using "
+ "fallback (/bin/sh) shell.", arg_principal);
+ shell = "/bin/sh";
+ }
+
+ } else {
+ warnx ("Can't get default shell for user %s, "
+ "using default shell for UID %d",
+ arg_principal, getuid());
+
+ shell = pwd->pw_shell;
+ }
+ } else {
+ shell = pwd->pw_shell;
+ }
+
+ execl(shell, shell, NULL);
+
+ /* the AFS token is useless if the shell exec fails, because it
+ is in a PAG that will soon go away. */
+ have_useless_token = 1;
+
+ diet (1, "Can't exec shell: %s", shell);
+ }
+
+ return 0;
+}
+#endif /* KERBEROS */
diff --git a/usr.sbin/afs/src/appl/afsutils/klog.ctx b/usr.sbin/afs/src/appl/afsutils/klog.ctx
new file mode 100644
index 00000000000..c9c10d6e185
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/klog.ctx
@@ -0,0 +1,221 @@
+#
+# $Id: klog.ctx,v 1.1 2000/09/11 14:40:33 art Exp $
+#
+
+%name description
+
+ get AFS tokens
+
+%name os
+
+ "Arla, KTH"
+
+%name section
+
+ 1
+
+%section history
+
+ Written by Chris Wing <wingc@engin.umich.edu>. Made nonworking
+ by Love Hörnquist-Åstrand <lha@stacken.kth.se> serveral times.
+
+%section see also
+
+ .Xr kauth 1 ,
+ .Xr kinit 1 ,
+ .Xr kauthd 8 ,
+ .Xr unlog 1 ,
+ .Xr tokens 1 ,
+ .Xr afslog 1
+
+%section authors
+
+ Chris Wing <wingc@engin.umich.edu>
+ \&...
+
+%section description
+
+ Get you a token from a kerberos server (not kaserver).
+
+%section bugs
+
+ The
+ .Ar servers
+ option only affects where the AFS ID is looked up, not
+ which servers are actually contacted to get the TGT or token.
+ .Pp
+ .Nm
+ should automatically deal with the case where the Kerberos realm is not
+ the same as the AFS cell name.
+
+%command _main
+
+ .Nm
+ obtains AFS tokens and possibly a Kerberos ticket granting ticket
+ as well. By default it only gets an AFS token for the named
+ principal and cell.
+ .Pp
+ .Nm
+ can be invoked more than once to acquire AFS
+ tokens in multiple cells. There is no way at present to write
+ Kerberos TGTs for different realms into the same ticket file.
+ .Pp
+ If
+ .Nm
+ is successful in getting a token and you already have a token for the same
+ cell in your current PAG, it will be overwritten by the new token. An
+ existing token will not be erased if a new token cannot be
+ acquired.
+ .Pp
+ You can specify part or whole of a Kerberos principal on the command line;
+ for instance:
+ .Pp
+ .Nm
+ username
+ .Pp
+ or
+ .Nm
+ username@cell.name
+ .Pp
+ or just
+ .Nm
+ @cell.name
+ .Pp
+ If neither is specified, the default is your current user name and the
+ local AFS cell.
+ .Pp
+ The following flags are supported:
+ .Bl -tag -width principal
+ .It Fl principal
+ Principal to get tokens for. If not specified,
+ .Nm
+ tries to use your user name, which is guessed from $USER or from the UID
+ that
+ .Nm
+ is run as.
+ .It Fl lifetime
+ Lifetime for the Kerberos TGT and/or AFS token. This can be specified as:
+ .Nm
+ .Ar lifetime
+ hours
+ .Pp
+ or
+ .Nm
+ .Ar lifetime
+ hours:minutes
+ .Pp
+ or
+ .Nm
+ .Ar lifetime
+ hours:minutes:seconds
+ .Pp
+ If this option is not specified, the default lifetime of 720 hours (30
+ days) is used; however, the administrators of your cell may
+ have chosen a lesser maximum lifetime.
+ .Pp
+ Please note that in Kerberos 4, only 255 discrete lifetimes are possible
+ spanning the range from 5 minutes to 30 days. The lifetime
+ that you specify will be rounded up to the next possible lifetime.
+ .It Fl cell
+ AFS cell to get tokens for. If not specified,
+ .Nm
+ guesses your local cell.
+ .It Fl password
+ You can specify the Kerberos password on the command line. This is a
+ really, really, really, bad idea on most systems out there, since any user
+ can use the
+ .Xr ps(1)
+ command to examine the command line of any running process.
+ .Pp
+ You should not use this option.
+ .It Fl realm
+ Most AFS cells are set up in such a way that the Kerberos realm name is
+ the same as the cell name (except in upper case). If the name
+ of your AFS cell differs from your Kerberos realm, however,
+ .Nm
+ may not be able to automatically fetch your tokens without specifying the
+ correct realm name with this option.
+ .It Fl servers
+ You can list one or more kaservers to contact directly here.
+ .Nm
+ will attempt to contact each of them until it finds one that works.
+ .It Fl timeout
+ You can specify the number of seconds that
+ .Nm
+ will wait for a network operation to complete. (there are 3 network
+ operations peformed by
+ .Nm
+ - the AFS ID is looked up from the dbserver, the Kerberos 4 TGT must be
+ obtained, and the AFS token must be fetched.
+ .Pp
+ If you do not use this option,
+ .Nm
+ will wait forever if necessary.
+ .It Fl silent
+ This causes
+ .Nm
+ not to write to the standard error channel. By default, error
+ messages are sent to stderr.
+ .It Fl pipe
+ If this flag is given, then
+ .Nm
+ will not write to the standard output, and will only accept a password
+ written to the standard input. Error messages will still be
+ printed to standard error unless the
+ .Ar silent
+ option is also specified.
+ .Pp
+ Because it does not attempt to verify that the TTY is safe, this should
+ only be used from scripts.
+ .It Fl setpag
+ Stores the AFS token in a new PAG, and then
+ .Fn exec
+ s a shell. The environment variable
+ .Ev KRBTKFILE
+ is set to point
+ to a unique name in
+ .Va /ticket,
+ so that the Kerberos TGT gathered (if any) is written to a
+ safe place. The shell is chosen via
+ .Fn getpwnam
+ called with the principal's name; if that fails, then
+ .Fn getpwuid
+ is tried with your current UID; if this fails,
+ .Nm
+ attempts to execute
+ .Va /bin/sh.
+ .It Fl tmp
+ Actually get a Kerberos TGT and writes it to
+ .Pa /tmp
+ (or the file specified in the
+ .Ev KRBTKFILE
+ environment variable). By default, only an AFS token is acquired.
+ .Pp
+ This is a poor choice of name, as in reality writing Kerberos tickets to
+ .Pa /tmp
+ is a bad idea and often a security risk. This name is only here for
+ compatibility with other AFS implementations. (
+ .Ar tgt
+ would have been a better choice of name)
+ .It Fl help
+ Prints out a help message.
+ .El
+ .Sh EXIT STATUS
+ .Nm
+ returns with exit status 0 (true) if and only if a Kerberos 4 TGT was
+ successfully acquired and an AFS token was successfully stored. In all
+ other cases, the return value is non-zero.
+ .Pp
+ It is possible to call
+ .Nm
+ from scripts or other programs for automated authentication with the
+ .Ar pipe
+ option, although discretion and caution is advised when doing so.
+ .Sh NOTES
+ By default,
+ .Nm
+ tries to look up your Kerberos principal in the kaserver's database to
+ figure out the proper AFSId to use. As far as I know, this only affects
+ the output of the
+ .Xr tokens(1)
+ program.
diff --git a/usr.sbin/afs/src/appl/afsutils/klog.h b/usr.sbin/afs/src/appl/afsutils/klog.h
new file mode 100644
index 00000000000..1dcdea258bc
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/klog.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: klog.h,v 1.1 2000/09/11 14:40:33 art Exp $ */
+
+/* Function prototypes for klog.c */
+
+int get_afs_id(void);
+
+/* prototype for die et al */
+
+void
+die (int retcode)
+ __attribute__ ((noreturn));
+
+void
+diet (int retcode, char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+
+void
+dietx (int retcode, char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+
+int get_k4_ticket(void);
+
+int get_afs_token(void);
+
+int do_timeout( int (*function)(void) );
+
+char *randfilename(void);
+
+
+/* Feel free to correct these definitions with the actual numbers. */
+
+#define CELL_MAX REALM_SZ
+#define REALM_MAX REALM_SZ
+
+/* According to code in arla/rxdef, max principal name length is 64. */
+#define PRINCIPAL_MAX 64
+
+#define PASSWD_MAX 200
+#define PW_PROMPT_MAX 256
+
+/* We use this and make it mode 1733; you should too */
+#define KLOG_TKT_ROOT "/ticket/"
diff --git a/usr.sbin/afs/src/appl/afsutils/sys.c b/usr.sbin/afs/src/appl/afsutils/sys.c
new file mode 100644
index 00000000000..1bf5cb0f899
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/sys.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * sys - a version of the sys command
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: sys.c,v 1.1 2000/09/11 14:40:33 art Exp $");
+
+#include "appl_locl.h"
+
+int
+main (int argc, char **argv)
+{
+ const char *sysname = arla_getsysname();
+ char buf[2048];
+ int ret;
+
+ if (sysname == NULL)
+ sysname = "unknown";
+
+ if (!k_hasafs()) {
+ printf ("%s\n", sysname);
+ exit (0);
+ }
+
+ ret = fs_get_sysname (buf, sizeof(buf));
+ if (ret) {
+ printf ("%s\n", sysname);
+ } else {
+ printf ("%s\n", buf);
+ }
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/afsutils/tokens.1 b/usr.sbin/afs/src/appl/afsutils/tokens.1
new file mode 100644
index 00000000000..25ccefeca0e
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/tokens.1
@@ -0,0 +1,95 @@
+.\" $Id: tokens.1,v 1.1 2000/09/11 14:40:33 art Exp $
+.\"
+.Dd July 7, 1999
+.Dt TOKENS 1
+.Os "The Arla Project"
+.Sh NAME
+.Nm tokens
+.Nd
+lists all AFS tokens in your current PAG.
+.Sh SYNOPSIS
+.Nm
+.Op Fl athena
+.Op Fl verbose, v
+.Sh DESCRIPTION
+The following flags are supported:
+.Bl -tag -width xxxx
+.It Fl athena
+Generate output in a format similar to that of Kerberos 4's 'klist'
+program
+.It Fl verbose,-v
+Generate slightly more verbose output (not particularly useful except for
+debugging purposes)
+.El
+.Pp
+The
+.Nm
+can produce two different styles of output, AFS-style (default) or
+Kerberos4-style (optional).
+.Pp
+The default output mimics the
+.Nm
+command from the official AFS.
+.Pp
+It looks something like this:
+.Bd -literal
+Tokens held by Arla:
+
+User's (AFS ID 4881) tokens for afs@umich.edu [Expires Jul 8 09:21]
+User's (AFS ID 4881) tokens for afs@engin.umich.edu [>>> Expired <<<]
+ --End of list--
+.Ed
+.Pp
+If you don't have any AFS tokens, you still get the banner:
+.Bd -literal
+Tokens held by Arla:
+
+ --End of list--
+.Ed
+.Pp
+When the
+.Fl athena
+option is specified on the command line, the output
+of
+.Nm
+looks like this:
+.Bd -literal
+Tokens held by Arla:
+
+ Issued Expires Principal
+Jul 7 23:40:22 Jul 8 00:40:21 User's (AFS ID 4881) tokens for umich.edu
+Jul 7 23:27:51 >>> Expired <<< User's (AFS ID 4881) tokens for engin.umich.edu
+ --End of list--
+.Ed
+.Pp
+If you don't have any AFS tokens,
+.Nm
+just prints
+.Bd -literal
+You have no AFS tokens.
+.Ed
+to the standard output.
+.Sh EXIT STATUS
+.Nm
+returns with exit status 0 (true) if the current PAG has at least 1 valid
+AFS token. Otherwise, the exit status of
+.Nm
+is 1.
+.Pp
+Thus, you can call this program from a script to determine whether or not
+AFS tokens are present. (e.g. in a login script)
+.Sh NOTES
+The AFS ID printed out may be arbitrary; it can be chosen at the time the
+token is set and does not necessarily correspond to the actual AFS ID on
+the kaserver.
+.Pp
+If you have AFS tokens, but they are all expired, the exit status of
+.Nm
+will be 1, not 0.
+.El
+.Sh SEE ALSO
+.Xr klog 1 ,
+.Xr klist 1 ,
+.Xr unlog 1
+.Sh BUGS
+None known.
diff --git a/usr.sbin/afs/src/appl/afsutils/tokens.c b/usr.sbin/afs/src/appl/afsutils/tokens.c
new file mode 100644
index 00000000000..8be36102348
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/tokens.c
@@ -0,0 +1,248 @@
+/*
+ tokens.c - a version of 'tokens' for Arla
+
+ Written by Chris Wing - wingc@engin.umich.edu
+ based on examples of AFS code: klist.c and libkafs (KTH-KRB)
+
+ This is a reimplementation of tokens from AFS. The following new
+ features have been added:
+ -athena Output format similar to the 'klist' program
+ in Kerberos 4
+
+ -v, -verbose Slightly more verbose output
+*/
+
+/*
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Lists your current Kerberos tickets.
+ * Written by Bill Sommerfeld, MIT Project Athena.
+ */
+
+#include "appl_locl.h"
+
+RCSID("$Id: tokens.c,v 1.1 2000/09/11 14:40:34 art Exp $");
+
+#include "tokens.h"
+
+
+/*
+ * State variables
+ */
+
+/* produce verbose output? */
+static int arg_verbose = 0;
+
+/* produce kerberos4 style output? */
+static int arg_athena = 0;
+
+/* print out help message */
+static int arg_help = 0;
+
+/* print out version number */
+static int arg_version = 0;
+
+/* do we actually have any valid AFS tokens? */
+static int got_tokens = 0;
+
+/* do we have any AFS tokens, valid or not? */
+static int got_anything = 0;
+
+
+/* arguments for getarg() */
+
+struct getargs args[] = {
+ { "athena", 0, arg_flag, &arg_athena,
+ "generate 'klist' style output instead of AFS style",
+ NULL, arg_optional},
+ { "verbose", 'v', arg_flag, &arg_verbose,
+ "generate verbose output",
+ NULL, arg_optional},
+ { "help", 0, arg_flag, &arg_help,
+ "display this message",
+ NULL, arg_optional},
+ { "version", 0, arg_flag, &arg_version,
+ "print version",
+ NULL, arg_optional},
+ { NULL, 0, arg_end, NULL, NULL }
+};
+
+/*
+ * Helper functions
+ */
+
+
+/* Print out a help message and exit */
+
+static void
+do_help(int exitval)
+{
+ arg_printusage(args, NULL, NULL, ARG_AFSSTYLE);
+ exit(exitval);
+}
+
+/* ASCII time formatting function from klist.c (Kerberos 4) */
+
+static char *short_date(int32_t dp)
+{
+ char *cp;
+ time_t t = (time_t)dp;
+
+ if (t == (time_t)(-1L)) return "*** Never *** ";
+ cp = ctime(&t) + 4;
+
+ /* Only display seconds in 'athena' mode */
+ if(arg_athena)
+ cp[15] = '\0';
+ else
+ cp[12] = '\0';
+
+ return (cp);
+}
+
+
+/* Display list of tokens */
+
+void display_tokens(void)
+{
+ u_int32_t i;
+ unsigned char t[128];
+ struct ViceIoctl parms;
+
+ int did_banner = 0;
+
+ parms.in = (void *)&i;
+ parms.in_size = sizeof(i);
+ parms.out = (void *)t;
+ parms.out_size = sizeof(t);
+
+ /* AFS-style always displays the banner */
+ if(!(arg_athena))
+ printf("\nTokens held by Arla:\n\n");
+
+ for (i = 0; k_pioctl(NULL, VIOCGETTOK, &parms, 0) == 0; i++) {
+ int32_t size_secret_tok, size_public_tok;
+ const char *cell;
+ struct ClearToken ct;
+ const unsigned char *r = t;
+ struct timeval tv;
+ char buf1[20], buf2[20];
+
+ got_anything = 1;
+
+ if ( (did_banner == 0) && (arg_athena) ) {
+ printf("\nTokens held by Arla:\n\n");
+ printf(" Issued Expires Principal\n");
+
+ did_banner = 1;
+ }
+
+ memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
+ /* dont bother about the secret token */
+ r += size_secret_tok + sizeof(size_secret_tok);
+ memcpy(&size_public_tok, r, sizeof(size_public_tok));
+ r += sizeof(size_public_tok);
+ memcpy(&ct, r, size_public_tok);
+ r += size_public_tok;
+ /* there is a int32_t with length of cellname, but we dont read it */
+ r += sizeof(int32_t);
+ cell = (const char *)r;
+
+ /* make sure cell name is null-terminated */
+ t[127] = '\0';
+
+#ifdef HAVE_KRB_KDCTIMEOFDAY
+ krb_kdctimeofday (&tv);
+#else
+ gettimeofday (&tv, NULL);
+#endif
+ strlcpy (buf1, short_date(ct.BeginTimestamp), sizeof(buf1));
+ if (arg_verbose || tv.tv_sec < ct.EndTimestamp)
+ strlcpy (buf2, short_date(ct.EndTimestamp), sizeof(buf2));
+ else
+ strlcpy (buf2, ">>> Expired <<<", sizeof(buf2));
+
+ /* only return success if we have non-expired tokens */
+ if (tv.tv_sec < ct.EndTimestamp)
+ got_tokens = 1;
+
+ /* make sure strings are null-terminated */
+ buf1[19] = '\0';
+ buf2[19] = '\0';
+
+ if(arg_athena) {
+ /* Athena klist style output */
+
+ printf("%s %s ", buf1, buf2);
+
+ if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
+ printf("User's (AFS ID %d) tokens for %s", ct.ViceId, cell);
+ else
+ printf("Tokens for %s", cell);
+
+ if (arg_verbose)
+ printf(" (%d)", ct.AuthHandle);
+
+ putchar('\n');
+ } else {
+ /* Traditional AFS output format */
+
+ if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
+ printf("User's (AFS ID %d) tokens for afs@%s", ct.ViceId, cell);
+ else
+ printf("Tokens for afs@%s", cell);
+
+ if (arg_verbose || tv.tv_sec < ct.EndTimestamp)
+ printf(" [Expires %s]\n", buf2);
+ else
+ printf(" [%s]\n", buf2);
+ }
+ }
+
+ /* Ick. Deal with AFS-style output and athena style output */
+
+ /* Skip printing this only if athena style output and have no tokens */
+ if(got_anything || !(arg_athena))
+ printf(" --End of list--\n");
+
+ /* Print this if athena style output and have no tokens */
+ if( !(got_anything) && (arg_athena) )
+ printf("You have no AFS tokens.\n");
+
+ /* erase the copy of the token in memory */
+ memset(t, 0, sizeof(t));
+}
+
+
+int main(int argc, char **argv)
+{
+ int optind = 0;
+
+#ifndef KERBEROS
+ errx (1, "kerberos support isn't compiled in");
+#endif
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ warnx ("Bad argument: %s", argv[optind]);
+ do_help(1);
+ }
+
+ if (arg_help)
+ do_help(0);
+
+ if (arg_version)
+ errx (0, "part of %s-%s", PACKAGE, VERSION);
+
+ if (k_hasafs())
+ display_tokens();
+ else
+ errx (1, "You don't seem to have AFS running");
+
+ if (!got_tokens)
+ return 1;
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/afsutils/tokens.h b/usr.sbin/afs/src/appl/afsutils/tokens.h
new file mode 100644
index 00000000000..569caa8f76f
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/tokens.h
@@ -0,0 +1,5 @@
+/* Function prototypes for tokens.c */
+
+static char *short_date(int32_t dp);
+
+void display_tokens(void);
diff --git a/usr.sbin/afs/src/appl/afsutils/unlog.1 b/usr.sbin/afs/src/appl/afsutils/unlog.1
new file mode 100644
index 00000000000..db9aa36af94
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/unlog.1
@@ -0,0 +1,60 @@
+.\" $Id: unlog.1,v 1.1 2000/09/11 14:40:34 art Exp $
+.\"
+.Dd July 7, 1999
+.Dt UNLOG 1
+.Os "The Arla Project"
+.Sh NAME
+.Nm unlog
+.Nd
+A program to destroy some or all of your AFS tokens
+.Sh SYNOPSIS
+.Nm
+.Op Fl cell Ar cells...
+.Op Ar cells...
+.Op Fl help
+.Sh DESCRIPTION
+The following flags are supported:
+.Bl -tag -width xxxx
+.It Fl cell
+List of cells to remove tokens from. You do not need to specify this flag;
+you can execute the command simply as:
+.Pp
+.Nm
+cellname cellname ...
+.It Fl help
+Prints out a help message.
+.El
+.Sh EXAMPLES
+Remove all tokens for cell umich.edu
+.Pp
+.Nm
+umich.edu
+.Ed
+.Pp
+Remove all tokens for umich.edu engin.umich.edu
+.Pp
+.Nm
+umich.edu engin.umich.edu
+.Sh EXIT STATUS
+If any errors occur during the unlog process, the exit status of
+.Nm
+is 1, otherwise it is 0.
+.Sh NOTES
+.Nm
+works by first stashing the tokens you want to \fBkeep\fP in a safe place,
+then removing \fBall\fP your tokens, and then restoring the tokens that
+you didn't want to get rid of. For this reason, if you use
+.Nm
+to remove only \fBsome\fP tokens, there will be a brief period while this
+program runs during which time your current PAG will have \fBno\fP tokens.
+(a so called "authentication outage") This may be problematic if a program
+is running simultaneously which requires constant authenticated access to
+AFS.
+.Sh SEE ALSO
+.Xr aklog 1 ,
+.Xr klog 1 ,
+.Xr kauth 1 ,
+.Xr tokens 1
+.Sh BUGS
+Arla should implement a specicial AFS \fBpioctl\fP to allow removing only
+one token at a time, to prevent the aforementioned problem.
diff --git a/usr.sbin/afs/src/appl/afsutils/unlog.c b/usr.sbin/afs/src/appl/afsutils/unlog.c
new file mode 100644
index 00000000000..568627a66d8
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/unlog.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ unlog.c - a version of 'unlog' for Arla
+
+ Written by Chris Wing - wingc@engin.umich.edu
+ based on examples of AFS code in klist.c and libkafs (KTH-KRB)
+
+ This is a reimplementation of unlog from AFS.
+*/
+
+#include "appl_locl.h"
+
+RCSID("$Id: unlog.c,v 1.1 2000/09/11 14:40:34 art Exp $");
+
+#include "unlog.h"
+
+
+/*
+ * State variables
+ */
+
+/* Holding space for saved tokens */
+struct token *saved_tokens;
+
+/* Number of saved tokens */
+static int numtokens;
+
+/* Did we lose any tokens when trying to restore? */
+static int lost_tokens = 0;
+
+static int unlog_version = 0;
+static int unlog_help = 0;
+static getarg_strings unlog_cells, unlog_cells_no_argument;
+
+/*
+ * Various helper functions that we call
+ */
+
+/* Get token # 'tnum' and store it into buffer pointed at by 'tok'
+ Return pointer to cell name for convenience */
+
+char *gettoken(int tnum, struct token *tok)
+{
+ u_int32_t i;
+ struct ViceIoctl parms;
+
+ int32_t zero_length = 0;
+
+ i = tnum;
+
+ parms.in = (void *)&i;
+ parms.in_size = sizeof(i);
+ parms.out = (void *)tok->tbuf;
+ parms.out_size = 128 * sizeof(char);
+
+ if(k_pioctl(NULL, VIOCGETTOK, &parms, 0) != 0)
+ return(NULL);
+ else {
+ int32_t size_secret_tok, size_public_tok, size_cell_name;
+ unsigned char *r = tok->tbuf;
+
+ /* get length of secret token */
+ memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
+
+ /* skip over secret token + length */
+ r += size_secret_tok + sizeof(size_secret_tok);
+ /* get length of public token */
+ memcpy(&size_public_tok, r, sizeof(size_public_tok));
+
+ r += size_public_tok + sizeof(size_public_tok);
+
+ /* get length of cell name */
+ memcpy(&size_cell_name, r, sizeof(size_cell_name));
+
+ /* FIXME: it seems we must set this value to 0 in order
+ 'not to mark this as the primary cell' when we re-store
+ the token. Is this right? */
+ memcpy(r, &zero_length, sizeof(zero_length));
+
+ r += sizeof(size_cell_name);
+
+ tok->size = size_secret_tok + size_public_tok + size_cell_name + 1
+ + 3 * sizeof(int32_t);
+
+ tok->cell = (char *)r;
+
+ /* handle overflows of cellname */
+ if(tok->size > 128) {
+ tok->size = 128;
+ tok->tbuf[127] = '\0';
+ fprintf(stderr, "Cell name overflowed: %s\n", tok->cell);
+ }
+
+ return(tok->cell);
+ }
+}
+
+
+/* Restore token from buffer 'tok' */
+
+void restoretoken(struct token *tok)
+{
+ struct ViceIoctl parms;
+ int ret;
+
+ parms.in = tok->tbuf;
+ parms.in_size = tok->size;
+ parms.out = 0;
+ parms.out_size = 0;
+ ret = k_pioctl(0, VIOCSETTOK, &parms, 0);
+
+ if(ret) {
+ fprintf(stderr, "Lost token for cell: %s\n", tok->cell);
+ lost_tokens = 1;
+ }
+
+ return;
+}
+
+/*
+ * options to program
+ */
+
+struct getargs args[] = {
+ { "cell", 0, arg_strings, &unlog_cells,
+ "only remove tokens for this cell or cells",
+ "AFS cell name(s)", arg_optional},
+ { NULL, 0, arg_generic_string, &unlog_cells_no_argument,
+ "only remove tokens for this cell or cells",
+ "AFS cell name(s)", arg_optional},
+ { "help", 0, arg_flag, &unlog_help, "help",
+ NULL, arg_optional},
+ { "version", 0, arg_flag, &unlog_version, "print version",
+ NULL, arg_optional},
+ { NULL, 0, arg_end, NULL, NULL }
+};
+
+/*
+ * Print out a help message and exit
+ */
+
+static void
+do_help(int exitval)
+{
+ arg_printusage(args, NULL, NULL, ARG_AFSSTYLE);
+ exit(exitval);
+}
+
+/*
+ * Main program code
+ */
+
+int
+main(int argc, char **argv)
+{
+ int i, j, optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ warnx("Bad argument: %s", argv[optind]);
+ do_help(1);
+ }
+
+ if (unlog_help)
+ do_help(0);
+
+ if (unlog_version)
+ errx (0, "part of %s-%s", PACKAGE, VERSION);
+
+ if(!k_hasafs())
+ errx (1, "You don't seem to have AFS running");
+
+ if(unlog_cells_no_argument.num_strings)
+ unlog_cells = unlog_cells_no_argument;
+
+ /* Save tokens if need be */
+ if(unlog_cells.num_strings) {
+ char *cell;
+ struct token *save;
+ int token_overflow = 0;
+
+ /* allocate space for 1 more token in case of overflow */
+ saved_tokens = malloc( (MAX_TOKENS + 1) * sizeof(struct token));
+
+ if(!saved_tokens) {
+ fprintf(stderr, "Can't malloc space to store tokens!\n");
+ exit(1);
+ }
+
+ numtokens = 0;
+ i=0;
+
+ save = saved_tokens;
+ while((cell = gettoken(i, &saved_tokens[numtokens]))) {
+ int keep_this_token = 1;
+
+ i++;
+
+ if(token_overflow) {
+ fprintf(stderr,
+ "Ran out of space to save token in cell %s\n",
+ cell);
+ lost_tokens = 1;
+ }
+
+ for (j = 0 ; j < unlog_cells.num_strings; j++)
+ if (strcmp (unlog_cells.strings[j], cell) == 0)
+ keep_this_token = 0;
+
+ if(keep_this_token) {
+ numtokens++;
+ save++;
+ }
+
+ if(numtokens == MAX_TOKENS) {
+ numtokens = MAX_TOKENS-1;
+ token_overflow = 1;
+ }
+ }
+ }
+
+ /* Now destroy all tokens */
+ if(k_unlog() != 0) {
+ fprintf(stderr, "pioctl(VIOCUNLOG) returned error!\n");
+
+ /* make sure the program exits with status 1 */
+ lost_tokens = 1;
+ }
+
+ /* Now restore tokens we want to keep */
+ if(numtokens) {
+ for(i=0; i<numtokens; i++) {
+ restoretoken(&saved_tokens[i]);
+ }
+
+ /* Erase the copy of all saved tokens in the process's
+ memory image! */
+ memset(saved_tokens, 0, MAX_TOKENS * sizeof(struct token));
+
+ /* Return an error code if we lost some tokens somehow, or if the
+ unlog pioctl failed */
+ exit(lost_tokens);
+ }
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/afsutils/unlog.h b/usr.sbin/afs/src/appl/afsutils/unlog.h
new file mode 100644
index 00000000000..d4252decab4
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/unlog.h
@@ -0,0 +1,21 @@
+/* Our silly token storage data structure */
+
+struct token {
+ /* FIXME: Is 128 bytes always enough? */
+ char tbuf[128];
+ int32_t size;
+ char *cell;
+};
+
+
+/* Function prototypes for unlog.c */
+
+char *gettoken(int tnum, struct token *tok);
+
+void restoretoken(struct token *tok);
+
+
+/* Maximum number of tokens to save */
+
+#define MAX_TOKENS 32
+
diff --git a/usr.sbin/afs/src/appl/afsutils/up.c b/usr.sbin/afs/src/appl/afsutils/up.c
new file mode 100644
index 00000000000..c82ef097e99
--- /dev/null
+++ b/usr.sbin/afs/src/appl/afsutils/up.c
@@ -0,0 +1,168 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+
+#include "appl_locl.h"
+#include <kafs.h>
+
+RCSID("$Id: up.c,v 1.1 2000/09/11 14:40:34 art Exp $");
+
+static void do_help (int exitval);
+static int copyacl (char *from, char *to);
+
+static int arg_help = 0;
+static int arg_verbose = 0;
+static int arg_one = 0;
+static int arg_force = 0;
+static int arg_backup = 0;
+static int arg_savedate = 0;
+
+struct getargs args[] = {
+ { NULL , 'h', arg_flag, &arg_help,
+ "verbose", NULL, arg_optional},
+ { NULL , 'v', arg_flag, &arg_verbose,
+ "verbose", NULL, arg_optional},
+ { NULL , '1', arg_flag, &arg_one,
+ "top level only", NULL, arg_optional},
+ { NULL , 'f', arg_flag, &arg_force,
+ "force", NULL, arg_optional},
+ { NULL , 'r', arg_flag, &arg_backup,
+ "verbose", NULL, arg_optional},
+ { NULL , 'x', arg_flag, &arg_savedate,
+ "verbose", NULL, arg_optional},
+ { NULL, 0, arg_end, NULL, NULL }
+};
+
+static void
+do_help (int exitval)
+{
+ arg_printusage(args, NULL,
+ "<from-directory> <to-directory>",
+ ARG_SHORTARG);
+ exit(exitval);
+}
+
+
+static int
+copyacl (char *from, char *to)
+{
+ struct ViceIoctl a_params;
+ char buf[AFSOPAQUEMAX];
+
+ a_params.in_size = 0;
+ a_params.in = NULL;
+ a_params.out_size = sizeof(buf);
+ a_params.out = buf;
+
+ if (k_pioctl (from, VIOCGETAL, &a_params, 1) != 0) {
+ fprintf (stderr, "k_pioctl(\"%s\", VIOCGETAL) failed %d\n",
+ from, errno);
+ return errno;
+ }
+
+ a_params.in_size = sizeof(buf);
+ a_params.in = buf;
+ a_params.out_size = 0;
+ a_params.out = NULL;
+
+ if (k_pioctl (to, VIOCSETAL, &a_params, 1) != 0) {
+ fprintf (stderr, "k_pioctl(\"%s\", VIOCSETAL) failed %d\n",
+ to, errno);
+ return errno;
+ }
+ return 0;
+}
+
+
+static int
+check_source_dir (const char *path)
+{
+ struct stat sb;
+ int ret;
+
+ ret = lstat (path, &sb);
+ if (ret) {
+ if (errno == ENOENT)
+ errx (1, "source diretory `%s' doesn't exist", path);
+ else
+ err (1, "check_source_dir: lstat: path `%s'", path);
+ }
+
+ /* XXX */
+
+ return 0;
+}
+
+
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+ char *fromdir;
+ char *todir;
+ int ret;
+
+ if (getarg (args, argc, argv, &optind, ARG_SHORTARG))
+ do_help(1);
+
+ if (arg_help)
+ do_help(0);
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ do_help(1);
+
+ if (!k_hasafs())
+ errx (1, "there seam to be no AFS no this computer");
+
+ fromdir = argv[0];
+ todir = argv[1];
+
+ if (arg_verbose)
+ printf ("fromdir: \"%s\" todir: \"%s\"\n", fromdir, todir);
+
+ check_source_dir (todir);
+ ret = copyacl (fromdir, todir);
+ if (ret)
+ errx (1, "copyacl failed with %s (%d)", strerror(ret), ret);
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/amon/Makefile.in b/usr.sbin/afs/src/appl/amon/Makefile.in
new file mode 100644
index 00000000000..1125f05dfa0
--- /dev/null
+++ b/usr.sbin/afs/src/appl/amon/Makefile.in
@@ -0,0 +1,121 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:34 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = @MAKE_X_PROGS_BIN@
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+AFSWSROOT = /usr/afsws
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../lib \
+ -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I../../include \
+ -I../../rxdef \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ @LIB_readline@ \
+ -L../../lib/roken \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+AMON_LIBS = @X_LIBS@ \
+ -lXaw -lXt -lXmu -lXext @X_PRE_LIBS@ -lX11 @X_EXTRA_LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+X_PROGS_BIN = amon
+PROGS = @MAKE_X_PROGS_BIN@
+AMON_SRCS = amon.c
+SRCS = $(AMON_SRCS)
+AMON_OBJS = amon.o
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+amon: $(AMON_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(AMON_OBJS) $(LIBS) $(AMON_LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/amon/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core arladeb.c
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/amon/amon.c b/usr.sbin/afs/src/appl/amon/amon.c
new file mode 100644
index 00000000000..0c7ad8c7b34
--- /dev/null
+++ b/usr.sbin/afs/src/appl/amon/amon.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 1998 - 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw/XawInit.h>
+#include <X11/Xaw/StripCharP.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xatom.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/StripChart.h>
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xmu/SysUtil.h>
+
+#include <parse_bytes.h>
+
+#include "appl_locl.h"
+
+RCSID("$Id: amon.c,v 1.1 2000/09/11 14:40:34 art Exp $");
+
+#if 0
+static XrmOptionDescRec options[] = {};
+#endif
+
+int debug = 0;
+XtAppContext app_con;
+
+#if 0
+/*
+ * Create a widget for doing the same thing as stripChartWidgetClass
+ * but add two lines
+ */
+
+#ifndef XtNmaxScale
+#define XtNmaxScale "XtNmaxScale"
+#endif
+
+/*
+ * Class
+ */
+typedef struct {int dummy;} StripChartMinMaxClassPart;
+
+typedef struct _StripChartMinMaxClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ StripChartClassPart strip_chart_class;
+ StripChartMinMaxClassPart strip_minmax_class;
+} StripChartMinMaxClassRec;
+
+/*
+ * Instance
+ */
+
+typedef struct {
+ GC sGC;
+
+ int min_value;
+ int max_value;
+} StripChartMinMaxRec_local;
+
+typedef struct _StripChartMinMaxRec {
+ CorePart core;
+ SimplePart simple;
+ StripChartPart strip_chart;
+ StripChartMinMaxRec_local strip_minmax;
+} StripChartMinMaxRec;
+
+typedef struct _StripChartMinMaxRec *StripChartMinMaxWidget;
+
+
+#define offset(field) XtOffsetOf(StripChartMinMaxRec, field)
+
+static XtResource resources[] = {
+ {XtNminScale, XtCScale, XtRInt, sizeof(int),
+ offset(strip_minmax.min_value), XtRImmediate, (XtPointer) 0},
+ {XtNmaxScale, XtCScale, XtRInt, sizeof(int),
+ offset(strip_minmax.min_value), XtRImmediate, (XtPointer) 0}
+};
+
+
+/*
+ * Prototypes
+ */
+
+static void Initialize (Widget greq, Widget gnew, ArgList args,
+ Cardinal *num_args);
+static void Destroy (Widget widget);
+static void SetPoints(Widget widget);
+static void Redisplay(Widget w, XEvent *event, Region region);
+static Boolean SetValues (Widget current, Widget request, Widget new,
+ ArgList args, Cardinal *num_args);
+
+
+/*
+ * The class struct
+ */
+
+
+StripChartMinMaxClassRec stripChartMinMaxClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &stripChartClassRec,
+ /* class_name */ "StripChartMinMax",
+ /* size */ sizeof(StripChartMinMaxRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ XtExposeCompressMultiple |
+ XtExposeGraphicsExposeMerged,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ SetPoints,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ NULL,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* Simple class fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ }
+};
+
+WidgetClass stripChartMinMaxWidgetClass =
+ (WidgetClass) &stripChartMinMaxClassRec;
+
+
+/*
+ *
+ *
+ */
+
+static void
+Initialize (Widget greq, Widget gnew,
+ ArgList args, Cardinal *num_args)
+{
+ printf ("initialize\n");
+#if 0
+ (stripChartMinMaxClassRec.core_class.superclass->core_class.initialize) (greq, gnew, args, num_args);
+#endif
+}
+
+static void
+Destroy (Widget widget)
+{
+ printf ("destroy\n");
+#if 0
+ (stripChartMinMaxClassRec.core_class.superclass->core_class.destroy) (widget);
+#endif
+}
+
+static void
+SetPoints(Widget widget)
+{
+ printf ("resize\n");
+#if 0
+ (stripChartMinMaxClassRec.core_class.superclass->core_class.resize) (widget);
+#endif
+}
+
+static void
+Redisplay(Widget w, XEvent *event, Region region)
+{
+ printf ("expose\n");
+#if 0
+ (stripChartMinMaxClassRec.core_class.superclass->core_class.expose) (w, event, region);
+#endif
+}
+
+static Boolean
+SetValues (Widget current, Widget request, Widget new,
+ ArgList args, Cardinal *num_args)
+{
+ printf ("set_values\n");
+#if 0
+ return (stripChartMinMaxClassRec.core_class.superclass->core_class.set_values) (current, request, new, args, num_args);
+#endif
+}
+
+#endif
+
+static void
+SetTitleOfLabel (Widget w_label, String string)
+{
+ Arg title_args[1];
+
+ XtSetArg (title_args[0], XtNlabel, string);
+ XtSetValues (w_label, title_args, ONE);
+}
+
+static void
+SetNotPaned (Widget w)
+{
+ Arg paned_args[1];
+
+ XtSetArg (paned_args[0], XtNshowGrip, FALSE);
+ XtSetValues (w, paned_args, ONE);
+}
+
+
+/*
+ * The program
+ */
+
+static void
+GetUsedBytes(Widget w, XtPointer closure, XtPointer call_data)
+{
+ u_int32_t max_bytes;
+ u_int32_t used_bytes;
+ static char str[100];
+ char ub[100], mb[100];
+
+ Widget label = (Widget) closure;
+
+ double *bytesavg = (double *)call_data;
+ int err;
+
+ err = fs_getfilecachestats (&max_bytes, &used_bytes, NULL, NULL);
+
+ if (err) {
+ warnx ("bytes: fs_getfilecachestats returned %d", err);
+ *bytesavg = 1.0;
+ return;
+ }
+
+ if (max_bytes == 0) {
+ *bytesavg = 1.0;
+ warnx ("bytes: will not divide with zero (used: %d)", used_bytes);
+ return;
+ }
+
+ *bytesavg = (float) used_bytes / max_bytes;
+
+ if (debug)
+ warnx ("kbytes: max: %d used: %d usage: %f",
+ max_bytes, used_bytes, *bytesavg);
+
+ unparse_bytes_short (used_bytes, ub, sizeof(ub));
+ unparse_bytes_short (max_bytes, mb, sizeof(mb));
+
+ snprintf (str, sizeof(str), "(%s/%s)", ub, mb);
+ SetTitleOfLabel (label, str);
+}
+
+static void
+GetUsedVnodes(Widget w, XtPointer closure, XtPointer call_data)
+{
+ u_int32_t max_vnodes;
+ u_int32_t used_vnodes;
+ static char str[100];
+
+ Widget label = (Widget) closure;
+
+ double *vnodeavg = (double *)call_data;
+ int err;
+
+
+ err = fs_getfilecachestats (NULL, NULL, &max_vnodes, &used_vnodes);
+
+ if (err) {
+ *vnodeavg = 1.0;
+ warnx ("vnodes: fs_getfilecachestats returned %d", err);
+ return;
+ }
+
+ if (max_vnodes == 0) {
+ *vnodeavg = 1.0;
+ warnx ("vnodes: will not divide with zero (used: %d)", used_vnodes);
+ return;
+ }
+
+ *vnodeavg = (float) used_vnodes / max_vnodes;
+
+ if (debug)
+ warnx ("vnode: max: %d used: %d usage: %f",
+ max_vnodes, used_vnodes, *vnodeavg);
+
+ snprintf (str, sizeof(str), "vnodes# (%d/%d)", used_vnodes, max_vnodes);
+ SetTitleOfLabel (label, str);
+}
+
+#ifdef VIOC_AVIATOR
+static void
+GetUsedWorkers(Widget w, XtPointer closure, XtPointer call_data)
+{
+ u_int32_t max_workers;
+ u_int32_t used_workers;
+ static char str[100];
+
+ Widget label = (Widget) closure;
+
+ double *workeravg = (double *)call_data;
+ int err;
+
+ err = fs_getaviatorstats (&max_workers, &used_workers);
+
+ if (err) {
+ *workeravg = 1.0;
+ warnx ("workers: fs_getfilecachestats returned %d", err);
+ return;
+ }
+
+ if (max_workers == 0) {
+ *workeravg = 1.0;
+ warnx ("workers: will not divide with zero (used: %d)", used_workers);
+ return;
+ }
+
+ *workeravg = (float) used_workers / max_workers;
+
+ if (debug)
+ warnx ("workers: max: %d used: %d usage: %f",
+ max_workers, used_workers, *workeravg);
+
+ snprintf (str, sizeof(str), "workers (%d/%d)", used_workers, max_workers);
+ SetTitleOfLabel (label, str);
+}
+#endif
+
+static void
+CreateMonitorBar (Widget frame, XtCallbackProc proc, String name)
+{
+ Widget box, bar, label;
+ Arg pretty_args[] = {
+ {XtNborderWidth, (XtArgVal)0},
+ };
+
+ box = XtCreateManagedWidget ("box", panedWidgetClass,
+ frame, (ArgList) NULL, ZERO);
+
+ label = XtCreateManagedWidget ("label", labelWidgetClass,
+ box, pretty_args,
+ XtNumber(pretty_args));
+
+ SetTitleOfLabel (label, name);
+ SetNotPaned (label);
+
+ bar = XtCreateManagedWidget ("bar", stripChartWidgetClass,
+ box, NULL, ZERO);
+ XtAddCallback (bar, XtNgetValue, proc, label);
+ SetNotPaned (bar);
+}
+
+
+
+/*
+ * Actions
+ */
+
+static void
+quit(Widget widget, XEvent *event, String *params, Cardinal *num_parms)
+{
+ XtDestroyApplicationContext(app_con);
+ exit(0);
+}
+
+
+/*
+ *
+ */
+
+int main (int argc, char **argv)
+{
+ Widget top, frame;
+
+ XtActionsRec Actions[] = {
+ { "quit", quit}
+ };
+
+ if (debug)
+ warnx ("has afs");
+
+ if (!k_hasafs())
+ errx (1, "no afs");
+
+ if (debug)
+ warnx ("init Xt");
+
+ top = XtAppInitialize(&app_con, "amon", NULL, ZERO,
+ /* options, XtNumber(options), */
+ &argc, argv, NULL, NULL, (Cardinal) 0);
+
+ if (argc != 1)
+ errx (1, "usage");
+
+ if (debug)
+ warnx ("creating windows");
+
+ XtAppAddActions (app_con, Actions, XtNumber(Actions));
+
+
+ frame = XtCreateManagedWidget ("frame", panedWidgetClass,
+ top, (ArgList) NULL, ZERO);
+
+ XtOverrideTranslations(frame,
+ XtParseTranslationTable("<Key>q:quit()\n"));
+
+ /* XXX */
+ CreateMonitorBar (frame, GetUsedBytes," bytes (0/0) ");
+ CreateMonitorBar (frame, GetUsedVnodes, "vnode# (0/0)");
+#ifdef VIOC_AVIATOR
+ CreateMonitorBar (frame, GetUsedWorkers, "workers# (0/0)");
+#endif
+
+ XtRealizeWidget (top);
+
+ if (debug)
+ warnx ("X-loop");
+
+ XtAppMainLoop(app_con);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/asrvutil/Makefile.in b/usr.sbin/afs/src/appl/asrvutil/Makefile.in
new file mode 100644
index 00000000000..bdaeeee23f3
--- /dev/null
+++ b/usr.sbin/afs/src/appl/asrvutil/Makefile.in
@@ -0,0 +1,119 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:34 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = asrvutil
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+READLINE_lib = @LIB_readline@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient -lkaclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ -L../../lib/roken \
+ $(READLINE_lib) \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = asrvutil
+ASRVUTIL_SRCS = asrvutil.c
+SRCS = $(ASRVUTIL_SRCS)
+ASRVUTIL_OBJS = asrvutil.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+asrvutil: $(ASRVUTIL_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(ASRVUTIL_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/asrvutil/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/asrvutil/README b/usr.sbin/afs/src/appl/asrvutil/README
new file mode 100644
index 00000000000..6168b21af74
--- /dev/null
+++ b/usr.sbin/afs/src/appl/asrvutil/README
@@ -0,0 +1,10 @@
+CURRENT STATUS:
+===============
+
+It seems to me that you can't get equivalent of changepw/kerberos thru
+the kerberos server running in the KA-server.
+
+Now I haven't found any documentation how you really get tokens from
+the ka-server. If someone helps me with that, ending the program is
+trivial (ahm, a least it should be).
+
diff --git a/usr.sbin/afs/src/appl/asrvutil/asrvutil.c b/usr.sbin/afs/src/appl/asrvutil/asrvutil.c
new file mode 100644
index 00000000000..0a41e76f3c0
--- /dev/null
+++ b/usr.sbin/afs/src/appl/asrvutil/asrvutil.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <sl.h>
+#include "appl_locl.h"
+#include <ka.h>
+#include <ka.cs.h>
+#include <err.h>
+
+RCSID("$Id: asrvutil.c,v 1.1 2000/09/11 14:40:34 art Exp $");
+
+static int help_cmd (int argc, char **argv);
+
+/*
+ * This code is pretty much just stolen out of ksrvutil_get.c
+ */
+
+void
+safe_write(char *filename, int fd, void *buf, size_t len)
+{
+ if (write(fd, buf, len) != len) {
+ warn("write %s", filename);
+ close(fd);
+ errx(1, "safe_write: In progress srvtab in this file. %s", filename);
+ }
+}
+
+#ifndef ANAME_SZ
+#define ANAME_SZ 40
+#define REALM_SZ 40
+#define SNAME_SZ 40
+#define INST_SZ 40
+#endif
+
+void
+add_key_to_file (char *file,
+ kaname *name,
+ kaname *instance,
+ int32_t kvno,
+ const EncryptionKey *key)
+{
+ char sname[ANAME_SZ]; /* name of service */
+ char sinst[INST_SZ]; /* instance of service */
+ char srealm[REALM_SZ]; /* realm of service */
+ char realm[REALM_SZ]; /* realm of service */
+ int8_t skvno;
+ des_cblock skey;
+ int fd;
+
+ strlcpy (realm, cell_getthiscell(), sizeof(realm));
+
+ {
+ char *cp;
+ for (cp = realm; *cp; cp++)
+ *cp = toupper(*cp);
+ }
+
+
+ if (file == NULL)
+ file = "/etc/srvtab";
+
+ fd = open (file, O_RDWR|O_CREAT, 0600);
+ if (fd < 0)
+ err (1, "add_key_to_file: open");
+
+ lseek(fd, 0, SEEK_SET);
+
+ while(getst(fd, sname, SNAME_SZ) > 0 &&
+ getst(fd, sinst, INST_SZ) > 0 &&
+ getst(fd, srealm, REALM_SZ) > 0 &&
+ read(fd, &skvno, sizeof(skvno)) > 0 &&
+ read(fd, skey, sizeof(skey)) > 0) {
+
+ if(strcmp((char *)name, sname) == 0 &&
+ strcmp((char *)instance, sinst) == 0 &&
+ strcasecmp(realm, srealm) == 0) {
+ lseek(fd, lseek(fd,0,SEEK_CUR)-(sizeof(skvno) + sizeof(skey)),
+ SEEK_SET);
+ safe_write(file, fd, &kvno, sizeof(kvno));
+ safe_write(file, fd, (EncryptionKey *)key,
+ sizeof(EncryptionKey));
+ if (close (fd))
+ err (1, "add_key_to_file: close");
+ return;
+ }
+ }
+ safe_write(file, fd, name, strlen((char *)name) + 1);
+ safe_write(file, fd, instance, strlen((char *)instance) + 1);
+ safe_write(file, fd, realm, strlen(realm) + 1);
+ safe_write(file, fd, &kvno, sizeof(kvno));
+ safe_write(file, fd, (EncryptionKey *)key,
+ sizeof(EncryptionKey));
+
+ if (close (fd))
+ err (1, "add_key_to_file: close");
+}
+
+/*
+ *
+ */
+
+static void
+asrvutil_usage(char *progname)
+{
+ printf("asrvutil - manages srvtabs. An afs replacement for ksrvutil\n");
+ printf("Type \"%s help\" to get a list of commands.\n",
+ progname);
+ exit(1);
+}
+
+/*
+ *
+ */
+
+void
+get_usage(void)
+{
+ printf("Usage: get [-cell <cell>] [-noauth] [-help]\n");
+}
+
+/*
+ *
+ */
+
+static int
+get_cmd (int argc, char **argv)
+{
+ int optind = 0;
+ int ret;
+ struct rx_connection *connkadb = NULL;
+ kaname name, instance;
+ kaentryinfo entry;
+ EncryptionKey key;
+ des_cblock deskey;
+ int32_t dbhost = 0;
+ char *file = NULL;
+
+ char *cell = (char *) cell_getthiscell();
+ int noauth = 0;
+
+ static struct getargs get_args[] = {
+ {"name", 0, arg_string, NULL, "what name to use",
+ NULL},
+ {"instance", 0, arg_string, NULL, "what instance to use",
+ NULL},
+ {"cell", 0, arg_string, NULL, "what cell to use",
+ NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}}, *arg;
+
+ memset (&name, 0, sizeof(name));
+ memset (&instance, 0, sizeof(instance));
+
+ arg = get_args;
+ arg->value = &name; arg++;
+ arg->value = &instance;arg++;
+ arg->value = &cell; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (get_args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ get_usage();
+ return 0;
+ }
+
+ memset (&entry, 0, sizeof(entry));
+ memset (&key, 0, sizeof(key));
+
+ if (name[0] == '\0') {
+ printf ("name: ");
+ fflush (stdout);
+ if (read(0, name, sizeof(name)-1) < 0) {
+ err(1, "get: read stdin");
+ }
+ name[sizeof(name)-1] = 0;
+ }
+
+ if (instance[0] == '\0') {
+ printf ("instace: ");
+ fflush (stdout);
+ if (read(0, instance, sizeof(instance)-1) < 0) {
+ err(1, "get: read stdin");
+ }
+ instance[sizeof(instance)-1] = 0;
+ }
+
+ /* XXX should really try all dbservers */
+
+ ret = arlalib_getsyncsite (cell, NULL, afskaport,
+ &dbhost,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (ret) {
+ warnx ("get: arlalib_getsyncsite: %s (%d)\n",
+ koerr_gettext(ret), ret);
+ return 0;
+ }
+ if (dbhost == 0)
+ errx (1, "arlalib_getsyncsite: returned dbhost == 0, that not valid");
+
+ printf ("dbhost: %d\n", dbhost);
+
+
+ connkadb = arlalib_getconnbyaddr(cell,
+ dbhost,
+ NULL,
+ afskaport,
+ KA_MAINTENANCE_SERVICE_ID,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+
+ if (connkadb == NULL)
+ errx(1, "Could not connect to kaserver");
+
+ des_new_random_key (&deskey);
+ assert (sizeof (key) == sizeof(deskey));
+ memcpy (&key, &deskey, sizeof(deskey));
+ memset (&key, 0, sizeof(key));
+
+ ret = KAM_GetEntry (connkadb, name, instance, KAMAJORVERSION, &entry);
+ switch (ret) {
+ case 0:
+ /* Entry does already exist, just get password */
+
+ ret = KAM_SetPassword (connkadb, name, instance,
+ entry.key_version + 1, key);
+ if (ret)
+ warnx ("get: KAM_SetPassword returned %s (%d)",
+ koerr_gettext(ret), ret);
+
+ add_key_to_file (file, &name, &instance, entry.key_version + 1, &key);
+
+ break;
+ case KANOENT:
+ /* Entry doesn't exist, create (and with that set password) */
+
+ ret = KAM_CreateUser (connkadb, name, instance, key);
+ if (ret)
+ warnx ("get: KAM_CreateUser returned %s (%d)",
+ koerr_gettext(ret), ret);
+
+ add_key_to_file (file, &name, &instance, 1, &key);
+
+ break;
+ default:
+ warnx ("get: KAM_GetEntry returned %s (%d)",
+ koerr_gettext(ret), ret);
+
+ ret = 0;
+ break;
+ }
+
+ memset (&key, 0, sizeof(key));
+ arlalib_destroyconn(connkadb);
+ return ret;
+}
+
+/*
+ *
+ */
+
+static SL_cmd cmds[] = {
+ {"get", get_cmd, "get a new cred"},
+ {"help", help_cmd, "get help on pts"},
+ {"?"},
+ {NULL}
+};
+
+/*
+ *
+ */
+
+static int
+help_cmd (int argc, char **argv)
+{
+ sl_help(cmds, argc, argv);
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+main (int argc, char **argv)
+{
+ int ret;
+
+ ports_init();
+ cell_init(0); /* XXX */
+
+ if(argc > 1) {
+ ret = sl_command(cmds, argc - 1, argv + 1);
+ if (ret == -1)
+ printf("%s: Unknown command\n", argv[1]);
+ }
+ else
+ asrvutil_usage(argv[0]);
+
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/appl/bos/Makefile.in b/usr.sbin/afs/src/appl/bos/Makefile.in
new file mode 100644
index 00000000000..8e3127cf153
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/Makefile.in
@@ -0,0 +1,119 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:35 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = bos
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+READLINE_lib = @LIB_readline@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ -L../../lib/roken \
+ $(READLINE_lib) \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = bos
+BOS_SRCS = bos.c bos_status.c bos_adduser.c bos_getrestart.c bos_listhosts.c bos_listusers.c
+SRCS = $(BOS_SRCS)
+BOS_OBJS = bos.o bos_status.o bos_adduser.o bos_getrestart.o bos_listhosts.o bos_listusers.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+bos: $(BOS_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(BOS_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/bos/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/bos/bos.c b/usr.sbin/afs/src/appl/bos/bos.c
new file mode 100644
index 00000000000..238c99d95b1
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos.c
@@ -0,0 +1,163 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "bos_local.h"
+
+RCSID("$Id: bos.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+int bos_interactive = 0;
+
+static int empty_cmd(int argc, char **argv);
+static int quit_cmd(int argc, char **argv);
+static int help_cmd(int argc, char **argv);
+static int apropos_cmd(int argc, char **argv);
+
+
+/*
+ * command table
+ */
+
+static SL_cmd cmds[] = {
+ {"addhost", empty_cmd, "not yet implemented"},
+ {"addkey", empty_cmd, "not yet implemented"},
+ {"adduser", bos_adduser, "add users to super-user list"},
+ {"apropos", apropos_cmd, "apropos help"},
+ {"create", empty_cmd, "not yet implemented"},
+ {"delete", empty_cmd, "not yet implemented"},
+ {"exec", empty_cmd, "not yet implemented"},
+ {"exit", quit_cmd, "exit interactive mode"},
+ {"getdate", empty_cmd, "not yet implemented"},
+ {"getlog", empty_cmd, "not yet implemented"},
+ {"getrestart",bos_getrestart, "get restart times"},
+ {"help", help_cmd, "print help"},
+ {"install", empty_cmd, "not yet implemented"},
+ {"listhosts", bos_listhosts, "list VLDB-servers"},
+ {"listkeys", empty_cmd, "not yet implemented"},
+ {"listusers", bos_listusers, "list super-users"},
+ {"prune", empty_cmd, "not yet implemented"},
+ {"removehost", empty_cmd, "not yet implemented"},
+ {"removekey", empty_cmd, "not yet implemented"},
+ {"removeuser", empty_cmd, "not yet implemented"},
+ {"restart", empty_cmd, "not yet implemented"},
+ {"salvage", empty_cmd, "not yet implemented"},
+ {"setauth", empty_cmd, "not yet implemented"},
+ {"setcellname", empty_cmd, "not yet implemented"},
+ {"setrestart", empty_cmd, "not yet implemented"},
+ {"shutdown", empty_cmd, "not yet implemented"},
+ {"start", empty_cmd, "not yet implemented"},
+ {"status", bos_status, "Show volume server transactions"},
+ {"stop", empty_cmd, "not yet implemented"},
+ {"uninstall", empty_cmd, "not yet implemented"},
+ {"quit", quit_cmd, "exit interactive mode"},
+ {NULL}
+};
+
+/*
+ * Dummy command
+ */
+
+static int
+empty_cmd(int argc, char **argv)
+{
+ printf("%s%s has not been implemented yet!\n", PROGNAME, argv[0]);
+ return 0;
+}
+
+/*
+ * quit
+ */
+
+static int
+quit_cmd(int argc, char **argv)
+{
+ printf("exiting\n");
+ return 1;
+}
+
+/*
+ * help
+ */
+
+static int
+help_cmd(int argc, char **argv)
+{
+ sl_help(cmds, argc, argv);
+ return 0;
+}
+
+/*
+ * apropos
+ */
+
+static int
+apropos_cmd(int argc, char **argv)
+{
+ if (argc == 0) {
+ fprintf (stderr, "apropos: missing topic");
+ return 0;
+ }
+
+ sl_apropos(cmds, argv[1]);
+ return 0;
+}
+
+
+/*
+ * Main program
+ */
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+
+ cell_init(0);
+ ports_init();
+
+ if (argc > 1)
+ ret = sl_command(cmds, argc - 1, argv + 1);
+ else {
+ bos_interactive = 1;
+ printf("bos - an arla tool for administrating AFS-servers.\n");
+ printf("Type \"help\" to get a list of commands.\n");
+ ret = sl_loop(cmds, __progname": ");
+ }
+ return ret;
+}
diff --git a/usr.sbin/afs/src/appl/bos/bos_adduser.c b/usr.sbin/afs/src/appl/bos/bos_adduser.c
new file mode 100644
index 00000000000..7e2283d16e6
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos_adduser.c
@@ -0,0 +1,140 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "bos_local.h"
+#include <bos.h>
+#include <bos.cs.h>
+
+
+RCSID("$Id: bos_adduser.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+static int
+adduser(const char *cell, const char *host, const char *user,
+ int noauth, int localauth, int verbose)
+{
+ struct rx_connection *connvolser = NULL;
+ int error;
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsbosport,
+ BOS_SERVICE_ID,
+ arlalib_getauthflag(noauth,localauth,0,0));
+ if (connvolser == NULL)
+ return -1;
+
+ printf ("65 %s on %s in %s\n", user, host, cell);
+ if (( error = BOZO_AddSUser(connvolser, user)) == 0) {
+ printf ("67\n");
+ printf ("bos: User %s added to the UserList on server %s\n", user, host);
+ }
+ switch (error) {
+ case BZACCESS:
+ printf ("bos: You are not allowed to add the user %s to the userlist on server %s\n", user,host);
+ break;
+ case EEXIST:
+ printf ("bos: User %s alredy exists on the userlist on host %s\n", user, host);
+ break;
+ case EIO:
+ printf ("bos: the UserList-file could not be opened or closed on server %s\n", host);
+ break;
+ default:
+ printf("bos: GetStat failed with: %s (%d)\n",koerr_gettext(error),error);
+
+ }
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+
+static int helpflag;
+static const char *server;
+static const char *cell;
+static const char *user;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"user", 0, arg_string, &user, "user", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"local", 0, arg_flag, &localauth, "localauth"},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (void)
+{
+ arg_printusage (args, "bos adduser", "", ARG_AFSSTYLE);
+}
+
+int
+bos_adduser(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ printf ("bos adduser: missing -server\n");
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+ printf ("3333 %s\n", cell);
+ adduser (cell, server, user, noauth, localauth, verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/bos/bos_getrestart.c b/usr.sbin/afs/src/appl/bos/bos_getrestart.c
new file mode 100644
index 00000000000..c39236cf47d
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos_getrestart.c
@@ -0,0 +1,130 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "bos_local.h"
+#include <bos.h>
+#include <bos.cs.h>
+/* #include <time.h> we schould .... */
+
+RCSID("$Id: bos_getrestart.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+static int
+printrestart(const char *cell, const char *host,
+ int noauth, int localauth, int verbose)
+{
+ struct rx_connection *connvolser = NULL;
+ struct bozo_netKTime time;
+ int error;
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsbosport,
+ BOS_SERVICE_ID,
+ arlalib_getauthflag(noauth,
+ localauth,0,0));
+
+ if (connvolser == NULL)
+ return -1;
+
+ if (( error = BOZO_GetRestartTime(connvolser, 1, &time)) == 0) {
+ printf ("Server %s restarts at %02d:%02d:%02d at day %d\n", host, time.hour, time.min, time.sec, time.day);
+
+ }
+ if (( error = BOZO_GetRestartTime(connvolser, 2, &time)) == 0) {
+ printf ("Server %s restarts for new binaries at %02d:%02d:%02d at day %d\n", host, time.hour, time.min, time.sec, time.day);
+ }
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+
+static int helpflag;
+static const char *server;
+static const char *cell;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"local", 0, arg_flag, &localauth, "localauth"},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (void)
+{
+ arg_printusage (args, "bos getrestart", "", ARG_AFSSTYLE);
+}
+
+int
+bos_getrestart(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ printf ("bos getrestart: missing -server\n");
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+
+ printrestart (cell, server, noauth, localauth, verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/bos/bos_listhosts.c b/usr.sbin/afs/src/appl/bos/bos_listhosts.c
new file mode 100644
index 00000000000..7722c00c647
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos_listhosts.c
@@ -0,0 +1,142 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "bos_local.h"
+#include <bos.h>
+#include <bos.cs.h>
+
+
+RCSID("$Id: bos_listhosts.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+static int
+printhosts(const char *cell, const char *host,
+ int noauth, int localauth, int verbose)
+{
+ struct rx_connection *connvolser = NULL;
+ unsigned int i;
+ int error;
+ char *server_name;
+ char *cell_name;
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsbosport,
+ BOS_SERVICE_ID,
+ arlalib_getauthflag(noauth,
+ localauth,0,0));
+
+ if (connvolser == NULL)
+ return -1;
+
+ /* which cell is this anyway ? */
+ if (( error = BOZO_GetCellName(connvolser, &cell_name)) == 0) {
+ printf("Cell name is %s\n",cell_name);
+ }
+ else {
+ printf ("bos %s: %s\n", host, koerr_gettext (error));
+ }
+
+ /* Who are the VLDB-servers ? */
+ i = 0;
+ while ((error = BOZO_GetCellHost(connvolser, i,
+ &server_name)) == 0) {
+ printf("\t Host %d is %s\n",i+1,server_name);
+ i++;
+ }
+
+ if (error != BZDOM)
+ printf ("bos %s: %s\n", host, koerr_gettext (error));
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+
+static int helpflag;
+static const char *server;
+static const char *cell;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"local", 0, arg_flag, &localauth, "localauth"},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (void)
+{
+ arg_printusage (args, "bos listhosts", "", ARG_AFSSTYLE);
+}
+
+int
+bos_listhosts(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ printf ("bos listhosts: missing -server\n");
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+
+ printhosts (cell, server, noauth, localauth, verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/bos/bos_listusers.c b/usr.sbin/afs/src/appl/bos/bos_listusers.c
new file mode 100644
index 00000000000..3fa4852d9e7
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos_listusers.c
@@ -0,0 +1,135 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "bos_local.h"
+#include <bos.h>
+#include <bos.cs.h>
+
+
+RCSID("$Id: bos_listusers.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+static int
+printusers(const char *cell, const char *host,
+ int noauth, int localauth, int verbose)
+{
+ struct rx_connection *connvolser = NULL;
+ unsigned int i;
+ int error;
+ char *user_name[256];
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsbosport,
+ BOS_SERVICE_ID,
+ 0);
+ if (connvolser == NULL)
+ return -1;
+
+ if (( error = BOZO_ListSUsers(connvolser, 0, &user_name[0])) == 1) {
+ printf ("bos %s: UserList could not be opened or no users on this server\n", host);
+ return -1;
+ }
+
+ /* who is superuser on server_name ? */
+ i = 0;
+ printf("SUsers are: ");
+ while (( error = BOZO_ListSUsers(connvolser, i, &user_name[i])) == 0) {
+ printf("%s ",user_name[i]);
+ i++;
+ }
+ printf("\n");
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+
+static int helpflag;
+static const char *server;
+static const char *cell;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"local", 0, arg_flag, &localauth, "localauth"},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (void)
+{
+ arg_printusage (args, "bos listusers", "", ARG_AFSSTYLE);
+}
+
+int
+bos_listusers(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ printf ("bos listusers: missing -server\n");
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+
+ printusers (cell, server, noauth, localauth, verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/bos/bos_local.h b/usr.sbin/afs/src/appl/bos/bos_local.h
new file mode 100644
index 00000000000..71a1b21f4cf
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos_local.h
@@ -0,0 +1,61 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * RCSID("$Id: bos_local.h,v 1.1 2000/09/11 14:40:35 art Exp $");
+ */
+
+/*
+#define LISTVOL_PART 0x1
+#define LISTVOL_NOAUTH 0x2
+#define LISTVOL_LOCALAUTH 0x4
+#define LISTVOL_FAST 0x8
+*/
+
+/* this program needs __progname defined as a macro */
+#define __progname "bos"
+#define PROGNAME (bos_interactive ? "" : __progname" ")
+
+/* if this is set the program runs in interactive mode */
+extern int bos_interactive;
+
+int bos_status (int, char **);
+int bos_listhosts (int, char **);
+int bos_listusers (int, char **);
+int bos_adduser (int, char **);
+int bos_getrestart (int, char **);
diff --git a/usr.sbin/afs/src/appl/bos/bos_status.c b/usr.sbin/afs/src/appl/bos/bos_status.c
new file mode 100644
index 00000000000..bc2473db685
--- /dev/null
+++ b/usr.sbin/afs/src/appl/bos/bos_status.c
@@ -0,0 +1,200 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "bos_local.h"
+#include <bos.h>
+#include <bos.cs.h>
+
+
+RCSID("$Id: bos_status.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+/*
+ *
+ */
+
+static void
+print_instance_status (char *instance_name,
+ int getstatus_int,
+ char *getstatus_str)
+{
+ switch (getstatus_int) {
+ case BSTAT_SHUTDOWN:
+ printf("Instance %s, disabled, currently shutdown.\n",
+ instance_name);
+ break;
+ case BSTAT_NORMAL:
+ printf("Instance %s, currently running normally.\n",
+ instance_name);
+ break;
+ case BSTAT_SHUTTINGDOWN:
+ printf("Instance %s, temporarily disabled, "
+ "currently shutting down.\n",
+ instance_name);
+ break;
+ case BSTAT_STARTINGUP:
+ printf("Instance %s, currently starting up.\n",
+ instance_name);
+ break;
+ default:
+ printf (" unknown Status = %d (%s)\n",
+ getstatus_int, getstatus_str);
+ break;
+ }
+}
+
+/*
+ *
+ */
+
+static int
+printstatus(const char *cell,
+ const char *host,
+ int noauth,
+ int localauth,
+ int verbose)
+{
+ struct rx_connection *conn;
+ unsigned int i;
+ int error;
+ char *instance_name;
+ int getstatus_int;
+ char getstatus_str[BOZO_BSSIZE];
+
+ conn = arlalib_getconnbyname(cell,
+ host,
+ afsbosport,
+ BOS_SERVICE_ID,
+ arlalib_getauthflag(noauth,localauth,0,0));
+
+ if (conn == NULL)
+ return -1;
+
+ i = 0;
+ do {
+ error = BOZO_EnumerateInstance(conn, i, &instance_name);
+ if (error == 0) {
+ error = BOZO_GetStatus(conn, instance_name,
+ &getstatus_int, getstatus_str);
+ if (error == -1) {
+ warnx ("failed to contact host's bosserver (%s) "
+ "(communications failure (-1)).",
+ host);
+ } else if (error != 0) {
+ warnx ("GetStatus(%s) failed with: %s (%d)",
+ instance_name,
+ koerr_gettext(error),
+ error);
+ } else {
+ print_instance_status (instance_name,
+ getstatus_int,
+ getstatus_str);
+ }
+ error = 0;
+ }
+ i++;
+ } while (error == 0);
+ if (error != BZDOM)
+ warnx ("%s: %s", host, koerr_gettext (error));
+
+ arlalib_destroyconn(conn);
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int helpflag;
+static const char *server;
+static const char *cell;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"local", 0, arg_flag, &localauth, "localauth"},
+ {"verbose", 0, arg_flag, &verbose, "be verbose"},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+/*
+ *
+ */
+
+static int
+usage (int exit_code)
+{
+ arg_printusage (args, "bos status", "", ARG_AFSSTYLE);
+ return exit_code;
+}
+
+/*
+ *
+ */
+
+int
+bos_status(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE))
+ return usage (0);
+
+ if (helpflag)
+ return usage (0);
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ printf ("bos status: missing -server\n");
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+
+ printstatus (cell, server, noauth, localauth, verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/fs/Makefile.in b/usr.sbin/afs/src/appl/fs/Makefile.in
new file mode 100644
index 00000000000..ffebeb9a762
--- /dev/null
+++ b/usr.sbin/afs/src/appl/fs/Makefile.in
@@ -0,0 +1,136 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:35 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+mandir = @mandir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = fs
+MANPAGES = fs.1
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+READLINE_lib = @LIB_readline@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ -L../../lib/roken \
+ $(READLINE_lib) \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = fs
+FS_SRCS = fs.c
+SRCS = $(FS_SRCS)
+FS_OBJS = fs.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir) ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+fs: $(FS_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(FS_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/fs/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/fs/fs.1 b/usr.sbin/afs/src/appl/fs/fs.1
new file mode 100644
index 00000000000..cd439e72857
--- /dev/null
+++ b/usr.sbin/afs/src/appl/fs/fs.1
@@ -0,0 +1,654 @@
+.\" $OpenBSD: fs.1,v 1.1 2000/09/11 14:40:35 art Exp $
+.\" $Id: fs.1,v 1.1 2000/09/11 14:40:35 art Exp $
+.Dd March 29, 2000
+.Dt FS 1
+.Os
+.Sh NAME
+.Nm fs
+.Nd Manage AFS directorys
+.Sh SYNOPSIS
+.Nm
+.Op Ar command
+.Op Ar args
+.Sh DESCRIPTION
+The
+.Nm
+utility is used to manipulate the AFS filesystem.
+Note that the
+.Nm
+utility does
+.Em not
+modify the traditional
+.Ux
+filesystem, only files in AFS.
+.Pp
+The
+.Nm
+utility provides several commands:
+.Pp
+.Bl -tag -width setmaxpriority -compact
+.It Cm apropos
+locate commands by keyword
+.It Cm arladebug
+tweek arla-debugging flags
+.It Cm checkservers
+check if servers are up
+.It Cm checkvolumes
+not yet implemented
+.It Cm cleanacl
+not yet implemented
+.It Cm copyacl
+not yet implemented
+.It Cm diskfree
+show free partition space
+.It Cm examine
+examine volume status
+.It Cm flush
+remove file from cache
+.It Cm flushvolume
+remove volumedata (and files in volume) from cache
+.It Cm gcpags
+garbage collect pags
+.It Cm getcacheparms
+get cache usage
+.It Cm getcrypt
+get encrypt status
+.It Cm getcellstatus
+get suid cell status
+.It Cm getfid
+get fid
+.It Cm getserverprefs
+not yet implemented
+.It Cm getpriority
+get priority of a file/dir
+.It Cm gp
+shorthand for the
+.Cm getpriority
+command
+.It Cm getmaxpriority
+get max priority for a file gc
+.It Cm gmp
+shorthand for the
+.Cm getmaxpriority
+command
+.It Cm help
+get help for
+.Nm
+.It Cm listacl
+show acl
+.It Cm la
+shorthand for the
+.Cm listacl
+command
+.It Cm listcells
+list cells that the cache handler can communicate with
+.It Cm listquota
+show volume quota
+.It Cm lq
+shorthand for the
+.Cm listquota
+command
+.It Cm quota
+shorthand for the
+.Cm listquota
+command
+.It Cm lsmount
+show a mount point
+.It Cm messages
+not yet implemented
+.It Cm mkmount
+create mount point
+.It Cm connect
+connect mode
+.It Cm monitor
+set remote logging host
+.It Cm newcell
+add new cell
+.It Cm nop
+do a pioctl-nop
+.It Cm quit
+leave interactive mode
+.It Cm exit
+leave interactive mode
+.It Cm rmmount
+delete a mount point
+.It Cm removepriority
+remove priority from file/directory
+.It Cm rmp
+shorthand for the
+.Cm removepriority
+command
+.It Cm setacl
+add an acl entry on a directory
+.It Cm sa
+shorthand for the
+.Cm setacl
+command
+.It Cm setcachesize
+change disk cache size
+.It Cm setcell
+change cell status
+.It Cm setpriority
+set priority of a file/directory
+.It Cm sp
+shorthand for the
+.Cm setpriority
+command
+.It Cm setmaxpriority
+set upper limit of prio gc
+.It Cm smq
+shorthand for the
+.Cm setmaxpriority
+comand
+.It Cm setquota
+change quota on a volume
+.It Cm sq
+shorthand for the
+.Cm setquota
+command
+.It Cm setserverprefs
+not yet implemented
+.It Cm setcrypt
+set encryption on/off
+.It Cm setvol
+not yet implemented
+.It Cm suidcells
+list status of cells
+.It Cm sysname
+read/change sysname
+.It Cm version
+get version of fs and fs_lib
+.It Cm venuslog
+make arlad print status
+.It Cm whereis
+show server(s) of file
+.It Cm whichcell
+show cell of file
+.It Cm wscell
+display cell of workstation
+.It Cm xfsdebug
+tweek xfs-debugging flags
+.It Cm xfsprint
+make xfs print debug info
+.El
+.Pp
+Most
+.Nm
+commands accept the following general arguments:
+.Pp
+.Bd -filled -offset indent -compact
+.Op Fl cell Ar cellname
+Specifies which AFS cell to use, if the default cell is not to be used.
+.Pp
+.Op Fl noauth
+Specifies that
+.Nm
+should not try to authenticate the connection to the server.
+This may be
+useful with shell scripts, or if there is a problem with the AFS cell.
+Note that the server will reject many commands if
+.Fl noauth
+is specified.
+.Pp
+.Ed
+The syntax of the
+.Nm
+commands:
+.Pp
+.Ic fs apropos
+.Bd -filled -offset indent -compact
+Locate commands by keyword
+.Ed
+.Pp
+.Ic fs arladebug
+.Op Ar flags
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Tweek arla-debugging flags.
+.Ed
+.Pp
+.Ic fs checkservers
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl nopoll
+.Bd -filled -offset indent -compact
+Check if the server in a cell are up.
+If
+.Fl nopoll
+is specified, the servers are not contactad; only internal information is
+printed.
+.Ed
+.Pp
+.Ic fs checkvolumes
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs cleanacl
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs copyacl
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs diskfree
+.Ar path
+.Bd -filled -offset indent -compact
+show free partition space
+.Ed
+.Pp
+.Ic fs examine
+.Op Ar path
+.Bd -filled -offset indent -compact
+Print detailed information about the volume mounted on the specified path
+or the current directory.
+.Ed
+.Pp
+.Ic fs flush
+.Ar path
+.Bd -filled -offset indent -compact
+Flush the file specified, causing it to be stored on the fileserver.
+.Ed
+.Pp
+.Ic fs flushvolume
+.Ar path
+.Bd -filled -offset indent -compact
+Flush all the files in the volume where the file specified is stored,
+causing them to be stored on the fileserver.
+Meta information about the volume is also flushed.
+.Ed
+.Pp
+.Ic fs gcpags
+.Bd -filled -offset indent -compact
+Remove unused PAGs from the kernel.
+.Ed
+.Pp
+.Ic fs getcacheparms
+.Bd -filled -offset indent -compact
+Print information about cache usage.
+.Ed
+.Pp
+.Ic fs getcrypt
+.Bd -filled -offset indent -compact
+Display wether traffic between the client and server is encrypted.
+.Ed
+.Pp
+.Ic fs getcellstatus
+.Ar cellname
+.Bd -filled -offset indent -compact
+Indicate if setuid files are enabled for the specified cell.
+.Ed
+.Pp
+.Ic fs getfid
+.Ar path
+.Bd -filled -offset indent -compact
+Print fid information for a file.
+.Ed
+.Pp
+.Ic fs getserverprefs
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs getpriority
+.Bd -filled -offset indent -compact
+Display priority of a file or directory.
+.Ed
+.Pp
+.Ic fs gp
+.Bd -filled -offset indent -compact
+shorthand for the
+.Cm getpriority
+command
+.Ed
+.Pp
+.Ic fs getmaxpriority
+.Bd -filled -offset indent -compact
+Display max priority for a file.
+.Ed
+.Pp
+.Ic fs gmp
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Shorthand for the
+.Cm getmaxpriority
+command.
+.Ed
+.Pp
+.Ic fs help
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Get help for
+.Nm
+.Ed
+.Pp
+.Ic fs listacl
+.Ar path
+.Bd -filled -offset indent -compact
+Show acl for the specified path or the current directory.
+.Ed
+.Pp
+.Ic fs la
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Shorthand for the
+.Cm listacl
+command.
+.Ed
+.Pp
+.Ic fs listcells
+.Bd -filled -offset indent -compact
+List cells that the cache handler can communicate with.
+These are the cells listed in the file
+.Pa /usr/arla/etc/CellServDB .
+.Ed
+.Pp
+.Ic fs listquota
+.Op Ar path
+.Bd -filled -offset indent -compact
+Show the quota for the volume of the file or directory specified.
+.Ed
+.Pp
+.Ic fs lq
+.Bd -filled -offset indent -compact
+shorthand for the
+.Cm listquota
+command
+.Ed
+.Pp
+.Ic fs quota
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Shorthand for the
+.Ic listquota
+command.
+.Ed
+.Pp
+.Ic fs lsmount
+.Bd -filled -offset indent -compact
+.Ar path
+Show a mount point.
+.Ed
+.Pp
+.Ic fs messages
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs mkmount
+.Ar directory
+.Ar volume
+.Bd -filled -offset indent -compact
+Create a mountpoint.
+Note that the there must not exist a directory named as
+the mount point you are creating.
+.Ed
+.Pp
+.Ic fs connect
+.Op Ar mode
+.Bd -filled -offset indent -compact
+Set or get connected mode, if a mode is specified, the cache manager will be
+set to that mode.
+If not, the current mode will be printed.
+Valid modes are:
+.Bl -tag -width -Fl -compact
+.It Cm connected
+Connected mode - this is the normal operating mode.
+.It Cm fetch
+Fetch only mode - files are retreived from fileserver but are not stored back.
+.It Cm disconnected
+Disconnected mode - files are read and written from/to the cache, and no
+attempt is made to contact a fileserver-
+.El
+.Pp
+Disconnected mode is very useful for machines that are not connected to
+the network at all times, such as laptops.
+Disconnected mode is to be considered very experimental at this stage.
+.Ed
+.Pp
+.Ic fs monitor
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs newcell
+.Fl cell Ar cellname
+.Fl servers Ar vldb-servers
+.Op Fl help
+.Bd -filled -offset indent -compact
+Add a new cell to the running configuration of the cache manager, or update
+already existing information.
+This information should also be entered in the file
+.Pa /usr/arla/etc/CellServDB .
+.Ed
+.Pp
+.Ic fs nop
+.Bd -filled -offset indent -compact
+Do a pioctl-nop.
+This is useful for debugging.
+.Ed
+.Pp
+.Ic fs quit
+.Bd -filled -offset indent -compact
+Leave interactive mode.
+.Ed
+.Pp
+.Ic fs exit
+.Bd -filled -offset indent -compact
+Leave interactive mode.
+.Ed
+.Pp
+.Ic fs rmmount
+.Ar mountpoint
+.Bd -filled -offset indent -compact
+Delete a mount point.
+.Ed
+.Pp
+.Ic fs removepriority
+.Ar file
+.Bd -filled -offset indent -compact
+Remove priority from file/directory.
+.Ed
+.Pp
+.Ic fs rmp
+.Bd -filled -offset indent -compact
+Shorthand for the
+.Cm removepriority
+command.
+.Ed
+.Pp
+.Ic fs setacl
+.Bd -filled -offset indent -compact
+Add an acl entry on a directory.
+Each entry consists of two components:
+a user or group and a character string describing the permissions granted
+for that user or group.
+These characters and the permission they represent are:
+.Bl -tag -width Fl -compact
+.It Cm r
+read the files
+.It Cm l
+list the files
+.It Cm i
+insert new files
+.It Cm d
+delete files
+.It Cm w
+write (change) the files
+.It Cm k
+lock files
+.It Cm a
+administer the acl, that is, to change the acl
+.El
+.Pp
+There are also a few convinience strings recognized by
+.Ic fs setacl :
+.Bl -tag -width Fl -compact
+.It Cm none
+removes all permissions.
+.It Cm read
+adds 'rl' permissions, which are suitable for a read-only directory.
+.It Cm write
+adds all permissions except 'a', that is, the user/group can read, write,
+delete etc. but not change the acl of the directory.
+.It Cm all
+add all permissions.
+.El
+.Pp
+Note that in AFS you set the permissions on a directory, and the permissions
+of a file are those of their directory.
+So, if you move a file from one
+directory to another, you might change the permission of the file, as
+the two directorys may have different permissions.
+.Pp
+Of the traditional
+.Ux
+permission bits only the user part is honored, and is used for any
+user permissioned by the directorys acl.
+The group and world permission bits are ignored, but they are stored.
+.Ed
+.Pp
+.Ic fs sa
+.Bd -filled -offset indent -compact
+shorthand for the
+.Cm setacl
+command
+.Ed
+.Pp
+.Ic fs setcachesize
+.Ar lowvnodes
+.Op Ar highvnodes Ar lowbytes Ar highbytes
+.Bd -filled -offset indent -compact
+Set the size of the disk cache.
+.Ed
+.Pp
+.Ic fs setcell
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs setpriority
+.Ar file
+.Ar priority
+.Bd -filled -offset indent -compact
+Set priority of a file/directory.
+.Ed
+.Pp
+.Ic fs sp
+.Bd -filled -offset indent -compact
+Shorthand for the
+.Cm setpriority
+command.
+.Ed
+.Pp
+.Ic fs setmaxpriority
+.Ar macprio
+.Bd -filled -offset indent -compact
+Set upper limit of priority.
+.Ed
+.Pp
+.Ic fs smq
+.Bd -filled -offset indent -compact
+shorthand for the
+.Cm setmaxpriority
+comand
+.Ed
+.Pp
+.Ic fs setquota
+.Ar path
+.Ar quota
+.Bd -filled -offset indent -compact
+Set the quota (in Kbytes) on a volume.
+.Ed
+.Pp
+.Ic fs sq
+.Bd -filled -offset indent -compact
+Shorthand for the
+.Cm setquota
+command.
+.Ed
+.Pp
+.Ic fs setserverprefs
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs setcrypt
+.Ar flag
+.Bd -filled -offset indent -compact
+If 'no' is specified, encryption of the traffic to/from fileservers is
+disabled, and if 'yes' is specified, it is enabled.
+.Ed
+.Pp
+.Ic fs setvol
+.Bd -filled -offset indent -compact
+Not implemented yet.
+.Ed
+.Pp
+.Ic fs suidcells
+.Bd -filled -offset indent -compact
+Print cells and wether setuid execution is allowed for them.
+.Ed
+.Pp
+.Ic fs sysname
+.Op Ar sysname
+.Bd -filled -offset indent -compact
+Get or set the value of the '@sys' value.
+.Ed
+.Pp
+.Ic fs version
+.Bd -filled -offset indent -compact
+Print version of fs and fs_lib.
+.Ed
+.Pp
+.Ic fs venuslog
+.Bd -filled -offset indent -compact
+Make afsd print status.
+.Ed
+.Pp
+.Ic fs whereis
+.Op Ar path
+.Bd -filled -offset indent -compact
+Show server(s) of the specified file or the current directory.
+.Ed
+.Pp
+.Ic fs whichcell
+.Op Ar path
+.Bd -filled -offset indent -compact
+Show cell of a file or the current directory.
+.Ed
+.Pp
+.Ic fs wscell
+.Bd -filled -offset indent -compact
+Display default cell of the client.
+.Ed
+.Pp
+.Ic fs xfsdebug
+.Bd -filled -offset indent -compact
+Tweek xfs-debugging flags
+.Ed
+.Pp
+.Ic fs xfsprint
+.Op Ar flags
+.Bd -filled -offset indent -compact
+Make xfs print debug info.
+.Ed
+.Sh SEE ALSO
+.Xr afsd 8 ,
+.Xr pts 1 ,
+.Xr vos 8
+.Sh STANDARDS
+The Arla authors are trying to mimic the behaviour of the original AFS
+utilities.
+.Sh AUTHORS
+The Arla project <http://www.stacken.kth.se/project/arla/>.
+.Sh BUGS
+Some commands are not implemented yet.
diff --git a/usr.sbin/afs/src/appl/fs/fs.c b/usr.sbin/afs/src/appl/fs/fs.c
new file mode 100644
index 00000000000..be74aece171
--- /dev/null
+++ b/usr.sbin/afs/src/appl/fs/fs.c
@@ -0,0 +1,2169 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+
+#include <sl.h>
+#include "appl_locl.h"
+#include <kafs.h>
+#include <parse_units.h>
+#include <xfs/xfs_debug.h>
+#include <xfs/xfs_deb.h>
+#include "fs_local.h"
+#include <arladeb.h>
+
+RCSID("$Id: fs.c,v 1.1 2000/09/11 14:40:35 art Exp $");
+
+static int empty_cmd (int argc, char **argv);
+static int apropos_cmd (int argc, char **argv);
+static int arladebug_cmd (int argc, char **argv);
+static int calculate_cmd (int argc, char **argv);
+static int checkservers_cmd (int argc, char **argv);
+static int copyacl_cmd (int argc, char **argv);
+static int diskfree_cmd (int argc, char **argv);
+static int examine_cmd (int argc, char **argv);
+static int flush_cmd (int argc, char **argv);
+static int flushvolume_cmd (int argc, char **argv);
+static int gc_cmd (int argc, char **argv);
+static int getcache_cmd (int argc, char **argv);
+static int getcrypt_cmd (int argc, char **argv);
+static int getcellstatus_cmd (int argc, char **argv);
+static int getfid_cmd (int argc, char **argv);
+static int getprio_cmd (int argc, char **argv);
+static int getmaxprio_cmd (int argc, char **argv);
+static int help_cmd (int argc, char **argv);
+static int invalidate_cmd (int argc, char **argv);
+static int listacl_cmd (int argc, char **argv);
+static int listcells_cmd (int argc, char **argv);
+static int suidcells_cmd (int argc, char **argv);
+static int listquota_cmd (int argc, char **argv);
+static int lsmount_cmd (int argc, char **argv);
+static int mkmount_cmd (int argc, char **argv);
+static int connect_cmd (int argc, char **argv);
+static int newcell_cmd (int argc, char **argv);
+static int nop_cmd (int argc, char **argv);
+static int quit_cmd (int argc, char **argv);
+static int quota_cmd (int argc, char **argv);
+static int rmmount_cmd (int argc, char **argv);
+static int rmprio_cmd (int argc, char **argv);
+static int setacl_cmd (int argc, char **argv);
+static int setcache_cmd (int argc, char **argv);
+static int setprio_cmd (int argc, char **argv);
+static int setmaxprio_cmd (int argc, char **argv);
+static int setquota_cmd (int argc, char **argv);
+static int setcrypt_cmd (int argc, char **argv);
+static int strerror_cmd (int argc, char **argv);
+static int sysname_cmd (int argc, char **argv);
+static int fsversion_cmd (int argc, char **argv);
+static int venuslog_cmd (int argc, char **argv);
+static int whereis_cmd (int argc, char **argv);
+static int whichcell_cmd (int argc, char **argv);
+static int wscell_cmd (int argc, char **argv);
+static int xfsdebug_cmd (int argc, char **argv);
+static int xfsdebug_print_cmd (int argc, char **argv);
+
+static SL_cmd cmds[] = {
+ {"apropos", apropos_cmd, "locate commands by keyword"},
+ {"arladebug", arladebug_cmd, "tweek arla-debugging flags"},
+ {"calculate cache", calculate_cmd, "calculate the usege of cache"},
+ {"checkservers", checkservers_cmd,"check if servers is up"},
+ {"checkvolumes", empty_cmd, "lookup mappings between volume-Id's and names"},
+ {"cleanacl", empty_cmd, "clear out numeric acl-entries"},
+ {"copyacl", copyacl_cmd, "copy acl"},
+ {"diskfree", diskfree_cmd, "show free partition space"},
+ {"examine", examine_cmd, "examine volume status"},
+ {"flush", flush_cmd, "remove file from cache"},
+ {"flushvolume", flushvolume_cmd, "remove volumedata (and files in volume) from cache"},
+ {"gcpags", gc_cmd, "garbage collect pags"},
+ {"getcacheparms", getcache_cmd, "get cache usage"},
+ {"getcrypt", getcrypt_cmd, "get encrypt status"},
+ {"getcellstatus", getcellstatus_cmd, "get suid cell status"},
+ {"getfid", getfid_cmd, "get fid"},
+ {"getserverprefs", empty_cmd, "show server rank"},
+ {"getpriority", getprio_cmd, "get priority of a file/dir"},
+ {"gp"},
+ {"getmaxpriority", getmaxprio_cmd, "get max priority for file gc"},
+ {"gmp"},
+ {"help", help_cmd, "help for commands"},
+ {"invalidate", invalidate_cmd, "invalidate (callback) path"},
+ {"listacl", listacl_cmd, "show acl"},
+ {"la"},
+ {"listcells", listcells_cmd, "show cells configured"},
+ {"listquota", listquota_cmd, "show volume quota"},
+ {"lq"},
+ {"lsmount", lsmount_cmd, "show mount point"},
+ {"messages", empty_cmd, "change arlad logging"},
+ {"mkmount", mkmount_cmd, "create mount point"},
+ {"connect", connect_cmd, "connect mode"},
+ {"monitor", empty_cmd, "set remote logging host"},
+ {"newcell", newcell_cmd, "add new cell"},
+ {"nop", nop_cmd, "do a pioctl-nop"},
+ {"quit", quit_cmd, "leave interactive mode"},
+ {"exit"},
+ {"quota", quota_cmd, "show quota"},
+ {"rmmount", rmmount_cmd, "delete mount point"},
+ {"removepriority", rmprio_cmd, "remove priority from file/directory"},
+ {"rmp"},
+ {"setacl", setacl_cmd, "set acl"},
+ {"sa"},
+ {"setcachesize", setcache_cmd, "change cache size"},
+ {"setcell", empty_cmd, "change cell status"},
+ {"setpriority", setprio_cmd, "set priority of a file/directory"},
+ {"sp"},
+ {"setmaxpriority", setmaxprio_cmd, "set upper limit of prio gc"},
+ {"smq"},
+ {"setquota", setquota_cmd, "change maxquota on volume"},
+ {"sq"},
+ {"setserverprefs", empty_cmd, "change server query order"},
+ {"setcrypt", setcrypt_cmd, "set encryption on/off"},
+ {"setvol", empty_cmd, "change status of volume"},
+/* {"storebehind", empty_cmd, ""}, */
+ {"strerror", strerror_cmd, "expand what errorcode this might be"},
+ {"suidcells", suidcells_cmd, "list status of cells"},
+ {"sysname", sysname_cmd, "read/change sysname"},
+ {"version", fsversion_cmd, "get version of fs and fs_lib"},
+ {"venuslog", venuslog_cmd, "make arlad print status"},
+ {"whereis", whereis_cmd, "show server(s) of file"},
+ {"whichcell", whichcell_cmd, "show cell of file"},
+ {"wscell", wscell_cmd, "display cell of workstation"},
+ {"xfsdebug", xfsdebug_cmd, "tweek xfs-debugging flags"},
+ {"xfsprint", xfsdebug_print_cmd,"make xfs print debug info"},
+ {NULL}
+};
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+
+ if(!k_hasafs()) {
+ printf ("Error detecting AFS\n");
+ exit(1);
+ }
+
+ if (argc > 1) {
+ ret = sl_command(cmds, argc - 1, argv + 1);
+ if (ret == SL_BADCOMMAND)
+ printf ("%s: Unknown command\n", argv[1]);
+ }
+ else {
+ fs_interactive = 1;
+ printf("fs - an arla tool for administrating AFS files.\n");
+ printf("Type \"help\" to get a list of commands.\n");
+ ret = sl_loop(cmds, __progname": ");
+ }
+
+ return ret;
+}
+
+
+static int
+nop_cmd(int argc, char **argv)
+{
+ if (argc > 1)
+ fprintf(stderr, "extraneous arguments ignored\n");
+
+ printf("VIOCNOP returns %d\n", fs_nop());
+
+ return 0;
+}
+
+static int
+connect_usage(void)
+{
+ printf("connect [connected|fetch|disconnected]\n");
+ return 0;
+}
+
+static int
+checkservers_cmd (int argc, char **argv)
+{
+ char *cell = NULL;
+ int flags = 0;
+ int nopoll = 0;
+ int optind = 0;
+ u_int32_t hosts[CKSERV_MAXSERVERS + 1];
+ int ret;
+ int i;
+
+ struct getargs cksargs[] = {
+ {"cell", 0, arg_string, NULL, "cell", NULL},
+ {"nopoll", 0, arg_flag, NULL, "dont ping each server, "
+ "use internal info", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = cksargs;
+ arg->value = &cell; arg++;
+ arg->value = &nopoll; arg++;
+
+ if (getarg (cksargs, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(cksargs, "checkservers", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ if (cell)
+ flags |= CKSERV_FSONLY;
+ if (nopoll)
+ flags |= CKSERV_DONTPING;
+
+ ret = fs_checkservers(cell, flags, hosts, sizeof(hosts)/sizeof(hosts[0]));
+ if (ret) {
+ if (ret == ENOENT)
+ fprintf (stderr, "%s: cell `%s' doesn't exist\n",
+ PROGNAME, cell);
+ else
+ fserr (PROGNAME, ret, NULL);
+ return 0;
+ }
+
+ if (hosts[0] == 0)
+ printf ("All servers are up");
+
+ for (i = 1; i < min(CKSERV_MAXSERVERS, hosts[0]) + 1; ++i) {
+ if (hosts[i]) {
+ struct hostent *he;
+
+ he = gethostbyaddr ((char *)&hosts[i], sizeof(hosts[i]), AF_INET);
+
+ if (he != NULL) {
+ printf ("%s ", he->h_name);
+ } else {
+ struct in_addr in;
+
+ in.s_addr = hosts[i];
+ printf ("%s ", inet_ntoa(in));
+
+ }
+ }
+ }
+ printf("\n");
+ return 0;
+}
+
+static int
+connect_cmd(int argc, char **argv)
+{
+ int ret;
+ int32_t flags;
+
+ argc--;
+ argv++;
+
+ if (argc == 0) {
+ ret = fs_connect(CONNMODE_PROBE, &flags);
+ if (ret) {
+ fserr(PROGNAME, ret, NULL);
+ return 0;
+ }
+
+ switch(flags) {
+ case CONNMODE_CONN:
+ printf("Connected mode\n");
+ break;
+ case CONNMODE_FETCH:
+ printf("Fetch only mode\n");
+ break;
+ case CONNMODE_DISCONN:
+ printf("Disconnected mode\n");
+ break;
+ default:
+ printf("Unknown or error\n");
+ break;
+ }
+ return 0;
+ }
+
+ if (strncmp("dis", *argv, 3) == 0)
+ ret = fs_connect(CONNMODE_DISCONN, &flags);
+ else if (strncmp("fetch", *argv, 5) == 0)
+ ret = fs_connect(CONNMODE_FETCH, &flags);
+ else if (strncmp("conn", *argv, 4) == 0)
+ ret = fs_connect(CONNMODE_CONN, &flags);
+ else
+ return connect_usage();
+
+ if (ret)
+ fserr(PROGNAME, ret, NULL);
+
+ return 0;
+}
+
+static int
+copyacl_cmd (int argc, char **argv)
+{
+ argc--;
+ argv++;
+
+ if (argc != 2) {
+ printf ("fs: copyacl: Too many or too few arguments\n");
+ return 0;
+ }
+
+ afs_copyacl (argv[0], argv[1]);
+
+ return 0;
+}
+
+static int
+diskfree_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ printf ("Volume Name kbytes used avail %%used\n");
+
+ if (argc == 0)
+ afs_diskfree (".");
+ else
+ for (i = 0; i < argc; i++)
+ afs_diskfree (argv[i]);
+
+ return 0;
+}
+
+static int
+empty_cmd (int argc, char **argv)
+{
+ printf ("%s%s not implemented yet!\n", PROGNAME, argv[0]);
+ return 0;
+}
+
+static int
+examine_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ afs_examine (".");
+ else
+ for (i = 0; i < argc; i++)
+ afs_examine (argv[i]);
+
+ return 0;
+}
+
+static int
+flushvolume_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ fs_flushvolume (".");
+ else
+ for (i = 0; i < argc; i++)
+ fs_flushvolume (argv[i]);
+
+ return 0;
+}
+
+static int
+flush_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ fs_flush (".");
+ else
+ for (i = 0; i < argc; i++)
+ fs_flush (argv[i]);
+
+ return 0;
+}
+
+static int
+gc_cmd (int argc, char **argv)
+{
+ int ret;
+
+ argc--;
+ argv++;
+
+ if (argc != 0)
+ printf ("gcpags: extraneous arguments ignored\n");
+
+ ret = fs_gcpags();
+ if (ret)
+ fserr(PROGNAME, ret, NULL);
+
+ return 0;
+}
+
+static int
+getcellstatus_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ printf ("%s: Missing required parameter '-cell'\n", PROGNAME);
+ else
+ for (i = 0; i < argc; i++)
+ afs_getcellstatus (argv[i]);
+
+ return 0;
+}
+
+static int
+getcrypt_cmd (int argc, char **argv)
+{
+ u_int32_t n;
+ int ret;
+
+ argc--;
+ argv++;
+
+ if (argc != 0)
+ printf ("getcrypt: extraneous arguments ignored\n");
+
+ ret = fs_getcrypt (&n);
+ if (ret) {
+ fserr(PROGNAME, ret, NULL);
+ return 0;
+ }
+
+ switch (n) {
+ case 0 :
+ printf ("not encrypted\n");
+ break;
+ case 1 :
+ printf ("encrypted\n");
+ break;
+ default :
+ printf ("getcrypt: unknown reply %d\n", n);
+ }
+ return 0;
+}
+
+static int
+setcrypt_cmd (int argc, char **argv)
+{
+ u_int32_t n;
+ int ret ;
+
+ --argc;
+ ++argv;
+
+ if (argc != 1) {
+ printf ("setcrypt: Missing parameter on/off\n");
+ return 0;
+ }
+ if (strcasecmp(argv[0], "on") == 0)
+ n = 1;
+ else if(strcasecmp(argv[0], "off") == 0)
+ n = 0;
+ else {
+ printf ("setcrypt: Unknown parameter '%s'\n", argv[0]);
+ return 0;
+ }
+ ret = fs_setcrypt (n);
+ if (ret)
+ fserr(PROGNAME, ret, NULL);
+
+ return 0;
+}
+
+static int
+getfid_cmd(int argc, char **argv)
+{
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ printf("%s: Missing required parameter '-path'\n", PROGNAME);
+ else if (argc == 1)
+ afs_getfid(*argv);
+ else
+ while (argc) {
+ afs_getfid(*argv);
+ argc--;
+ argv++;
+ }
+ return 0;
+}
+
+static
+int setmaxprio_usage()
+{
+ fprintf(stderr, "usage: setmaxprio maxprio");
+ return 0;
+}
+
+static int
+setmaxprio_cmd (int argc, char **argv)
+{
+ int prio_tmp;
+ int16_t maxprio;
+ int ret;
+
+ if (argc != 1)
+ return setmaxprio_usage();
+
+ if (sscanf(argv[1], "%d", &prio_tmp) != 1)
+ return setmaxprio_usage();
+
+ maxprio = prio_tmp;
+
+ ret = fs_setmaxfprio(maxprio);
+ if (ret) {
+ fserr(PROGNAME, ret, argv[1]);
+ return 0;
+ }
+
+ return 0;
+
+}
+
+static int
+setprio_usage(void)
+{
+ fprintf(stderr, "usage: file prio\n");
+ return 0;
+}
+
+static int
+setprio_cmd (int argc, char **argv)
+{
+ VenusFid fid;
+ int prio_tmp;
+ int16_t prio;
+ int ret;
+
+ if (argc != 2)
+ return setprio_usage();
+
+ if (sscanf(argv[2], "%d", &prio_tmp) != 1)
+ return setprio_usage();
+
+ prio = prio_tmp;
+
+ ret = fs_getfid(argv[1], &fid);
+ if (ret) {
+ fserr(PROGNAME, ret, argv[1]);
+ return 0;
+ }
+
+ ret = fs_setfprio(fid, prio);
+ if (ret) {
+ fserr(PROGNAME, ret, argv[1]);
+ return 0;
+ }
+
+ return 0;
+}
+
+static int
+help_cmd (int argc, char **argv)
+{
+ SL_cmd *cmd;
+
+ for (cmd = cmds; cmd->name != NULL; ++cmd)
+ if (cmd->usage != NULL)
+ printf ("%-20s%s\n", cmd->name, cmd->usage);
+
+ return 0;
+}
+
+static int
+apropos_cmd (int argc, char **argv)
+{
+ if (argc == 0) {
+ printf ("apropos: missing topic\n");
+ return 0;
+ }
+
+ sl_apropos (cmds, argv[1]);
+ return 0;
+}
+
+static int
+mkmount_cmd (int argc, char **argv)
+{
+ char buf[MAXSIZE];
+
+ argc--;
+ argv++;
+
+ if (argc == 0) {
+ printf ("fs: Required parameter '-dir' missing\n");
+ return 0;
+ }
+ else if (argc == 1) {
+ printf ("fs: Required parameter '-vol' missing\n");
+ return 0;
+ }
+ else {
+ if (argc > 2)
+ snprintf(buf, sizeof(buf), "#%s:%s.", argv[2], argv[1]);
+ else
+ snprintf(buf, sizeof(buf), "#%s.", argv[1]);
+
+ if (symlink (buf, argv[0]) == -1) {
+ perror ("fs");
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+static int
+invalidate_cmd (int argc, char **argv)
+{
+ unsigned int i;
+
+ argc--;
+ argv++;
+
+ if(!argc)
+ fs_invalidate(".");
+ else
+ for(i=0;i<argc;i++) {
+ if(i)
+ printf("\n");
+ fs_invalidate(argv[i]);
+ }
+
+ return 0;
+}
+
+static int
+listacl_cmd (int argc, char **argv)
+{
+ unsigned int i;
+
+ argc--;
+ argv++;
+
+ if(!argc)
+ afs_listacl(".");
+ else
+ for(i=0;i<argc;i++) {
+ if(i)
+ printf("\n");
+ afs_listacl(argv[i]);
+ }
+
+ return 0;
+}
+
+static int
+listcells_cmd (int argc, char **argv)
+{
+ int printhosts = 1;
+ int resolve = 1;
+ int printsuid = 0;
+ int optind = 0;
+
+ struct getargs lcargs[] = {
+ {"servers", 's', arg_negative_flag,
+ NULL,"do not print servers in cell", NULL},
+ {"resolve", 'r', arg_negative_flag,
+ NULL,"do not resolve hostnames", NULL},
+ {"suid", 'p', arg_flag,
+ NULL,"print if cell is suid", NULL },
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = lcargs;
+ arg->value = &printhosts; arg++;
+ arg->value = &resolve; arg++;
+ arg->value = &printsuid; arg++;
+
+ if (getarg (lcargs, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(lcargs, "listcells", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ printf ("%d %d %d\n", printhosts, resolve, printsuid);
+
+ afs_listcells (printhosts,resolve,printsuid);
+
+ return 0;
+}
+
+static int
+strerror_cmd (int argc, char **argv)
+{
+ if (argc == 0) {
+ fprintf (stderr, "usage: fs strerror errno ...\n");
+ } else {
+ int error;
+ argv++;
+
+ while (--argc) {
+ if (sscanf (argv[0], "%d", &error) != 1) {
+ fprintf (stderr, "warning: %s isn't a number\n", argv[0]);
+ } else {
+ printf ("%d => %s\n", error, koerr_gettext(error));
+ }
+ argv++;
+ }
+ }
+
+ return 0;
+}
+
+static int
+suidcells_cmd (int argc, char **argv)
+{
+ afs_listcells (0, 0, 1);
+
+ return 0;
+}
+
+static int
+newcell_cmd (int argc, char **argv)
+{
+ char *cell = NULL;
+ getarg_strings servers = { 0, NULL };
+ int ret, help = 0;
+ int optind = 0;
+
+ struct getargs ncargs[] = {
+ {"cell", 'c', arg_string,
+ NULL, "new cell", NULL},
+ {"servers", 's', arg_strings,
+ NULL, "server in cell", "one server"},
+ {"help", 'h', arg_flag,
+ NULL, "get help", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = ncargs;
+ arg->value = &cell; arg++;
+ arg->value = &servers; arg++;
+ arg->value = &help; arg++;
+
+ if (getarg (ncargs, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(ncargs, "newcell", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ if (help) {
+ arg_printusage(ncargs, "newcell", NULL, ARG_AFSSTYLE);
+ goto out;
+ }
+
+ if (cell == NULL) {
+ fprintf (stderr, "You have to give a cell\n");
+ goto out;
+ }
+
+ if (servers.num_strings == 0) {
+ fprintf (stderr, "You didn't give servers, will use DNS\n");
+ goto out;
+ }
+
+ ret = fs_newcell (cell, servers.num_strings, servers.strings);
+ if (ret)
+ fprintf (stderr, "fs_newcell failed with %s (%d)\n",
+ koerr_gettext(ret), ret);
+
+ out:
+ if (servers.strings)
+ free (servers.strings);
+
+ return 0;
+}
+
+static int
+listquota_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ printf("Volume Name Quota Used %% Used Partition\n");
+
+ if (argc == 0)
+ afs_listquota (".");
+ else
+ for (i = 0; i < argc; i++)
+ afs_listquota (argv[i]);
+
+ return 0;
+}
+
+static int
+getprio_usage(void)
+{
+ fprintf(stderr, "usage getprio file ...\n");
+ return 0;
+}
+
+static int
+getprio_cmd (int argc, char **argv)
+{
+ VenusFid fid;
+ int16_t prio;
+ int ret, i;
+ char *path;
+ char cell[MAXNAME];
+
+ if (argc == 0)
+ return getprio_usage();
+
+ for (i = 0; i < argc; i++) {
+ path = argv[i];
+
+ ret = fs_getfid(path, &fid);
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ continue;
+ }
+
+ ret = fs_getfprio(fid, &prio);
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ continue;
+ }
+
+ ret = fs_getfilecellname(path, cell, sizeof(cell));
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ continue;
+ }
+
+ printf("File %s(%s %d.%d.%d) have priority %d\n",
+ path, cell, fid.fid.Volume, fid.fid.Vnode,
+ fid.fid.Unique, prio);
+
+ }
+ return 0;
+}
+
+static int
+getmaxprio_cmd (int argc, char **argv)
+{
+ int16_t prio;
+ int ret;
+
+ if (argc != 0)
+ fprintf(stderr, "getmaxprio: extraneous argumets ignored\n");
+
+ ret = fs_getmaxfprio(&prio);
+ if (ret) {
+ fserr(PROGNAME, ret, NULL);
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static int
+setquota_cmd (int argc, char **argv)
+{
+ if(argc!=3) {
+ printf("Usage: fs sq <path> <max quota in kbytes>\n");
+ return 0;
+ }
+
+ afs_setmaxquota(argv[1],(int32_t) atoi(argv[2]));
+
+ return 0;
+}
+
+static int
+lsmount_cmd (int argc, char **argv)
+{
+ int i, ret;
+
+ argc--;
+ argv++;
+
+ if (argc == 0) {
+ printf ("fs: Required parameter '-dir' missing\n");
+ return 0;
+ }
+
+ for (i = 0; i < argc; i++) {
+ ret = fs_lsmount (argv[i]);
+ if (ret == EINVAL)
+ fserr (PROGNAME, ret, argv[i]);
+ else if (ret)
+ printf ("'%s' is not a mount point.\n", argv[i]);
+ }
+
+ return 0;
+}
+
+static void
+setcache_usage()
+{
+ fprintf(stderr, "Usage: setcachesize <lowvnodes> [<highvnodes> "
+ "<lowbytes> <highbytes>]\n");
+
+}
+
+static int
+setcache_cmd (int argc, char **argv)
+{
+ int lv, hv, lb, hb;
+
+ argc--;
+ argv++;
+
+ if (argc != 1 && argc != 4) {
+ setcache_usage();
+ return 0;
+ }
+
+ if (argc == 4) {
+ if (sscanf(argv[0], "%d", &lv) &&
+ sscanf(argv[1], "%d", &hv) &&
+ sscanf(argv[2], "%d", &lb) &&
+ sscanf(argv[3], "%d", &hb))
+ afs_setcache(lv, hv, lb, hb);
+ else
+ setcache_usage();
+ } else {
+ if (sscanf(argv[0], "%d", &lv))
+ afs_setcache(lv, 0, 0, 0);
+ else
+ setcache_usage();
+ }
+
+ return 0;
+}
+
+static int
+quit_cmd (int argc, char **argv)
+{
+ printf ("Exiting...\n");
+ return 1;
+}
+
+static int
+quota_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ afs_quota (".");
+ else
+ for (i = 0; i < argc; i++)
+ afs_quota (argv[i]);
+
+ return 0;
+}
+
+static int
+rmmount_cmd (int argc, char **argv)
+{
+ int i, ret;
+
+ argc--;
+ argv++;
+
+ if (argc == 0) {
+ printf ("fs: Required parameter '-dir' missing\n");
+ return 0;
+ }
+
+ for (i = 0; i < argc; i++) {
+ ret = fs_rmmount (argv[i]);
+ if (ret == EINVAL)
+ fserr (PROGNAME, ret, argv[i]);
+ else if (ret)
+ printf ("'%s' is not a mount point.\n", argv[i]);
+ }
+ return 0;
+}
+
+static int
+rmprio_usage(void)
+{
+ printf("usage: rmpriority file ...\n");
+ return 0;
+}
+
+static int
+rmprio_cmd(int argc, char **argv)
+{
+ VenusFid fid;
+ int ret, i;
+ char *path;
+
+ if (argc == 0)
+ return rmprio_usage();
+
+ for (i = 0; i < argc; i++) {
+ path = argv[i];
+
+ ret = fs_getfid(path, &fid);
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ return 0;
+ }
+
+ ret = fs_setfprio(fid, 0);
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+
+static int
+setacl_cmd (int argc, char **argv)
+{
+ argc--;
+ argv++;
+
+ if (argc != 3) {
+ printf ("fs: setacl: Too many or too few arguments\n");
+ return 0;
+ }
+
+ afs_setacl (argv[0], argv[1], argv[2]);
+
+ return 0;
+}
+
+static int
+sysname_cmd (int argc, char **argv)
+{
+ argc--;
+ argv++;
+ if (argc == 0)
+ afs_print_sysname ();
+ else
+ afs_set_sysname (argv[0]);
+
+ return 0;
+}
+
+static int
+whereis_cmd (int argc, char **argv)
+{
+ argc--;
+ argv++;
+ if (argc == 0)
+ afs_whereis (".");
+ else
+ afs_whereis (argv[0]);
+
+ return 0;
+}
+
+static int
+whichcell_cmd (int argc, char **argv)
+{
+ int i;
+
+ argc--;
+ argv++;
+
+ if (argc == 0) {
+ afs_whichcell (".");
+ }
+
+ for (i = 0; i < argc; i++)
+ afs_whichcell (argv[i]);
+
+ return 0;
+}
+
+static int
+wscell_cmd (int argc, char **argv)
+{
+ argc--;
+ argv++;
+
+ afs_wscell ();
+
+ return 0;
+}
+
+static int
+venuslog_cmd (int argc, char **argv)
+{
+ int ret = fs_venuslog();
+ if (ret)
+ fserr (PROGNAME, ret, NULL);
+ return 0;
+}
+
+static int
+fsversion_cmd(int argc, char **argv)
+{
+ if (argc != 0)
+ printf ("version: extraneous arguments ignored\n");
+
+ printf("fs: %s\nfs_lib: %s\n",
+ "$Id: fs.c,v 1.1 2000/09/11 14:40:35 art Exp $",
+ fslib_version());
+ return 0;
+}
+
+static const unsigned all = (0
+#ifdef HAVE_XDEBDEV
+ | XDEBDEV
+#endif
+#ifdef HAVE_XDEBMSG
+ | XDEBMSG
+#endif
+#ifdef HAVE_XDEBDNLC
+ | XDEBDNLC
+#endif
+#ifdef HAVE_XDEBNODE
+ | XDEBNODE
+#endif
+#ifdef HAVE_XDEBVNOPS
+ | XDEBVNOPS
+#endif
+#ifdef HAVE_XDEBVFOPS
+ | XDEBVFOPS
+#endif
+#ifdef HAVE_XDEBLKM
+ | XDEBLKM
+#endif
+#ifdef HAVE_XDEBSYS
+ | XDEBSYS
+#endif
+#ifdef HAVE_XDEBMEM
+ | XDEBMEM
+#endif
+#ifdef HAVE_XDEBREADDIR
+ | XDEBREADDIR
+#endif
+#ifdef HAVE_XDEBLOCK
+ | XDEBLOCK
+#endif
+#ifdef HAVE_XDEBCACHE
+ | XDEBCACHE
+#endif
+ );
+
+static const unsigned almost_all_mask = (0
+#ifdef HAVE_XDEBDEV
+ | XDEBDEV
+#endif
+#ifdef HAVE_XDEBMEM
+ | XDEBMEM
+#endif
+#ifdef HAVE_XDEBREADDIR
+ | XDEBREADDIR
+#endif
+ );
+
+static struct units xfsdebug_units[] = {
+ {"all", 0},
+ {"almost-all", 0},
+#ifdef HAVE_XDEBCACHE
+ {"cache", XDEBCACHE},
+#endif
+#ifdef HAVE_XDEBLOCK
+ {"lock", XDEBLOCK},
+#endif
+#ifdef HAVE_XDEBREADDIR
+ {"readdir", XDEBREADDIR},
+#endif
+#ifdef HAVE_XDEBMEM
+ {"mem", XDEBMEM},
+#endif
+#ifdef HAVE_XDEBSYS
+ {"sys", XDEBSYS},
+#endif
+#ifdef HAVE_XDEBLKM
+ {"lkm", XDEBLKM},
+#endif
+#ifdef HAVE_XDEBVFOPS
+ {"vfsops", XDEBVFOPS},
+#endif
+#ifdef HAVE_XDEBVNOPS
+ {"vnops", XDEBVNOPS},
+#endif
+#ifdef HAVE_XDEBNODE
+ {"node", XDEBNODE},
+#endif
+#ifdef HAVE_XDEBDNLC
+ {"dnlc", XDEBDNLC},
+#endif
+#ifdef HAVE_XDEBMSG
+ {"msg", XDEBMSG},
+#endif
+#ifdef HAVE_XDEBDEV
+ {"dev", XDEBDEV},
+#endif
+ {"none", 0 },
+ { NULL, 0 }
+};
+
+static int
+xfsdebug_cmd (int argc, char **argv)
+{
+ int ret;
+ int flags;
+
+ xfsdebug_units[0].mult = all;
+ xfsdebug_units[1].mult = all & ~almost_all_mask;
+
+ if ((argc > 1 && strncmp(argv[1], "-h", 2) == 0) || argc > 2) {
+ fprintf (stderr, "usage: xfsdebug [-h] [");
+ print_flags_table (xfsdebug_units, stderr);
+ fprintf (stderr, "]\n");
+ return 0;
+ }
+
+ ret = xfs_debug (-1, &flags);
+ if (ret) {
+ fprintf (stderr, "xfs_debug: %s\n", strerror(ret));
+ return 0;
+ }
+
+ if (argc == 1) {
+ char buf[1024];
+
+ unparse_flags (flags, xfsdebug_units, buf, sizeof(buf));
+ printf("xfsdebug is: %s\n", buf);
+ } else if (argc == 2) {
+ char *textflags;
+
+ textflags = argv[1];
+
+ ret = parse_flags (textflags, xfsdebug_units, flags);
+
+ if (ret < 0) {
+ fprintf (stderr, "xfsdebug: unknown/bad flags `%s'\n",
+ textflags);
+ return 0;
+ }
+
+ flags = ret;
+ ret = xfs_debug(flags, NULL);
+ if (ret)
+ fprintf (stderr, "xfs_debug: %s\n", strerror(ret));
+ }
+ return 0;
+}
+
+static int
+xfsdebug_print_cmd (int argc, char **argv)
+{
+ int ret;
+ int flags = 0;
+ char *textflags;
+
+ xfsdebug_units[0].mult = all;
+ xfsdebug_units[1].mult = all & ~almost_all_mask;
+
+ if (argc != 2) {
+ fprintf (stderr, "usage: xfsprint <");
+ print_flags_table (xfsdebug_units, stderr);
+ fprintf (stderr, ">\n");
+ return 0;
+ }
+
+ textflags = argv[1];
+
+ ret = parse_flags (textflags, xfsdebug_units, flags);
+
+ if (ret < 0) {
+ fprintf (stderr, "xfsprint: unknown/bad flags `%s'\n",
+ textflags);
+ return 0;
+ }
+
+ flags = ret;
+ ret = xfs_debug_print(flags);
+ if (ret)
+ fprintf (stderr, "xfsprint: %s\n", strerror(ret));
+ return 0;
+}
+
+static int
+arladebug_cmd (int argc, char **argv)
+{
+ int ret;
+ int flags;
+
+ if ((argc > 1 && strncmp("-h", argv[1], 2) == 0) || argc > 2) {
+ fprintf (stderr, "arladebug [-h] [");
+ arla_log_print_levels (stderr);
+ fprintf (stderr, "]\n");
+ return 0;
+ }
+
+ ret = arla_debug (-1, &flags);
+ if (ret) {
+ fprintf (stderr, "arla_debug: %s\n", strerror(ret));
+ return 0;
+ }
+
+ if (argc == 1) {
+ char buf[1024];
+
+ unparse_flags (flags, arla_deb_units, buf, sizeof(buf));
+ printf ("arladebug is: %s\n", buf);
+ } else if (argc == 2) {
+ const char *textflags = argv[1];
+
+ ret = parse_flags (textflags, arla_deb_units, flags);
+ if (ret < 0) {
+ fprintf (stderr, "arladebug: unknown/bad flags `%s'\n",
+ textflags);
+ return 0;
+ }
+
+ flags = ret;
+ ret = arla_debug (flags, NULL);
+ if (ret)
+ fprintf (stderr, "arla_debug: %s\n", strerror(ret));
+ }
+ return 0;
+}
+
+static int
+calculate_cmd (int argc, char **argv)
+{
+ int ret;
+ u_int32_t used, calc;
+
+ ret = fs_calculate_cache(&calc, &used);
+ if (ret)
+ warn ("fs_calculate_cache");
+ else
+ printf ("usedbytes: %10d\n"
+ "calculated: %10d\n"
+ "diff: c - u %10d\n",
+ used, calc, calc - used );
+
+ return 0;
+}
+
+void
+afs_getfid(char *path)
+{
+ VenusFid fid;
+ int ret;
+ char cellname[MAXNAME];
+
+ ret = fs_getfid(path, &fid);
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ return;
+ }
+
+ ret = fs_getfilecellname(path, cellname, sizeof(cellname));
+ if (ret) {
+ fserr(PROGNAME, ret, path);
+ return;
+ }
+
+ printf("Fid: %u.%u.%u in %s (%u) \n", fid.fid.Volume,
+ fid.fid.Vnode, fid.fid.Unique, cellname, fid.Cell);
+}
+
+void
+afs_copyacl(char *fromdir, char *todir)
+{
+ struct Acl *acl;
+ struct AclEntry *position;
+ struct ViceIoctl a_params;
+ int i;
+ char acltext[MAXSIZE];
+ char tmpstr[MAXSIZE];
+
+ if((acl=afs_getacl(fromdir))==NULL)
+ exit(1);
+
+ sprintf(acltext,"%d\n%d\n", acl->NumPositiveEntries,
+ acl->NumNegativeEntries);
+ position=acl->pos;
+ for(i=0; i<acl->NumPositiveEntries; i++) {
+ sprintf(tmpstr, "%s %d\n", position->name, position->RightsMask);
+ strcat(acltext,tmpstr);
+ position=position->next;
+ }
+ position=acl->neg;
+ for(i=0; i<acl->NumNegativeEntries; i++) {
+ sprintf(tmpstr, "%s %d\n", position->name, position->RightsMask);
+ strcat(acltext,tmpstr);
+ position=position->next;
+ }
+
+ a_params.in_size=strlen(acltext);
+ a_params.out_size=0;
+ a_params.in=acltext;
+ a_params.out=0;
+
+ if(k_pioctl(todir,VIOCSETAL,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, todir);
+ return;
+ }
+}
+
+void
+afs_listacl(char *path)
+{
+ struct Acl *acl;
+ struct AclEntry *position;
+ int i;
+
+ if((acl=afs_getacl(path))==NULL)
+ exit(1);
+
+ printf("Access list for %s is\n", path);
+ if(acl->NumPositiveEntries) {
+ printf("Normal rights:\n");
+
+ position=acl->pos;
+ for(i=0;i<acl->NumPositiveEntries;i++) {
+ printf(" %s ", position->name);
+ if(position->RightsMask&PRSFS_READ)
+ printf("r");
+ if(position->RightsMask&PRSFS_LOOKUP)
+ printf("l");
+ if(position->RightsMask&PRSFS_INSERT)
+ printf("i");
+ if(position->RightsMask&PRSFS_DELETE)
+ printf("d");
+ if(position->RightsMask&PRSFS_WRITE)
+ printf("w");
+ if(position->RightsMask&PRSFS_LOCK)
+ printf("k");
+ if(position->RightsMask&PRSFS_ADMINISTER)
+ printf("a");
+ printf("\n");
+ position=position->next;
+ }
+ }
+ if(acl->NumNegativeEntries) {
+ printf("Negative rights:\n");
+
+ position=acl->neg;
+ for(i=0;i<acl->NumNegativeEntries;i++) {
+ printf(" %s ", position->name);
+ if(position->RightsMask&PRSFS_READ)
+ printf("r");
+ if(position->RightsMask&PRSFS_LOOKUP)
+ printf("l");
+ if(position->RightsMask&PRSFS_INSERT)
+ printf("i");
+ if(position->RightsMask&PRSFS_DELETE)
+ printf("d");
+ if(position->RightsMask&PRSFS_WRITE)
+ printf("w");
+ if(position->RightsMask&PRSFS_LOCK)
+ printf("k");
+ if(position->RightsMask&PRSFS_ADMINISTER)
+ printf("a");
+ printf("\n");
+ position=position->next;
+ }
+ }
+}
+
+void
+afs_setacl(char *path, char *user, char *rights)
+{
+ struct Acl *acl;
+ struct AclEntry *position;
+ struct ViceIoctl a_params;
+ int i;
+ int newrights=0;
+ int foundit=0;
+ char *ptr;
+ char acltext[MAXSIZE];
+ char tmpstr[MAXSIZE];
+
+ if((acl=afs_getacl(path))==NULL)
+ exit(1);
+
+ if(!strcmp(rights,"read"))
+ newrights=PRSFS_READ | PRSFS_LOOKUP;
+ else if(!strcmp(rights,"write"))
+ newrights=PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE |
+ PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
+ else if(!strcmp(rights,"mail"))
+ newrights=PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
+ else if(!strcmp(rights,"all"))
+ newrights=PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE |
+ PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
+ else {
+ ptr=rights;
+ while(*ptr!=0) {
+ if(*ptr=='r')
+ newrights|=PRSFS_READ;
+ if(*ptr=='l')
+ newrights|=PRSFS_LOOKUP;
+ if(*ptr=='i')
+ newrights|=PRSFS_INSERT;
+ if(*ptr=='d')
+ newrights|=PRSFS_DELETE;
+ if(*ptr=='w')
+ newrights|=PRSFS_WRITE;
+ if(*ptr=='k')
+ newrights|=PRSFS_LOCK;
+ if(*ptr=='a')
+ newrights|=PRSFS_ADMINISTER;
+ ptr++;
+ }
+ }
+
+ position=acl->pos;
+ for(i=0; i<acl->NumPositiveEntries; i++) {
+ if(!strncmp(user, position->name, 100)) {
+ position->RightsMask=newrights;
+ foundit=1;
+ }
+ if(position->next)
+ position=position->next;
+ }
+
+ if(!foundit) {
+ if (position) {
+ position->next=malloc(sizeof(struct AclEntry));
+ position=position->next;
+ } else {
+ acl->pos = malloc(sizeof(struct AclEntry));
+ position = acl->pos;
+ }
+ if(position==NULL) {
+ printf("fs: Out of memory\n");
+ exit(1);
+ }
+ acl->NumPositiveEntries++;
+
+ position->next=NULL;
+ strlcpy(position->name, user, sizeof(position->name));
+ position->RightsMask=newrights;
+ }
+
+ acltext[0] = 0;
+ for(position=acl->pos;
+ position && acl->NumPositiveEntries;
+ position = position->next) {
+ if (position->RightsMask) {
+ sprintf(tmpstr, "%s %d\n", position->name, position->RightsMask);
+ strcat(acltext,tmpstr);
+ } else
+ acl->NumPositiveEntries--;
+ }
+ for(position=acl->neg;
+ position && acl->NumNegativeEntries;
+ position = position->next) {
+ if (position->RightsMask) {
+ sprintf(tmpstr, "%s %d\n", position->name, position->RightsMask);
+ strcat(acltext,tmpstr);
+ } else
+ acl->NumNegativeEntries--;
+ }
+ strlcpy (tmpstr, acltext, sizeof(tmpstr));
+ snprintf(acltext, sizeof(acltext), "%d\n%d\n%s",
+ acl->NumPositiveEntries, acl->NumNegativeEntries, tmpstr);
+
+ a_params.in_size=strlen(acltext);
+ a_params.out_size=0;
+ a_params.in=acltext;
+ a_params.out=0;
+
+
+ if(k_pioctl(path,VIOCSETAL,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, path);
+ return;
+ }
+
+ /* free(oldacl); and its contents */
+}
+
+struct Acl *
+afs_getacl(char *path)
+{
+ struct Acl *oldacl;
+ struct ViceIoctl a_params;
+ struct AclEntry *pos=NULL;
+ struct AclEntry *neg=NULL;
+ char *curptr;
+ char tmpname[MAXNAME];
+ int tmprights;
+ int i;
+
+ oldacl=(struct Acl *) malloc(sizeof(struct Acl));
+ if(oldacl == NULL) {
+ printf("fs: Out of memory\n");
+ return NULL;
+ }
+
+ a_params.in_size=0;
+ a_params.out_size=MAXSIZE;
+ a_params.in=NULL;
+ a_params.out=malloc(MAXSIZE);
+
+ if(a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ free (oldacl);
+ return NULL;
+ }
+
+ if(k_pioctl(path,VIOCGETAL,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, path);
+ free (oldacl);
+ free(a_params.out);
+ return NULL;
+ }
+
+ curptr=a_params.out;
+
+ /* Number of pos/neg entries parsing */
+ sscanf(curptr, "%d\n%d\n", &oldacl->NumPositiveEntries,
+ &oldacl->NumNegativeEntries);
+ skipline(&curptr);
+ skipline(&curptr);
+
+ if(oldacl->NumPositiveEntries)
+ for(i=0; i<oldacl->NumPositiveEntries; i++) {
+ sscanf(curptr, "%100s %d", tmpname, &tmprights);
+ skipline(&curptr);
+ if(!i) {
+ pos=malloc(sizeof(struct AclEntry));
+ oldacl->pos=pos;
+ }
+ else {
+ pos->next=malloc(sizeof(struct AclEntry));
+ pos=pos->next;
+ }
+ pos->RightsMask=tmprights;
+ strlcpy(pos->name, tmpname, sizeof(pos->name));
+ pos->next=NULL;
+ }
+
+ if(oldacl->NumNegativeEntries)
+ for(i=0; i<oldacl->NumNegativeEntries; i++) {
+ sscanf(curptr, "%100s %d", tmpname, &tmprights);
+ skipline(&curptr);
+ if(!i) {
+ neg=malloc(sizeof(struct AclEntry));
+ oldacl->neg=neg;
+ }
+ else {
+ neg->next=malloc(sizeof(struct AclEntry));
+ neg=neg->next;
+ }
+ neg->RightsMask=tmprights;
+ strlcpy(neg->name, tmpname, sizeof(neg->name));
+ neg->next=NULL;
+ }
+
+ free(a_params.out);
+ return oldacl;
+}
+
+/*
+ * Print current sysname.
+ */
+
+void
+afs_print_sysname (void)
+{
+ int ret;
+ char buf[2048];
+
+ ret = fs_get_sysname (buf, sizeof(buf));
+ if (ret)
+ fserr (PROGNAME, ret, NULL);
+ else
+ printf ("Current sysname is '%s'\n", buf);
+}
+
+/*
+ * Set sysname
+ */
+
+void
+afs_set_sysname (const char *sys)
+{
+ int ret;
+
+ ret = fs_set_sysname (sys);
+ if (ret)
+ fserr (PROGNAME, ret, NULL);
+ else
+ printf ("fs: new sysname set to `%s'\n", sys);
+}
+
+void
+afs_listquota(char *path)
+{
+ struct ViceIoctl a_params;
+ struct VolumeStatus *vs;
+ char *name;
+ double used_vol, used_part;
+
+ a_params.in_size=0;
+ a_params.out_size=MAXSIZE;
+ a_params.in=NULL;
+ a_params.out=malloc(MAXSIZE);
+
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ if(k_pioctl(path,VIOCGETVOLSTAT,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ vs=(struct VolumeStatus *) a_params.out;
+ name=a_params.out+sizeof(struct VolumeStatus);
+
+ if (vs->MaxQuota)
+ used_vol = ((double) vs->BlocksInUse / vs->MaxQuota) * 100;
+ else
+ used_vol = 0.0;
+
+ if (vs->PartMaxBlocks)
+ used_part = (1.0 - (double) vs->PartBlocksAvail / vs->PartMaxBlocks)
+ * 100;
+ else
+ used_part = 0.0;
+
+ printf("%-20s%8d%8d%9.0f%%%s%9.0f%%%s%s\n",
+ name,
+ vs->MaxQuota,
+ vs->BlocksInUse,
+ used_vol,
+ used_vol > 90 ? "<<" : " ",
+ used_part,
+ used_part > 97 ? "<<" : " ",
+
+ /* Print a warning if more than 90% on home volume or 97% on */
+ /* the partion is being used */
+ (used_vol > 90 || used_part > 97) ? "\t<<WARNING" : "");
+
+ free(a_params.out);
+}
+
+void
+afs_setmaxquota(char *path, int32_t maxquota)
+{
+ struct ViceIoctl a_params;
+ struct VolumeStatus *vs;
+ int insize;
+
+ a_params.in_size=0;
+ a_params.out_size=MAXSIZE;
+ a_params.in=NULL;
+ a_params.out=malloc(MAXSIZE);
+
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ /* Read the old volume status */
+ if(k_pioctl(path,VIOCGETVOLSTAT,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ insize=sizeof(struct VolumeStatus)+strlen(path)+2;
+
+ a_params.in_size=MAXSIZE<insize?MAXSIZE:insize;
+ a_params.out_size=0;
+ a_params.in=a_params.out;
+ a_params.out=NULL;
+
+ vs=(struct VolumeStatus *) a_params.in;
+ vs->MaxQuota=maxquota;
+
+ if(k_pioctl(path,VIOCSETVOLSTAT,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.in);
+ return;
+ }
+
+ free(a_params.in);
+}
+
+void
+afs_whereis(char *path)
+{
+ struct ViceIoctl a_params;
+ struct in_addr addr;
+ int32_t *curptr;
+ int i=0;
+
+ a_params.in_size=0;
+ a_params.out_size=8*sizeof(int32_t);
+ a_params.in=NULL;
+ a_params.out=malloc(8*sizeof(int32_t));
+
+ if(a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ if(k_pioctl(path,VIOCWHEREIS,&a_params,1)==-1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ curptr=(int32_t *) a_params.out;
+ printf("File %s is on host%s", path, curptr[0]&&curptr[1]?"s":"");
+
+ while(curptr[i] && i<8) {
+ struct hostent *h;
+ addr.s_addr = curptr[i];
+ h=gethostbyaddr((const char *) &addr, sizeof(addr), AF_INET);
+ if (h == NULL)
+ printf (" %s", inet_ntoa (addr));
+ else {
+ printf(" %s", h->h_name);
+ }
+ i++;
+ }
+ printf("\n");
+ free(a_params.out);
+}
+
+int
+afs_setcache(int lv, int hv, int lb, int hb)
+{
+ int ret;
+
+ ret = fs_setcache (lv, hv, lb, hb);
+ if (ret)
+ fserr(PROGNAME, ret, ".");
+ return ret;
+}
+
+void
+afs_examine (char *path)
+{
+ struct ViceIoctl a_params;
+ struct VolumeStatus *status;
+
+ a_params.in_size = 0;
+ a_params.out_size = MAXSIZE;
+ a_params.in = NULL;
+ a_params.out = malloc (MAXSIZE);
+
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 1) == -1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ status = (struct VolumeStatus *) a_params.out;
+
+ printf ("Volume status for vid = %d named %s\n", status->Vid,
+ a_params.out + sizeof (struct VolumeStatus));
+ printf ("Current disk quota is %d\n", status->MaxQuota);
+ printf ("Current blocks used are %d\n", status->BlocksInUse);
+ printf ("The partition has %d blocks available out of %d\n\n", status->PartBlocksAvail, status->PartMaxBlocks);
+
+ free (a_params.out);
+}
+
+void
+afs_wscell (void)
+{
+ char buf[2048];
+ int ret;
+
+ ret = fs_wscell (buf, sizeof(buf));
+ if (ret) {
+ fserr (PROGNAME, ret, NULL);
+ return;
+ }
+
+ printf ("This workstation belongs to cell '%s'\n", buf);
+}
+
+void
+afs_whichcell (char *path)
+{
+ struct ViceIoctl a_params;
+
+ a_params.in_size = 0;
+ a_params.out_size = MAXSIZE;
+ a_params.in = NULL;
+ a_params.out = malloc (MAXSIZE);
+
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ if (k_pioctl (path, VIOC_FILE_CELL_NAME, &a_params, 0) == -1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ printf ("File %s lives in cell '%s'\n", path, a_params.out);
+ free (a_params.out);
+}
+
+void
+afs_diskfree (char *path)
+{
+ struct ViceIoctl a_params;
+ struct VolumeStatus *status;
+
+ a_params.in_size = 0;
+ a_params.out_size = MAXSIZE;
+ a_params.in = NULL;
+ a_params.out = malloc (MAXSIZE);
+
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 1) == -1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ status = (struct VolumeStatus *) a_params.out;
+
+ printf ("%-20s%8d%8d%8d%9.0f%%\n",
+ a_params.out + sizeof (struct VolumeStatus),
+ status->PartMaxBlocks,
+ status->PartMaxBlocks - status->PartBlocksAvail,
+ status->PartBlocksAvail,
+ (float) (status->PartMaxBlocks - status->PartBlocksAvail) / status->PartMaxBlocks * 100);
+
+ free (a_params.out);
+}
+
+void
+afs_quota (char *path)
+{
+ struct ViceIoctl a_params;
+ struct VolumeStatus *status;
+
+ a_params.in_size = 0;
+ a_params.out_size = MAXSIZE;
+ a_params.in = NULL;
+ a_params.out = malloc (MAXSIZE);
+
+ if (a_params.out == NULL) {
+ printf ("fs: Out of memory\n");
+ return;
+ }
+
+ if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 1) == -1) {
+ fserr(PROGNAME, errno, path);
+ free(a_params.out);
+ return;
+ }
+
+ status = (struct VolumeStatus *) a_params.out;
+
+ printf("%.0f%% of quota used.\n",
+ ((float) status->BlocksInUse / status->MaxQuota) * 100);
+
+ free(a_params.out);
+}
+
+void
+afs_getcellstatus (char *cell)
+{
+ u_int32_t flags;
+ int ret;
+
+ ret = fs_getcellstatus (cell, &flags);
+ if (ret) {
+ fserr(PROGNAME, ret, cell);
+ return;
+ }
+ printf ("Cell %s status: %ssetuid allowed\n", cell,
+ !SETUID_HONORED(flags) ? "no " : "");
+}
+
+/*
+ * List all the known cells, with servers iff printservers, resolving
+ * IP addresses to names iff resolve and printing suid status iff
+ * suid.
+ */
+
+int
+afs_listcells (int printservers, int resolve, int suid)
+{
+ struct in_addr addr;
+ int i, j;
+ char cellname[MAXSIZE];
+ u_int32_t servers[8];
+ int ret;
+ unsigned max_servers = sizeof(servers)/sizeof(servers[0]);
+
+ for (i = 1;
+ (ret = fs_getcells (i, servers,
+ max_servers,
+ cellname, sizeof (cellname))) == 0;
+ ++i) {
+ printf ("%s", cellname);
+
+ if (printservers) {
+ printf (": ");
+
+ for (j = 0; j < max_servers && servers[j]; ++j) {
+ struct hostent *h = NULL;
+ addr.s_addr = servers[j];
+ if (resolve)
+ h = gethostbyaddr ((const char *) &addr,
+ sizeof(addr),
+ AF_INET);
+ if (h == NULL) {
+ printf (" %s", inet_ntoa (addr));
+ } else {
+ printf (" %s", h->h_name);
+ }
+ }
+ }
+ if (suid) {
+ u_int32_t status;
+
+ ret = fs_getcellstatus (cellname, &status);
+ if (ret)
+ fserr (PROGNAME, ret, NULL);
+ else {
+ if (status & CELLSTATUS_SETUID)
+ printf (", suid cell");
+ }
+ }
+ printf (".\n");
+ }
+
+ if (errno != EDOM)
+ fserr(PROGNAME, errno, NULL);
+
+ return 0;
+}
+
+void
+skipline(char **curptr)
+{
+ while(**curptr!='\n') (*curptr)++;
+ (*curptr)++;
+}
+
+
+/*
+ *
+ */
+
+static int
+getcache_cmd (int argc, char **argv)
+{
+ int ret, help = 0;
+ u_int32_t max_bytes, used_bytes, max_vnodes, used_vnodes;
+ int optind = 0, bytes_flag = 0;
+
+ struct getargs ncargs[] = {
+ {"byte", 'b', arg_flag,
+ NULL, "show result in byte instead of kbyte", NULL},
+ {"help", 'h', arg_flag,
+ NULL, "get help", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = ncargs;
+ arg->value = &bytes_flag; arg++;
+ arg->value = &help; arg++;
+
+ if (getarg (ncargs, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(ncargs, "getcacheparams", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ if (help) {
+ arg_printusage(ncargs, "getcacheparams", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+
+ ret = fs_getfilecachestats (&max_bytes,
+ &used_bytes,
+ &max_vnodes,
+ &used_vnodes);
+ if (ret) {
+ fserr (PROGNAME, ret, NULL);
+ return 0;
+ }
+ if (bytes_flag) {
+ printf("Arla is using %lu of the cache's available "
+ "%lu byte blocks\n",
+ (unsigned long)used_bytes, (unsigned long)max_bytes);
+ if (max_vnodes)
+ printf("(and %lu of the cache's available %lu vnodes)\n",
+ (unsigned long)used_vnodes, (unsigned long)max_vnodes);
+ } else {
+ printf("Arla is using %lu of the cache's available "
+ "%lu 1K byte blocks\n",
+ (unsigned long)used_bytes/1024, (unsigned long)max_bytes/1024);
+ if (max_vnodes)
+ printf("(and %lu of the cache's available %lu vnodes)\n",
+ (unsigned long)used_vnodes, (unsigned long)max_vnodes);
+ }
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/fs/fs_local.h b/usr.sbin/afs/src/appl/fs/fs_local.h
new file mode 100644
index 00000000000..8128de4e427
--- /dev/null
+++ b/usr.sbin/afs/src/appl/fs/fs_local.h
@@ -0,0 +1,111 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: fs_local.h,v 1.1 2000/09/11 14:40:36 art Exp $
+ */
+
+#define MAXNAME 100
+#define MAXSIZE 2048
+
+struct Acl {
+ int NumPositiveEntries;
+ int NumNegativeEntries;
+ struct AclEntry *pos;
+ struct AclEntry *neg;
+};
+
+struct AclEntry {
+ struct AclEntry *next;
+ int32_t RightsMask;
+ char name[MAXNAME];
+};
+
+struct VolumeStatus {
+ int32_t Vid;
+ int32_t ParentId;
+ char Online;
+ char InService;
+ char Blessed;
+ char NeedsSalvage;
+ int32_t Type;
+ int32_t MinQuota;
+ int32_t MaxQuota;
+ int32_t BlocksInUse;
+ int32_t PartBlocksAvail;
+ int32_t PartMaxBlocks;
+};
+
+/* Flags for cell status */
+#define PRIMARY_CELL(flags) ((flags) & CELLSTATUS_PRIMARY)
+#define SETUID_HONORED(flags) ((flags) & CELLSTATUS_SETUID)
+#define OBSOLETE_VERSION(flags) ((flags) & CELLSTATUS_OBSOLETE_VL)
+
+void afs_copyacl(char *fromdir, char *todir);
+void afs_listacl(char *path);
+void afs_setacl(char *path, char *user, char *rights);
+struct Acl *afs_getacl(char *path);
+void afs_sysname(char *name);
+void afs_listquota(char *path);
+void afs_setmaxquota(char *path, int32_t maxquota);
+void afs_whereis(char *path);
+void afs_lsmount(const char *path);
+void afs_rmmount(const char *path);
+void afs_examine(char *path);
+int afs_setcache(int, int, int, int);
+void afs_whichcell (char *path);
+void afs_diskfree (char *path);
+void afs_quota (char *path);
+void afs_getcellstatus (char *cell);
+void afs_getfid(char *path);
+int afs_listcells (int printservers, int resolve, int suid);
+int afs_connect(int32_t type);
+int afs_getcrypt (void);
+int afs_setcrypt (int n);
+void afs_print_sysname (void);
+void afs_set_sysname (const char *sys);
+void afs_wscell (void);
+
+void skipline(char **curptr);
+
+/* this program needs __progname defined as a macro */
+#define __progname "fs"
+#define PROGNAME (fs_interactive ? "" : __progname" ")
+
+/* if this is set the program runs in interactive mode */
+static int fs_interactive = 0;
diff --git a/usr.sbin/afs/src/appl/lib/Makefile.in b/usr.sbin/afs/src/appl/lib/Makefile.in
new file mode 100644
index 00000000000..8a4777045c1
--- /dev/null
+++ b/usr.sbin/afs/src/appl/lib/Makefile.in
@@ -0,0 +1,111 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:36 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I../../include \
+ -I$(srcdir)/../../include \
+ -I../.. -I$(srcdir)/../.. \
+ -I../../rxdef \
+ -I$(srcdir)/../../arlad \
+ -I$(srcdir)/../../xfs/include \
+ @KRB4_INC_FLAGS@
+
+CFLAGS = @CFLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+LN_S = @LN_S@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+target_os = @target_os@
+target_vendor = @target_vendor@
+target_cpu = @target_cpu@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)arlalib
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = arlalib.c arladeb.c fs_lib.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = arlalib.o arladeb.o fs_lib.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+arladeb.c: $(srcdir)/../../arlad/arladeb.c
+ test -f arladeb.c || $(LN_S) $(srcdir)/../../arlad/arladeb.c arladeb.c
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../include/config.h
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/lib/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/appl/lib/appl_locl.h b/usr.sbin/afs/src/appl/lib/appl_locl.h
new file mode 100644
index 00000000000..f743979f2f6
--- /dev/null
+++ b/usr.sbin/afs/src/appl/lib/appl_locl.h
@@ -0,0 +1,136 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: appl_locl.h,v 1.1 2000/09/11 14:40:36 art Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <atypes.h>
+#include <roken.h>
+#include <getarg.h>
+#include <err.h>
+
+#include <assert.h>
+
+#include <cb.h>
+#include <time.h>
+#include <lock.h>
+#include <ctype.h>
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+#include <rx/rxgencon.h>
+#ifdef KERBEROS
+#include <krb.h>
+#include <des.h>
+#include <rxkad.h>
+#endif
+#include <kafs.h>
+#ifdef HAVE_STDS_H
+#include <stds.h>
+#endif
+
+#include "arlalib.h"
+
+#include <service.h>
+#include <ports.h>
+#include <volumeserver.h>
+#include <volumeserver.cs.h>
+#include <vldb.h>
+#include <vldb.cs.h>
+#include <fs.h>
+#include <fs.cs.h>
+#include <ubik.h>
+#include <ubik.cs.h>
+#include <pts.h>
+#include <pts.cs.h>
+
+#include <ko.h>
+#include <part.h>
+
+#include <parse_time.h>
+
+
+
+
diff --git a/usr.sbin/afs/src/appl/lib/arlalib.c b/usr.sbin/afs/src/appl/lib/arlalib.c
new file mode 100644
index 00000000000..b51285187d1
--- /dev/null
+++ b/usr.sbin/afs/src/appl/lib/arlalib.c
@@ -0,0 +1,580 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+
+RCSID("$Id: arlalib.c,v 1.1 2000/09/11 14:40:36 art Exp $");
+
+
+static struct rx_securityClass *secureobj = NULL ;
+int secureindex = -1 ;
+
+#ifdef KERBEROS
+
+static int
+get_cred(const char *princ, const char *inst, const char *krealm,
+ CREDENTIALS *c)
+{
+ KTEXT_ST foo;
+ int k_errno;
+
+ k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c);
+
+ if(k_errno != KSUCCESS) {
+ k_errno = krb_mk_req(&foo, (char*)princ, (char*)inst, (char*)krealm, 0);
+ if (k_errno == KSUCCESS)
+ k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c);
+ }
+ return k_errno;
+}
+
+static int
+arlalib_get_cred(const char *cell, const char *host, CREDENTIALS *c,
+ arlalib_authflags_t auth)
+{
+ char krealm[REALM_SZ];
+ char *rrealm;
+ int k_errno;
+ int ret;
+
+ if (auth & (AUTHFLAGS_TICKET|AUTHFLAGS_ANY)) {
+ rrealm = krb_realmofhost(host);
+ strlcpy(krealm, rrealm, REALM_SZ);
+
+ k_errno = get_cred("afs", cell ? cell : "", krealm, c);
+ if (k_errno != KSUCCESS)
+ k_errno = get_cred("afs", "", krealm, c);
+
+ if (k_errno != KSUCCESS) {
+ fprintf(stderr,
+ "Can't get a ticket for realm %s: %s\n",
+ krealm, krb_get_err_text(k_errno));
+ return -1;
+ }
+ ret = k_errno;
+ } else
+ ret = EOPNOTSUPP;
+
+ return ret;
+}
+#endif /* KERBEROS */
+
+int
+arlalib_getservername(u_int32_t serverNumber, char **servername)
+{
+ struct hostent *he;
+
+ he = gethostbyaddr((char*) &serverNumber, sizeof(serverNumber), AF_INET);
+
+ if (he != NULL)
+ *servername = strdup(he->h_name);
+ else {
+ struct in_addr addr;
+ addr.s_addr = serverNumber;
+
+ *servername = strdup(inet_ntoa(addr));
+ }
+
+ return (*servername == NULL);
+}
+
+
+struct rx_securityClass*
+arlalib_getsecurecontext(const char *cell, const char *host,
+ arlalib_authflags_t auth)
+{
+#ifdef KERBEROS
+ CREDENTIALS c;
+#endif /* KERBEROS */
+ struct rx_securityClass* sec;
+
+ if (secureobj != NULL)
+ return secureobj;
+
+#ifdef KERBEROS
+
+ if (auth &&
+ arlalib_get_cred(cell, host, &c, auth) == KSUCCESS) {
+
+ sec = rxkad_NewClientSecurityObject(rxkad_auth,
+ &c.session,
+ c.kvno,
+ c.ticket_st.length,
+ c.ticket_st.dat);
+ secureindex = 2;
+ } else {
+#endif /* KERBEROS */
+
+ sec = rxnull_NewClientSecurityObject();
+ secureindex = 0;
+
+#ifdef KERBEROS
+ }
+#endif /* KERBEROS */
+
+ secureobj = sec;
+
+ return sec;
+
+}
+
+
+struct rx_connection *
+arlalib_getconnbyaddr(const char *cell, int32_t addr,
+ const char *host, int32_t port, int32_t servid,
+ arlalib_authflags_t auth)
+{
+ struct rx_connection *conn;
+ int allocedhost = 0;
+ char *serv;
+
+ rx_Init(0);
+
+ if (host == NULL) {
+ arlalib_getservername(addr, &serv);
+ allocedhost= 1;
+ host = serv;
+ }
+
+ if (arlalib_getsecurecontext(cell, host, auth)== NULL)
+ return NULL;
+
+ conn = rx_NewConnection (addr,
+ htons (port),
+ servid,
+ secureobj,
+ secureindex);
+
+ if (conn == NULL)
+ fprintf (stderr, "Cannot start rx-connection, something is WRONG\n");
+
+ if (allocedhost)
+ free(serv);
+
+ return conn;
+}
+
+struct rx_connection *
+arlalib_getconnbyname(const char *cell, const char *host,
+ int32_t port, int32_t servid,
+ arlalib_authflags_t auth)
+{
+ struct in_addr server;
+
+ if (str2inaddr (host, &server) == NULL ) {
+ fprintf (stderr, "Cannot find host %s\n", host);
+ return NULL;
+ }
+
+ return arlalib_getconnbyaddr(cell, server.s_addr, host, port, servid,
+ auth);
+}
+
+int
+arlalib_destroyconn(struct rx_connection *conn)
+{
+ if (conn == NULL)
+ return 0 ;
+
+ rx_DestroyConnection(conn);
+ return 0;
+}
+
+/*
+ * arlalib_getsyncsite
+ *
+ * if cell and host is NULL, local cell is assumed and a local dbserver is used
+ * if cell is NULL and host not, cell is figured out
+ * (if that fail, localcell is assumed)
+ * if cell is set but not host, host is found i CellServerDB or DNS
+ *
+ *
+ * RETURNS: 0 is ok, otherwise an error that should be handled to
+ * koerr_gettext()
+ */
+
+int
+arlalib_getsyncsite(const char *cell, const char *host, int32_t port,
+ u_int32_t *synchost, arlalib_authflags_t auth)
+{
+ struct rx_connection *conn;
+ ubik_debug db;
+ int error;
+
+ if (synchost == NULL)
+ return EINVAL;
+
+ if (cell == NULL && host != NULL)
+ cell = cell_getcellbyhost(host);
+ if (cell == NULL) {
+ cell = cell_getthiscell();
+ if (cell == NULL)
+ return ENOENT;
+ }
+ if (host == NULL) {
+ host = cell_findnamedbbyname (cell);
+ if (host == NULL)
+ return ENOENT;
+ }
+
+ conn = arlalib_getconnbyname(cell,
+ host,
+ port,
+ VOTE_SERVICE_ID,
+ auth);
+
+ if (conn == NULL)
+ return ENETDOWN;
+
+ error = Ubik_Debug(conn, &db);
+ if (!error) {
+ if (db.amSyncSite)
+ *synchost = rx_HostOf(rx_PeerOf(conn));
+ else
+ *synchost = htonl(db.syncHost);
+ }
+ arlalib_destroyconn(conn);
+
+ return error;
+}
+
+
+/*
+ * get a arlalib_authflags_t type
+ */
+
+arlalib_authflags_t
+arlalib_getauthflag (int noauth,
+ int localauth,
+ int ticket,
+ int token)
+{
+ arlalib_authflags_t ret = AUTHFLAGS_ANY;
+
+ if (noauth)
+ ret = AUTHFLAGS_NOAUTH;
+ if (localauth)
+ ret |= AUTHFLAGS_LOCALAUTH;
+ if (ticket)
+ ret |= AUTHFLAGS_TICKET;
+ if (token)
+ ret |= AUTHFLAGS_TOKEN;
+
+ return ret;
+}
+
+
+/*
+ * set `viceId' to the(a) id for username@cellname
+ * return 0 or error
+ */
+
+int
+arlalib_get_viceid (const char *username, const char *cellname,
+ int32_t *viceId)
+{
+ const cell_db_entry *db_entry;
+ int32_t cell;
+ int num;
+ const char **servers;
+ int i;
+ int ret;
+
+ cell = cell_name2num (cellname);
+ if (cell == -1)
+ return -1;
+
+ db_entry = cell_dbservers_by_id (cell, &num);
+ if (NULL)
+ return -1;
+
+ servers = malloc (num * sizeof(*servers));
+ if (servers == NULL)
+ return -1;
+
+ for (i = 0; i < num; ++i)
+ servers[i] = db_entry[i].name;
+
+ ret = arlalib_get_viceid_servers (username, cellname,
+ num, servers, viceId);
+ free (servers);
+ return ret;
+}
+
+/*
+ * * set `viceId' to the(a) id for username@cellname
+ * use nservers, servers to query for pt database.
+ * return 0 or error
+ */
+
+int
+arlalib_get_viceid_servers (const char *username, const char *cellname,
+ int nservers, const char *servers[],
+ int32_t *viceId)
+{
+ int i=0;
+ int32_t returned_id;
+ int32_t res;
+
+/* FIXME: Should we use authorization when connecting to the dbserver?
+ noauth=0 sometimes gives warnings, e.g. if the realm name is
+ not the same as the name of the cell...
+*/
+ int noauth = 1;
+
+ struct rx_connection *connptdb = NULL;
+ namelist nlist;
+ idlist ilist;
+ prname pr_name_buf;
+
+ /* set up necessary crap to use PR_NameToID */
+ nlist.len = 1;
+ nlist.val = &pr_name_buf;
+
+ ilist.len = 1;
+ ilist.val = &returned_id;
+
+ strlcpy (pr_name_buf, username, sizeof(pr_name_buf));
+
+ /* try all known servers :) */
+ for (i = 0; i < nservers; i++) {
+ connptdb = arlalib_getconnbyname(cellname,
+ servers[i],
+ afsprport,
+ PR_SERVICE_ID,
+ arlalib_getauthflag (noauth, 0,
+ 0, 0));
+ if (connptdb == NULL)
+ return ENETDOWN;
+ }
+
+ if (connptdb) {
+ res = PR_NameToID(connptdb, &nlist, &ilist);
+
+ arlalib_destroyconn(connptdb);
+
+ if (res == 0) {
+ *viceId = ilist.val[0];
+ return 0;
+ }
+ }
+
+ return res;
+}
+
+/*
+ * try to come with a reasonable uid to use for tokens
+ */
+
+static void
+fallback_vice_id (const char *username, const char *cellname,
+ int32_t *token_id)
+{
+ struct passwd *pwd;
+
+ pwd = getpwnam(username);
+ if(pwd == NULL) {
+ *token_id = getuid();
+ warnx ("Couldn't get AFS ID for %s@%s, using current UID (%d)",
+ username, cellname, (int)*token_id);
+ } else {
+ *token_id = pwd->pw_uid;
+ warnx ("Couldn't get AFS ID for %s@%s, using %d from /etc/passwd",
+ username, cellname, (int)*token_id);
+ }
+}
+
+/*
+ * Come with a number to use in a token for for username@cellname
+ * in token_id
+ */
+
+int
+arlalib_get_token_id (const char *username, const char *cellname,
+ int32_t *token_id)
+{
+ int ret;
+
+ ret = arlalib_get_viceid (username, cellname, token_id);
+ if (ret == 0)
+ return ret;
+
+ fallback_vice_id (username, cellname, token_id);
+ return 0;
+}
+
+/*
+ * Come with a number to use in a token for for username@cellname
+ * in token_id
+ * use nservers, servers for querying
+ */
+
+int
+arlalib_get_token_id_servers (const char *username, const char *cellname,
+ int nservers, const char *servers[],
+ int32_t *token_id)
+{
+ int ret;
+
+ ret = arlalib_get_viceid_servers (username, cellname,
+ nservers, servers, token_id);
+ if (ret == 0)
+ return ret;
+
+ fallback_vice_id (username, cellname, token_id);
+ return 0;
+}
+
+/*
+ * Initialize `context' for a db connection to cell `cell', looping
+ * over all db servers if `host' == NULL, and else just try that host.
+ * `port', `serv_id', and `auth' specify where and how the connection works.
+ * Return a rx connection or NULL
+ */
+
+struct rx_connection *
+arlalib_first_db(struct db_server_context *context,
+ const char *cell,
+ const char *host,
+ int port,
+ int serv_id,
+ arlalib_authflags_t auth)
+{
+ const cell_entry *c_entry;
+ int i;
+
+ /* Set struct values from args */
+ context->cell = cell;
+ context->port = port;
+ context->serv_id = serv_id;
+ context->auth = auth;
+
+ if (host != NULL) {
+ context->nhosts = 1;
+ context->hosts = malloc (sizeof (char *));
+ if (context->hosts == NULL)
+ return NULL;
+ context->hosts[0] = host;
+ } else {
+ /* Calculate missing context values */
+ c_entry = cell_get_by_name(cell);
+ if (c_entry == NULL) {
+ warn("Cannot find cell %s", cell);
+ return NULL;
+ }
+ if (c_entry->ndbservers == 0) {
+ warn("No DB servers for cell %s", cell);
+ return NULL;
+ }
+ context->nhosts = c_entry->ndbservers;
+ context->hosts = malloc(context->nhosts * sizeof(char *));
+ if (context->hosts == NULL)
+ return NULL;
+ for(i = 0; i < context->nhosts; i++)
+ context->hosts[i] = c_entry->dbservers[i].name;
+ }
+
+ /* Try to get connection handles until we have one */
+ context->conn = malloc(context->nhosts * sizeof(struct rx_connection*));
+ if (context->conn == NULL) {
+ free (context->hosts);
+ return NULL;
+ }
+ for (i = 0; i < context->nhosts; ++i)
+ context->conn[i] = NULL;
+
+ context->curhost = -1;
+ return arlalib_next_db(context);
+}
+
+/*
+ * Return next connection from `context' or NULL.
+ */
+
+struct rx_connection*
+arlalib_next_db(struct db_server_context *context)
+{
+ int i;
+
+ for(i = context->curhost + 1; i < context->nhosts; i++) {
+ context->curhost = i;
+ context->conn[i] = arlalib_getconnbyname(context->cell,
+ context->hosts[i],
+ context->port,
+ context->serv_id,
+ context->auth);
+ if(context->conn[i] != NULL)
+ return context->conn[i];
+ }
+ return NULL;
+}
+
+/*
+ * return TRUE iff error makes it worthwhile to try the next db.
+ */
+
+int
+arlalib_try_next_db (int error)
+{
+ switch (error) {
+ case UNOTSYNC :
+ case ENETDOWN :
+ return TRUE;
+ case 0 :
+ default :
+ return FALSE;
+ }
+}
+
+/*
+ * free all memory associated with `context'
+ */
+
+void
+free_db_server_context(struct db_server_context *context)
+{
+ int i;
+
+ for (i = 0; i < context->nhosts; i++) {
+ if (context->conn[i] != NULL)
+ arlalib_destroyconn(context->conn[i]);
+ }
+ free(context->hosts);
+ free(context->conn);
+}
+
diff --git a/usr.sbin/afs/src/appl/lib/arlalib.h b/usr.sbin/afs/src/appl/lib/arlalib.h
new file mode 100644
index 00000000000..9f87e44b3f0
--- /dev/null
+++ b/usr.sbin/afs/src/appl/lib/arlalib.h
@@ -0,0 +1,210 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: arlalib.h,v 1.1 2000/09/11 14:40:36 art Exp $ */
+
+#ifndef ARLALIB_H
+#define ARLALIB_H 1
+
+/*
+ * Credentinals
+ */
+
+typedef enum { AUTHFLAGS_NOAUTH = 0,
+ AUTHFLAGS_ANY = 1,
+ AUTHFLAGS_LOCALAUTH = 2,
+ AUTHFLAGS_TICKET = 4,
+ AUTHFLAGS_TOKEN = 8 } arlalib_authflags_t;
+
+arlalib_authflags_t
+arlalib_getauthflag (int noauth,
+ int localauth,
+ int ticket,
+ int token);
+
+/*
+ * Connections
+ */
+
+struct rx_connection *
+arlalib_getconnbyaddr(const char *cell, int32_t addr, const char *host,
+ int32_t port, int32_t servid,
+ arlalib_authflags_t auth);
+
+struct rx_connection *
+arlalib_getconnbyname(const char *cell, const char *host,
+ int32_t port, int32_t servid,
+ arlalib_authflags_t auth);
+
+int arlalib_destroyconn(struct rx_connection *conn);
+int arlalib_getservername(u_int32_t serverNumber, char **servername);
+struct rx_securityClass*
+arlalib_getsecurecontext(const char *cell, const char *host,
+ arlalib_authflags_t auth);
+int arlalib_getsyncsite(const char *cell, const char *host, int32_t port,
+ u_int32_t *synchost, arlalib_authflags_t auth);
+
+
+/*
+ * Wrappers around pioctl calls
+ */
+
+void fserr(const char *progname, int error, const char *realpath);
+
+int fs_getfid (char *path, VenusFid *fid);
+int fs_getfilecellname (char *path, char *cell, size_t len);
+int fs_nop(void);
+
+/* arla extensions */
+
+const char *fslib_version(void);
+
+int fs_setcrypt (u_int32_t level);
+int fs_getcrypt (u_int32_t *level);
+
+int fs_connect (int32_t type, int32_t *flags);
+
+int fs_setfprio(VenusFid fid, int16_t prio);
+int fs_getfprio(VenusFid fid, int16_t *prio);
+int fs_setmaxfprio(int16_t maxprio);
+int fs_getmaxfprio(int16_t *maxprio);
+
+int fs_gcpags(void);
+
+int fs_calculate_cache(u_int32_t *calculated,
+ u_int32_t *usedbytes);
+
+int fs_getfilecachestats(u_int32_t *max_bytes, u_int32_t *used_bytes,
+ u_int32_t *max_vnodes, u_int32_t *used_vnodes);
+
+int fs_getaviatorstats(u_int32_t *max_workers,
+ u_int32_t *used_workers);
+
+int fs_checkservers(char *cell, int32_t flags,
+ u_int32_t *hosts, int numhosts);
+
+int
+fs_set_sysname (const char *sys);
+
+int
+fs_get_sysname (char *sys, size_t sys_sz);
+
+int
+fs_setcache(int lv, int hv, int lb, int hb);
+
+int
+fs_wscell (char *cell, size_t cell_sz);
+
+int
+fs_flushvolume (const char *path);
+
+int
+fs_flush (const char *path);
+
+int
+fs_venuslog (void);
+
+int
+fs_newcell (const char *cell, int nservers, char **servers);
+
+int
+fs_getcells (int32_t num, u_int32_t *server, int numservers,
+ char *cell, size_t cell_sz);
+
+int
+fs_getcellstatus (char *cellname, u_int32_t *flags);
+
+int
+fs_invalidate (const char *path);
+
+int
+fs_lsmount (const char *path);
+
+int
+fs_rmmount (const char *path);
+
+int
+arlalib_get_viceid (const char *username, const char *cellname,
+ int32_t *viceId);
+
+int
+arlalib_get_viceid_servers (const char *username, const char *cellname,
+ int nservers, const char *servers[],
+ int32_t *viceId);
+
+int xfs_debug(int inflags, int *outflags);
+int xfs_debug_print(int inflags);
+int arla_debug(int inflags, int *outflags);
+
+/* db server context */
+
+struct db_server_context {
+ const char *cell;
+ int port;
+ int serv_id;
+ arlalib_authflags_t auth;
+ const char **hosts;
+ int nhosts;
+ int curhost;
+ struct rx_connection **conn;
+};
+
+struct rx_connection*
+arlalib_first_db(struct db_server_context *context, const char *cell,
+ const char *host,
+ int port, int serv_id, arlalib_authflags_t auth);
+
+struct rx_connection*
+arlalib_next_db(struct db_server_context *context);
+
+int
+arlalib_try_next_db (int error);
+
+void
+free_db_server_context(struct db_server_context *context);
+
+int
+arlalib_get_token_id (const char *username, const char *cellname,
+ int32_t *token_id);
+
+int
+arlalib_get_token_id_servers (const char *username, const char *cellname,
+ int nservers, const char *servers[],
+ int32_t *token_id);
+
+#endif /* ARLALIB_H */
diff --git a/usr.sbin/afs/src/appl/lib/fs_lib.c b/usr.sbin/afs/src/appl/lib/fs_lib.c
new file mode 100644
index 00000000000..64ce7a315ba
--- /dev/null
+++ b/usr.sbin/afs/src/appl/lib/fs_lib.c
@@ -0,0 +1,921 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <kafs.h>
+
+RCSID("$Id: fs_lib.c,v 1.1 2000/09/11 14:40:36 art Exp $");
+
+enum { PIOCTL_MAXSIZE = 2000 };
+
+/*
+ *
+ */
+
+const char *
+fslib_version(void)
+{
+ return "$Id: fs_lib.c,v 1.1 2000/09/11 14:40:36 art Exp $";
+}
+
+/*
+ * fserr, try to implement a generic function for fs error messages
+ */
+
+void
+fserr(const char *progname, int error, const char *realpath)
+{
+ const char *path = realpath ? realpath : "[unknown path]";
+
+ switch(error) {
+ case EACCES:
+ fprintf(stderr, "%s: You don't have the required access rights on"
+ " '%s'\n", progname, path);
+ break;
+ case EINVAL:
+ fprintf(stderr, "%s: Invalid argument; it is possible that %s is"
+ " not in AFS.\n", progname, path);
+ break;
+ case ENOENT:
+ fprintf(stderr, "%s: '%s' doesn't exist\n", progname, path);
+ break;
+ case EPERM:
+ fprintf(stderr, "%s: You do not have the required rights to do"
+ " this operation\n", progname);
+ break;
+ case ESRCH:
+ fprintf (stderr, "%s: Home cell information not available\n",
+ progname);
+ break;
+ case EDOM:
+ default:
+ fprintf(stderr, "%s: error %s (%d) return from pioctl\n",
+ progname, koerr_gettext(error), error);
+ break;
+ }
+}
+
+/*
+ * fs_getfid, the the `fid' that `path' points on.
+ */
+
+int
+fs_getfid(char *path, VenusFid *fid)
+{
+ struct ViceIoctl a_params;
+
+ if (path == NULL || fid == NULL)
+ return EINVAL;
+
+ a_params.in_size=0;
+ a_params.out_size=sizeof(*fid);
+ a_params.in=NULL;
+ a_params.out=(void*) fid;
+
+ if(k_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 (k_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 (k_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 (k_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 (k_pioctl (NULL, VIOC_GETRXKCRYPT, &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ * get and set the connect-mode
+ */
+
+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 (k_pioctl (NULL, VIOCCONNECTMODE, &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+#ifdef VIOC_FPRIOSTATUS
+int
+fs_setfprio(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 (k_pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+#ifdef VIOC_FPRIOSTATUS
+int
+fs_getfprio(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 (k_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 (k_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 (k_pioctl (NULL, VIOC_FPRIOSTATUS , &a_params, 0) == -1)
+ return errno;
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+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 (k_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;
+}
+
+
+/*
+ *
+ */
+
+#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 (k_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 (k_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 (k_pioctl (NULL, VIOC_CALCULATE_CACHE , &a_params, 0) == -1)
+ return errno;
+
+ if (calculated)
+ *calculated = parms[0];
+ if (usedbytes)
+ *usedbytes = parms[1];
+
+ return 0;
+}
+#endif
+
+/*
+ *
+ */
+
+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 (k_pioctl ((char *)path, VIOC_BREAKCALLBACK, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * 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)
+{
+ 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 (k_pioctl (NULL, 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);
+}
+#endif
+
+/*
+ * xfs_debug_print
+ */
+
+#ifdef VIOC_XFSDEBUG_PRINT
+int
+xfs_debug_print(int inflags)
+{
+ return debug (VIOC_XFSDEBUG_PRINT, inflags, NULL);
+}
+#endif
+
+/*
+ * arla_debug
+ */
+
+#ifdef VIOC_ARLADEBUG
+int
+arla_debug (int inflags, int *outflags)
+{
+ return debug (VIOC_ARLADEBUG, inflags, outflags);
+}
+#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 (k_pioctl (NULL, VIOCCKSERV, &a_params, 0) == -1)
+ ret = errno;
+
+ if (in)
+ free(in);
+
+ return ret;
+}
+
+/*
+ * return current sysname in `sys' (of max length `sys_sz')
+ */
+
+int
+fs_get_sysname (char *sys, size_t sys_sz)
+{
+ struct ViceIoctl a_params;
+ int32_t set = 0;
+ char *buf;
+
+ buf = malloc (sys_sz + 4);
+ if (buf == NULL)
+ return ENOMEM;
+
+ a_params.in = (caddr_t)&set;
+ a_params.in_size = sizeof(set);
+ a_params.out = buf;
+ a_params.out_size = sys_sz + 4;
+
+ if(k_pioctl (NULL, VIOC_AFS_SYSNAME, &a_params, 1) < 0)
+ return errno;
+ else {
+ strlcpy (sys, buf + 4, sys_sz);
+ 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(k_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 (k_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 (k_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 (k_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 (k_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 (k_pioctl (NULL, VIOC_VENUSLOG, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * Create a new cell (or change servers for an existing one), with
+ * name `cell' and `nservers' servers in `servers'.
+ */
+
+int
+fs_newcell (const char *cell, int nservers, char **servers)
+{
+ struct ViceIoctl a_params;
+ int len;
+ char *buf;
+ int i;
+ u_int32_t *hp;
+
+ nservers = min (nservers, 8);
+
+ len = 8 * sizeof(u_int32_t) + strlen(cell) + 1;
+ buf = malloc (len);
+ if (buf == NULL)
+ return errno;
+
+ memset (buf, 0, len);
+ strcpy (buf + 8 * sizeof(u_int32_t), cell);
+ hp = (u_int32_t *)buf;
+ for (i = 0; i < nservers; ++i) {
+ struct in_addr addr;
+
+ if (str2inaddr (servers[i], &addr) == NULL) {
+ free (buf);
+ return EINVAL;
+ }
+ hp[i] = addr.s_addr;
+ }
+
+ a_params.in_size = len;
+ a_params.out_size = 0;
+ a_params.in = (caddr_t)buf;
+ a_params.out = NULL;
+
+ if (k_pioctl (NULL, VIOCNEWCELL, &a_params, 0) < 0)
+ return errno;
+ else
+ return 0;
+}
+
+/*
+ * Fetch cell status for cell `num', and put the ip-numbers to the servers
+ * in the array `server' of length `numservers'. `Cell' is the name
+ * of the cell and has length `sell_sz'.
+ */
+
+int
+fs_getcells (int32_t num, u_int32_t *server, int numservers,
+ char *cell, size_t cell_sz)
+{
+ struct ViceIoctl a_params;
+ int32_t *server_list;
+ int i;
+
+ if (server == NULL && numservers != 0)
+ return EINVAL;
+
+ memset(server, 0, numservers * sizeof(*server));
+
+#define GETCELL_MAXSERVER 8
+ a_params.in_size = sizeof (num);
+ a_params.out_size = sizeof (u_int32_t) * GETCELL_MAXSERVER + cell_sz + 1;
+ a_params.in = (char *) &num;
+ a_params.out = malloc (a_params.out_size);
+
+ if (a_params.out == NULL)
+ return ENOMEM;
+
+ server_list = (int32_t *) a_params.out;
+
+ if (k_pioctl (NULL, VIOCGETCELL, &a_params, 0) != 0)
+ return errno;
+
+ if (numservers > GETCELL_MAXSERVER)
+ numservers = GETCELL_MAXSERVER;
+ for (i = 0 ; i < numservers; i++)
+ server[i] = server_list[i];
+
+ strlcpy (cell,
+ (char *) a_params.out + GETCELL_MAXSERVER * sizeof(u_int32_t),
+ cell_sz);
+
+ 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 (k_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 = k_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);
+}
diff --git a/usr.sbin/afs/src/appl/pts/Makefile.in b/usr.sbin/afs/src/appl/pts/Makefile.in
new file mode 100644
index 00000000000..59f0ce3fe4f
--- /dev/null
+++ b/usr.sbin/afs/src/appl/pts/Makefile.in
@@ -0,0 +1,136 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:36 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+mandir = @mandir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = pts
+MANPAGES = pts.1
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+READLINE_lib = @LIB_readline@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ -L../../lib/roken \
+ $(READLINE_lib) \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = pts
+PTS_SRCS = pts.c
+SRCS = $(PTS_SRCS)
+PTS_OBJS = pts.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir) ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+pts: $(PTS_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(PTS_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/pts/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/pts/pts.1 b/usr.sbin/afs/src/appl/pts/pts.1
new file mode 100644
index 00000000000..0d178253e63
--- /dev/null
+++ b/usr.sbin/afs/src/appl/pts/pts.1
@@ -0,0 +1,259 @@
+.\" $OpenBSD: pts.1,v 1.1 2000/09/11 14:40:36 art Exp $
+.\" $Id: pts.1,v 1.1 2000/09/11 14:40:36 art Exp $
+.Dd March 25, 2000
+.Dt PTS 1
+.Os
+.Sh NAME
+.Nm pts
+.Nd Manage AFS protection database
+.Sh SYNOPSIS
+.Nm pts
+.Op Ar command
+.Op Ar args
+.Sh DESCRIPTION
+The
+.Nm
+utility is used to manipulate the contents of the AFS Protection Database,
+which contains information about users and groups and is handled by the
+Protection Server.
+Note that the
+.Nm
+utility does
+.Em not
+modify the traditional
+.Ux
+user and group database, only the AFS specific information.
+.Pp
+The
+.Nm
+utility provides several commands:
+.Pp
+.Bl -tag -width "membership groups" -compact
+.It Cm adduser
+add a user to a group
+.It Cm chown
+change owner of user or group
+.It Cm creategroup / cg
+create a new group
+.It Cm createuser
+create a new user
+.It Cm dump
+dump pts database
+.It Cm delete
+delete user or group
+.It Cm examine
+examine a user or a group
+.It Cm help Cm ?
+get help on
+.Nm
+.It Cm listmax
+print largest uid and gid
+.It Cm listowned
+list groups owned by a user or group, or orphaned groups
+.It Cm membership Cm groups
+list group or user membership
+.It Cm removeuser
+remove a user from a group
+.It Cm rename
+rename user/group
+.It Cm setfields
+not yet implemented
+.It Cm setmax
+not yet implemented
+.It Cm syncdb
+not yet implemented
+.El
+.Pp
+Most
+.Nm
+commands accept the following general arguments:
+.Pp
+.Bd -filled -offset indent -compact
+.Op Fl cell Ar cellname
+Specifies which AFS cell to use, if the default cell is not to be used.
+.Pp
+.Op Fl noauth
+Specifies that
+.Nm
+should not try to authenticate the connection to the server.
+This may be
+useful with shell scripts, or if there is a problem with the AFS cell.
+Note that the server will reject many commands if
+.Fl noauth
+is specified.
+.Ed
+.Pp
+The syntax of the
+.Nm
+commands:
+.Pp
+.Ic pts adduser
+.Op Fl name
+.Ar user
+.Op Fl group
+.Ar group
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Add the specified user to the specified group.
+.Ed
+.Pp
+.Ic pts chown
+.Op Fl name
+.Ar user/group
+.Op Fl owner
+.Ar owner
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Change owner of a group or user.
+.Ed
+.Pp
+.Ic pts creategroup
+.Op Fl name
+.Ar name
+.Op Fl id Ar idnumber
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Create a new group.
+If
+.Fl id
+is not specified, a new idnumber is taken automatically.
+.Ed
+.Pp
+.Ic pts cg
+.Bd -filled -offset indent -compact
+.Ic pts cg
+is an alias for the
+.Ic pts creategroup
+command.
+.Ed
+.Pp
+.Ic pts createuser
+.Op Fl name
+.Ar name
+.Op Fl id Ar idnumber
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Create a new user.
+If
+.Fl id
+is not specified, a new idnumber is taken automatically.
+.Ed
+.Pp
+.Ic pts dump
+.Ar server
+.Op Fl cell cellname
+.Bd -filled -offset indent -compact
+Dump the Protection Database in a human readable form.
+The database is read from the given database server.
+.Ed
+.Pp
+.Ic pts delete
+.Op Fl name
+.Ar name/group
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Delete a user or group from the database.
+.Ed
+.Pp
+.Ic pts examine
+.Ar user/group
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Print verbose information about a user or a group.
+.Ed
+.Pp
+.Ic pts help
+or
+.Ic pts ?
+.Bd -filled -offset indent -compact
+Print help about
+.Nm
+.Ed
+.Pp
+.Ic pts listmax
+.Op Fl cell Ar cellname
+.Bd -filled -offset indent -compact
+Print the largest uid and gid.
+.Ed
+.Pp
+.Ic pts listowned
+.Op Fl id
+.Ar user/group
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+List the groups owned by a user or group.
+.Ed
+.Pp
+.Ic pts membership
+.Op Fl nameorid Ar user/group
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+List the members of a group, or the groups a user is a member of.
+.Ed
+.Pp
+.Ic pts groups
+.Bd -filled -offset indent -compact
+.Ic pts groups
+is an alias for the
+.Ic pts membership
+command.
+.Ed
+.Pp
+.Ic pts removeuser
+.Op Fl user
+.Ar user
+.Op Fl group
+.Ar group
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Remove a users membership from a group.
+.Ed
+.Pp
+.Ic pts rename
+.Op Fl from
+.Ar "old name"
+.Op Fl to
+.Ar "new name"
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Bd -filled -offset indent -compact
+Rename a user or group.
+.Ed
+.Pp
+.Ic pts setfields
+.Bd -filled -offset indent -compact
+This command is available in the original AFS client, but has not been
+implemented yet.
+.Ed
+.Pp
+.Ic pts setmax
+.Bd -filled -offset indent -compact
+This command is available in the original AFS client, but has not been
+implemented yet.
+.Ed
+.Pp
+.Ic pts syncdb
+.Bd -filled -offset indent -compact
+This command has not been implemented yet.
+.Ed
+.Pp
+.Sh SEE ALSO
+.Xr afsd 8 ,
+.Xr fs 1 ,
+.Xr vos 8
+.Sh STANDARDS
+The Arla authors are trying to mimic the behaviour of the original AFS
+utilities.
+.Sh AUTHORS
+The Arla project <http://www.stacken.kth.se/project/arla/>.
+.Sh BUGS
+Some commands are not implemented yet.
diff --git a/usr.sbin/afs/src/appl/pts/pts.c b/usr.sbin/afs/src/appl/pts/pts.c
new file mode 100644
index 00000000000..61755ade643
--- /dev/null
+++ b/usr.sbin/afs/src/appl/pts/pts.c
@@ -0,0 +1,1526 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Höskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <sl.h>
+#include "appl_locl.h"
+
+RCSID("$Id: pts.c,v 1.1 2000/09/11 14:40:36 art Exp $");
+
+static int help_cmd (int argc, char **argv);
+
+/* Debugging on/off */
+static int prdebug = 0;
+
+static int
+empty_cmd (int argc, char **argv)
+{
+ printf ("%s not implemented yet!\n", argv[0]);
+ return 0;
+}
+
+static void
+dump_usage (void)
+{
+ printf("Usage: pts dump <vldb server>+ [-cell <cell>]\n");
+}
+
+static int
+dump_cmd (int argc, char **argv)
+{
+ struct rx_connection *connptdb = NULL;
+ struct prdebugentry entry;
+ struct prheader header;
+ const char *host;
+ int noauth = 0;
+ unsigned int pos;
+ int error;
+
+ argc--;
+ argv++;
+
+ if (argc < 1) {
+ dump_usage ();
+ return -1;
+ }
+
+ host = argv[0];
+
+ connptdb = arlalib_getconnbyname(cell_getcellbyhost(host),
+ host,
+ afsprport,
+ PR_SERVICE_ID,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+
+ if (connptdb == NULL)
+ return 0;
+
+ error = PR_DumpEntry(connptdb, 0, (struct prdebugentry *) &header);
+
+ if (error) {
+ printf("dump_cmd: DumpEntry failed with: %s (%d)\n",
+ koerr_gettext(error),
+ error);
+ return 0;
+ }
+
+ for (pos = header.headerSize; pos < header.eofPtr; pos += sizeof (struct prdebugentry)) {
+ error = PR_DumpEntry(connptdb, pos, &entry);
+ if (error) {
+ printf("dump_cmd: DumpEntry failed with: %s (%d)\n",
+ koerr_gettext(error),
+ error);
+/* return -1;*/
+ }
+ else {
+ printf("-----\n");
+ printf("Name: %s, id: %d, owner: %d, creator: %d,\n",
+ entry.name, entry.id, entry.owner, entry.creator);
+ printf(" membership: %d, flags:", entry.ngroups);
+ if ((entry.flags & PRTYPE) == PRFREE)
+ printf (" PRFREE");
+ if ((entry.flags & PRTYPE) == PRGRP)
+ printf (" PRGRP");
+ if ((entry.flags & PRTYPE) == PRCONT)
+ printf (" PRCONT");
+ if ((entry.flags & PRTYPE) == PRCELL)
+ printf (" PRCELL");
+ if ((entry.flags & PRTYPE) == PRFOREIGN)
+ printf (" PRFOREIGN");
+ if ((entry.flags & PRTYPE) == PRINST)
+ printf (" PRINST");
+ if ((entry.flags & PRTYPE) == PRUSER)
+ printf (" PRUSER");
+ if ((entry.flags & PRACCESS) == PRACCESS)
+ printf (" PRACCESS");
+ if ((entry.flags & PRQUOTA) == PRQUOTA)
+ printf (" PRQUOTA");
+
+ printf (" , group quota: %d.\n",
+ entry.ngroups);
+ }
+ }
+
+ arlalib_destroyconn(connptdb);
+ return 0;
+}
+
+static int
+flags_to_string(int flags, char *string)
+{
+ strcpy(string, "-----");
+ if((flags & PRP_STATUS_ANY) != 0)
+ string[0]='S';
+ else if((flags & PRP_STATUS_MEM) != 0)
+ string[0]='s';
+ if((flags & PRP_OWNED_ANY) != 0)
+ string[1]='O';
+ if((flags & PRP_MEMBER_ANY) != 0)
+ string[2]='M';
+ else if((flags & PRP_MEMBER_MEM) != 0)
+ string[2]='m';
+ if((flags & PRP_ADD_ANY) != 0)
+ string[3]='A';
+ else if((flags & PRP_ADD_MEM) != 0)
+ string[3]='a';
+ if((flags & PRP_REMOVE_MEM) != 0)
+ string[4]='r';
+ return 0;
+}
+
+static int
+examine_id(struct rx_connection *conn, int32_t id, char *idname)
+{
+ prcheckentry ent;
+ int error;
+ namelist nlist;
+ idlist ilist;
+ char flags_str[6];
+
+ error = PR_ListEntry(conn, id, &ent);
+ if (error) {
+ fprintf(stderr, "ListEntry in examine: error %s (%d)\n",
+ koerr_gettext(error), error);
+ return error;
+ }
+
+ nlist.len = 3;
+ nlist.val = malloc(sizeof(prname) * nlist.len);
+ if(nlist.val == NULL)
+ errx(1, "Out of memory");
+
+ ilist.len = 3;
+ ilist.val = malloc(sizeof(int32_t) * ilist.len);
+ if(ilist.val == NULL)
+ errx(1, "Out of memory");
+
+ ilist.val[0] = ent.id;
+ ilist.val[1] = ent.owner;
+ ilist.val[2] = ent.creator;
+
+ error = PR_IDToName(conn, &ilist, &nlist);
+ if (error) {
+ fprintf(stderr, "IDToName in examine: error %s (%d)\n",
+ koerr_gettext(error), error);
+ return error;
+ }
+
+ flags_to_string(ent.flags << 16, flags_str); /* XXX why do i have to shift by 16? seems strange */
+
+ printf("Name: %s, id: %d, owner: %s, creator: %s,\n",
+ nlist.val[0], ent.id, nlist.val[1], nlist.val[2]);
+ printf(" membership: %d, flags: %s, group quota: %d.\n",
+ ent.count, flags_str, ent.ngroups);
+ free(ilist.val);
+ free(nlist.val);
+ return 0;
+}
+
+
+/*
+ * convert a `name' to `id'
+ */
+
+static int
+pr_name2id(struct rx_connection *conn, const char *name, int32_t *id)
+{
+ int error;
+ namelist nlist;
+ idlist ilist;
+ char rname[PR_MAXNAMELEN];
+
+ assert(id);
+
+ if (prdebug)
+ printf("pr_name2id(%s, x)", name);
+
+ strlcpy(rname, name, sizeof(rname));
+
+ nlist.len = 1;
+ nlist.val = &rname;
+
+ error = PR_NameToID(conn, &nlist, &ilist);
+
+ if (error || ilist.len != 1)
+ *id = 0;
+ else
+ *id = *ilist.val;
+
+ if (prdebug)
+ printf(" id = %d, error= %d\n", *id, error);
+
+ free(ilist.val);
+
+ return error;
+}
+
+/*
+ * add `user' to `group' on `conn'. Return 0 or error.
+ */
+
+static int
+adduser_1 (struct rx_connection *conn, const char *user, const char *group)
+{
+ int32_t uid;
+ int32_t gid;
+ int error;
+
+ error = pr_name2id(conn, user, &uid);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding user %s, error %s (%d)",
+ user, koerr_gettext(error), error);
+ return error;
+ }
+
+ error = pr_name2id(conn, group, &gid);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding group %s, error %s (%d)",
+ user, koerr_gettext(error), error);
+ return error;
+ }
+
+ if (prdebug)
+ printf("PR_AddToGroup(conn, uid = %d, gid = %d);\n", uid, gid);
+
+ error = PR_AddToGroup(conn, uid, gid);
+ return error;
+}
+
+/*
+ * add `user' to `group' in `cell'
+ */
+
+static int
+pr_adduser(const char *cell, const char *host,
+ const char *user, const char *group,
+ arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = adduser_1 (conn, user, group);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+
+/*
+ * create user/group
+ * if you want the id returned
+ * set *id = 0
+ * if you want to decide what the userid is set the *id != 0,
+ * id is still returned in this variable.
+ *
+ */
+
+#define PR_CREATE_USER 0
+#define PR_CREATE_GROUP 2
+
+static int
+pr_create(const char *cell, const char *host,
+ const char *name, const char *owner,
+ int32_t *id, int flag, arlalib_authflags_t auth)
+{
+ int error;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ error = ENETDOWN;
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db (error);
+ conn = arlalib_next_db(&conn_context)) {
+ int32_t owner_id = 0;
+ int32_t out_id;
+
+ if (owner != NULL) {
+ error = pr_name2id (conn, owner, &owner_id);
+ if (error)
+ continue;
+ }
+
+ if (id == NULL || *id == 0) {
+ if (prdebug)
+ printf("PR_NewEntry(%s, %d, %d, OUT)\n",
+ name, flag, owner_id);
+
+ error = PR_NewEntry(conn, name, flag, owner_id, &out_id);
+ if (id != NULL && error == 0)
+ *id = out_id;
+ } else {
+ if (prdebug)
+ printf("PR_INewEntry(%s, %d, %d, OUT)\n",
+ name, *id, owner_id);
+
+ error = PR_INewEntry(conn, name, *id, owner_id);
+ }
+ }
+ if(error)
+ fprintf(stderr, "pts create: error %s (%d)\n",
+ koerr_gettext(error), error);
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+/*
+ *
+ */
+
+static int
+delete_1 (struct rx_connection *conn, const char *name)
+{
+ int error;
+ int32_t id;
+
+ error = pr_name2id(conn, name, &id);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ name, koerr_gettext(error), error);
+ return error;
+ }
+
+ if (prdebug)
+ printf("PR_Delete(%s, %d)\n", name, id);
+
+ error = PR_Delete(conn, id);
+ return error;
+}
+
+static int
+pr_delete(const char *cell, const char *host,
+ const char *name, arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = delete_1 (conn, name);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+
+static int
+remove_1(struct rx_connection *conn, const char *user, const char *group)
+{
+ int error;
+ int32_t uid;
+ int32_t gid;
+
+ error = pr_name2id(conn, user, &uid);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ user, koerr_gettext(error), error);
+ return error;
+ }
+
+ error = pr_name2id(conn, group, &gid);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ group, koerr_gettext(error), error);
+ return error;
+ }
+
+ if (prdebug)
+ printf("PR_RemoveFromGroup(%d, %d)\n", uid, gid);
+
+ error = PR_RemoveFromGroup(conn, uid, gid);
+ return error;
+}
+
+/*
+ *
+ */
+
+static int
+pr_removeuser(const char *cell, const char *host,
+ const char *user, const char *group,
+ arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = remove_1 (conn, user, group);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+static int
+rename_1 (struct rx_connection *conn,
+ const char *fromname, const char *toname)
+{
+ int error;
+ int32_t id;
+
+ error = pr_name2id(conn, fromname, &id);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ fromname, koerr_gettext(error), error);
+ return error;
+ }
+
+ if (prdebug)
+ printf("PR_ChangeEntry(%d, %s, 0, 0)\n", id, toname);
+
+ error = PR_ChangeEntry(conn, id, toname, 0, 0);
+ return error;
+}
+
+/*
+ *
+ */
+
+static int
+pr_rename(const char *cell, const char *host,
+ const char *fromname, const char *toname,
+ arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = rename_1 (conn, fromname, toname);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+static int
+setfields_1 (struct rx_connection *conn, const char *name,
+ int mask, int flags, int ngroup, int nusers)
+{
+ int error;
+ int32_t id;
+
+ error = pr_name2id(conn, name, &id);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ name, koerr_gettext(error), error);
+ return error;
+ }
+
+ if (prdebug)
+ printf("PR_ChangeFields(%d, %d, %d, %d, %d, 0, 0)\n",
+ id, mask, flags, ngroup, nusers);
+
+ error = PR_SetFieldsEntry(conn, id, mask, flags, ngroup, nusers, 0, 0);
+ return error;
+}
+
+/*
+ *
+ */
+
+static int
+pr_setfields(const char *cell, const char *host,
+ const char *name, int flags, int ngroup, int nusers,
+ arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+ int mask = 0;
+
+ if (flags != -1)
+ mask |= PR_SF_ALLBITS;
+ if (ngroup != -1)
+ mask |= PR_SF_NGROUPS;
+ if (nusers != -1)
+ mask |= PR_SF_NUSERS;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = setfields_1 (conn, name, mask, flags, ngroup, nusers);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+static int
+chown1(struct rx_connection *conn, const char *name, const char *owner)
+{
+ int error;
+ int32_t id;
+ int32_t ownerid;
+
+ error = pr_name2id(conn, name, &id);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ name, koerr_gettext(error), error);
+ return error;
+ }
+
+ error = pr_name2id(conn, owner, &ownerid);
+ if (error) {
+ if (prdebug)
+ warn("Problems finding name: %s, error %s (%d)",
+ name, koerr_gettext(error), error);
+ return error;
+ }
+
+ if (prdebug)
+ printf("PR_ChangeEntry(%d, \"\", %d, 0)\n",
+ id, ownerid);
+
+ error = PR_ChangeEntry(conn, id, "", ownerid, 0);
+ return error;
+}
+
+/*
+ *
+ */
+
+static int
+pr_chown(const char *cell, const char *host,
+ const char *name, const char *owner,
+ arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = chown1 (conn, name, owner);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+static int
+pts_id_to_name(struct rx_connection *conn, int id, prname *pr)
+{
+ int32_t res = 0;
+ namelist nlist;
+ idlist ilist;
+ nlist.len = 1;
+ nlist.val = malloc(sizeof(prname) * nlist.len);
+ ilist.len = 1;
+ ilist.val = malloc(sizeof(int32_t) * ilist.len);
+ if((ilist.val == NULL) || (nlist.val == NULL))
+ errx(1, "Out of memory");
+ ilist.val[0]=id;
+ res = PR_IDToName(conn, &ilist, &nlist);
+ if(res == 0)
+ strlcpy((char *)pr, (char *)nlist.val[0], PR_MAXNAMELEN);
+ free(ilist.val);
+ free(nlist.val);
+ return res;
+}
+
+static int
+pts_name_to_id(struct rx_connection *conn, const char *name, int32_t *id)
+{
+ int32_t res = 0;
+ namelist nlist;
+ idlist ilist;
+ int isdig = 1;
+ const char *ptr = name;
+
+ while(*ptr && isdig) {
+ if(!isdigit((unsigned char)*ptr))
+ isdig = 0;
+ ptr++;
+ }
+ if(isdig) {
+ *id = atoi(name);
+ return 0;
+ }
+
+ nlist.len = 1;
+ nlist.val = malloc(sizeof(prname) * nlist.len);
+ ilist.len = 1;
+ ilist.val = malloc(sizeof(int32_t) * ilist.len);
+ if((nlist.val == NULL) || (ilist.val == NULL))
+ errx(1, "Out of memory");
+ strlcpy(nlist.val[0], name, sizeof(prname));
+ res = PR_NameToID(conn, &nlist, &ilist);
+ *id = ilist.val[0];
+ free(ilist.val);
+ free(nlist.val);
+ return res;
+}
+
+static int
+listowned_1 (struct rx_connection *conn, const char *user)
+{
+ int error;
+ int32_t id;
+ int32_t over;
+ prname *name;
+ prlist pr;
+ int i;
+
+ printf("%s\n", user);
+
+ error = pts_name_to_id (conn, user, &id);
+ if(error != 0)
+ return error;
+
+ pr.len = PR_MAXGROUPS;
+ pr.val = malloc(sizeof(int32_t) * pr.len);
+ if(pr.val == NULL)
+ errx(1, "Out of memory");
+
+ printf("%d\n", id);
+ error = PR_ListOwned(conn, id, &pr, &over);
+ if(error != 0)
+ return error;
+
+ printf("id = %d\n", id);
+ printf("pr.len = %d\n", pr.len);
+
+ i = 0;
+ name = malloc(PR_MAXNAMELEN);
+ if(name == NULL)
+ errx(1, "Out of memory");
+
+ printf("Groups owned by %s (id: %d) are:\n", user, id);
+
+ while(pr.val[i] != 0 && i < pr.len) {
+ pts_id_to_name(conn, pr.val[i++], name);
+ printf(" %s\n", (char *) name);
+ }
+
+ free(pr.val);
+ return 0;
+}
+
+static int
+pr_listowned (const char *cell, const char *host, const char *user,
+ arlalib_authflags_t auth)
+{
+ int error = ENETDOWN;
+ struct rx_connection *conn;
+ struct db_server_context conn_context;
+
+ for (conn = arlalib_first_db(&conn_context,
+ cell, host, afsprport, PR_SERVICE_ID, auth);
+ conn != NULL && arlalib_try_next_db(error);
+ conn = arlalib_next_db(&conn_context)) {
+ error = listowned_1 (conn, user);
+ }
+ free_db_server_context(&conn_context);
+ return error;
+}
+
+/*
+ * create user
+ */
+
+static int
+create_cmd(int argc, char **argv, int groupp, const char *cmd_name)
+{
+ const char *name;
+ const char *owner = NULL;
+ const char *cell = (char *) cell_getthiscell();
+ const char *host = NULL;
+ int32_t id = 0;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs createuserarg[] = {
+ {"name", 0, arg_string, NULL, NULL, NULL, arg_mandatory},
+ {"owner", 0, arg_string, NULL, "owner of the group"},
+ {"id", 0, arg_integer, NULL, "id of user", NULL},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = createuserarg;
+ if (groupp)
+ arg->help = "name of user";
+ else
+ arg->help = "name of group";
+ arg->value = &name; arg++;
+ arg->value = &owner; arg++;
+ arg->value = &id; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (!groupp)
+ memmove (&createuserarg[1], &createuserarg[2],
+ 6 * sizeof(createuserarg[0]));
+
+ if (getarg (createuserarg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(createuserarg, cmd_name, NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = pr_create(cell, host, name, owner, &id, groupp,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_create failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ } else
+ printf("%s %s created with id %d\n",
+ groupp ? "Group": "User", name, id);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+createuser_cmd(int argc, char **argv)
+{
+ return create_cmd(argc, argv, PR_CREATE_USER, "pts createuser");
+}
+
+/*
+ *
+ */
+
+static int
+creategroup_cmd(int argc, char **argv)
+{
+ return create_cmd(argc, argv, PR_CREATE_GROUP, "pts creategroup");
+}
+
+/*
+ *
+ */
+
+static int
+adduser_cmd(int argc, char **argv)
+{
+ const char *user;
+ const char *group;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs addarg[] = {
+ {"name", 0, arg_string, NULL, "username", NULL, arg_mandatory},
+ {"group", 0, arg_string, NULL, "groupname",NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = addarg;
+ arg->value = &user; arg++;
+ arg->value = &group; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (addarg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(addarg, "pts adduser", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = pr_adduser(cell, host, user, group,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_adduser failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+delete_cmd(int argc, char **argv)
+{
+ const char *user;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs deletearg[] = {
+ {"name", 0, arg_string, NULL, "username", NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = deletearg;
+ arg->value = &user; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (deletearg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(deletearg, "pts delete", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = pr_delete(cell, host, user,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_delete failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ } else
+ if (prdebug)
+ printf("Entry %s deleted successful\n", user);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+removeuser_cmd(int argc, char **argv)
+{
+ const char *user;
+ const char *group;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs removearg[] = {
+ {"user", 0, arg_string, NULL, "username", NULL, arg_mandatory},
+ {"group", 0, arg_string, NULL, "group", NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = removearg;
+ arg->value = &user; arg++;
+ arg->value = &group; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (removearg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(removearg, "pts remove", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = pr_removeuser(cell, host, user, group,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_remove failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ } else
+ if (prdebug)
+ printf("User %s removed from group %s.\n", user, group);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+rename_cmd(int argc, char **argv)
+{
+ const char *fromname;
+ const char *toname;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs renamearg[] = {
+ {"from", 0, arg_string, NULL, "from name",NULL, arg_mandatory},
+ {"to", 0, arg_string, NULL, "to name", NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = renamearg;
+ arg->value = &fromname;arg++;
+ arg->value = &toname; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (renamearg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(renamearg, "pts rename", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = pr_rename(cell, host, fromname, toname,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_rename failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ } else
+ if (prdebug)
+ printf("Changed name from %s to %s.\n", fromname, toname);
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+static int
+setfields_error(void)
+{
+ printf("text must be a union of the sets 'SOMA-' and 's-mar'\n");
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+setfields_cmd(int argc, char **argv)
+{
+ const char *name;
+ const char *strflags = NULL;
+ int flags = -1;
+ int gquota = -1;
+ int uquota = -1;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs setfieldarg[] = {
+ {"name", 0, arg_string, NULL, "name of user/group",
+ NULL, arg_mandatory},
+ {"flags", 0, arg_string, NULL, "flags", NULL},
+ {"groupquota", 0, arg_integer, NULL, "groupquota",NULL},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = setfieldarg;
+ arg->value = &name; arg++;
+ arg->value = &flags; arg++;
+ arg->value = &gquota; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (setfieldarg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(setfieldarg, "pts setfields", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ if(strflags) {
+ if (strlen(strflags) != 5)
+ return setfields_error();
+
+ flags = 0;
+
+ if (strflags[0] == 'S')
+ flags |= PRP_STATUS_ANY;
+ else if (strflags[0] == 's')
+ flags |= PRP_STATUS_MEM;
+ else if (strflags[0] != '-')
+ return setfields_error();
+
+ if (strflags[1] == 'O')
+ flags |= PRP_OWNED_ANY;
+ else if (strflags[1] != '-')
+ return setfields_error();
+
+ if (strflags[2] == 'M')
+ flags |= PRP_MEMBER_ANY;
+ else if (strflags[2] == 'm')
+ flags |= PRP_MEMBER_MEM;
+ else if (strflags[2] != '-')
+ return setfields_error();
+
+ if (strflags[3] == 'A') {
+ flags |= PRP_ADD_ANY;
+ } else if (strflags[3] == 'a')
+ flags |= PRP_ADD_MEM;
+ else if (strflags[3] != '-')
+ return setfields_error();
+
+ if (strflags[4] == 'r')
+ flags |= PRP_REMOVE_MEM;
+ else if (strflags[4] != '-')
+ return setfields_error();
+ }
+
+ error = pr_setfields(cell, host, name, flags, gquota, uquota,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_setfields failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ } else
+ if (prdebug)
+ printf("Changed fields for %s.\n", name);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+chown_cmd(int argc, char **argv)
+{
+ const char *name;
+ const char *owner;
+ const char *cell = cell_getthiscell();
+ const char *host;
+ int noauth = 0;
+ int error;
+ int optind = 0;
+
+ struct getargs chownarg[] = {
+ {"name", 0, arg_string, NULL, "user or group name",
+ NULL, arg_mandatory},
+ {"owner", 0, arg_string, NULL, "new owner",
+ NULL, arg_mandatory},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"cell", 0, arg_string, NULL, "what cell to use", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}},
+ *arg;
+
+ arg = chownarg;
+ arg->value = &name; arg++;
+ arg->value = &owner; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (chownarg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(chownarg, "pts chown", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = pr_chown(cell, host, name, owner,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error) {
+ printf("pr_chown failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ } else
+ if (prdebug)
+ printf("Changed owner of %s to %s.\n", name, owner);
+
+ return 0;
+}
+
+/*
+ * examine `users' in `cell'
+ */
+
+static int
+examine1 (struct rx_connection *conn, getarg_strings *users)
+{
+ namelist nlist;
+ idlist ilist;
+ int i;
+ int error;
+
+ nlist.len = users->num_strings;
+ nlist.val = malloc(sizeof(prname) * nlist.len);
+ if(nlist.val == NULL)
+ errx(1, "Out of memory.");
+
+ ilist.len = nlist.len;
+ ilist.val = malloc(sizeof(int32_t)*ilist.len);
+ if(ilist.val == NULL)
+ errx(1, "Out of memory.");
+
+ for(i = 0; i < nlist.len; i++)
+ strlcpy(nlist.val[i], users->strings[i], sizeof(prname));
+
+ error = PR_NameToID(conn, &nlist, &ilist);
+ if (error) {
+ free(nlist.val);
+ free(ilist.val);
+ return error;
+ }
+
+ for(i = 0; i < nlist.len; i++) {
+ if(ilist.val[i] == PR_ANONYMOUSID) {
+ ilist.val[i] = atoi(nlist.val[i]);
+ }
+ }
+
+ for(i = 0; i < nlist.len; i++) {
+ error = examine_id(conn, ilist.val[i], nlist.val[i]);
+ if (error)
+ break;
+ }
+ free(nlist.val);
+ free(ilist.val);
+ return error;
+}
+
+
+/*
+ *
+ */
+
+static int
+examine_cmd (int argc, char **argv)
+{
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ struct rx_connection *connptdb = NULL;
+ struct db_server_context conn_context;
+ int noauth = 1;
+ getarg_strings users = {0 , NULL };
+ int optind = 0;
+ int error = -1;
+
+ struct getargs examinearg[] = {
+ {"nameorid", 0, arg_strings, NULL, "user or group name",
+ NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use",
+ NULL, arg_optional},
+ {"host", 0, arg_string, NULL, "specified db",
+ NULL, arg_optional},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate",
+ NULL, arg_optional},
+ {NULL, 0, arg_end, NULL}}, *arg;
+
+ arg = examinearg;
+ arg->value = &users; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (examinearg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(examinearg, "pts examine", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = ENETDOWN;
+ for (connptdb = arlalib_first_db(&conn_context, cell, host, afsprport,
+ PR_SERVICE_ID,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ connptdb != NULL && arlalib_try_next_db (error);
+ connptdb = arlalib_next_db(&conn_context)) {
+ error = examine1 (connptdb, &users);
+ }
+ free_db_server_context(&conn_context);
+ return 0;
+}
+
+static int
+listmax_cmd (int argc, char **argv)
+{
+ int error;
+ int32_t uid = 0;
+ int32_t gid = 0;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ struct rx_connection *connptdb = NULL;
+ struct db_server_context conn_context;
+ int optind = 0;
+ int noauth = 0;
+
+ struct getargs examinearg[] = {
+ {"cell", 0, arg_string, NULL, "what cell to use",
+ NULL, arg_optional},
+ {"host", 0, arg_string, NULL, "specified db",
+ NULL, arg_optional},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate",
+ NULL, arg_optional},
+ {NULL, 0, arg_end, NULL}}, *arg;
+
+ arg = examinearg;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (examinearg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(examinearg, "pts listmax", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ error = ENETDOWN;
+ for (connptdb = arlalib_first_db(&conn_context, cell, host, afsprport,
+ PR_SERVICE_ID,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ connptdb != NULL && arlalib_try_next_db (error);
+ connptdb = arlalib_next_db(&conn_context)) {
+ error = PR_ListMax (connptdb, &uid, &gid);
+ }
+ free_db_server_context(&conn_context);
+ if (error == 0)
+ printf("Max user id is %d and max group id is %d.\n", uid, gid);
+ else
+ warnx("PR_ListMax failed: %s", koerr_gettext (error));
+ return 0;
+}
+
+static int
+listmembershipbyname(struct rx_connection *conn, const char *name)
+{
+ int32_t res = 0;
+ int32_t id = 0;
+
+ res = pts_name_to_id(conn, name, &id);
+ if(res) {
+ fprintf(stderr, "membership: error %s (%d)\n",
+ koerr_gettext(res), res);
+ return res;
+ } else {
+ int32_t over;
+ int i;
+ prlist elist;
+ elist.len = PR_MAXGROUPS; /* XXX this will allocate 5000 ints, should
+ check how many groups first. That will take
+ a lot of code though. */
+ elist.val = malloc(sizeof(int32_t) * elist.len);
+ if(elist.val == NULL)
+ errx(1, "Out of memory");
+ res = PR_ListElements(conn, id, &elist, &over);
+ if(res != 0) {
+ fprintf(stderr, "membership: error %s (%d)\n",
+ koerr_gettext(res), res);
+ return res;
+ } else {
+ if(id>=0)
+ printf("Groups %s (id: %d) is a member of:\n", name, id);
+ else
+ printf("Members of %s (id: %d) are:\n", name, id);
+ for(i = 0; i < elist.len; i++) {
+ prname pr;
+ res = pts_id_to_name(conn, elist.val[i], &pr);
+ printf(" %s\n", (char *)&pr);
+ }
+ free(elist.val);
+ return 0;
+ }
+ }
+}
+
+static int
+member_cmd (int argc, char **argv)
+{
+ int error;
+ const char *cell = cell_getthiscell ();
+ const char *host = NULL;
+ struct rx_connection *connptdb = NULL;
+ struct db_server_context conn_context;
+ int32_t noauth = 0;
+ int i = 0;
+ int optind = 0;
+ getarg_strings users = {0 , NULL };
+
+ struct getargs memarg[] = {
+ {"nameorid", 0, arg_strings, NULL, "user or group name",
+ NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use",
+ NULL, arg_optional},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate",
+ NULL, arg_optional},
+ {NULL, 0, arg_end, NULL}}, *arg;
+
+ arg = memarg;
+ arg->value = &users; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (memarg, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(memarg, "pts membership", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ for(i=0;i<users.num_strings;i++)
+ printf("%s\n", users.strings[i]);
+
+ error = ENETDOWN;
+ for (connptdb = arlalib_first_db(&conn_context, cell, host, afsprport,
+ PR_SERVICE_ID,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ connptdb != NULL && arlalib_try_next_db (error);
+ connptdb = arlalib_next_db(&conn_context)) {
+ error = 0;
+ for (i = 0; i < users.num_strings; ++i) {
+ int tmp = listmembershipbyname(connptdb, users.strings[i]);
+ if (error == 0 && tmp != 0)
+ error = tmp;
+ }
+ }
+ free_db_server_context(&conn_context);
+ return 0;
+}
+
+static void
+listowned_usage(void)
+{
+ printf("Usage: pts [-id] <user or group> [-cell <cell>] [-noauth] [-help]\n");
+}
+
+static int
+listowned_cmd(int argc, char **argv)
+{
+ int error;
+ int optind = 0;
+ const char *user = NULL;
+ const char *cell = cell_getthiscell();
+ const char *host = NULL;
+ int noauth = 0;
+
+ static struct getargs listowned_args[] = {
+ {"id", 0, arg_string, NULL, "id of user/group",
+ NULL, arg_mandatory},
+ {"cell", 0, arg_string, NULL, "what cell to use",
+ NULL},
+ {"host", 0, arg_string, NULL, "specified db", NULL},
+ {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL},
+ {NULL, 0, arg_end, NULL}}, *arg;
+
+ arg = listowned_args;
+ arg->value = &user; arg++;
+ arg->value = &cell; arg++;
+ arg->value = &host; arg++;
+ arg->value = &noauth; arg++;
+
+ if (getarg (listowned_args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ listowned_usage();
+ return 0;
+ }
+
+ error = pr_listowned (cell, host, user,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ if (error)
+ printf ("pr_listowned failed: %s\n",
+ koerr_gettext (error));
+ return 0;
+}
+
+static int
+syncdb_cmd(int argc, char **argv)
+{
+ printf("sync...not implemented\n");
+ return 0;
+}
+
+static void
+pts_usage(void)
+{
+ printf("pts - an arla tool for administrating AFS users"
+ " and groups.\n");
+ printf("Type \"pts help\" to get a list of commands.\n");
+ exit(1);
+}
+
+
+/*
+ * SL - switch
+ */
+
+static SL_cmd cmds[] = {
+ {"adduser", adduser_cmd, "add a user to a group"},
+ {"chown", chown_cmd, "change owner of user/group"},
+ {"creategroup", creategroup_cmd,"create a group"},
+ {"cg"},
+ {"createuser", createuser_cmd, "create a user"},
+ {"dump", dump_cmd, "dump pts database"},
+ {"delete", delete_cmd, "delete entry"},
+ {"examine", examine_cmd, "examine a user or a group"},
+ {"help", help_cmd, "get help on pts"},
+ {"?"},
+ {"listmax", listmax_cmd, "print largest uid and gid"},
+ {"listowned", listowned_cmd, "list groups owned by a user or group, or orphaned groups"},
+ {"membership", member_cmd, "list group or user membership"},
+ {"groups"},
+ {"removeuser", removeuser_cmd, "remove user from group"},
+ {"rename", rename_cmd, "rename user/group"},
+ {"setfields", setfields_cmd, "not yet implemented"},
+ {"setmax", empty_cmd, "not yet implemented"},
+ {"syncdb", syncdb_cmd, "sync ptsdb with /etc/passwd"},
+ {NULL}
+};
+
+
+static int
+help_cmd (int argc, char **argv)
+{
+ sl_help(cmds, argc, argv);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+ char **myargv;
+ int pos = 0;
+ int i;
+
+ ports_init();
+ cell_init(0); /* XXX */
+
+ myargv = malloc((argc + 1) * sizeof(char *));
+ if (myargv == NULL)
+ err(1, "malloc");
+
+ for (i = 0; i < argc; ++i)
+ myargv[i] = argv[i];
+ myargv[argc] = NULL;
+
+ if(argc > 1) {
+ if (strcmp(myargv[1], "-debug") == 0) {
+ prdebug = 1;
+ argc--;
+ myargv[pos+1] = myargv[pos];
+ ++pos;
+ }
+ ret = sl_command(cmds, argc - 1, &myargv[pos+1]);
+ if (ret == -1)
+ printf("%s: Unknown command\n", myargv[pos+1]);
+ } else
+ pts_usage();
+
+ return ret;
+}
diff --git a/usr.sbin/afs/src/appl/udebug/Makefile.in b/usr.sbin/afs/src/appl/udebug/Makefile.in
new file mode 100644
index 00000000000..9213138dca7
--- /dev/null
+++ b/usr.sbin/afs/src/appl/udebug/Makefile.in
@@ -0,0 +1,136 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:36 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+mandir = @mandir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = udebug
+MANPAGES = udebug.1
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+LIB_tgetent = @LIB_tgetent@
+READLINE_lib = @LIB_readline@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ -L../../lib/roken \
+ $(READLINE_lib) \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = udebug
+UDEBUG_SRCS = udebug.c
+SRCS = $(UDEBUG_SRCS)
+UDEBUG_OBJS = udebug.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir) ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+udebug: $(UDEBUG_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(UDEBUG_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/udebug/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/udebug/udebug.1 b/usr.sbin/afs/src/appl/udebug/udebug.1
new file mode 100644
index 00000000000..f0237220327
--- /dev/null
+++ b/usr.sbin/afs/src/appl/udebug/udebug.1
@@ -0,0 +1,61 @@
+.\" Copyright (c) 2000 Kungliga Tekniska Högskolan
+.\" $Id: udebug.1,v 1.1 2000/09/11 14:40:36 art Exp $
+.Dd Aug 06, 2000
+.Dt UDEBUG SECTION
+.Os Arla
+.Sh NAME
+.Nm udebug
+.Nd
+a tool to diagnose synchronization problems with ubik-database
+servers.
+.Sh SYNOPSIS
+.Nm
+.Op Fl servers Ar servers ...
+.Op Fl port Ar port
+.Op Fl long
+.Sh DESCRIPTION
+Supported options:
+.Bl -tag -width Ds
+.It Fl servers Ar servers ...
+A list of server to probe.
+.It Fl port Ar port
+The port number of where the server resides.
+.It Fl long
+Verbose information.
+.El
+.Sh DIAGNOSTICS
+.Nm
+is used to diagnose synchronization problems with ubik-servers.
+.Pp
+Ubik is quorum-complete protocol. Servers vote on each other to elect
+a sync-sit.e. The sync-site have the ability to synchronize a
+two-phase write with the other servers if at least half of them is
+available.
+.Sh EXAMPLES
+.Bd -literal
+datan# udebug -servers anden.e.kth.se -port 7003
+Host 130.237.48.7 time is Mon Aug 7 13:46:24 2000
+Localtime is Mon Aug 7 13:46:43 2000, differ 19 seconds
+Last yes vote for 130.237.48.7 secs was 8 ago (at Mon Aug 7 13:46:16 2000)
+Last vote started 8 secs ago (at Mon Aug 7 13:46:16 2000)
+Local db version is 965530500.199
+Syncsite db version is 965530500.199
+0 locked pages, 0 of them for write
+I'm the synchost for 49 seconds more (Mon Aug 7 13:47:13 2000)
+Recover state is 0x1f
+Last time a new db version was laballed was:
+ 118284 secs ago (at Sun Aug 6 04:55:00 2000)
+
+Server 130.237.48.244: (db 965530500.199)
+ last vote recived 8 secs ago (at Mon Aug 7 13:46:16 2000)
+ last beacon sent 8 secs ago (at Mon Aug 7 13:46:16 2000)
+ dbcurrent=1, up=1, beaconSince=1
+
+Server 130.237.48.8: (db 965530500.199)
+ last vote recived 11 secs ago (at Mon Aug 7 13:46:13 2000)
+ last beacon sent 8 secs ago (at Mon Aug 7 13:46:16 2000)
+ dbcurrent=1, up=1, beaconSince=1
+
+.Ed
+.\".Sh SEE ALSO
+.\"XXX \ No newline at end of file
diff --git a/usr.sbin/afs/src/appl/udebug/udebug.c b/usr.sbin/afs/src/appl/udebug/udebug.c
new file mode 100644
index 00000000000..b5d62b76351
--- /dev/null
+++ b/usr.sbin/afs/src/appl/udebug/udebug.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 1998 - 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+RCSID("$Id: udebug.c,v 1.1 2000/09/11 14:40:36 art Exp $");
+
+static int verbose = 0;
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "udebug: Version $Id: udebug.c,v 1.1 2000/09/11 14:40:36 art Exp $\n"
+ "usage: udebug -servers server ... -port port -noauth -long\n");
+ exit(1);
+}
+
+
+static void
+newhost(u_int32_t **hosts, int *len, char *host)
+{
+ struct in_addr server;
+ u_int32_t *ptr;
+
+ if (host == NULL)
+ return;
+
+ if (str2inaddr (host, &server) == NULL) {
+ warnx("cant find addr for '%s'.", host);
+ return;
+ }
+
+ ptr = realloc(*hosts, sizeof(u_int32_t) * ++*len);
+ if (ptr == NULL)
+ err(1, "realloc");
+
+ *hosts = ptr;
+
+ ptr[*len-1] = server.s_addr;
+}
+
+static const char *
+myctime(const time_t *time, char *datestr, size_t sz)
+{
+ struct tm tm;
+ strftime (datestr, sz, "%c", localtime_r(time, &tm));
+ return datestr;
+}
+
+static void
+ProbeHost(u_int32_t host, u_int16_t port, arlalib_authflags_t auth)
+{
+ struct rx_connection *conn;
+ ubik_debug db;
+ int error;
+ struct in_addr server;
+
+ server.s_addr = host;
+
+ conn = arlalib_getconnbyaddr(NULL,
+ host,
+ NULL,
+ port,
+ VOTE_SERVICE_ID,
+ auth);
+
+ if (conn == NULL) {
+ warnx("Could not contact host %s", inet_ntoa(server));
+ return;
+ }
+
+ error = Ubik_Debug(conn, &db);
+ if (error) {
+ fprintf(stderr, "ProbeHost: Ubik_Debug: %s (%d)\n",
+ koerr_gettext(error), error);
+
+ return;
+ }
+
+#define ABS_COMP_DB(dbname,field) (abs(db.now - dbname##.##field))
+
+ {
+ struct timeval tv;
+ char datestring[100];
+
+ gettimeofday(&tv, NULL);
+
+ printf("Host %s time is %s\n",
+ inet_ntoa(server),
+ myctime(&db.now, datestring, sizeof(datestring)));
+ printf("Localtime is %s, differ %d seconds\n",
+ myctime(&tv.tv_sec, datestring, sizeof(datestring)),
+ abs(db.now - tv.tv_sec));
+ server.s_addr = htonl(db.syncHost);
+ printf("Last yes vote for %s secs was %d ago (at %s)\n",
+ inet_ntoa(server),
+ ABS_COMP_DB(db,lastYesTime),
+ myctime(&db.lastYesTime, datestring, sizeof(datestring)));
+ printf("Last vote started %d secs ago (at %s)\n",
+ ABS_COMP_DB(db,syncTime),
+ myctime(&db.lastYesTime, datestring, sizeof(datestring)));
+ printf("Local db version is %u.%u\n",
+ db.localVersion.epoch,
+ db.localVersion.counter);
+ printf("Syncsite db version is %u.%u\n",
+ db.syncVersion.epoch,
+ db.syncVersion.counter);
+ printf("%d locked pages, %d of them for write\n",
+ db.anyReadLocks + db.anyWriteLocks, db.anyWriteLocks);
+
+ if (db.amSyncSite) {
+
+ printf("I'm the synchost for %d seconds more (%s)\n",
+ db.syncSiteUntil - db.now,
+ myctime(&db.syncSiteUntil, datestring, sizeof(datestring)));
+ } else {
+ server.s_addr = htonl(db.syncHost);
+ printf("I'm not the synchost, but %s is.\n",
+ inet_ntoa(server));
+ }
+
+ if (verbose || db.amSyncSite) {
+ int i;
+ ubik_sdebug sdb;
+
+ if (!db.amSyncSite) {
+ arlalib_destroyconn (conn);
+ conn = arlalib_getconnbyaddr(NULL, server.s_addr,
+ NULL, port,
+ VOTE_SERVICE_ID, auth);
+ if (conn == NULL) {
+ warnx("Could not contact host %s", inet_ntoa(server));
+ return;
+ }
+ error = Ubik_Debug(conn, &db);
+ if (error) {
+ fprintf(stderr, "ProbeHost: Ubik_Debug: %s (%d)\n",
+ koerr_gettext(error), error);
+
+ return;
+ }
+ }
+
+ printf("Recover state is 0x%x\n", db.recoveryState);
+ printf("Last time a new db version was laballed was:\n"
+ "\t\t%d secs ago (at %s)\n\n",
+ ABS_COMP_DB(db,epochTime),
+ myctime(&db.epochTime, datestring, sizeof(datestring)));
+
+ for (i = 0; i < db.nServers - 1; i++) {
+
+ error = Ubik_SDebug(conn, i, &sdb);
+ if (error) {
+ printf("Problem with host %d\n\n", i);
+ continue;
+ }
+
+ server.s_addr = htonl(sdb.addr);
+ printf("Server %s: (db %u.%u)\n",
+ inet_ntoa(server),
+ sdb.remoteVersion.epoch,
+ sdb.remoteVersion.counter);
+ printf("\tlast vote recived %d secs ago (at %s)\n",
+ ABS_COMP_DB(sdb,lastVoteTime),
+ myctime(&sdb.lastVoteTime,
+ datestring, sizeof(datestring)));
+ printf("\tlast beacon sent %d secs ago (at %s)\n",
+ ABS_COMP_DB(sdb,lastBeaconSent),
+ myctime(&sdb.lastBeaconSent,
+ datestring, sizeof(datestring)));
+ printf("\tdbcurrent=%d, up=%d, beaconSince=%u\n",
+ sdb.currentDB,
+ sdb.up,
+ sdb.beaconSinceDown);
+
+ printf("\n");
+
+ }
+ }
+ }
+}
+
+
+int
+main(int argc, char **argv)
+{
+ u_int32_t *hosts = NULL;
+ int len = 0;
+ u_int16_t port = 0;
+ enum { START, NOWHERE, HOST, PORT } state = START;
+
+ if (argc < 2)
+ usage();
+
+ argv++;
+ argc--;
+
+ while (argc) {
+ if (*argv[0] == '-') {
+ if (strncmp(*argv, "-server", 7) == 0)
+ state = HOST;
+ else if (strcmp(*argv, "-port") == 0)
+ state = PORT;
+ else if (strcmp(*argv, "-long") == 0)
+ verbose = 1;
+ else
+ usage();
+ } else {
+ switch (state) {
+ case START:
+ if (argc != 2)
+ usage();
+ newhost(&hosts, &len, *argv);
+ argv++;
+ argc--;
+ port = atoi(*argv);
+ break;
+ case HOST:
+ newhost(&hosts, &len, *argv);
+ break;
+ case PORT:
+ port = atoi(*argv);
+ state = NOWHERE;
+ break;
+ case NOWHERE:
+ usage();
+ default:
+ abort();
+ }
+ }
+ argc--;
+ argv++;
+ }
+
+ if (hosts == NULL)
+ errx(1, "No hosts found !");
+
+ if (port == 0)
+ errx(1, "No port given");
+
+ while (len) {
+ ProbeHost(*hosts, port, AUTHFLAGS_NOAUTH); /* XXX */
+ hosts++;
+ len--;
+ }
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/Makefile.in b/usr.sbin/afs/src/appl/vos/Makefile.in
new file mode 100644
index 00000000000..d43e09975b1
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/Makefile.in
@@ -0,0 +1,144 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:37 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+mandir = @mandir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = vos
+MANPAGES = vos.8
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+X_CFLAGS = @X_CFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+RXKADINC = -I$(srcdir)/../../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib \
+ -I../../include \
+ -I../../rxdef \
+ -I. \
+ $(KERNEL_INCLUDE) \
+ -I$(srcdir)/../../xfs/include \
+ -I$(srcdir)/../../arlad \
+ $(RXKADINC)
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ $(X_CFLAGS) @PLWP_INC_FLAGS@
+RXKAD_LIBS = @MILKO_RXKAD_LIBS@
+KERNEL_INCLUDE = @KERNEL_INCLUDE@
+READLINE_lib = @LIB_readline@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib -larlalib \
+ -L../../rxdef -lrxdefclient \
+ -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/ko -lko -L../../util -lutil \
+ -L../../lib/sl -lsl \
+ -L../../lib/roken \
+ $(READLINE_lib) \
+ $(RXKAD_LIBS) \
+ $(KAFS_LIBS) \
+ $(RXKAD_LIBS) \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a ../../lwp/liblwp.a \
+ ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
+ ../../lib/ko/libko.a
+
+PROGS = vos
+VOS_SRCS = vos.c vos_common.c vos_examine.c vos_listvol.c \
+ vos_partinfo.c vos_status.c vos_createentry.c \
+ vos_listpart.c vos_syncsite.c vos_listvldb.c vos_dump.c \
+ vos_createvolume.c vos_endtrans.c vos_vldbexamine.c \
+ vos_lock.c vos_unlock.c
+SRCS = $(VOS_SRCS)
+VOS_OBJS = vos.o vos_common.o vos_examine.o vos_listvol.o \
+ vos_partinfo.o vos_status.o vos_createentry.o \
+ vos_listpart.o vos_syncsite.o vos_listvldb.o vos_dump.o \
+ vos_createvolume.o vos_endtrans.o vos_vldbexamine.o \
+ vos_lock.o vos_unlock.o
+HDRS =
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ;\
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir) ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+vos: $(VOS_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(VOS_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=appl/vos/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/appl/vos/vos.8 b/usr.sbin/afs/src/appl/vos/vos.8
new file mode 100644
index 00000000000..4722f419fc9
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos.8
@@ -0,0 +1,392 @@
+.\" $OpenBSD: vos.8,v 1.1 2000/09/11 14:40:37 art Exp $
+.\" $Id: vos.8,v 1.1 2000/09/11 14:40:37 art Exp $
+.Dd March 26, 2000
+.Dt VOS 1
+.Os
+.Sh NAME
+.Nm vos
+.Nd manage AFS volumes and the VLDB
+.Sh SYNOPSIS
+.Nm vos
+.Op Ar command
+.Op Ar args
+.Sh DESCRIPTION
+The
+.Nm
+utility is used to manage AFS volumes and the volume location database (VLDB).
+.Pp
+.Nm
+provides several commands:
+.Pp
+.Bl -tag -width createentry -compact
+.It Cm addsite
+not yet implemented
+.It Cm apropos
+apropos
+.It Cm backup
+not yet implemented
+.It Cm backupsys
+not yet implemented
+.It Cm changeaddr
+not yet implemented
+.It Cm create
+create a volume
+.It Cm createentry
+create a vldb entry
+.It Cm delentry
+not yet implemented
+.It Cm dump
+dump a volume
+.It Cm endtrans
+end a transaction
+.It Cm examine
+print information about a volume
+.It Cm volinfo
+print information about a volume
+.It Cm help
+print help
+.It Cm ?
+print help
+.It Cm listpart
+list partitions on a server
+.It Cm listvldb
+list volumes in volume-location-database
+.It Cm listvol
+list volumes on a server
+.It Cm lock
+not yet implemented
+.It Cm move
+not yet implemented
+.It Cm partinfo
+print partition information on a server
+.It Cm release
+not yet implemented
+.It Cm remove
+not yet implemented
+.It Cm remsite
+not yet implemented
+.It Cm rename
+not yet implemented
+.It Cm restore
+not yet implemented
+.It Cm status
+Show volume server transactions
+.It Cm syncserv
+not yet implemented
+.It Cm syncvldb
+not yet implemented
+.It Cm syncsite
+print the syncsite
+.It Cm unlock
+not yet implemented
+.It Cm unlockvldb
+not yet implemented
+.It Cm zap
+not yet implemented
+.It Cm quit
+exit interactive mode
+.El
+.Pp
+Most
+.Nm
+commands accept the following general arguments:
+.Pp
+.Bd -filled -offset indent -compact
+.Op Fl cell Ar cellname
+Specifies which AFS cell to use, if the default cell is not to be used.
+.Pp
+.Op Fl noauth
+Specifies that
+.Nm
+should not try to authenticate the connection to the server.
+This may be
+useful with shell scripts, or if there is a problem with the AFS cell.
+Note that the server will reject many commands if
+.Fl noauth
+is specified.
+.Pp
+.Op Fl localauth
+Create a ticket using the AFS server key, that is, you don't need a token.
+This will generally only work on AFS servers, and is very useful for
+performing automatic tasks.
+.Ed
+.Pp
+The syntax of the
+.Nm
+commands:
+.Pp
+.Ic vos addsite
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos apropos
+.Bd -filled -offset indent -compact
+apropos
+.Ed
+.Pp
+.Ic vos backup
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos backupsys
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos changeaddr
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos create
+.Op Fl server
+.Ar fileserver
+.Op Fl part
+.Ar partition
+.Op Fl volume
+.Ar "volume name"
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+Create a new volume named
+.Ar "volume name"
+on server
+.Ar fileserver
+partition
+.Ar partition .
+.Ed
+.Pp
+.Ic vos createentry
+.Op Fl id
+.Ar "id of volume"
+.Op Fl host
+.Ar "host to use"
+.Op Fl fsserver
+.Ar fileserver
+.Op Fl rw
+.Ar "volume RW number"
+.Op Fl ro
+.Ar "volume RO number"
+.Op Fl bk
+.Ar "volume BK number"
+.Op Fl noauth
+.Op Fl localauth
+.Bd -filled -offset indent -compact
+Create a vldb entry manually.
+This command should
+.Em not
+be used unless you know
+.Em exactly
+what you are doing.
+.Ed
+.Pp
+.Ic vos delentry
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos dump
+.Op Fl id
+.Ar volume
+.Op Fl server Ar fileserver
+.Op Fl partition Ar partition
+.Op Fl cell Ar cellname
+.Op Fl file Ar filename
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+Dump a volume to a file.
+.Ed
+.Pp
+.Ic vos endtrans
+.Op Fl server
+.Ar server
+.Op Fl trans
+.Ar transaction
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+End a transaction.
+XXX what is this?
+.Ed
+.Pp
+.Ic vos examine
+.Op Fl id
+.Ar volume
+.Op Fl host
+.Ar server
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Op Fl extended
+.Bd -filled -offset indent -compact
+Print information about a volume.
+.Ed
+.Pp
+.Ic vos volinfo
+.Bd -filled -offset indent -compact
+.Ic vos volinfo
+is an alias for the
+.Ic vos examine
+command.
+.Ed
+.Pp
+.Ic vos help
+.Bd -filled -offset indent -compact
+print help
+.Ed
+.Pp
+.Ic vos ?
+.Bd -filled -offset indent -compact
+.Ic vos ?
+is an alias for the
+.Ic vos help
+command.
+.Ed
+.Pp
+.Ic vos listpart
+.Op Fl server
+.Ar fileserver
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+List partitions on a fileserver.
+.Ed
+.Pp
+.Ic vos listvldb
+.Op Fl server
+.Ar fileserver
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+List volumes in the volume location database without reading them on the
+fileserver.
+.Ed
+.Pp
+.Ic vos listvol
+.Op Fl server
+.Ar fileserver
+.Op Fl partition
+.Ar partition
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+List volumes on a fileserver, without consulting the volume location database.
+.Ed
+.Pp
+.Ic vos lock
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos move
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos partinfo
+.Op Fl server
+.Ar fileserver
+.Op Fl partition
+.Ar partition
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl localauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+Print the total and remaining diskspace on a fileserver.
+.Ed
+.Pp
+.Ic vos release
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos remove
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos remsite
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos rename
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos restore
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos status
+.Op Fl server
+.Ar fileserver
+.Op Fl cell Ar cellname
+.Op Fl noauth
+.Op Fl verbose
+.Bd -filled -offset indent -compact
+Show volume server transactions.
+.Ed
+.Pp
+.Ic vos syncserv
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos syncvldb
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos syncsite
+.Bd -filled -offset indent -compact
+print the syncsite
+.Ed
+.Pp
+.Ic vos unlock
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos unlockvldb
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos zap
+.Bd -filled -offset indent -compact
+not yet implemented
+.Ed
+.Pp
+.Ic vos quit
+.Bd -filled -offset indent -compact
+Exit interactive mode.
+.Ed
+.Sh SEE ALSO
+.Xr afsd 8 ,
+.Xr pts 1 ,
+.Xr fs 1
+.Sh STANDARDS
+The Arla authors are trying to mimic the behaviour of the original AFS
+utilities.
+.Sh AUTHORS
+The Arla project <http://www.stacken.kth.se/project/arla/>.
+.Sh BUGS
+Quite a lot of commands are not implemented yet.
diff --git a/usr.sbin/afs/src/appl/vos/vos.c b/usr.sbin/afs/src/appl/vos/vos.c
new file mode 100644
index 00000000000..8835ae52219
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos.c
@@ -0,0 +1,166 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos.c,v 1.1 2000/09/11 14:40:37 art Exp $");
+
+int vos_interactive = 0;
+
+static int empty_cmd(int argc, char **argv);
+static int quit_cmd(int argc, char **argv);
+static int help_cmd(int argc, char **argv);
+static int apropos_cmd(int argc, char **argv);
+
+
+/*
+ * command table
+ */
+
+static SL_cmd cmds[] = {
+ {"addsite", empty_cmd, "not yet implemented"},
+ {"apropos", apropos_cmd, "apropos"},
+ {"backup", empty_cmd, "not yet implemented"},
+ {"backupsys", empty_cmd, "not yet implemented"},
+ {"changeaddr", empty_cmd, "not yet implemented"},
+ {"create", vos_create, "create a volume"},
+ {"createentry",vos_createentry, "create a vldb entry"},
+ {"delentry", empty_cmd, "not yet implemented"},
+ {"dump", vos_dump, "dump a volume"},
+ {"endtrans", vos_endtrans, "end a transaction"},
+ {"examine", vos_examine, "print information about a volume"},
+ {"volinfo"},
+ {"help", help_cmd, "print help"},
+ {"?"},
+ {"listpart", vos_listpart, "list partitions on a server"},
+ {"listvldb", vos_listvldb, "list volumes in volume-location-database"},
+ {"listvol", vos_listvol, "list volumes on a server"},
+ {"lock", vos_lock, "lock VLDB entry"},
+ {"move", empty_cmd, "not yet implemented"},
+ {"partinfo", vos_partinfo, "print partition information on a server"},
+ {"release", empty_cmd, "not yet implemented"},
+ {"remove", empty_cmd, "not yet implemented"},
+ {"remsite", empty_cmd, "not yet implemented"},
+ {"rename", empty_cmd, "not yet implemented"},
+ {"restore", empty_cmd, "not yet implemented"},
+ {"status", vos_status, "Show volume server transactions"},
+ {"syncserv", empty_cmd, "not yet implemented"},
+ {"syncvldb", empty_cmd, "not yet implemented"},
+ {"syncsite", vos_syncsite, "print the syncsite"},
+ {"vldbexamine",vos_vldbexamine, "print only vldb info"},
+ {"unlock", vos_unlock, "Unlock a VLDB entry"},
+ {"unlockvldb", empty_cmd, "not yet implemented"},
+ {"zap", empty_cmd, "not yet implemented"},
+ {"quit", quit_cmd, "exit interactive mode"},
+ {NULL}
+};
+
+/*
+ * Dummy command
+ */
+
+static int
+empty_cmd(int argc, char **argv)
+{
+ printf("%s%s has not been implemented yet!\n", PROGNAME, argv[0]);
+ return 0;
+}
+
+/*
+ * quit
+ */
+
+static int
+quit_cmd(int argc, char **argv)
+{
+ printf("exiting\n");
+ return 1;
+}
+
+/*
+ * help
+ */
+
+static int
+help_cmd(int argc, char **argv)
+{
+ sl_help(cmds, argc, argv);
+ return 0;
+}
+
+/*
+ * apropos
+ */
+
+static int
+apropos_cmd(int argc, char **argv)
+{
+ if (argc == 0) {
+ fprintf (stderr, "apropos: missing topic");
+ return 0;
+ }
+
+ sl_apropos(cmds, argv[1]);
+ return 0;
+}
+
+
+/*
+ * Main program
+ */
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+
+ cell_init(0);
+ ports_init();
+
+ if (argc > 1)
+ ret = sl_command(cmds, argc - 1, argv + 1);
+ else {
+ vos_interactive = 1;
+ printf("vos - an arla tool for administrating AFS volumes.\n");
+ printf("Type \"help\" to get a list of commands.\n");
+ ret = sl_loop(cmds, __progname": ");
+ }
+ return ret;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_common.c b/usr.sbin/afs/src/appl/vos/vos_common.c
new file mode 100644
index 00000000000..36733c4c398
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_common.c
@@ -0,0 +1,352 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_common.c,v 1.1 2000/09/11 14:40:37 art Exp $");
+
+/*
+ * Print the first of RW, RO, or BACKUP that there's a clone of
+ * according to serverFlag.
+ */
+
+const char *
+getvolumetype(int32_t flag)
+{
+ const char *str;
+
+ if (flag & VLSF_RWVOL)
+ str = "RW";
+ else if (flag & VLSF_ROVOL)
+ str = "RO";
+ else if (flag & VLSF_BACKVOL)
+ str = "BACKUP";
+ else if (flag & VLSF_NEWREPSITE)
+ str = "NewRepSite";
+ else
+ str = "FOO!";
+
+ return str;
+}
+
+/*
+ * Convert a volume `type' to a string.
+ */
+
+const char *
+getvolumetype2(int32_t type)
+{
+ const char *str;
+
+ switch (type) {
+ case RWVOL:
+ str = "RW";
+ break;
+ case ROVOL:
+ str = "RO";
+ break;
+ case BACKVOL:
+ str = "BK";
+ break;
+ default:
+ str = "FOO!";
+ }
+ return str;
+}
+
+/*
+ * Get the list of partitions from the server `host' in cell `cell'
+ * and store them in `parts'. Use authentication as specifined in `auth'.
+ */
+
+int
+getlistparts(const char *cell, const char *host,
+ part_entries *parts, arlalib_authflags_t auth)
+{
+ struct rx_connection *connvolser;
+ int error;
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (connvolser == NULL)
+ return -1 ;
+
+ error = VOLSER_AFSVolXListPartitions(connvolser, parts);
+ if (error == RXGEN_OPCODE) {
+ pIDs old_parts;
+
+ error = VOLSER_AFSVolListPartitions(connvolser, &old_parts);
+ if (error == 0) {
+ int n, i;
+
+ for (n = 0, i = 0; i < 26; ++i)
+ if (old_parts.partIds[i] != -1)
+ ++n;
+ parts->len = n;
+ parts->val = emalloc(n * sizeof(*parts->val));
+
+ for (n = 0, i = 0; i < 26; ++i)
+ if (old_parts.partIds[i] != -1)
+ parts->val[n++] = old_parts.partIds[i];
+ }
+ }
+
+ if (error != 0) {
+ printf("getlistparts: ListPartitions failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ return -1;
+ }
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+static void
+print_fast_vols (volEntries ve)
+{
+ int i;
+
+ for (i = 0; i < ve.len; ++i)
+ printf ("%d\n", ve.val[i].volid);
+}
+
+static void
+print_slow_vols (volEntries ve, const char *part_name, int flags)
+{
+ int i;
+ int busy = 0, online = 0, offline = 0;
+
+ for (i = 0; i < ve.len; i++) {
+ volintInfo *vi = &ve.val[i];
+
+ if (vi->status == VBUSY)
+ busy++;
+ else if (vi->inUse)
+ online++;
+ else
+ offline++;
+
+ if(vi->status == VOK) {
+ printf("%-38s %10u %s %10u K %s %s\n",
+ vi->name,
+ vi->volid,
+ getvolumetype2(vi->type),
+ vi->size,
+ vi->inUse ? "On-line" : "Off-line",
+ flags & LISTVOL_PART ? part_name : "");
+ }
+ }
+
+ for (i = 0; i < ve.len; i++) {
+ volintInfo *vi = &ve.val[i];
+
+ if(vi->status == VBUSY)
+ printf("Volume with id number %u is currently busy\n",
+ vi->volid);
+ }
+
+ printf("\nTotal volumes onLine %d ; Total volumes offLine %d " \
+ "; Total busy %d\n\n",
+ online, offline, busy);
+}
+
+/*
+ * print all the volumes of host `host' in cell `cell' and partition `part'.
+ */
+
+int
+printlistvol(const char *cell, const char *host, int part, int flags,
+ arlalib_authflags_t auth)
+{
+ struct rx_connection *connvolser;
+ part_entries parts;
+ int error;
+ int i;
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (connvolser == NULL)
+ return -1 ;
+
+ if (part == -1) {
+ if ((error = getlistparts(cell, host, &parts,
+ auth)) != 0)
+ return -1;
+ } else {
+ parts.len = 1;
+ parts.val = emalloc (sizeof(*parts.val));
+ parts.val[0] = part;
+ }
+
+ for (i = 0; i < parts.len; ++i) {
+ char part_name[17];
+ volEntries volint;
+
+ volint.val = NULL;
+ if ((error = VOLSER_AFSVolListVolumes(connvolser,
+ parts.val[i],
+ 1, /* We want full info */
+ &volint)) != 0) {
+ printf("printlistvol: PartitionInfo failed with: %s (%d)\n",
+ koerr_gettext(error),
+ error);
+ return -1;
+ }
+ partition_num2name (parts.val[i], part_name, sizeof(part_name));
+
+ printf("Total number of volumes on server %s partition %s: %d\n",
+ host, part_name, volint.len);
+
+ if (flags & LISTVOL_FAST)
+ print_fast_vols (volint);
+ else
+ print_slow_vols (volint, part_name, flags);
+ free(volint.val);
+ }
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+/*
+ * Return the volume entry for `volname' in `cell' by asking the DB
+ * server at `host', with the auth flags in `auth' and returning the
+ * result in `nvldbentry'. Returns 0 or error.
+ */
+
+int
+get_vlentry (const char *cell, const char *host, const char *volname,
+ arlalib_authflags_t auth, nvldbentry *nvldbentry)
+{
+ struct rx_connection *conn;
+ int error;
+
+ conn = arlalib_getconnbyname(cell, host, afsvldbport, VLDB_SERVICE_ID,
+ auth);
+ if (conn == NULL)
+ return -1;
+
+ error = VL_GetEntryByNameN (conn, volname, nvldbentry);
+
+ if (error == RXGEN_OPCODE) {
+ vldbentry vlentry;
+
+ error = VL_GetEntryByName (conn, volname, &vlentry);
+ if (error == 0)
+ vldb2vldbN (&vlentry, nvldbentry);
+ }
+ arlalib_destroyconn(conn);
+ return error;
+}
+
+
+/*
+ * insert `nvldbentry' to the dbserver using `conn' or it `conn' ==
+ * NULL use `cell' (and if specified `host') to get a new conn. If the
+ * db-server is old, use old method.
+ */
+
+int
+new_vlentry (struct rx_connection *conn, const char *cell, const char *host,
+ nvldbentry *nvldbentry, arlalib_authflags_t auth)
+{
+ int error;
+ int freeconnp = 0;
+
+ if (conn == NULL) {
+ find_db_cell_and_host (&cell, &host);
+
+ if (cell == NULL) {
+ fprintf (stderr, "Unable to find cell of host '%s'\n", host);
+ return -1;
+ }
+
+ if (host == NULL) {
+ fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell);
+ return -1;
+ }
+
+ conn = arlalib_getconnbyname(cell, host, afsvldbport, VLDB_SERVICE_ID,
+ auth);
+ freeconnp = 1;
+ if (conn == NULL)
+ return -1;
+ }
+
+ error = VL_CreateEntryN (conn, nvldbentry);
+
+ if (error == RXGEN_OPCODE) {
+#if 0
+ vldbentry vlentry;
+
+ vldbN2vldb (nvldbentry, &vlentry);
+ error = VL_CreateEntry (conn, volname, &vlentry);
+#endif
+ abort();
+ }
+ if (freeconnp)
+ arlalib_destroyconn(conn);
+ return error;
+}
+
+/*
+ * Try to set *cell and *host to reasonable values.
+ */
+
+void
+find_db_cell_and_host (const char **cell, const char **host)
+{
+ if (*cell == NULL && *host != NULL) {
+ *cell = cell_getcellbyhost (*host);
+ return;
+ }
+ if (*cell == NULL) {
+ *cell = cell_getthiscell();
+ }
+ if (*host == NULL) {
+ *host = cell_findnamedbbyname (*cell);
+ }
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_createentry.c b/usr.sbin/afs/src/appl/vos/vos_createentry.c
new file mode 100644
index 00000000000..84b7fb6c911
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_createentry.c
@@ -0,0 +1,164 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_createentry.c,v 1.1 2000/09/11 14:40:37 art Exp $");
+
+static int helpflag;
+static char *vol;
+static char *host;
+static char *fsserver;
+static char *partition;
+static char *cell;
+static int noauth;
+static int localauth;
+static int rw_number;
+static int ro_number;
+static int bk_number;
+
+static struct getargs args[] = {
+ {"id", 0, arg_string, &vol, "id of volume", NULL, arg_mandatory},
+ {"host", 0, arg_string, &host, "what host to use", NULL, arg_mandatory},
+ {"fsserver",0, arg_string, &fsserver, "fsserver where the volume resides", NULL, arg_mandatory},
+ {"partition",0, arg_string, &partition, "partition where the volume resides", NULL, arg_mandatory},
+ {"rw", 0, arg_integer, &rw_number, "volume RW number", NULL},
+ {"ro", 0, arg_integer, &ro_number, "volume RO number", NULL},
+ {"bk", 0, arg_integer, &bk_number, "volume BK number", NULL},
+ {"cell", 0, arg_string, &cell, "what cell to use", NULL},
+ {"noauth", 0, arg_flag, &noauth, "if to use authentication", NULL},
+ {"localauth",0,arg_flag, &localauth, "localauth", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos createentry", "", ARG_AFSSTYLE);
+}
+
+int
+vos_createentry(int argc, char **argv)
+{
+ int optind = 0;
+ struct rx_connection *connvldb = NULL;
+ struct nvldbentry newentry;
+ struct hostent *he;
+ int error;
+
+ helpflag = 0;
+ vol = NULL;
+ host = NULL;
+ fsserver = NULL;
+ partition = NULL;
+ noauth = 0;
+ localauth = 0;
+ rw_number = 0;
+ ro_number = 0;
+ bk_number = 0;
+ cell = NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 0;
+ }
+
+ connvldb = arlalib_getconnbyname(cell,
+ host,
+ afsvldbport,
+ VLDB_SERVICE_ID,
+ arlalib_getauthflag (noauth, localauth,
+ 0, 0));
+ if (connvldb == NULL)
+ return -1;
+ memset (&newentry, 0, sizeof (newentry));
+ strlcpy(newentry.name, vol, VLDB_MAXNAMELEN);
+ newentry.nServers = 1;
+ he = gethostbyname(fsserver);
+ if (he == NULL) {
+ fprintf(stderr, "unknown host: %s\n", fsserver);
+ return -1;
+ }
+
+ memcpy (&newentry.serverNumber[0], he->h_addr_list[0], 4);
+ newentry.serverNumber[0] = ntohl(newentry.serverNumber[0]);
+ newentry.serverPartition[0] = partition_name2num(partition);
+ if (newentry.serverPartition[0] == -1) {
+ fprintf(stderr, "incorrect partition\n");
+ usage();
+ return 0;
+ }
+
+ newentry.flags = 0;
+ newentry.flags |= rw_number ? VLF_RWEXISTS : 0;
+ newentry.flags |= ro_number ? VLF_ROEXISTS : 0;
+ newentry.flags |= bk_number ? VLF_BOEXISTS : 0;
+
+ newentry.serverFlags[0] = 0;
+ newentry.serverFlags[0] |= rw_number ? VLSF_RWVOL : 0;
+ newentry.serverFlags[0] |= ro_number ? VLSF_ROVOL : 0;
+ newentry.serverFlags[0] |= bk_number ? VLSF_BACKVOL : 0;
+
+ newentry.volumeId[0] = rw_number;
+ newentry.volumeId[1] = ro_number;
+ newentry.volumeId[2] = bk_number;
+ newentry.cloneId = 0;
+ error = VL_CreateEntryN(connvldb, &newentry);
+ if (error) {
+ fprintf(stderr, "vos_createentry: error %s (%d)\n", koerr_gettext(error), error);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_createvolume.c b/usr.sbin/afs/src/appl/vos/vos_createvolume.c
new file mode 100644
index 00000000000..9b5fc50bc5e
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_createvolume.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include "vos_local.h"
+
+RCSID("$Id: vos_createvolume.c,v 1.1 2000/09/11 14:40:37 art Exp $");
+
+/*
+ * create volume
+ */
+
+
+int
+vos_createvolume (char *host, int32_t part, char *cell,
+ arlalib_authflags_t auth,
+ char *name, int verbose)
+{
+ struct rx_connection *connvldb = NULL;
+ struct rx_connection *volser = NULL;
+ nvldbentry entry;
+ int32_t dbhost;
+ int32_t fshost;
+ int32_t volid;
+ int32_t rcode;
+ int32_t trans; /* transaction id */
+ int error;
+
+ if (host == NULL && name == NULL)
+ return EINVAL;
+
+ if (cell == NULL)
+ cell = (char *)cell_getthiscell();
+
+ error = arlalib_getsyncsite (cell, NULL, afsvldbport,
+ &dbhost, auth);
+ if (error) {
+ fprintf (stderr, "vos_createvolume: arla_getsyncsite: %s\n",
+ koerr_gettext(error));
+ return -1;
+ }
+
+ connvldb = arlalib_getconnbyaddr(cell, dbhost, NULL,
+ afsvldbport,
+ VLDB_SERVICE_ID,
+ auth);
+ if (connvldb == NULL) {
+ fprintf (stderr,
+ "vos_createvolume: arlalib_getconnbyaddr: vldb-host: 0x%x\n",
+ dbhost);
+ return -1;
+ }
+
+ volser = arlalib_getconnbyname (cell, host,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (volser == NULL) {
+ fprintf (stderr,"vos_createvolume: arlalib_getconnbyname: volser: %s\n",
+ host);
+ arlalib_destroyconn (connvldb);
+ return -1;
+ }
+
+ fshost = rx_HostOf(rx_PeerOf(volser));
+ if (fshost == 0) {
+ fprintf (stderr, "vos_createvolume: address of 0 is not permited\n");
+ goto errout;
+ }
+
+ /*
+ * Get three (3) new Id's from the vldb server's
+ */
+
+ error = VL_GetNewVolumeId (connvldb, 3, &volid);
+ if (error) {
+ fprintf (stderr, "vos_createvolume: VL_GetNewVolumeID: %s\n",
+ koerr_gettext (error));
+ goto errout;
+ }
+ if (verbose)
+ printf ("vos_createvolume: got a VolumeID: %d\n", volid);
+
+ /*
+ * Create new volume on the server
+ */
+
+ error = VOLSER_AFSVolCreateVolume (volser, part, name,
+ RWVOL,
+ /* parent */ 0, &volid,
+ &trans);
+ if (error) {
+ fprintf (stderr, "vosler_createvolume: VOLSER_AFSVolCreateVolume: %s\n",
+ koerr_gettext (error));
+ goto errout;
+ }
+ if (verbose)
+ printf ("vos_createvolume: created volume on %s, got trans %d\n",
+ host, trans);
+
+ /*
+ * Bring the volume on-line
+ */
+
+ error = VOLSER_AFSVolSetFlags(volser, trans, 0);
+ if (error) {
+ fprintf (stderr, "vos_createvolume: VOLSER_AFSVolSetFlags: %s\n",
+ koerr_gettext (error));
+ goto errout;
+ }
+ if (verbose)
+ printf ("vos_createvolume: updated flag for trans %d\n", trans);
+
+ /*
+ * Create vldb-entry for the volume, if that failes, remove the volume
+ * from the server.
+ */
+
+ memset (&entry, 0, sizeof (entry));
+ strlcpy (entry.name, name, sizeof(entry.name));
+ entry.nServers = 1;
+ entry.serverNumber[0] = ntohl(fshost);
+ entry.serverPartition[0] = part;
+ entry.serverFlags[0] = VLSF_RWVOL;
+ entry.volumeId[RWVOL] = volid;
+ entry.volumeId[ROVOL] = volid+1;
+ entry.volumeId[BACKVOL] = volid+2;
+ entry.cloneId = 0;
+ entry.flags = VLF_RWEXISTS;
+
+ error = new_vlentry (connvldb, NULL, NULL, &entry, auth);
+ if (error) {
+ fprintf (stderr, "vos_createvolume: new_vlentry: %s\n",
+ koerr_gettext (error));
+
+ fprintf (stderr, "vos_createvolume: removing new volume");
+ error = VOLSER_AFSVolDeleteVolume (volser, trans);
+ if (error)
+ fprintf (stderr, "vos_createvolume: failed to remove volume: %s\n",
+ koerr_gettext (error));
+ else
+ fprintf (stderr, "vos_createvolume: removed volume\n");
+
+ } else if (verbose)
+ printf ("vos_createvolume: added entry to vldb\n");
+
+ /*
+ * End transaction to volumeserver
+ */
+
+ errout:
+ error = VOLSER_AFSVolEndTrans(volser, trans, &rcode);
+ if (error) {
+ fprintf (stderr,
+ "vos_createvolume: VOLSER_AFSVolEndTrans: %s, rcode: %d\n",
+ koerr_gettext (error),
+ rcode);
+ return -1;
+ }
+ if (verbose)
+ printf ("vos_createvolume: ending transaction %d, rcode %d\n",
+ trans, rcode);
+
+ arlalib_destroyconn(volser);
+ arlalib_destroyconn(connvldb);
+ return error;
+}
+
+/*
+ * list vldb
+ */
+
+static char *server;
+static char *part;
+static char *volume;
+static char *cell;
+static int noauth;
+static int localauth;
+static int helpflag;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server,
+ "server", NULL, arg_mandatory},
+ {"part", 0, arg_string, &part,
+ "part", NULL, arg_mandatory},
+ {"volume", 0, arg_string, &volume,
+ "volume", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell,
+ "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth,
+ "do not authenticate", NULL},
+ {"localauth", 0, arg_flag, &localauth,
+ "use local authentication", NULL},
+ {"verbose", 0, arg_flag, &verbose,
+ "verbose output", NULL},
+ {"help", 0, arg_flag, &helpflag,
+ NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+/*
+ * print usage
+ */
+
+static void
+usage(void)
+{
+ arg_printusage (args, "vos create", "", ARG_AFSSTYLE);
+}
+
+/*
+ * createvolume, to be called from libsl
+ */
+
+int
+vos_create(int argc, char **argv)
+{
+ int optind = 0;
+ int npart = -1;
+ int error;
+
+ server = cell = NULL;
+ noauth = localauth = helpflag = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage();
+ return 0;
+ }
+
+ if(helpflag) {
+ usage();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0) {
+ fprintf (stderr, "create volume: unparsed arguments\n");
+ return 0;
+ }
+
+ npart = partition_name2num (part);
+
+ error = vos_createvolume (server, npart, cell,
+ arlalib_getauthflag (noauth, localauth, 0, 0),
+ volume, verbose);
+ if (error) {
+ fprintf (stderr, "vos_createvolume failed (%d)\n", error);
+ return 0;
+ }
+
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/appl/vos/vos_dump.c b/usr.sbin/afs/src/appl/vos/vos_dump.c
new file mode 100644
index 00000000000..9c81f06998b
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_dump.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_dump.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static void
+dump_volume (const char *volume,
+ const char *cell, const char *host, const char *part,
+ const char *file, arlalib_authflags_t auth)
+{
+ struct rx_connection *conn_volser = NULL;
+ struct rx_call *call;
+ int error;
+ int fd;
+ nvldbentry the_vlentry;
+ int32_t trans_id;
+ int ret;
+ u_int32_t size, nread;
+ char buf[8192];
+
+ if (file != NULL) {
+ fd = open (file, O_WRONLY | O_CREAT, 0666);
+ if (fd < 0) {
+ warn ("open %s", file);
+ return;
+ }
+ } else {
+ fd = STDOUT_FILENO;
+ }
+
+ if (cell == NULL)
+ cell = cell_getthiscell ();
+
+ error = get_vlentry (cell, NULL, volume, auth, &the_vlentry);
+ if (error)
+ goto out;
+
+ conn_volser = arlalib_getconnbyaddr(cell,
+ htonl(the_vlentry.serverNumber[0]),
+ NULL,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (conn_volser == NULL) {
+ fprintf (stderr, "dump_volume: getconnbyaddr failed\n");
+ goto out;
+ }
+
+ error = VOLSER_AFSVolTransCreate(conn_volser,
+ the_vlentry.volumeId[0], /* XXX */
+ the_vlentry.serverPartition[0],
+ ITReadOnly,
+ &trans_id);
+ if (error) {
+ fprintf (stderr, "dump_volume: VolTransCreate failed: %s\n",
+ koerr_gettext(error));
+ goto out;
+ }
+
+ call = rx_NewCall (conn_volser);
+ if (call == NULL) {
+ fprintf (stderr, "dump_volume: rx_NewCall failed: %s\n",
+ koerr_gettext(error));
+ goto out;
+ }
+
+ error = StartVOLSER_AFSVolDump(call, trans_id, 0 /* XXX */);
+ if (error) {
+ rx_EndCall (call, 0);
+ fprintf (stderr, "dump_volume: start AFSVolDump failed: %s\n",
+ koerr_gettext(error));
+ goto out;
+ }
+
+ ret = rx_Read (call, &size, sizeof(size));
+
+ if (ret != sizeof(size)) {
+ ret = conv_to_arla_errno(rx_Error(call));
+ rx_EndCall (call, 0);
+ fprintf (stderr, "dump_volume: start AFSVolDump failed: %s\n",
+ koerr_gettext(ret));
+ goto out;
+ }
+ size = ntohl(size);
+
+ while (size && (nread = rx_Read (call, buf, min(sizeof(buf), size))) > 0) {
+ if (write (fd, buf, nread) != nread) {
+ warn ("write");
+ rx_EndCall(call, 0);
+ goto trans_out;
+ }
+ size -= nread;
+ }
+
+ error = EndVOLSER_AFSVolDump (call);
+ if (error) {
+ rx_EndCall (call, 0);
+ fprintf (stderr, "dump_volume: end AFSVolDump failed: %s\n",
+ koerr_gettext(error));
+ goto out;
+ }
+ rx_EndCall (call, 0);
+
+trans_out:
+ ret = 0;
+
+ error = VOLSER_AFSVolEndTrans(conn_volser, trans_id, &ret);
+ if (error)
+ fprintf (stderr, "dump_volume: VolEndTrans failed: %s\n",
+ koerr_gettext(error));
+
+out:
+ if (conn_volser != NULL)
+ arlalib_destroyconn (conn_volser);
+
+ if (file != NULL)
+ close (fd);
+}
+
+static char *vol;
+static char *server;
+static char *part;
+static char *cell;
+static char *file;
+static int noauth;
+static int localauth;
+static int verbose;
+static int helpflag;
+
+static struct getargs args[] = {
+ {"id", 0, arg_string, &vol, "id of volume", "volume",
+ arg_mandatory},
+ {"server", 0, arg_string, &server, "what server to use", NULL},
+ {"partition",0, arg_string, &part, "what partition to use", NULL},
+ {"cell", 0, arg_string, &cell, "what cell to use", NULL},
+ {"file", 0, arg_string, &file, "file to dump to", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"localauth",0,arg_flag, &localauth, "localauth", NULL},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos dump", "", ARG_AFSSTYLE);
+}
+
+int
+vos_dump(int argc, char **argv)
+{
+ int optind = 0;
+
+ noauth = localauth = verbose = 0;
+ file = cell = server = part = vol = NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ dump_volume (vol, cell, server, part, file,
+ arlalib_getauthflag (noauth, localauth, 0, 0));
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_endtrans.c b/usr.sbin/afs/src/appl/vos/vos_endtrans.c
new file mode 100644
index 00000000000..b00daab733f
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_endtrans.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include "vos_local.h"
+
+RCSID("$Id: vos_endtrans.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+/*
+ * end a transaction on `host' with transaction id `trans'
+ */
+
+int
+vos_endtransaction (const char *cell, const char *host, int32_t trans,
+ arlalib_authflags_t auth, int verbose)
+{
+ struct rx_connection *volser = NULL;
+ int error;
+ int32_t rcode;
+
+ if (host == NULL)
+ return EINVAL;
+
+ if (cell == NULL)
+ cell = (char *)cell_getthiscell();
+
+ volser = arlalib_getconnbyname (cell, host,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (volser == NULL) {
+ fprintf (stderr,
+ "vos_endtransaction: arlalib_getconnbyname: volser: %s\n",
+ host);
+ return -1;
+ }
+
+
+ error = VOLSER_AFSVolEndTrans(volser, trans, &rcode);
+ if (error) {
+ fprintf (stderr, "vos_createvolume: VOLSER_AFSVolEndTrans: %s\n",
+ koerr_gettext (error));
+ return -1;
+ }
+ if (verbose)
+ printf ("vos_endtransaction: VOLSER_AFSVolEndTrans: rcode = %d",
+ rcode);
+
+ arlalib_destroyconn(volser);
+ return error;
+}
+
+/*
+ * list vldb
+ */
+
+static char *server;
+static char *cell;
+static int transid;
+static int noauth;
+static int localauth;
+static int helpflag;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server,
+ "server", NULL, arg_mandatory},
+ {"trans", 0, arg_integer, &transid,
+ "trans", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell,
+ "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth,
+ "do not authenticate", NULL},
+ {"localauth", 0, arg_flag, &localauth,
+ "use local authentication", NULL},
+ {"verbose", 0, arg_flag, &verbose,
+ "verbose output", NULL},
+ {"help", 0, arg_flag, &helpflag,
+ NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+/*
+ * print usage
+ */
+
+static void
+usage(void)
+{
+ arg_printusage (args, "vos endtransaction", "", ARG_AFSSTYLE);
+}
+
+/*
+ * end a transaction, to be called from libsl
+ */
+
+int
+vos_endtrans(int argc, char **argv)
+{
+ int optind = 0;
+ int error;
+
+ server = cell = NULL;
+ noauth = localauth = helpflag = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage();
+ return 0;
+ }
+
+ if(helpflag) {
+ usage();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0) {
+ fprintf (stderr, "vos_endtrans: unparsed arguments\n");
+ return 0;
+ }
+
+ error = vos_endtransaction (cell, server, transid,
+ arlalib_getauthflag (noauth, localauth, 0, 0),
+ verbose);
+ if (error) {
+ fprintf (stderr, "vos_endtrans failed (%d)\n", error);
+ return 0;
+ }
+
+ return 0;
+}
+
+
diff --git a/usr.sbin/afs/src/appl/vos/vos_examine.c b/usr.sbin/afs/src/appl/vos/vos_examine.c
new file mode 100644
index 00000000000..ccf73d7d118
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_examine.c
@@ -0,0 +1,327 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_examine.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static void
+print_extended_stats (const xvolintInfo *v)
+{
+ printf(" Raw Read/Write Stats\n"
+ " |-------------------------------------------|\n"
+ " | Same Network | Diff Network |\n"
+ " |----------|----------|----------|----------|\n"
+ " | Total | Auth | Total | Auth |\n"
+ " |----------|----------|----------|----------|\n");
+ printf("Reads |%9d |%9d |%9d |%9d |\n",
+ v->stat_reads[0],
+ v->stat_reads[1],
+ v->stat_reads[2],
+ v->stat_reads[3]);
+ printf("Writes |%9d |%9d |%9d |%9d |\n",
+ v->stat_writes[0],
+ v->stat_writes[1],
+ v->stat_writes[2],
+ v->stat_writes[3]);
+ printf(" |-------------------------------------------|\n");
+ printf("\n");
+ printf(" Writes Affecting Authorship\n"
+ " |-------------------------------------------|\n"
+ " | File Authorship | Directory Authorship|\n"
+ " |----------|----------|----------|----------|\n"
+ " | Same | Diff | Same | Diff |\n"
+ " |----------|----------|----------|----------|\n");
+ printf("0-60 sec |%9d |%9d |%9d |%9d |\n",
+ v->stat_fileSameAuthor[0], v->stat_fileDiffAuthor[0],
+ v->stat_dirSameAuthor[0], v->stat_dirDiffAuthor[0]);
+ printf("1-10 min |%9d |%9d |%9d |%9d |\n",
+ v->stat_fileSameAuthor[1], v->stat_fileDiffAuthor[1],
+ v->stat_dirSameAuthor[1], v->stat_dirDiffAuthor[1]);
+ printf("10min-1hr |%9d |%9d |%9d |%9d |\n",
+ v->stat_fileSameAuthor[2], v->stat_fileDiffAuthor[2],
+ v->stat_dirSameAuthor[2], v->stat_dirDiffAuthor[2]);
+ printf("1hr-1day |%9d |%9d |%9d |%9d |\n",
+ v->stat_fileSameAuthor[3], v->stat_fileDiffAuthor[3],
+ v->stat_dirSameAuthor[3], v->stat_dirDiffAuthor[3]);
+ printf("1day-1wk |%9d |%9d |%9d |%9d |\n",
+ v->stat_fileSameAuthor[4], v->stat_fileDiffAuthor[4],
+ v->stat_dirSameAuthor[4], v->stat_dirDiffAuthor[4]);
+ printf("> 1wk |%9d |%9d |%9d |%9d |\n",
+ v->stat_fileSameAuthor[5], v->stat_fileDiffAuthor[5],
+ v->stat_dirSameAuthor[5], v->stat_dirDiffAuthor[5]);
+ printf(" |-------------------------------------------|\n");
+}
+
+static void
+print_volume (const nvldbentry *nvlentry, const xvolintInfo *v,
+ const char *server_name, int extended)
+{
+ char part_name[17];
+ char timestr[30];
+
+ printf("%s\t\t\t%10u %s ",
+ nvlentry->name,
+ nvlentry->volumeId[0],
+ getvolumetype(nvlentry->serverFlags[0]));
+
+ if (v != NULL)
+ printf("%8d K %s\n", v->size, v->status == VOK ? "On-line" : "Busy");
+ else
+ printf("unknown K\n");
+
+ if (v != NULL && v->status == VOK) {
+ partition_num2name (nvlentry->serverPartition[0],
+ part_name, sizeof(part_name));
+
+ printf(" %s %s\n", server_name, part_name);
+ printf(" ");
+
+ if (nvlentry->flags & VLF_RWEXISTS)
+ printf("RWrite %u\t", nvlentry->volumeId[RWVOL]);
+
+ if (nvlentry->flags & VLF_ROEXISTS )
+ printf("ROnly %u\t", nvlentry->volumeId[ROVOL]);
+
+ if (nvlentry->flags & VLF_BACKEXISTS)
+ printf("Backup %u\t", nvlentry->volumeId[BACKVOL]);
+
+ printf("\n MaxQuota %10d K\n", v->maxquota);
+
+ /* Get and format date */
+ strlcpy(timestr,
+ ctime( (time_t*) &v->creationDate),
+ sizeof(timestr));
+ printf(" Creation %s\n", timestr);
+
+ /* Get and format date */
+ strlcpy(timestr,
+ ctime((time_t *) &v->updateDate),
+ sizeof(timestr));
+ printf(" Last Update %s\n", timestr);
+
+ printf(" %d accesses in the past day (i.e., vnode references)\n\n",
+ v->dayUse);
+ }
+
+ if (extended && v != NULL)
+ print_extended_stats (v);
+}
+
+static int
+printvolstat(const char *volname, const char *cell, const char *host,
+ arlalib_authflags_t auth, int verbose, int extended)
+{
+ struct rx_connection *connvolser;
+ int error;
+ int i;
+ xvolEntries xvolint;
+ nvldbentry nvlentry;
+ struct in_addr server_addr;
+ char server_name[MAXHOSTNAMELEN];
+ char part_name[17];
+ int was_xvol = 1;
+
+ find_db_cell_and_host (&cell, &host);
+
+ if (cell == NULL) {
+ fprintf (stderr, "Unable to find cell of host '%s'\n", host);
+ return -1;
+ }
+
+ if (host == NULL) {
+ fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell);
+ return -1;
+ }
+
+ if (verbose)
+ fprintf (stderr,
+ "Getting volume `%s' from the VLDB at `%s'...",
+ volname, host);
+
+ error = get_vlentry (cell, host, volname, auth, &nvlentry);
+
+ if (error) {
+ fprintf(stderr, "VL_GetEntryByName(%s) failed: %s\n",
+ volname, koerr_gettext(error));
+ return -1;
+ }
+
+ if (verbose)
+ fprintf (stderr, "done\n");
+
+ server_addr.s_addr = htonl(nvlentry.serverNumber[0]);
+ inaddr2str (server_addr, server_name, sizeof(server_name));
+
+ connvolser = arlalib_getconnbyaddr(cell,
+ server_addr.s_addr,
+ NULL,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (connvolser == NULL)
+ return -1;
+
+ if (verbose) {
+ fprintf (stderr, "getting information on `%s' from %s\n",
+ volname, server_name);
+ }
+
+ xvolint.val = NULL;
+ error = VOLSER_AFSVolXListOneVolume(connvolser,
+ nvlentry.serverPartition[0],
+ nvlentry.volumeId[0],
+ &xvolint);
+
+ if (error == RXGEN_OPCODE) {
+ volEntries volint;
+
+ was_xvol = 0;
+ volint.val = NULL;
+ error = VOLSER_AFSVolListOneVolume(connvolser,
+ nvlentry.serverPartition[0],
+ nvlentry.volumeId[0],
+ &volint);
+ if (error == 0) {
+ xvolint.val = emalloc (sizeof (*xvolint.val));
+ volintInfo2xvolintInfo (volint.val, xvolint.val);
+ }
+ }
+
+ if (error != 0)
+ printf("ListOneVolume of %s from %s failed with: %s (%d)\n",
+ volname, server_name,
+ koerr_gettext(error), error);
+
+ if (verbose)
+ fprintf (stderr, "done\n");
+
+ print_volume (&nvlentry, xvolint.val, server_name, was_xvol && extended);
+
+ printf(" ");
+ printf("RWrite: %u\t", nvlentry.flags & VLF_RWEXISTS ? nvlentry.volumeId[RWVOL] : 0);
+ printf("ROnly: %u\t", nvlentry.flags & VLF_ROEXISTS ? nvlentry.volumeId[ROVOL] : 0);
+ printf("Backup: %u\t", nvlentry.flags & VLF_BACKEXISTS ? nvlentry.volumeId[BACKVOL] : 0);
+
+ printf("\n number of sites -> %d\n", nvlentry.nServers );
+
+ for (i = 0; i < nvlentry.nServers; i++) {
+ printf(" ");
+
+ server_addr.s_addr = htonl(nvlentry.serverNumber[i]);
+ inaddr2str (server_addr, server_name, sizeof(server_name));
+
+ partition_num2name (nvlentry.serverPartition[i],
+ part_name, sizeof(part_name));
+ printf("server %s partition %s %s Site\n",
+ server_name, part_name,
+ getvolumetype(nvlentry.serverFlags[i]));
+ }
+
+ free(xvolint.val);
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+static int helpflag;
+static char *host;
+static char *cell;
+static char *vol;
+static int noauth;
+static int localauth;
+static int verbose;
+static int extended;
+
+static struct getargs args[] = {
+ {"id", 0, arg_string, &vol, "id of volume", "volume",
+ arg_mandatory},
+ {"host", 0, arg_string, &host, "what host to use", NULL},
+ {"cell", 0, arg_string, &cell, "what cell to use", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"localauth",0,arg_flag, &localauth, "localauth", NULL},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"extended",0, arg_flag, &extended, "more output", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos examine", "", ARG_AFSSTYLE);
+}
+
+int
+vos_examine(int argc, char **argv)
+{
+ int optind = 0;
+
+ helpflag = noauth = localauth = verbose = extended = 0;
+ host = cell = vol = NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 0;
+ }
+
+ /* don't allow any bogus volname */
+ if (vol == NULL || vol[0] == '\0') {
+ usage ();
+ return 0;
+ }
+
+ printvolstat(vol, cell, host,
+ arlalib_getauthflag (noauth, localauth, 0, 0),
+ verbose, extended);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_listpart.c b/usr.sbin/afs/src/appl/vos/vos_listpart.c
new file mode 100644
index 00000000000..6f8c6c2e424
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_listpart.c
@@ -0,0 +1,125 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_listpart.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static int
+printlistparts(const char *cell, const char *server,
+ arlalib_authflags_t auth, int verbose)
+{
+ part_entries parts;
+ int error;
+ int i;
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+
+ error = getlistparts(cell, server, &parts, auth);
+
+ if (error != 0)
+ return error;
+
+ printf("The partitions on the server are:\n ");
+ for (i = 0; i < parts.len; ++i) {
+ char part_name[17];
+
+ partition_num2name (parts.val[i], part_name, sizeof(part_name));
+ printf(" %s%c", part_name, i % 6 == 5 ? '\n' : ' ');
+ }
+ printf("\nTotal: %d\n", parts.len);
+ free (parts.val);
+ return 0;
+}
+
+static int helpflag;
+static char *server;
+static char *cell;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs listp_args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "no authentication", NULL},
+ {"localauth",0, arg_flag, &localauth, "local authentication", NULL},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(listp_args, "vos listpart", "", ARG_AFSSTYLE);
+}
+
+int
+vos_listpart(int argc, char **argv)
+{
+ int optind = 0;
+
+ helpflag = noauth = localauth = verbose = 0;
+ server = cell = NULL;
+
+ if (getarg (listp_args,argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 0;
+ }
+
+ if (server == NULL || server[0] == '\0') {
+ usage ();
+ return 0;
+ }
+
+ printlistparts(cell, server,
+ arlalib_getauthflag (noauth, localauth, 0, 0),
+ verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_listvldb.c b/usr.sbin/afs/src/appl/vos/vos_listvldb.c
new file mode 100644
index 00000000000..0817df0c94b
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_listvldb.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_listvldb.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+/*
+ * listvldb iteration over all entries in the DB
+ */
+
+int
+vos_listvldb_iter (const char *host, const char *cell,
+ arlalib_authflags_t auth,
+ int (*proc)(void *data, struct vldbentry *), void *data)
+{
+ struct rx_connection *connvldb = NULL;
+ struct vldbentry entry;
+ int error;
+ int32_t num, count;
+
+ find_db_cell_and_host (&cell, &host);
+
+ if (cell == NULL) {
+ fprintf (stderr, "Unable to find cell of host '%s'\n", host);
+ return -1;
+ }
+
+ if (host == NULL) {
+ fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell);
+ return -1;
+ }
+
+ connvldb = arlalib_getconnbyname(cell, host,
+ afsvldbport,
+ VLDB_SERVICE_ID,
+ auth);
+ num = 0;
+ do {
+ error = VL_ListEntry (connvldb,
+ num,
+ &count,
+ &num,
+ &entry);
+ if (error)
+ break;
+
+ entry.name[VLDB_MAXNAMELEN-1] = '\0';
+
+ error = proc (data, &entry);
+ if (error)
+ break;
+
+ } while (num != -1);
+
+ if (error) {
+ warnx ("listvldb: VL_ListEntry: %s", koerr_gettext(error));
+ return -1;
+ }
+
+ arlalib_destroyconn(connvldb);
+ return 0;
+}
+
+/*
+ * Print vldbentry on listvldb style
+ */
+
+static int
+listvldb_print (void *data, struct vldbentry *e)
+{
+ int i;
+ char *hostname;
+
+ assert (e);
+
+ printf ("%s\n", e->name);
+ printf (" Number of sites -> %d\n", e->nServers);
+ for (i = 0 ; i < e->nServers ; i++) {
+ if (e->serverNumber[i] == 0)
+ continue;
+ if (arlalib_getservername(htonl(e->serverNumber[i]), &hostname))
+ continue;
+ printf (" server %s partition /vicep%c Site %s\n",
+ hostname,
+ 'a' + e->serverPartition[i],
+ getvolumetype (e->serverFlags[i]));
+ free (hostname);
+ }
+
+ printf ("\n");
+
+ return 0;
+}
+
+
+/*
+ * list vldb
+ */
+
+char *server;
+char *cell;
+int noauth;
+int localauth;
+int helpflag;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server,
+ "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell,
+ "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth,
+ "do not authenticate", NULL},
+ {"localauth", 0, arg_flag, &localauth,
+ "use local authentication", NULL},
+ {"help", 0, arg_flag, &helpflag,
+ NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage (args, "vos listvldb", "", ARG_AFSSTYLE);
+}
+
+int
+vos_listvldb(int argc, char **argv)
+{
+ int optind = 0;
+
+ server = cell = NULL;
+ noauth = localauth = helpflag = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage();
+ return 0;
+ }
+
+ if(helpflag) {
+ usage();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+
+ vos_listvldb_iter (server, cell,
+ arlalib_getauthflag (noauth, localauth, 0, 0),
+ listvldb_print, NULL);
+
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/appl/vos/vos_listvol.c b/usr.sbin/afs/src/appl/vos/vos_listvol.c
new file mode 100644
index 00000000000..d02fdcb2261
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_listvol.c
@@ -0,0 +1,132 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_listvol.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+/*
+ * list volume on a afs-server
+ */
+
+char *server;
+char *partition;
+int listvol_machine;
+char *cell;
+int noauth;
+int localauth;
+int helpflag;
+int fast;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server,
+ "server", NULL, arg_mandatory},
+ {"partition", 0, arg_string, &partition,
+ "partition", NULL},
+ {"machine", 'm', arg_flag, &listvol_machine,
+ "machineparseableform", NULL},
+ {"cell", 0, arg_string, &cell,
+ "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth,
+ "do not authenticate", NULL},
+ {"localauth", 0, arg_flag, &localauth,
+ "use local authentication", NULL},
+ {"fast", 0, arg_flag, &fast,
+ "only list IDs", NULL},
+ {"help", 0, arg_flag, &helpflag,
+ NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage (args, "vos listvol", "", ARG_AFSSTYLE);
+}
+
+int
+vos_listvol(int argc, char **argv)
+{
+ int optind = 0;
+ int flags = 0;
+ int part;
+
+ server = partition = cell = NULL;
+ listvol_machine = noauth = localauth = helpflag = fast = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage();
+ return 0;
+ }
+
+ if(helpflag) {
+ usage();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ usage();
+ return 0;
+ }
+
+ if (partition == NULL) {
+ part = -1;
+ } else {
+ part = partition_name2num(partition);
+ if (part == -1) {
+ usage();
+ return 0;
+ }
+ }
+
+ if (listvol_machine)
+ flags |= LISTVOL_PART;
+ if (localauth)
+ flags |= LISTVOL_LOCALAUTH;
+ if (fast)
+ flags |= LISTVOL_FAST;
+
+ printlistvol(cell, server, part, flags,
+ arlalib_getauthflag (noauth, 0, 0, 0));
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_local.h b/usr.sbin/afs/src/appl/vos/vos_local.h
new file mode 100644
index 00000000000..f01220ebcc8
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_local.h
@@ -0,0 +1,94 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * RCSID("$Id: vos_local.h,v 1.1 2000/09/11 14:40:38 art Exp $");
+ */
+
+#define LISTVOL_PART 0x1
+#define LISTVOL_NOAUTH 0x2
+#define LISTVOL_LOCALAUTH 0x4
+#define LISTVOL_FAST 0x8
+
+/* this program needs __progname defined as a macro */
+#define __progname "vos"
+#define PROGNAME (vos_interactive ? "" : __progname" ")
+
+/* if this is set the program runs in interactive mode */
+extern int vos_interactive;
+
+int vos_examine (int, char **);
+int vos_vldbexamine (int, char **);
+int vos_listpart (int, char **);
+int vos_listvol (int, char **);
+int vos_lock (int, char **);
+int vos_unlock (int, char **);
+int vos_listvldb(int argc, char **argv);
+int vos_partinfo (int, char **);
+int vos_status (int, char **);
+int vos_createentry (int, char **);
+int vos_syncsite (int, char **);
+int vos_dump (int, char **);
+int vos_create(int argc, char **argv);
+int vos_endtrans(int argc, char **argv);
+
+int vos_listvldb_iter (const char *host, const char *cell,
+ arlalib_authflags_t auth,
+ int (*proc)(void *data, struct vldbentry *),
+ void *data);
+
+const char *getvolumetype(int32_t flag);
+const char *getvolumetype2(int32_t type);
+int getlistparts(const char *cell, const char *host,
+ part_entries *parts, arlalib_authflags_t auth);
+int printlistvol(const char *cell, const char *host, int part, int flags,
+ arlalib_authflags_t auth);
+int get_vlentry (const char *cell, const char *host, const char *volname,
+ arlalib_authflags_t auth, nvldbentry *nvlentry);
+int new_vlentry (struct rx_connection *conn, const char *cell, const char *host,
+ nvldbentry *nvldbentry, arlalib_authflags_t auth);
+
+
+
+int vos_createvolume (char *host, int32_t part, char *cell,
+ arlalib_authflags_t auth,
+ char *name, int verbose);
+int vos_endtransaction (const char *cell, const char *host,
+ int32_t trans, arlalib_authflags_t auth, int verbose);
+
+void find_db_cell_and_host (const char **cell, const char **host);
diff --git a/usr.sbin/afs/src/appl/vos/vos_lock.c b/usr.sbin/afs/src/appl/vos/vos_lock.c
new file mode 100644
index 00000000000..125166e3b85
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_lock.c
@@ -0,0 +1,167 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_lock.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+/*
+ * lock a volume
+ */
+
+static char *vol;
+static char *cell;
+static int noauth;
+static int localauth;
+static int helpflag;
+static int verbose;
+
+static struct getargs args[] = {
+ {"id", 0, arg_string, &vol,
+ "id or name of volume", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell,
+ "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth,
+ "do not authenticate", NULL},
+ {"localauth", 0, arg_flag, &localauth,
+ "use local authentication", NULL},
+ {"verbose", 0, arg_flag, &verbose,
+ "verbose output", NULL},
+ {"help", 0, arg_flag, &helpflag,
+ NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static int
+vos_lock_volume(char *volname)
+{
+ struct rx_connection *connvldb;
+ const char *host = NULL;
+ arlalib_authflags_t auth;
+ int error;
+ vldbentry vol;
+
+ find_db_cell_and_host((const char **)&cell, &host);
+ if(cell == NULL) {
+ fprintf(stderr, "unable to find cell\n");
+ return -1;
+ }
+ if(host == NULL) {
+ fprintf(stderr, "unable to find a vldb host in cell %s", cell);
+ return -1;
+ }
+
+ auth = arlalib_getauthflag(noauth, localauth, 0, 0);
+
+ connvldb = arlalib_getconnbyname(cell, host,
+ afsvldbport,
+ VLDB_SERVICE_ID,
+ auth);
+
+ if(connvldb == NULL) {
+ fprintf(stderr, "can't connect to vldb server %s in cell %s\n",
+ host, cell);
+ return -1;
+ }
+
+ error = VL_GetEntryByName(connvldb, volname, &vol);
+ if (error) {
+ fprintf(stderr, "vos_lock: error %s (%d)\n",
+ koerr_gettext(error), error);
+ return 1;
+ }
+
+ /* XXX Are you really supposed to use RWVOL here? */
+ error = VL_SetLock(connvldb, vol.volumeId[RWVOL], RWVOL, VLOP_DELETE);
+
+ if(!error) {
+ printf("Locked VLDB entry for volume %s\n", vol.name);
+ } else {
+ fprintf(stderr, "vos_lock: error %s (%d)\n",
+ koerr_gettext(error), error);
+ return 1;
+ }
+
+ arlalib_destroyconn(connvldb);
+ return 0;
+}
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos dump", "", ARG_AFSSTYLE);
+}
+
+int
+vos_lock(int argc, char **argv)
+{
+ int optind = 0;
+
+ cell = vol = NULL;
+ noauth = localauth = helpflag = verbose = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 0;
+ }
+
+ /* don't allow any bogus volname */
+ if (vol == NULL || vol[0] == '\0') {
+ usage ();
+ return 0;
+ }
+
+ vos_lock_volume(vol);
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_partinfo.c b/usr.sbin/afs/src/appl/vos/vos_partinfo.c
new file mode 100644
index 00000000000..958bc25b011
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_partinfo.c
@@ -0,0 +1,177 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_partinfo.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static int
+print_one_partition (struct rx_connection *conn, const char *part)
+{
+ int error;
+ struct diskPartition partinfo ;
+
+ error = VOLSER_AFSVolPartitionInfo(conn, part, &partinfo);
+ if (error != 0) {
+ printf("printpartinfo: PartitionInfo failed with: %s (%d)\n",
+ koerr_gettext(error), error);
+ return -1;
+ }
+
+ printf("Free space on partition %s %d K blocks out of total %d\n",
+ partinfo.name,
+ partinfo.free,
+ partinfo.minFree
+/* XXX - partinfo.totalUsable */
+ );
+ return 0;
+}
+
+static int
+printpartinfo(const char *cell, const char *host, const char *part,
+ int verbose, arlalib_authflags_t auth)
+{
+ struct rx_connection *connvolser;
+ char part_name[30];
+ int error;
+
+ find_db_cell_and_host (&cell, &host);
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsvolport,
+ VOLSERVICE_ID,
+ auth);
+ if (connvolser == NULL)
+ return -1;
+
+ if (part == NULL) {
+ int i;
+ part_entries parts;
+
+ error = getlistparts (cell, host, &parts, auth);
+ if (error != 0)
+ return error;
+
+ for (i = 0; i < parts.len; ++i) {
+ partition_num2name (parts.val[i], part_name, sizeof(part_name));
+ error = print_one_partition (connvolser, part_name);
+ if (error != 0)
+ return error;
+ }
+ } else {
+ if (strlen(part) <= 2) {
+ snprintf(part_name, sizeof(part_name), "/vicep%s", part);
+ part = part_name;
+ }
+ error = print_one_partition (connvolser, part);
+ if (error != 0)
+ return error;
+ }
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+static int helpflag;
+static char *server;
+static char *cell;
+static char *part;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"partition",0, arg_string, &part, "partition", NULL},
+ {"noauth", 0, arg_flag, &noauth, "no authentication", NULL},
+ {"localauth",0,arg_flag, &localauth, "localauth", NULL},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos partinfo", "", ARG_AFSSTYLE);
+}
+
+int
+vos_partinfo(int argc, char **argv)
+{
+ int optind = 0;
+
+ helpflag = noauth = localauth = verbose = 0;
+ server = cell = part = NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 1 && part == NULL) {
+ part = argv[0];
+ --argc;
+ ++argv;
+ }
+
+ if (argc != 0) {
+ usage ();
+ return 0;
+ }
+
+ if (server == NULL) {
+ printf ("vos partinfo: you need to specify server\n");
+ return 0;
+ }
+
+ printpartinfo(cell, server, part, verbose,
+ arlalib_getauthflag (noauth, localauth, 0, 0));
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_status.c b/usr.sbin/afs/src/appl/vos/vos_status.c
new file mode 100644
index 00000000000..3cae9eaca96
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_status.c
@@ -0,0 +1,154 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_status.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static int
+printstatus(const char *cell, const char *host,
+ int noauth, int verbose)
+{
+ struct rx_connection *connvolser = NULL;
+ struct transDebugInfo *entries;
+ transDebugEntries info;
+ unsigned int entries_len, i;
+ int error;
+
+ connvolser = arlalib_getconnbyname(cell,
+ host,
+ afsvolport,
+ VOLSERVICE_ID,
+ 0);
+
+ if (connvolser == NULL)
+ return -1;
+
+ if ((error = VOLSER_AFSVolMonitor(connvolser,
+ &info)) != 0) {
+ printf("printstatus: GetStat failed with: %s (%d)\n",
+ koerr_gettext(error),
+ error);
+ return -1;
+ }
+
+ entries_len = info.len;
+ entries = info.val;
+
+ if (entries_len == 0)
+ printf ("No active transactions on %s\n", host);
+ else {
+ for (i = 0; i < entries_len; i--) {
+ printf("--------------------------------------\n");
+ printf("transaction: %d created: %s", entries->tid, ctime((time_t *) &entries->creationTime));
+ printf("attachFlags: ");
+
+ if ((entries->iflags & ITOffline) == ITOffline)
+ printf(" offline");
+ if ((entries->iflags & ITBusy) == ITBusy)
+ printf(" busy");
+ if ((entries->iflags & ITReadOnly) == ITReadOnly)
+ printf("read-only");
+ if ((entries->iflags & ITCreate) == ITCreate)
+ printf("create");
+ if ((entries->iflags & ITCreateVolID) == ITCreateVolID)
+ printf("create-VolID");
+
+ printf("\nvolume: %d partition: <insert partition name here> procedure: %s\n", entries->volid, entries->lastProcName);
+ printf("packetRead: %d lastReceiveTime: %d packetSend: %d lastSendTime: %d\n", entries->readNext, entries->lastReceiveTime, entries->transmitNext, entries->lastSendTime);
+ entries++;
+ }
+ printf("--------------------------------------\n");
+ }
+
+ arlalib_destroyconn(connvolser);
+ return 0;
+}
+
+static int helpflag;
+static const char *server;
+static const char *cell;
+static int noauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"server", 0, arg_string, &server, "server", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell, "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (void)
+{
+ arg_printusage (args, "vos status", "", ARG_AFSSTYLE);
+}
+
+int
+vos_status(int argc, char **argv)
+{
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (server == NULL) {
+ printf ("vos status: missing -server\n");
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = cell_getcellbyhost (server);
+
+ printstatus (cell, server, noauth, verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_syncsite.c b/usr.sbin/afs/src/appl/vos/vos_syncsite.c
new file mode 100644
index 00000000000..3d3c78b2054
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_syncsite.c
@@ -0,0 +1,100 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_syncsite.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static int helpflag;
+static char *cell;
+static int resolvep = 1;
+
+static struct getargs args[] = {
+ {"cell", 'c', arg_string, &cell, "cell", NULL},
+ {"help", 'h', arg_flag, &helpflag, NULL, NULL},
+ {"resolve", 'n', arg_negative_flag, &resolvep, NULL, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos syncsite", "", ARG_AFSSTYLE);
+}
+
+int
+vos_syncsite (int argc, char **argv)
+{
+ struct in_addr saddr;
+ int error;
+ int optind = 0;
+
+ helpflag = 0;
+ cell = NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ if (cell == NULL)
+ cell = (char *)cell_getthiscell();
+
+ error = arlalib_getsyncsite(cell, NULL, afsvldbport, &saddr.s_addr, 0);
+ if (error) {
+ fprintf(stderr, "syncsite: %s (%d)\n", koerr_gettext(error), error);
+ return 0;
+ }
+
+ if (!resolvep)
+ printf("%s's vldb syncsite is %s.\n", cell, inet_ntoa(saddr));
+ else {
+ char name[256];
+
+ inaddr2str (saddr, name, sizeof(name));
+ printf("%s's vldb syncsite is %s (%s).\n", cell, name,
+ inet_ntoa(saddr));
+ }
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_unlock.c b/usr.sbin/afs/src/appl/vos/vos_unlock.c
new file mode 100644
index 00000000000..1d5985db87d
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_unlock.c
@@ -0,0 +1,169 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_unlock.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+/*
+ * unlock a volume
+ */
+
+static char *vol;
+static char *cell;
+static int noauth;
+static int localauth;
+static int helpflag;
+static int verbose;
+
+static struct getargs args[] = {
+ {"id", 0, arg_string, &vol,
+ "id or name of volume", NULL, arg_mandatory},
+ {"cell", 0, arg_string, &cell,
+ "cell", NULL},
+ {"noauth", 0, arg_flag, &noauth,
+ "do not authenticate", NULL},
+ {"localauth", 0, arg_flag, &localauth,
+ "use local authentication", NULL},
+ {"verbose", 0, arg_flag, &verbose,
+ "verbose output", NULL},
+ {"help", 0, arg_flag, &helpflag,
+ NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static int
+vos_unlock_volume(char *volname)
+{
+ struct rx_connection *connvldb;
+ const char *host = NULL;
+ arlalib_authflags_t auth;
+ int error;
+ vldbentry vol;
+
+ find_db_cell_and_host((const char **)&cell, &host);
+ if(cell == NULL) {
+ fprintf(stderr, "unable to find cell\n");
+ return -1;
+ }
+ if(host == NULL) {
+ fprintf(stderr, "unable to find a vldb host in cell %s", cell);
+ return -1;
+ }
+
+ auth = arlalib_getauthflag(noauth, localauth, 0, 0);
+
+ connvldb = arlalib_getconnbyname(cell, host,
+ afsvldbport,
+ VLDB_SERVICE_ID,
+ auth);
+
+ if(connvldb == NULL) {
+ fprintf(stderr, "can't connect to vldb server %s in cell %s\n",
+ host, cell);
+ return -1;
+ }
+
+ error = VL_GetEntryByName(connvldb, volname, &vol);
+
+ if(error) {
+ fprintf(stderr, "vos_unlock: error %s (%d)\n",
+ koerr_gettext(error), error);
+ return 1;
+ }
+
+ /* XXX Are you really supposed to use RWVOL here? */
+ error = VL_ReleaseLock(connvldb, vol.volumeId[RWVOL], RWVOL,
+ LOCKREL_TIMESTAMP | LOCKREL_OPCODE | LOCKREL_AFSID);
+
+ if(!error) {
+ printf("Unlocked VLDB entry for volume %s\n", vol.name);
+ } else {
+ fprintf(stderr, "vos_unlock: error %s (%d)\n",
+ koerr_gettext(error), error);
+ return 1;
+ }
+
+ arlalib_destroyconn(connvldb);
+ return 0;
+}
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos dump", "", ARG_AFSSTYLE);
+}
+
+int
+vos_unlock(int argc, char **argv)
+{
+ int optind = 0;
+
+ cell = vol = NULL;
+ noauth = localauth = helpflag = verbose = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 0;
+ }
+
+ /* don't allow any bogus volname */
+ if (vol == NULL || vol[0] == '\0') {
+ usage ();
+ return 0;
+ }
+
+ vos_unlock_volume(vol);
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/appl/vos/vos_vldbexamine.c b/usr.sbin/afs/src/appl/vos/vos_vldbexamine.c
new file mode 100644
index 00000000000..6e09e62d1a4
--- /dev/null
+++ b/usr.sbin/afs/src/appl/vos/vos_vldbexamine.c
@@ -0,0 +1,202 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "appl_locl.h"
+#include <sl.h>
+#include "vos_local.h"
+
+RCSID("$Id: vos_vldbexamine.c,v 1.1 2000/09/11 14:40:38 art Exp $");
+
+static void
+print_volume (const nvldbentry *nvlentry, const char *server_name)
+{
+ char part_name[17];
+
+ printf("%s\t\t\t%10u %s\n",
+ nvlentry->name,
+ nvlentry->volumeId[0],
+ getvolumetype(nvlentry->serverFlags[0]));
+
+ partition_num2name (nvlentry->serverPartition[0],
+ part_name, sizeof(part_name));
+
+ printf(" %s %s\n", server_name, part_name);
+ printf(" ");
+
+ if (nvlentry->flags & VLF_RWEXISTS)
+ printf("RWrite %u\t", nvlentry->volumeId[RWVOL]);
+
+ if (nvlentry->flags & VLF_ROEXISTS )
+ printf("ROnly %u\t", nvlentry->volumeId[ROVOL]);
+
+ if (nvlentry->flags & VLF_BACKEXISTS)
+ printf("Backup %u\t", nvlentry->volumeId[BACKVOL]);
+
+}
+
+
+static int
+printvolstat(const char *volname, const char *cell, const char *host,
+ arlalib_authflags_t auth, int verbose)
+{
+ int error;
+ int i;
+ nvldbentry nvlentry;
+ struct in_addr server_addr;
+ char server_name[MAXHOSTNAMELEN];
+ char part_name[17];
+
+ find_db_cell_and_host (&cell, &host);
+
+ if (cell == NULL) {
+ fprintf (stderr, "Unable to find cell of host '%s'\n", host);
+ return -1;
+ }
+
+ if (host == NULL) {
+ fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell);
+ return -1;
+ }
+
+ if (verbose)
+ fprintf (stderr,
+ "Getting volume `%s' from the VLDB at `%s'...",
+ volname, host);
+
+ error = get_vlentry (cell, host, volname, auth, &nvlentry);
+
+ if (error) {
+ fprintf(stderr, "VL_GetEntryByName(%s) failed: %s\n",
+ volname, koerr_gettext(error));
+ return -1;
+ }
+
+ if (verbose)
+ fprintf (stderr, "done\n");
+
+ server_addr.s_addr = htonl(nvlentry.serverNumber[0]);
+ inaddr2str (server_addr, server_name, sizeof(server_name));
+
+ print_volume (&nvlentry, server_name);
+
+ printf(" ");
+ printf("RWrite: %u\t", nvlentry.flags & VLF_RWEXISTS ? nvlentry.volumeId[RWVOL] : 0);
+ printf("ROnly: %u\t", nvlentry.flags & VLF_ROEXISTS ? nvlentry.volumeId[ROVOL] : 0);
+ printf("Backup: %u\t", nvlentry.flags & VLF_BACKEXISTS ? nvlentry.volumeId[BACKVOL] : 0);
+
+ printf("\n number of sites -> %d\n", nvlentry.nServers );
+
+ for (i = 0; i < nvlentry.nServers; i++) {
+ printf(" ");
+
+ server_addr.s_addr = htonl(nvlentry.serverNumber[i]);
+ inaddr2str (server_addr, server_name, sizeof(server_name));
+
+ partition_num2name (nvlentry.serverPartition[i],
+ part_name, sizeof(part_name));
+ printf("server %s partition %s %s Site\n",
+ server_name, part_name,
+ getvolumetype(nvlentry.serverFlags[i]));
+ }
+
+ return 0;
+}
+
+static int helpflag;
+static char *host;
+static char *cell;
+static char *vol;
+static int noauth;
+static int localauth;
+static int verbose;
+
+static struct getargs args[] = {
+ {"id", 0, arg_string, &vol, "id of volume", "volume",
+ arg_mandatory},
+ {"host", 0, arg_string, &host, "what host to use", NULL},
+ {"cell", 0, arg_string, &cell, "what cell to use", NULL},
+ {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL},
+ {"localauth",0,arg_flag, &localauth, "localauth", NULL},
+ {"verbose", 0, arg_flag, &verbose, "be verbose", NULL},
+ {"help", 0, arg_flag, &helpflag, NULL, NULL},
+ {NULL, 0, arg_end, NULL}
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "vos vldbexamine", "", ARG_AFSSTYLE);
+}
+
+int
+vos_vldbexamine(int argc, char **argv)
+{
+ int optind = 0;
+
+ helpflag = noauth = localauth = verbose = 0;
+ host = cell = vol = NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 0;
+ }
+
+ if (helpflag) {
+ usage ();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 0;
+ }
+
+ /* don't allow any bogus volname */
+ if (vol == NULL || vol[0] == '\0') {
+ usage ();
+ return 0;
+ }
+
+ printvolstat(vol, cell, host,
+ arlalib_getauthflag (noauth, localauth, 0, 0),
+ verbose);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/arlad/.gdbinit b/usr.sbin/afs/src/arlad/.gdbinit
new file mode 100644
index 00000000000..cab126d8928
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/.gdbinit
@@ -0,0 +1,109 @@
+#
+# $Id: .gdbinit,v 1.1 2000/09/11 14:40:39 art Exp $
+#
+
+
+define listfcachenodes
+set $foo = lrulist->head
+while $foo != 0
+print *(FCacheEntry *) $foo->data
+set $foo = $foo->next
+end
+print 4711
+end
+
+document listfcachenodes
+List all fcache nodes in the lru-list
+end
+
+
+define listfcachenodes_fid
+set $foo = lrulist->head
+while $foo != 0
+print ((FCacheEntry *) $foo->data)->fid
+set $foo = $foo->next
+end
+print 4711
+end
+
+document listfcachenodes_fid
+List all fcache nodes's fids in the lru-list
+end
+
+define fcache_lru_num_nodes
+set $bar = 0
+set $foo = lrulist->head
+while $foo != 0
+set $bar = $bar + 1
+set $foo = $foo->next
+end
+print $bar
+end
+
+document fcache_lru_num_nodes
+Count number of nodes in the fcache lrulist
+end
+
+define fcache_lru_num_used_nodes
+set $bar = 0
+set $foo = lrulist->head
+while $foo != 0
+if ((FCacheEntry *) $foo->data)->flags.usedp != 0
+set $bar = $bar + 1
+end
+set $foo = $foo->next
+end
+print $bar
+end
+
+document fcache_lru_num_used_nodes
+Count number of USED nodes in the fcache lrulist
+end
+
+define lwp_ps_internal
+set $lwp_ps_queue = $arg0
+set $lwp_ps_counter = $lwp_ps_queue.count
+set $lwp_ps_foo = $lwp_ps_queue->head
+while $lwp_ps_counter != 0
+ printf " name: %s", (char *) $lwp_ps_foo->name
+ if $lwp_ps_foo == lwp_cpptr
+ printf " RUNNING THREAD"
+ end
+ printf "\n"
+ printf " eventlist:"
+ set $lwp_ps_envcnt = 0
+ while $lwp_ps_envcnt < $lwp_ps_foo->eventcnt
+ printf " %x", $lwp_ps_foo->eventlist[$lwp_ps_envcnt]
+ set $lwp_ps_envcnt = $lwp_ps_envcnt + 1
+ end
+ printf "\n"
+ if $lwp_ps_foo == lwp_cpptr
+ printf " fp: 0x%x\n", $fp
+ printf " pc: 0x%x\n", $pc
+ printf " pointers on topstack added for completeness\n"
+ end
+ printf " fp: 0x%x\n", ((int *)$lwp_ps_foo->context->topstack)[2]
+ printf " pc: 0x%x\n", ((int *)$lwp_ps_foo->context->topstack)[3]
+ set $lwp_ps_foo = $lwp_ps_foo->next
+ set $lwp_ps_counter = $lwp_ps_counter - 1
+end
+end
+
+define lwp_ps
+echo Runnable[0]\n
+lwp_ps_internal runnable[0]
+echo Runnable[1]\n
+lwp_ps_internal runnable[1]
+echo Runnable[2]\n
+lwp_ps_internal runnable[2]
+echo Runnable[3]\n
+lwp_ps_internal runnable[3]
+echo Runnable[4]\n
+lwp_ps_internal runnable[4]
+echo Blocked\n
+lwp_ps_internal blocked
+end
+
+document lwp_ps
+Print all processes, running or blocked
+end
diff --git a/usr.sbin/afs/src/arlad/CellServDB.5 b/usr.sbin/afs/src/arlad/CellServDB.5
new file mode 100644
index 00000000000..bbd835c6a0a
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/CellServDB.5
@@ -0,0 +1,35 @@
+.\" $OpenBSD: CellServDB.5,v 1.1 2000/09/11 14:40:39 art Exp $
+.\" $Id: CellServDB.5,v 1.1 2000/09/11 14:40:39 art Exp $
+.Dd April 19, 2000
+.Dt CellServDB 5
+.Os
+.Sh NAME
+.Nm CellServDB
+.Nd AFS cells and database servers
+.Sh DESCRIPTION
+The file
+.Nm
+lists AFS cells known to the local AFS cache manager.
+Each entry describes the name of an AFS cell and specifies the
+servers for that cell.
+.Pp
+Here is an example of the format of an entry in the file:
+.Bd -literal
+>cellname # Freetext comment describing the cell
+ip-address #first.server.for.cell
+ip-address #second.server.for.cell
+ip-adresss #third.server.for.cell
+.Ed
+.Pp
+.Nm
+is read when
+.Nm arlad
+is started, normally when the system boots.
+.Pp
+The text after the # is NOT a comment, it the hostname of the db-server.
+.Pp
+Entires in the file are searched and expanded by many programs
+.Sh FILES
+.Pa CellServDB
+.Sh SEE ALSO
+.Xr arlad 1
diff --git a/usr.sbin/afs/src/arlad/Makefile.in b/usr.sbin/afs/src/arlad/Makefile.in
new file mode 100644
index 00000000000..a2044d467c8
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/Makefile.in
@@ -0,0 +1,198 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:39 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sysconfdir = @sysconfdir@
+mandir = @mandir@
+transform = @program_transform_name@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+ARLA_BIN = arlad
+
+MANPAGES = CellServDB.5 ThisCell.5 SuidCells.5 arlad.1
+
+DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DARLACACHEDIR=\"$(ARLACACHEDIR)\" \
+ -DARLACONFFILE=\"$(ARLACONFFILE)\"
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+AFSWSROOT = /usr/afsws
+RXKADINC = -I$(srcdir)/../rxkad
+INCLUDES = -I$(srcdir)/.. \
+ @KERNEL_INCLUDE@ \
+ -I../include \
+ -I$(srcdir)/../include \
+ -I$(srcdir)/../xfs/include \
+ -I../rxdef \
+ $(RXKADINC)
+DEFINES = -DDEBUG
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) \
+ -DRXDEBUG @PLWP_INC_FLAGS@
+RXKADLIB = @RXKAD_LIBS@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../lib/bufdir -lbufdir \
+ -L../rxdef -lrxdefclient -L../rx -lrx -L../lwp \
+ -llwp @PLWP_LIB_FLAGS@ \
+ -L../lib/sl -lsl @LIB_readline@ \
+ -L../lib/ko -lko -L../util -lutil\
+ -L../lib/roken -lroken $(RXKADLIB) $(KAFS_LIBS) @LIBS@
+LIBDEPENDS = ../rxdef/librxdefclient.a ../rx/librx.a ../lwp/liblwp.a \
+ ../util/libutil.a ../lib/sl/libsl.a ../lib/roken/libroken.a \
+ ../lib/ko/libko.a
+KERNEL_SRCS = @KERNEL_SRCS@
+PROGS = arlad afsdir_check
+SRCS = \
+ adir.c \
+ afsdir_check.c \
+ arla.c \
+ arladeb.c \
+ arladeb2.c \
+ cmcb.c \
+ conn.c \
+ cred.c \
+ darla.c \
+ discon_log.c \
+ dynroot.c \
+ fcache.c \
+ fprio.c \
+ inter.c \
+ kernel.c \
+ messages.c \
+ reconnect.c \
+ subr.c \
+ volcache.c \
+ xfs.c \
+ $(KERNEL_SRCS)
+
+HDRS = \
+ adir.h \
+ afs_dir.h \
+ arla_local.h \
+ arladeb.h \
+ cmcb.h \
+ conn.h \
+ cred.h \
+ darla.h \
+ discon.h \
+ discon_fix.h \
+ discon_log.h \
+ dynroot.h \
+ fcache.h \
+ fprio.h \
+ inter.h \
+ kernel.h \
+ messages.h \
+ service.h \
+ subr.h \
+ xfs.h \
+ volcache.h
+
+arlad_OBJS = \
+ adir.o \
+ arla.o \
+ arladeb.o \
+ arladeb2.o \
+ cmcb.o \
+ conn.o \
+ cred.o \
+ darla.o \
+ discon_log.o \
+ dynroot.o \
+ fcache.o \
+ fprio.o \
+ inter.o \
+ kernel.o \
+ messages.o \
+ reconnect.o \
+ subr.o \
+ volcache.o \
+ xfs.o \
+ $(KERNEL_SRCS:.c=.o)
+
+afsdir_check_OBJS = \
+ arladeb.o \
+ afsdir_check.o
+
+.PHONY: all install uninstall depend tags clean
+
+all: $(PROGS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ PROG_BIN='$(ARLA_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir) ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+uninstall:
+ PROG_BIN='$(ARLA_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+arlad: $(arlad_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(arlad_OBJS) $(LIBS)
+
+afsdir_check: $(afsdir_check_OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(afsdir_check_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=arlad/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(SRCS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/arlad/SuidCells.5 b/usr.sbin/afs/src/arlad/SuidCells.5
new file mode 100644
index 00000000000..4f857d86b04
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/SuidCells.5
@@ -0,0 +1,16 @@
+.\" $OpenBSD: SuidCells.5,v 1.1 2000/09/11 14:40:39 art Exp $
+.\" $Id: SuidCells.5,v 1.1 2000/09/11 14:40:39 art Exp $
+.Dd April 19, 2000
+.Dt SuidCells 5
+.Os
+.Sh NAME
+.Nm SuidCells
+.Nd lists AFS cells for which the setuid bit is honored
+.Sh DESCRIPTION
+The setuid bit on binaries executed from within AFS are ignored
+for the cells that are not listed in
+.Nm
+.Sh SEE ALSO
+.Xr arlad 1 ,
+.Xr CellServDB 5
+
diff --git a/usr.sbin/afs/src/arlad/ThisCell.5 b/usr.sbin/afs/src/arlad/ThisCell.5
new file mode 100644
index 00000000000..aaa90f3ed3b
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/ThisCell.5
@@ -0,0 +1,29 @@
+.\" $OpenBSD: ThisCell.5,v 1.1 2000/09/11 14:40:39 art Exp $
+.\" $Id: ThisCell.5,v 1.1 2000/09/11 14:40:39 art Exp $
+.Dd April 19, 2000
+.Dt ThisCell 5
+.Os
+.Sh NAME
+.Nm ThisCell
+.Nd specify a hosts home AFS cell
+.Sh DESCRIPTION
+The file
+.Nm
+specifies which cell the AFS cache manager belongs to. This affects the
+default cell to use for commands such as
+.Xr pts 1 ,
+.Xr fs 1 ,
+.Xr vos 8 ,
+.Xr kauth 1 ,
+.Xr kinit 1 ,
+.Xr afslog 1 ,
+but other cells can still be used.
+.Pp
+It also affects where the cache manager reads the root of afs, so
+having good connectivity to the default cell is very important. This
+can be avoided by using the dynroot feature of arlad.
+.Pp
+.Sh SEE ALSO
+.Xr arlad 1 ,
+.Xr SuidCells 5 ,
+.Xr CellServDB 5
diff --git a/usr.sbin/afs/src/arlad/aix-subr.c b/usr.sbin/afs/src/arlad/aix-subr.c
new file mode 100644
index 00000000000..43c9a9f9fec
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/aix-subr.c
@@ -0,0 +1,153 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+RCSID("$Id: aix-subr.c,v 1.1 2000/09/11 14:40:39 art Exp $");
+
+static long blocksize = 1024;
+
+static void
+flushbuf (void *vargs)
+{
+ struct write_dirent_args *args = (struct write_dirent_args *)vargs;
+ struct dirent *last = (struct dirent *)args->last;
+ unsigned inc = blocksize - (args->ptr - args->buf);
+
+ last->d_reclen += inc;
+ last->d_offset += inc;
+ if (write (args->fd, args->buf, blocksize) != blocksize)
+ arla_warn (ADEBWARN, errno, "write");
+ args->ptr = args->buf;
+ args->last = NULL;
+}
+
+#undef DIRSIZ
+#define DIRSIZ(name) \
+ (((sizeof(struct dirent)+ (strlen(name)+1)) + \
+ 3) & ~3)
+
+static void
+write_dirent(VenusFid *fid, const char *name, void *arg)
+{
+ struct dirent *real;
+ struct write_dirent_args *args = (struct write_dirent_args *)arg;
+ u_short reclen;
+
+ reclen = DIRSIZ(name);
+
+ if (args->ptr + reclen > args->buf + blocksize)
+ flushbuf (args);
+ real = (struct dirent *)args->ptr;
+
+ real->d_reclen = reclen;
+ real->d_ino = dentry2ino (name, fid, args->e);
+ strcpy (real->d_name, name);
+ args->ptr += real->d_reclen;
+ args->off += real->d_reclen;
+ real->d_offset = args->off;
+ args->last = real;
+}
+
+Result
+conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ return conv_dir_sub (e, ce, tokens, cache_handle, cache_name,
+ cache_name_sz, write_dirent, flushbuf, blocksize);
+}
+
+/*
+ * remove `filename` from the converted directory for `e'
+ */
+
+int
+dir_remove_name (FCacheEntry *e, const char *filename,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ int ret;
+ int fd;
+ fbuf fb;
+ struct stat sb;
+ char *buf;
+ char *p;
+ size_t len;
+ struct dirent *dp;
+ struct dirent *last_dp;
+
+ fcache_extra_file_name (e, cache_name, cache_name_sz);
+ fd = open (cache_name, O_RDWR, 0);
+ if (fd < 0)
+ return errno;
+ fcache_fhget (cache_name, cache_handle);
+ if (fstat (fd, &sb) < 0) {
+ ret = errno;
+ close (fd);
+ return ret;
+ }
+ len = sb.st_size;
+
+ ret = fbuf_create (&fb, fd, len, FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ last_dp = NULL;
+ ret = ENOENT;
+ for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) {
+ dp = (struct dirent *)p;
+
+ if (strcmp (filename, dp->d_name) == 0) {
+ if (last_dp != NULL) {
+ struct dirent new_last;
+
+ new_last.d_reclen = last_dp->d_reclen + dp->d_reclen;
+ if (new_last.d_reclen >= last_dp->d_reclen)
+ last_dp->d_reclen = new_last.d_reclen;
+ }
+ dp->d_ino = 0;
+ ret = 0;
+ break;
+ }
+ last_dp = dp;
+ }
+ fbuf_end (&fb);
+ close (fd);
+ return ret;
+}
diff --git a/usr.sbin/afs/src/arlad/dynroot.c b/usr.sbin/afs/src/arlad/dynroot.c
new file mode 100644
index 00000000000..a28e92738d1
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/dynroot.c
@@ -0,0 +1,376 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * Keep our own root.afs
+ *
+ * uses cell DYNROOTCELL as cell number.
+ */
+
+#include <arla_local.h>
+
+RCSID("$Id: dynroot.c,v 1.1 2000/09/11 14:40:41 art Exp $");
+
+struct create_entry {
+ fbuf *thedir; /* pointer to the fbuf that contains the dir */
+ AFSFid fid; /* the current fid */
+ int len; /* num of links in the dir */
+};
+
+#define DYNROOT_ROOTVOLUME 1
+#define DYNROOT_ROOTDIR 1
+#define DYNROOT_UNIQUE 1
+
+static int32_t dynrootcell = 0; /* this is the dynroocell */
+static Bool dynroot_enable = 0; /* is dynroot enabled ? */
+static unsigned long last_celldb_version = 0; /* last version of celldb */
+
+/*
+ * Magic glue wrt afsvnode#
+ */
+
+static int32_t
+cellnum2afs (int cellno)
+{
+ return (cellno << 1) + 1;
+}
+
+static int
+afs2cellnum (int32_t afsvnode)
+{
+ return (afsvnode - 1) >> 1;
+}
+
+/*
+ * helper functions for dynroot_create_root that for
+ * each `cell' creates a entry in the root directory.
+ */
+
+static int
+create_entry_func (const cell_entry *cell, void *arg)
+{
+ struct create_entry *entry = (struct create_entry *) arg;
+ int ret;
+
+ entry->fid.Vnode = cellnum2afs (cell->id);
+
+ ret = fdir_creat (entry->thedir, cell->name, entry->fid);
+ if (ret)
+ return ret;
+
+ entry->len++;
+
+ return 0;
+}
+
+/*
+ * create the dynroot root directory in `fbuf', return number
+ * of entries in `len'.
+ */
+
+static int
+dynroot_create_root (fbuf *fbuf, size_t *len)
+{
+ int ret;
+ AFSFid dot = { DYNROOT_ROOTVOLUME,
+ DYNROOT_ROOTDIR,
+ DYNROOT_UNIQUE};
+ struct create_entry entry;
+
+ ret = fdir_mkdir (fbuf, dot, dot);
+ if (ret)
+ return ret;
+
+ entry.thedir = fbuf;
+
+ entry.fid.Volume = DYNROOT_ROOTVOLUME;
+ entry.fid.Vnode = DYNROOT_ROOTDIR + 2;
+ entry.fid.Unique = DYNROOT_UNIQUE;
+ entry.len = 0;
+
+ ret = cell_foreach (create_entry_func, &entry);
+ if (ret)
+ return ret;
+
+ *len = entry.len;
+
+ return 0;
+}
+
+/*
+ * for the `vnode' create apropriate symlink in `fbuf'
+ */
+
+static int
+dynroot_create_symlink (fbuf *fbuf, int32_t vnode)
+{
+ char name[MAXPATHLEN];
+ cell_entry *cell;
+ int len, ret;
+
+ cell = cell_get_by_id (afs2cellnum (vnode));
+ if (cell == NULL)
+ return ENOENT;
+
+ len = snprintf (name, sizeof(name), "#%s:root.cell.", cell->name);
+ assert (len > 0 && len <= sizeof (name));
+
+ ret = fbuf_truncate (fbuf, len);
+ if (ret)
+ return ret;
+
+ memmove (fbuf_buf(fbuf), name, len);
+ return 0;
+}
+
+/*
+ * Return TRUE if the combination `cell' and `volume' is
+ * in the dynroot.
+ */
+
+Bool
+dynroot_isvolumep (int cell, const char *volume)
+{
+ assert (volume);
+
+ if (cell == 0 && strcmp (volume, "1") == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Create a dummy nvldbentry in `entry'
+ */
+
+int
+dynroot_fetch_vldbN (nvldbentry *entry)
+{
+ memset (entry, 0, sizeof(*entry));
+
+ strlcpy(entry->name, "root.cell", sizeof(entry->name));
+ entry->nServers = 0;
+ entry->volumeId[RWVOL] = DYNROOT_ROOTVOLUME;
+ entry->flags = VLF_RWEXISTS;
+
+ return 0;
+}
+
+/*
+ * Update `entry' to contain the correct information
+ * Note: doesn't update status.Length and status.LinkCount
+ */
+
+static void
+dynroot_update_entry (FCacheEntry *entry, int32_t filetype)
+{
+ struct timeval tv;
+
+ assert (entry);
+ entry->status.InterfaceVersion = 1;
+ entry->status.FileType = filetype;
+ entry->status.DataVersion = 1;
+ entry->status.Author = 0;
+ entry->status.Owner = 0;
+ entry->status.CallerAccess = ALIST | AREAD;
+ entry->status.AnonymousAccess = ALIST | AREAD;
+ entry->status.UnixModeBits =
+ S_IRUSR|S_IXUSR|
+ S_IRGRP|S_IXGRP|
+ S_IROTH|S_IXOTH;
+ entry->status.ParentVnode = DYNROOT_ROOTDIR;
+ entry->status.ParentUnique = DYNROOT_UNIQUE;
+ entry->status.SegSize = 64*1024;
+ entry->status.ClientModTime = 0;
+ entry->status.ServerModTime = 0;
+ entry->status.Group = 0;
+ entry->status.SyncCount = 0;
+ entry->status.spare1 = 0;
+ entry->status.spare2 = 0;
+ entry->status.spare3 = 0;
+ entry->status.spare4 = 0;
+
+ gettimeofday (&tv, NULL);
+
+ memset (&entry->volsync, 0, sizeof (entry->volsync));
+
+ entry->callback.CallBackVersion = 1;
+ entry->callback.ExpirationTime = tv.tv_sec + 3600 * 24 * 7;
+ entry->callback.CallBackType = CBSHARED;
+
+ entry->anonaccess = entry->status.AnonymousAccess;
+
+ /* XXX CallerAccess */
+}
+
+/*
+ * Fetch data and attr for `entry'
+ */
+
+static int
+dynroot_get_node (FCacheEntry *entry)
+{
+ int ret, fd, len, rootnode;
+ fbuf dir;
+
+ rootnode = entry->fid.fid.Vnode == DYNROOT_ROOTDIR ? 1 : 0;
+
+ if (entry->flags.attrp &&
+ entry->flags.datap &&
+ (!rootnode || last_celldb_version == cell_get_version()))
+ return 0;
+
+ fd = fcache_open_file (entry, O_RDWR);
+ if (fd < 0)
+ return errno;
+
+ ret = fbuf_create (&dir, fd, 0, FBUF_READ | FBUF_WRITE | FBUF_SHARED);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+
+ if (rootnode) {
+ ret = dynroot_create_root (&dir, &len);
+ entry->status.LinkCount = len;
+ } else {
+ ret = dynroot_create_symlink (&dir, entry->fid.fid.Vnode);
+ entry->status.LinkCount = 1;
+ }
+
+ if (ret) {
+ fbuf_end (&dir);
+ close(fd);
+ return ret;
+ }
+
+ entry->status.Length = dir.len;
+ entry->length = dir.len;
+
+ ret = fbuf_end (&dir);
+ close(fd);
+ if (ret)
+ return ret;
+
+ dynroot_update_entry (entry, rootnode ? TYPE_DIR : TYPE_LINK);
+
+ entry->flags.attrp = TRUE;
+ entry->flags.datap = TRUE;
+
+ entry->tokens |= XFS_ATTR_R|XFS_DATA_R;
+
+ return 0;
+}
+
+/*
+ * Fetch attr for `entry'
+ */
+
+int
+dynroot_get_attr (FCacheEntry *entry)
+{
+ return dynroot_get_node (entry);
+}
+
+
+/*
+ * Fetch data for `entry'
+ */
+
+int
+dynroot_get_data (FCacheEntry *entry)
+{
+ return dynroot_get_node (entry);
+}
+
+/*
+ * returns TRUE if `entry' is a dynroot entry.
+ */
+
+Bool
+dynroot_is_dynrootp (FCacheEntry *entry)
+{
+ assert (entry);
+
+ if (dynroot_enable &&
+ entry->fid.Cell == dynrootcell &&
+ entry->fid.fid.Volume == DYNROOT_ROOTVOLUME)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Return what status the dynroot is in.
+ */
+
+Bool
+dynroot_enablep (void)
+{
+ return dynroot_enable;
+}
+
+/*
+ * Enable/Disable the dynroot depending on `enable', returns previous state.
+ */
+
+Bool
+dynroot_setenable (Bool enable)
+{
+ Bool was = dynroot_enable;
+ dynroot_enable = enable;
+ return was;
+}
+
+/*
+ * Returns the dynroot_cellid.
+ */
+
+int32_t dynroot_cellid (void)
+{
+ return dynrootcell;
+}
+
+/*
+ * Return the dynroot volumeid.
+ */
+
+int32_t dynroot_volumeid (void)
+{
+ return DYNROOT_ROOTVOLUME;
+}
diff --git a/usr.sbin/afs/src/arlad/dynroot.h b/usr.sbin/afs/src/arlad/dynroot.h
new file mode 100644
index 00000000000..ee875c928a6
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/dynroot.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: dynroot.h,v 1.1 2000/09/11 14:40:41 art Exp $
+ */
+
+#define DYNROOT_DEFAULT 0
+
+int dynroot_fetch_vldbN (nvldbentry *entry);
+
+Bool dynroot_isvolumep (int cell, const char *volume);
+
+int dynroot_get_attr (FCacheEntry *entry);
+
+int dynroot_get_data (FCacheEntry *entry);
+
+Bool dynroot_is_dynrootp (FCacheEntry *entry);
+
+Bool dynroot_enablep (void);
+
+Bool dynroot_setenable (Bool enable);
+
+int32_t dynroot_cellid (void);
+
+int32_t dynroot_volumeid (void);
diff --git a/usr.sbin/afs/src/arlad/hpux-subr.c b/usr.sbin/afs/src/arlad/hpux-subr.c
new file mode 100644
index 00000000000..874f242c4d0
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/hpux-subr.c
@@ -0,0 +1,161 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/* If this isn't defined, we get a constant for DIRSIZ */
+
+#define DIRSIZ_MACRO
+
+#include "arla_local.h"
+RCSID("$Id: hpux-subr.c,v 1.1 2000/09/11 14:40:42 art Exp $");
+
+static long blocksize = 1024; /* XXX */
+
+static void
+flushbuf (void *vargs)
+{
+ struct write_dirent_args *args = (struct write_dirent_args *)vargs;
+ struct dirent *last = (struct dirent *)args->last;
+ unsigned inc = blocksize - (args->ptr - args->buf);
+
+ last->d_reclen += inc;
+#if 0
+ last->d_off += inc;
+#endif
+ if (write (args->fd, args->buf, blocksize) != blocksize)
+ arla_warn (ADEBWARN, errno, "write");
+ args->ptr = args->buf;
+ args->last = NULL;
+}
+
+#if 0 /* this seems wrong? */
+#define DIRSIZ(dp) \
+ (((sizeof(struct dirent)+ (strlen((dp)->d_name)+1)) +3) & ~3)
+#endif
+
+static void
+write_dirent(VenusFid *fid, const char *name, void *arg)
+{
+ struct dirent dirent, *real;
+ struct write_dirent_args *args = (struct write_dirent_args *)arg;
+
+/* dirent.d_namlen = strlen (name);*/
+ dirent.d_reclen = DIRSIZ(&dirent);
+
+ if (args->ptr + dirent.d_reclen > args->buf + blocksize)
+ flushbuf (args);
+ real = (struct dirent *)args->ptr;
+
+/* real->d_namlen = dirent.d_namlen;*/
+ real->d_reclen = dirent.d_reclen;
+ real->d_ino = dentry2ino (name, fid, args->e);
+ strcpy (real->d_name, name);
+ args->ptr += real->d_reclen;
+ args->off += real->d_reclen;
+#if 0
+ real->d_off = args->off;
+#endif
+ args->last = real;
+}
+
+Result
+conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ return conv_dir_sub (e, ce, tokens, cache_handle, cache_name,
+ cache_name_sz, write_dirent, flushbuf, blocksize);
+}
+/*
+ * remove `filename` from the converted directory for `e'
+ */
+
+int
+dir_remove_name (FCacheEntry *e, const char *filename,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ int ret;
+ int fd;
+ fbuf fb;
+ struct stat sb;
+ char *buf;
+ char *p;
+ size_t len;
+ struct dirent *dp;
+ struct dirent *last_dp;
+
+ fcache_extra_file_name (e, cache_name, cache_name_sz);
+ fd = open (cache_name, O_RDWR, 0);
+ if (fd < 0)
+ return errno;
+ fcache_fhget (cache_name, cache_handle);
+ if (fstat (fd, &sb) < 0) {
+ ret = errno;
+ close (fd);
+ return ret;
+ }
+ len = sb.st_size;
+
+ ret = fbuf_create (&fb, fd, len, FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ last_dp = NULL;
+ ret = ENOENT;
+ for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) {
+ dp = (struct dirent *)p;
+
+ if (strcmp (filename, dp->d_name) == 0) {
+ if (last_dp != NULL) {
+ struct dirent new_last;
+
+ new_last.d_reclen = last_dp->d_reclen + dp->d_reclen;
+ if (new_last.d_reclen >= last_dp->d_reclen)
+ last_dp->d_reclen = new_last.d_reclen;
+ }
+ dp->d_ino = 0;
+ ret = 0;
+ break;
+ }
+ last_dp = dp;
+ }
+ fbuf_end (&fb);
+ close (fd);
+ return ret;
+}
diff --git a/usr.sbin/afs/src/arlad/irix-subr.c b/usr.sbin/afs/src/arlad/irix-subr.c
new file mode 100644
index 00000000000..a4b4b46813e
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/irix-subr.c
@@ -0,0 +1,148 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+RCSID("$Id: irix-subr.c,v 1.1 2000/09/11 14:40:42 art Exp $");
+
+static long blocksize = 1024; /* XXX */
+
+static void
+flushbuf (void *vargs)
+{
+ struct write_dirent_args *args = (struct write_dirent_args *)vargs;
+ struct dirent *last = (struct dirent *)args->last;
+ unsigned inc = blocksize - (args->ptr - args->buf);
+
+ last->d_reclen += inc;
+ last->d_off += inc;
+ if (write (args->fd, args->buf, blocksize) != blocksize)
+ arla_warn (ADEBWARN, errno, "write");
+ args->ptr = args->buf;
+ args->last = NULL;
+}
+
+static void
+write_dirent(VenusFid *fid, const char *name, void *arg)
+{
+ struct dirent64 dirent, *real;
+ struct write_dirent_args *args = (struct write_dirent_args *)arg;
+ size_t namelen = strlen (name);
+
+ dirent.d_reclen = DIRENT64SIZE(namelen);
+
+ if (args->ptr + dirent.d_reclen > args->buf + blocksize)
+ flushbuf (args);
+ real = (struct dirent64 *)args->ptr;
+
+ real->d_reclen = dirent.d_reclen;
+ real->d_ino = dentry2ino (name, fid, args->e);
+ strcpy (real->d_name, name);
+ args->ptr += real->d_reclen;
+ args->off += real->d_reclen;
+ real->d_off = args->off;
+ args->last = real;
+}
+
+Result
+conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ return conv_dir_sub (e, ce, tokens, cache_handle, cache_name,
+ cache_name_sz, write_dirent, flushbuf, blocksize);
+}
+
+/*
+ * remove `filename` from the converted directory for `e'
+ */
+
+int
+dir_remove_name (FCacheEntry *e, const char *filename,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ int ret;
+ int fd;
+ fbuf fb;
+ struct stat sb;
+ char *buf;
+ char *p;
+ size_t len;
+ struct dirent64 *dp;
+ struct dirent64 *last_dp;
+
+ fcache_extra_file_name (e, cache_name, cache_name_sz);
+ fd = open (cache_name, O_RDWR, 0);
+ if (fd < 0)
+ return errno;
+ fcache_fhget (cache_name, cache_handle);
+ if (fstat (fd, &sb) < 0) {
+ ret = errno;
+ close (fd);
+ return ret;
+ }
+ len = sb.st_size;
+
+ ret = fbuf_create (&fb, fd, len, FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ last_dp = NULL;
+ ret = ENOENT;
+ for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) {
+ dp = (struct dirent64 *)p;
+
+ if (strcmp (filename, dp->d_name) == 0) {
+ if (last_dp != NULL) {
+ struct dirent new_last;
+
+ new_last.d_reclen = last_dp->d_reclen + dp->d_reclen;
+ if (new_last.d_reclen >= last_dp->d_reclen)
+ last_dp->d_reclen = new_last.d_reclen;
+ }
+ dp->d_ino = 0;
+ ret = 0;
+ break;
+ }
+ last_dp = dp;
+ }
+ fbuf_end (&fb);
+ close (fd);
+ return ret;
+}
diff --git a/usr.sbin/afs/src/arlad/solaris-subr.c b/usr.sbin/afs/src/arlad/solaris-subr.c
new file mode 100644
index 00000000000..b5d33f5225b
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/solaris-subr.c
@@ -0,0 +1,164 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+RCSID("$Id: solaris-subr.c,v 1.1 2000/09/11 14:40:43 art Exp $");
+
+static long blocksize = DIRBUF;
+
+#ifndef _LARGEFILE_SOURCE
+#define dirent64 dirent
+#define LARGEFILE_ALIGN 3
+#else
+#define LARGEFILE_ALIGN 7
+#endif
+
+static void
+flushbuf (void *vargs)
+{
+ struct write_dirent_args *args = (struct write_dirent_args *)vargs;
+ struct dirent64 *last = (struct dirent64 *)args->last;
+ unsigned inc = blocksize - (args->ptr - args->buf);
+
+ last->d_reclen += inc;
+ last->d_off += inc;
+ if (write (args->fd, args->buf, blocksize) != blocksize)
+ arla_warn (ADEBWARN, errno, "write");
+ args->ptr = args->buf;
+ args->last = NULL;
+}
+
+#define DIRSIZ(name) \
+ (((sizeof(struct dirent64)+ (strlen(name)+1)) + \
+ LARGEFILE_ALIGN) & ~LARGEFILE_ALIGN)
+
+static void
+write_dirent(VenusFid *fid, const char *name, void *arg)
+{
+ struct dirent64 *real;
+ struct write_dirent_args *args = (struct write_dirent_args *)arg;
+ u_short reclen;
+
+ reclen = DIRSIZ(name);
+
+ if (args->ptr + reclen > args->buf + blocksize)
+ flushbuf (args);
+ real = (struct dirent64 *)args->ptr;
+
+ real->d_reclen = reclen;
+ real->d_ino = dentry2ino (name, fid, args->e);
+ strcpy (real->d_name, name);
+ args->ptr += real->d_reclen;
+ args->off += real->d_reclen;
+ real->d_off = args->off;
+ args->last = real;
+}
+
+Result
+conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ return conv_dir_sub (e, ce, tokens, cache_handle, cache_name,
+ cache_name_sz, write_dirent, flushbuf, blocksize);
+}
+
+/*
+ * remove `filename` from the converted directory for `e'
+ */
+
+int
+dir_remove_name (FCacheEntry *e, const char *filename,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ int ret;
+ int fd;
+ fbuf fb;
+ struct stat sb;
+ char *buf;
+ char *p;
+ size_t len;
+ struct dirent64 *dp;
+ struct dirent64 *last_dp;
+
+ fcache_extra_file_name (e, cache_name, cache_name_sz);
+ fd = open (cache_name, O_RDWR, 0);
+ if (fd < 0)
+ return errno;
+ fcache_fhget (cache_name, cache_handle);
+ if (fstat (fd, &sb) < 0) {
+ ret = errno;
+ close (fd);
+ return ret;
+ }
+ len = sb.st_size;
+
+ ret = fbuf_create (&fb, fd, len, FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ last_dp = NULL;
+ ret = ENOENT;
+ for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) {
+ dp = (struct dirent64 *)p;
+
+ if (strcmp (filename, dp->d_name) == 0) {
+ if (last_dp != NULL) {
+ unsigned len;
+
+ /*
+ * It's not totally clear how large we can make
+ * d_reclen without loosing. Not making it larger
+ * than DIRBUF seems safe.
+ */
+ len = last_dp->d_reclen + dp->d_reclen;
+ if (len <= DIRBUF)
+ last_dp->d_reclen = len;
+ }
+ dp->d_ino = 0;
+ ret = 0;
+ break;
+ }
+ last_dp = dp;
+ }
+ fbuf_end (&fb);
+ close (fd);
+ return ret;
+}
diff --git a/usr.sbin/afs/src/arlad/subr.c b/usr.sbin/afs/src/arlad/subr.c
new file mode 100644
index 00000000000..1aec0b63e34
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/subr.c
@@ -0,0 +1,136 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+RCSID("$Id: subr.c,v 1.1 2000/09/11 14:40:43 art Exp $");
+
+/*
+ * come up with a good inode number for `name', `fid' in `parent'
+ */
+
+ino_t
+dentry2ino (const char *name, const VenusFid *fid, const FCacheEntry *parent)
+{
+ if (strcmp (name, ".") == 0
+ && (parent->flags.vol_root
+ || (fid->fid.Vnode == 1 && fid->fid.Unique == 1))
+ && parent->volume != NULL)
+ return afsfid2inode (&parent->volume->mp_fid);
+ else if (strcmp (name, "..") == 0
+ && (parent->flags.vol_root
+ || (parent->fid.fid.Vnode == 1
+ && parent->fid.fid.Unique == 1))
+ && parent->volume != NULL)
+ return afsfid2inode (&parent->volume->parent_fid);
+ else if (strcmp (name, "..") == 0
+ && fid->fid.Vnode == 1 && fid->fid.Unique == 1
+ && parent->volume != NULL)
+ return afsfid2inode (&parent->volume->mp_fid);
+ else
+ return afsfid2inode (fid);
+}
+
+/*
+ * Assume `e' has valid data.
+ */
+
+Result
+conv_dir_sub (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz,
+ fdir_readdir_func func,
+ void (*flush_func)(void *),
+ size_t blocksize)
+{
+ struct write_dirent_args args;
+ Result res;
+ int ret;
+ int fd;
+ fbuf the_fbuf;
+
+ e->flags.extradirp = TRUE;
+ fcache_extra_file_name (e, cache_name, cache_name_sz);
+ res.tokens = e->tokens |= XFS_DATA_R | XFS_OPEN_NR;
+
+ args.fd = open (cache_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ if (args.fd == -1) {
+ res.res = -1;
+ res.error = errno;
+ arla_warn (ADEBWARN, errno, "open %s", cache_name);
+ return res;
+ }
+ ret = fcache_fhget (cache_name, cache_handle);
+
+ args.off = 0;
+ args.buf = (char *)malloc (blocksize);
+ if (args.buf == NULL) {
+ arla_warn (ADEBWARN, errno, "malloc %u", (unsigned)blocksize);
+ res.res = -1;
+ res.error = errno;
+ close (args.fd);
+ return res;
+ }
+
+ ret = fcache_get_fbuf (e, &fd, &the_fbuf,
+ O_RDONLY, FBUF_READ|FBUF_PRIVATE);
+ if (ret) {
+ res.res = -1;
+ res.error = ret;
+ close (args.fd);
+ free (args.buf);
+ return res;
+ }
+
+ args.ptr = args.buf;
+ args.last = NULL;
+ args.e = e;
+ args.ce = ce;
+
+ fdir_readdir (&the_fbuf, func, (void *)&args, &e->fid);
+
+ fbuf_end (&the_fbuf);
+ close (fd);
+
+ if (args.last)
+ (*flush_func) (&args);
+ free (args.buf);
+ res.res = close (args.fd);
+ if (res.res)
+ res.error = errno;
+ return res;
+}
diff --git a/usr.sbin/afs/src/arlad/sunos-subr.c b/usr.sbin/afs/src/arlad/sunos-subr.c
new file mode 100644
index 00000000000..f95d763d151
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/sunos-subr.c
@@ -0,0 +1,148 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+RCSID("$Id: sunos-subr.c,v 1.1 2000/09/11 14:40:43 art Exp $");
+
+static long blocksize = 1024; /* XXX */
+
+static void
+flushbuf (void *vargs)
+{
+ struct write_dirent_args *args = (struct write_dirent_args *)vargs;
+ struct dirent *last = (struct dirent *)args->last;
+ unsigned inc = blocksize - (args->ptr - args->buf);
+
+ last->d_reclen += inc;
+ last->d_off += inc;
+ if (write (args->fd, args->buf, blocksize) != blocksize)
+ arla_warn (ADEBWARN, errno, "write");
+ args->ptr = args->buf;
+ args->last = NULL;
+}
+
+static void
+write_dirent(VenusFid *fid, const char *name, void *arg)
+{
+ struct dirent dirent, *real;
+ struct write_dirent_args *args = (struct write_dirent_args *)arg;
+
+ dirent.d_namlen = strlen (name);
+ dirent.d_reclen = DIRSIZ(&dirent);
+
+ if (args->ptr + dirent.d_reclen > args->buf + blocksize)
+ flushbuf (args);
+ real = (struct dirent *)args->ptr;
+
+ real->d_namlen = dirent.d_namlen;
+ real->d_reclen = dirent.d_reclen;
+ real->d_fileno = dentry2ino (name, fid, args->e);
+ strcpy (real->d_name, name);
+ args->ptr += real->d_reclen;
+ args->off += real->d_reclen;
+ real->d_off = args->off;
+ args->last = real;
+}
+
+Result
+conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ return conv_dir_sub (e, ce, tokens, cache_handle, cache_name,
+ cache_name_sz, write_dirent, flushbuf, blocksize);
+}
+
+/*
+ * remove `filename` from the converted directory for `e'
+ */
+
+int
+dir_remove_name (FCacheEntry *e, const char *filename,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ int ret;
+ int fd;
+ fbuf fb;
+ struct stat sb;
+ char *buf;
+ char *p;
+ size_t len;
+ struct dirent *dp;
+ struct dirent *last_dp;
+
+ fcache_extra_file_name (e, cache_name, cache_name_sz);
+ fd = open (cache_name, O_RDWR, 0);
+ if (fd < 0)
+ return errno;
+ fcache_fhget (cache_name, cache_handle);
+ if (fstat (fd, &sb) < 0) {
+ ret = errno;
+ close (fd);
+ return ret;
+ }
+ len = sb.st_size;
+
+ ret = fbuf_create (&fb, fd, len, FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ last_dp = NULL;
+ ret = ENOENT;
+ for (p = buf = fbuf_buf (&fb); p < buf + len; p += dp->d_reclen) {
+ dp = (struct dirent *)p;
+
+ if (strcmp (filename, dp->d_name) == 0) {
+ if (last_dp != NULL) {
+ struct dirent new_last;
+
+ new_last.d_reclen = last_dp->d_reclen + dp->d_reclen;
+ if (new_last.d_reclen >= last_dp->d_reclen)
+ last_dp->d_reclen = new_last.d_reclen;
+ }
+ ret = 0;
+ break;
+ }
+ last_dp = dp;
+ }
+ fbuf_end (&fb);
+ close (fd);
+ return ret;
+}
diff --git a/usr.sbin/afs/src/arlad/unknown-subr.c b/usr.sbin/afs/src/arlad/unknown-subr.c
new file mode 100644
index 00000000000..e4e0fa78801
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/unknown-subr.c
@@ -0,0 +1,60 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+RCSID("$Id: unknown-subr.c,v 1.1 2000/09/11 14:40:43 art Exp $");
+
+int
+dir_remove_name (FCacheEntry *e, const char *filename,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ return 0;
+}
+
+
+Result
+conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens,
+ xfs_cache_handle *cache_handle,
+ char *cache_name, size_t cache_name_sz)
+{
+ Result res;
+
+ res.res = 0;
+ return res;
+}
diff --git a/usr.sbin/afs/src/arlad/xfs.c b/usr.sbin/afs/src/arlad/xfs.c
new file mode 100644
index 00000000000..a1b45d92ae7
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/xfs.c
@@ -0,0 +1,543 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "arla_local.h"
+
+RCSID("$Id: xfs.c,v 1.1 2000/09/11 14:40:44 art Exp $");
+
+/*
+ * Begining of breakout of xfs releated junk
+ */
+
+static u_int *seqnums;
+
+static List *sleepers;
+
+/* number of times each type of message has been sent */
+
+static unsigned sent_stat[XFS_MSG_COUNT];
+
+/* number of times each type of message has been received */
+
+static unsigned recv_stat[XFS_MSG_COUNT];
+
+static char *rcvfuncs_name[] =
+{
+ "version",
+ "wakeup",
+ "getroot",
+ "installroot",
+ "getnode",
+ "installnode",
+ "getattr",
+ "installattr",
+ "getdata",
+ "installdata",
+ "inactivenode",
+ "invalidnode",
+ "open",
+ "put_data",
+ "put_attr",
+ "create",
+ "mkdir",
+ "link",
+ "symlink",
+ "remove",
+ "rmdir",
+ "rename",
+ "pioctl",
+ "wakeup_data",
+ "updatefid",
+ "advlock",
+ "gc nodes"
+};
+
+/*
+ * A interface for the userland to talk the kernel and recv
+ * back a integer. For larger messages implement a simularfunction
+ * that uses the `wakeup_data' message.
+ */
+
+int
+xfs_message_rpc (int fd, struct xfs_message_header *h, u_int size)
+{
+ int ret;
+
+ ret = xfs_message_send (fd, h, size);
+ if (ret)
+ return ret;
+ return xfs_message_sleep (h->sequence_num);
+}
+
+/*
+ * Try to probe the version on `fd', returning the version.
+ */
+
+static int
+xfs_send_message_version (int fd)
+{
+ struct xfs_message_version msg;
+ int ret;
+
+ msg.header.opcode = XFS_MSG_VERSION;
+ arla_warnx (ADEBMSG, "sending version");
+ ret = xfs_message_rpc (fd, (struct xfs_message_header *)&msg,
+ sizeof(msg));
+ return ret;
+}
+
+/*
+ * Probe for version on `fd'. Fail if != version
+ */
+
+void
+xfs_probe_version (int fd, int version)
+{
+ int ret = xfs_send_message_version (fd);
+
+ if (ret != version)
+ arla_errx (1, ADEBERROR,
+ "Wrong version of xfs. Please {up,down}grade to %d",
+ version);
+}
+
+/*
+ * Send `num' `fids' to xfs on `fd' as proposed gc-able fids
+ * If `num' is 0 xfs should gc everything gc:able.
+ */
+
+/* XXX VenusFid is wrong here */
+
+void
+xfs_send_message_gc_nodes (int fd, int num, VenusFid *fids)
+{
+ struct xfs_message_gc_nodes msg;
+ int i;
+
+ arla_warnx (ADEBMSG,
+ "xfs_send_message_gc_nodes sending gc: num = %d", num);
+
+ if (num > XFS_GC_NODES_MAX_HANDLE)
+ num = XFS_GC_NODES_MAX_HANDLE;
+
+ msg.header.opcode = XFS_MSG_GC_NODES;
+ msg.len = num;
+
+ for (i = 0; i < num; i++)
+ memcpy (&msg.handle[i], &fids[i], sizeof(*fids));
+
+ xfs_message_send (fd, (struct xfs_message_header *)&msg,
+ sizeof(msg));
+}
+
+/*
+ * Init the xfs message passing things.
+ */
+
+void
+xfs_message_init (void)
+{
+ unsigned i;
+
+ seqnums = (u_int *)malloc (sizeof (*seqnums) * getdtablesize ());
+ if (seqnums == NULL)
+ arla_err (1, ADEBERROR, errno, "xfs_message_init: malloc");
+ for (i = 0; i < getdtablesize (); ++i)
+ seqnums[i] = 0;
+ sleepers = listnew ();
+ if (sleepers == NULL)
+ arla_err (1, ADEBERROR, errno, "xfs_message_init: listnew");
+
+ assert (sizeof(rcvfuncs_name) / sizeof(*rcvfuncs_name) == XFS_MSG_COUNT);
+}
+
+/*
+ * Go to entry in jump-table depending on entry.
+ */
+
+int
+xfs_message_receive (int fd, struct xfs_message_header *h, u_int size)
+{
+ unsigned opcode = h->opcode;
+
+ if (opcode >= XFS_MSG_COUNT || rcvfuncs[opcode] == NULL ) {
+ arla_warnx (ADEBMSG, "Bad message opcode = %u", opcode);
+ return -1;
+ }
+
+ ++recv_stat[opcode];
+
+ arla_warnx (ADEBMSG, "Rec message: opcode = %u (%s), size = %u",
+ opcode, rcvfuncs_name[opcode], h->size);
+
+ return (*rcvfuncs[opcode])(fd, h, size);
+}
+
+/*
+ * Send a message to the kernel module.
+ */
+
+int
+xfs_message_send (int fd, struct xfs_message_header *h, u_int size)
+{
+ unsigned opcode = h->opcode;
+ int ret;
+
+ h->size = size;
+ h->sequence_num = seqnums[fd]++;
+
+ if (opcode >= XFS_MSG_COUNT) {
+ arla_warnx (ADEBMSG, "Bad message opcode = %u", opcode);
+ return -1;
+ }
+
+ ++sent_stat[opcode];
+
+ arla_warnx (ADEBMSG, "Send message: opcode = %u (%s), size = %u",
+ opcode, rcvfuncs_name[opcode], h->size);
+
+ ret = kern_write (fd, h, size);
+ if (ret != size) {
+ arla_warn (ADEBMSG, errno, "xfs_message_send: write");
+ return errno;
+ } else
+ return 0;
+}
+
+/*
+ * This code can only wake up message of type `xfs_message_wakeup'
+ */
+
+int
+xfs_message_wakeup (int fd, struct xfs_message_wakeup *h, u_int size)
+{
+ Listitem *i, *next;
+ struct xfs_message_wakeup *w;
+
+ assert (sizeof(*w) >= size);
+
+ for (i = listhead (sleepers); i; i = next) {
+ next = listnext (sleepers, i);
+ w = (struct xfs_message_wakeup *)listdata(i);
+ if (w->header.sequence_num == h->sleepers_sequence_num) {
+ listdel (sleepers, i);
+ memcpy (w, h, size);
+ LWP_SignalProcess ((char *)w);
+ break;
+ }
+ }
+ if (i == NULL)
+ arla_warnx (ADEBWARN, "xfs_message_wakeup: no message to wakeup!");
+ return 0;
+}
+
+/*
+ * The middle and last part of the xfs_message_rpc.
+ */
+
+int
+xfs_message_sleep (u_int seqnum)
+{
+ struct xfs_message_wakeup h;
+
+ h.header.sequence_num = seqnum;
+
+ listaddtail (sleepers, &h);
+ LWP_WaitProcess ((char *)&h);
+ return h.error;
+}
+
+/*
+ * Wake up a sleeping kernel-thread that sleeps on `seqnum'
+ * and pass on `error' as an error the thread.
+ */
+
+int
+xfs_send_message_wakeup (int fd, u_int seqnum, int error)
+{
+ struct xfs_message_wakeup msg;
+
+ msg.header.opcode = XFS_MSG_WAKEUP;
+ msg.sleepers_sequence_num = seqnum;
+ msg.error = error;
+ arla_warnx (ADEBMSG, "sending wakeup: seq = %u, error = %d",
+ seqnum, error);
+ return xfs_message_send (fd, (struct xfs_message_header *)&msg,
+ sizeof(msg));
+}
+
+
+/*
+ * Wake-up a kernel-thread with `seqnum', and pass on `error'
+ * ad return value. Add also a data blob for gerneric use.
+ */
+
+int
+xfs_send_message_wakeup_data (int fd, u_int seqnum, int error,
+ void *data, int size)
+{
+ struct xfs_message_wakeup_data msg;
+
+ msg.header.opcode = XFS_MSG_WAKEUP_DATA;
+ msg.sleepers_sequence_num = seqnum;
+ msg.error = error;
+ arla_warnx (ADEBMSG,
+ "sending wakeup: seq = %u, error = %d", seqnum, error);
+
+ if (sizeof(msg) >= size && size != 0) {
+ memcpy(msg.msg, data, size);
+ }
+
+ msg.len = size;
+
+ return xfs_message_send (fd, (struct xfs_message_header *)&msg,
+ sizeof(msg));
+}
+
+/*
+ *
+ */
+
+struct write_buf {
+ unsigned char buf[MAX_XMSG_SIZE];
+ size_t len;
+};
+
+/*
+ * Return 1 it buf is full, 0 if it's not.
+ */
+
+static int
+add_new_msg (int fd,
+ struct xfs_message_header *h, size_t size,
+ struct write_buf *buf)
+{
+ /* align on 8 byte boundery */
+
+ if (size > sizeof (buf->buf) - buf->len)
+ return 1;
+
+ h->sequence_num = seqnums[fd]++;
+ h->size = (size + 8) & ~ 7;
+
+ assert (h->opcode >= 0 && h->opcode < XFS_MSG_COUNT);
+ ++sent_stat[h->opcode];
+
+ arla_warnx (ADEBMSG, "Multi-send: opcode = %u (%s), size = %u",
+ h->opcode, rcvfuncs_name[h->opcode], h->size);
+
+ memcpy (buf->buf + buf->len, h, size);
+ memset (buf->buf + buf->len + size, 0, h->size - size);
+ buf->len += h->size;
+ return 0;
+}
+
+/*
+ * Blast of a `buf' to `fd'.
+ */
+
+static int
+send_msg (int fd, struct write_buf *buf)
+{
+ int ret;
+
+ if (buf->len == 0)
+ return 0;
+
+ ret = kern_write (fd, buf->buf, buf->len);
+ if (ret != buf->len) {
+ arla_warn (ADEBMSG, errno,
+ "send_msg: write");
+ buf->len = 0;
+ return errno;
+ }
+ buf->len = 0;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+xfs_send_message_vmultiple (int fd,
+ va_list args)
+{
+ struct xfs_message_header *h;
+ struct write_buf *buf;
+ size_t size;
+ int ret;
+
+ buf = malloc (sizeof (*buf));
+ if (buf == NULL)
+ return ENOMEM;
+
+ h = va_arg (args, struct xfs_message_header *);
+ size = va_arg (args, size_t);
+ buf->len = 0;
+ while (h != NULL) {
+ if (add_new_msg (fd, h, size, buf)) {
+ ret = send_msg (fd, buf);
+ if (ret) {
+ free (buf);
+ return ret;
+ }
+ if (add_new_msg (fd, h, size, buf))
+ arla_warnx (ADEBERROR,
+ "xfs_send_message_vmultiple: "
+ "add_new_msg failed");
+ }
+
+ h = va_arg (args, struct xfs_message_header *);
+ size = va_arg (args, size_t);
+ }
+ ret = send_msg (fd, buf);
+ free (buf);
+ return ret;
+}
+
+/*
+ * Same as above but diffrent.
+ */
+
+int
+xfs_send_message_multiple (int fd,
+ ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, fd);
+ ret = xfs_send_message_vmultiple (fd, args);
+ va_end (args);
+ return ret;
+}
+
+/*
+ * Almost same as above but diffrent.
+ */
+
+int
+xfs_send_message_multiple_list (int fd,
+ struct xfs_message_header *h,
+ size_t size,
+ u_int num)
+{
+ struct write_buf *buf;
+ int ret = 0;
+
+ buf = malloc (sizeof (*buf));
+ if (buf == NULL)
+ return ENOMEM;
+ buf->len = 0;
+ while (num && ret == 0) {
+ if (add_new_msg (fd, h, size, buf)) {
+ ret = send_msg (fd, buf);
+ if (add_new_msg (fd, h, size, buf))
+ arla_warnx (ADEBERROR,
+ "xfs_send_message_multiple_list: "
+ "add_new_msg failed");
+ }
+ h = (struct xfs_message_header *) (((unsigned char *)h) + size);
+ num--;
+ }
+ if (ret) {
+ free (buf);
+ return ret;
+ }
+ ret = send_msg (fd, buf);
+ free (buf);
+ return ret;
+}
+
+/*
+ * Send multiple message to the kernel (for performace/simple resons)
+ */
+
+int
+xfs_send_message_wakeup_vmultiple (int fd,
+ u_int seqnum,
+ int error,
+ va_list args)
+{
+ struct xfs_message_wakeup msg;
+ int ret;
+
+ ret = xfs_send_message_vmultiple (fd, args);
+ if (ret)
+ arla_warnx (ADEBERROR, "xfs_send_message_wakeup_vmultiple: "
+ "failed sending messages with error %d", ret);
+
+ msg.header.opcode = XFS_MSG_WAKEUP;
+ msg.header.size = sizeof(msg);
+ msg.header.sequence_num = seqnums[fd]++;
+ msg.sleepers_sequence_num = seqnum;
+ msg.error = error;
+
+ ++sent_stat[XFS_MSG_WAKEUP];
+
+ arla_warnx (ADEBMSG, "multi-sending wakeup: seq = %u, error = %d",
+ seqnum, error);
+
+ ret = kern_write (fd, &msg, sizeof(msg));
+ if (ret != sizeof(msg)) {
+ arla_warn (ADEBMSG, errno,
+ "xfs_send_message_wakeup_vmultiple: writev");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Same as above but diffrent.
+ */
+
+int
+xfs_send_message_wakeup_multiple (int fd,
+ u_int seqnum,
+ int error,
+ ...)
+{
+ va_list args;
+ int ret;
+
+ va_start (args, error);
+ ret = xfs_send_message_wakeup_vmultiple (fd, seqnum, error, args);
+ va_end (args);
+ return ret;
+}
diff --git a/usr.sbin/afs/src/arlad/xfs.h b/usr.sbin/afs/src/arlad/xfs.h
new file mode 100644
index 00000000000..0e0f685ba25
--- /dev/null
+++ b/usr.sbin/afs/src/arlad/xfs.h
@@ -0,0 +1,74 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: xfs.h,v 1.1 2000/09/11 14:40:44 art Exp $
+ */
+
+#ifndef __XFS_H_V
+#define __XFS_H_V 1
+
+void xfs_probe_version (int fd, int version);
+
+void xfs_message_init (void);
+int xfs_message_receive (int fd, struct xfs_message_header *h, u_int size);
+int xfs_message_receive (int fd, struct xfs_message_header *h, u_int size);
+void xfs_send_message_gc_nodes (int fd, int num, VenusFid *fids);
+int xfs_message_wakeup (int fd, struct xfs_message_wakeup *h, u_int size);
+int xfs_message_sleep (u_int seqnum);
+int xfs_send_message_wakeup (int fd, u_int seqnum, int error);
+int xfs_send_message_wakeup_vmultiple (int fd, u_int seqnum,
+ int error, va_list args);
+int xfs_send_message_wakeup_multiple (int fd, u_int seqnum,
+ int error, ...);
+int xfs_send_message_wakeup_data (int fd, u_int seqnum, int error,
+ void *data, int size);
+int xfs_send_message_multiple_list (int fd, struct xfs_message_header *h,
+ size_t size, u_int num);
+int xfs_send_message_multiple (int fd, ...);
+int xfs_send_message_vmultiple (int fd, va_list args);
+
+int xfs_message_send (int fd, struct xfs_message_header *h, u_int size);
+int xfs_message_rpc (int fd, struct xfs_message_header *h, u_int size);
+
+typedef int
+(*xfs_message_function) (int, struct xfs_message_header*, u_int);
+
+extern xfs_message_function rcvfuncs[XFS_MSG_COUNT];
+
+#endif /* __XFS_H_V */
diff --git a/usr.sbin/afs/src/cf/auth-modules.m4 b/usr.sbin/afs/src/cf/auth-modules.m4
new file mode 100644
index 00000000000..59f746e6d78
--- /dev/null
+++ b/usr.sbin/afs/src/cf/auth-modules.m4
@@ -0,0 +1,27 @@
+dnl $Id: auth-modules.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+dnl Figure what authentication modules should be built
+
+AC_DEFUN(AC_AUTH_MODULES,[
+AC_MSG_CHECKING(which authentication modules should be built)
+
+LIB_AUTH_SUBDIRS=
+
+if test "$ac_cv_header_siad_h" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS sia"
+fi
+
+if test "$ac_cv_header_security_pam_modules_h" = yes -a "$enable_shared" = yes; then
+ LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS pam"
+fi
+
+case "${host}" in
+changequote(,)dnl
+*-*-irix[56]*) LIB_AUTH_SUBDIRS="$LIB_AUTH_SUBDIRS afskauthlib" ;;
+changequote([,])dnl
+esac
+
+AC_MSG_RESULT($LIB_AUTH_SUBDIRS)
+
+AC_SUBST(LIB_AUTH_SUBDIRS)dnl
+])
diff --git a/usr.sbin/afs/src/cf/broken-glob.m4 b/usr.sbin/afs/src/cf/broken-glob.m4
new file mode 100644
index 00000000000..d158e0d5925
--- /dev/null
+++ b/usr.sbin/afs/src/cf/broken-glob.m4
@@ -0,0 +1,22 @@
+dnl $Id: broken-glob.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+dnl check for glob(3)
+dnl
+AC_DEFUN(AC_BROKEN_GLOB,[
+AC_CACHE_CHECK(for working glob, ac_cv_func_glob_working,
+ac_cv_func_glob_working=yes
+AC_TRY_LINK([
+#include <stdio.h>
+#include <glob.h>],[
+glob(NULL, GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE, NULL, NULL);
+],:,ac_cv_func_glob_working=no,:))
+
+if test "$ac_cv_func_glob_working" = yes; then
+ AC_DEFINE(HAVE_GLOB, 1, [define if you have a glob() that groks
+ GLOB_BRACE, GLOB_NOCHECK, GLOB_QUOTE, and GLOB_TILDE])
+fi
+if test "$ac_cv_func_glob_working" = yes; then
+AC_NEED_PROTO([#include <stdio.h>
+#include <glob.h>],glob)
+fi
+])
diff --git a/usr.sbin/afs/src/cf/broken-snprintf.m4 b/usr.sbin/afs/src/cf/broken-snprintf.m4
new file mode 100644
index 00000000000..3b31ffa8a19
--- /dev/null
+++ b/usr.sbin/afs/src/cf/broken-snprintf.m4
@@ -0,0 +1,58 @@
+dnl $Id: broken-snprintf.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+AC_DEFUN(AC_BROKEN_SNPRINTF, [
+AC_CACHE_CHECK(for working snprintf,ac_cv_func_snprintf_working,
+ac_cv_func_snprintf_working=yes
+AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+int main()
+{
+changequote(`,')dnl
+ char foo[3];
+changequote([,])dnl
+ snprintf(foo, 2, "12");
+ return strcmp(foo, "1");
+}],:,ac_cv_func_snprintf_working=no,:))
+
+if test "$ac_cv_func_snprintf_working" = yes; then
+ AC_DEFINE(HAVE_SNPRINTF, 1, [define if you have a working snprintf])
+fi
+if test "$ac_cv_func_snprintf_working" = yes; then
+ AC_NEED_PROTO([#include <stdio.h>],snprintf)
+fi
+])
+
+AC_DEFUN(AC_BROKEN_VSNPRINTF,[
+AC_CACHE_CHECK(for working vsnprintf,ac_cv_func_vsnprintf_working,
+ac_cv_func_vsnprintf_working=yes
+AC_TRY_RUN([
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+int foo(int num, ...)
+{
+changequote(`,')dnl
+ char bar[3];
+changequote([,])dnl
+ va_list arg;
+ va_start(arg, num);
+ vsnprintf(bar, 2, "%s", arg);
+ va_end(arg);
+ return strcmp(bar, "1");
+}
+
+
+int main()
+{
+ return foo(0, "12");
+}],:,ac_cv_func_vsnprintf_working=no,:))
+
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+ AC_DEFINE(HAVE_VSNPRINTF, 1, [define if you have a working vsnprintf])
+fi
+if test "$ac_cv_func_vsnprintf_working" = yes; then
+ AC_NEED_PROTO([#include <stdio.h>],vsnprintf)
+fi
+])
diff --git a/usr.sbin/afs/src/cf/broken.m4 b/usr.sbin/afs/src/cf/broken.m4
new file mode 100644
index 00000000000..74a3f351edd
--- /dev/null
+++ b/usr.sbin/afs/src/cf/broken.m4
@@ -0,0 +1,19 @@
+dnl $Id: broken.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+dnl
+dnl Same as AC _REPLACE_FUNCS, just define HAVE_func if found in normal
+dnl libraries
+
+AC_DEFUN(AC_BROKEN,
+[for ac_func in $1
+do
+AC_CHECK_FUNC($ac_func, [
+ac_tr_func=HAVE_[]upcase($ac_func)
+AC_DEFINE_UNQUOTED($ac_tr_func)],[LIBOBJS[]="$LIBOBJS ${ac_func}.o"])
+dnl autoheader tricks *sigh*
+: << END
+@@@funcs="$funcs $1"@@@
+END
+done
+AC_SUBST(LIBOBJS)dnl
+])
diff --git a/usr.sbin/afs/src/cf/bsd-func-lockmgr.m4 b/usr.sbin/afs/src/cf/bsd-func-lockmgr.m4
new file mode 100644
index 00000000000..f9064df82c1
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-func-lockmgr.m4
@@ -0,0 +1,24 @@
+dnl
+dnl $Id: bsd-func-lockmgr.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_LOCKMGR, [
+AC_CACHE_CHECK(if lockmgr takes four arguments,
+ac_cv_func_lockmgr_four_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+], [lockmgr(NULL, 0, NULL, NULL)],
+ac_cv_func_lockmgr_four_args=yes,
+ac_cv_func_lockmgr_four_args=no))
+if test "$ac_cv_func_lockmgr_four_args" = yes; then
+ AC_DEFINE(HAVE_FOUR_ARGUMENT_LOCKMGR, 1,
+ [define if lockmgr takes four arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-func-lockstatus.m4 b/usr.sbin/afs/src/cf/bsd-func-lockstatus.m4
new file mode 100644
index 00000000000..78bcb9f7a1c
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-func-lockstatus.m4
@@ -0,0 +1,49 @@
+dnl
+dnl $Id: bsd-func-lockstatus.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_LOCKSTATUS, [
+AC_CHECK_KERNEL_FUNCS(lockstatus)
+if test "$ac_cv_kernel_func_lockstatus" = "yes"; then
+AC_CACHE_CHECK(if lockstatus takes two arguments,
+ac_cv_func_lockstatus_two_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+], [lockstatus(NULL, NULL)],
+ac_cv_func_lockstatus_two_args=yes,
+ac_cv_func_lockstatus_two_args=no))
+if test "$ac_cv_func_lockstatus_two_args" = yes; then
+ AC_DEFINE(HAVE_TWO_ARGUMENT_LOCKSTATUS, 1,
+ [define if lockstatus takes two arguments])
+fi
+
+AC_CACHE_CHECK(if lockstatus takes one argument,
+ac_cv_func_lockstatus_one_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+], [lockstatus(NULL)],
+ac_cv_func_lockstatus_one_args=yes,
+ac_cv_func_lockstatus_one_args=no))
+if test "$ac_cv_func_lockstatus_one_args" = yes; then
+ AC_DEFINE(HAVE_ONE_ARGUMENT_LOCKSTATUS, 1,
+ [define if lockstatus takes one argument])
+fi
+
+if test "$ac_cv_func_lockstatus_two_args" = "no" -a "$ac_cv_func_lockstatus_one_args" = "no"; then
+ AC_MSG_ERROR([unable to figure out how many args lockstatus takes])
+fi
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-func-suser.m4 b/usr.sbin/afs/src/cf/bsd-func-suser.m4
new file mode 100644
index 00000000000..c55e73b157c
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-func-suser.m4
@@ -0,0 +1,23 @@
+dnl
+dnl $Id: bsd-func-suser.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_SUSER, [
+AC_CACHE_CHECK(if suser takes two arguments,
+ac_cv_func_suser_two_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+], [suser(NULL, NULL)],
+ac_cv_func_suser_two_args=yes,
+ac_cv_func_suser_two_args=no))
+if test "$ac_cv_func_suser_two_args" = yes; then
+ AC_DEFINE(HAVE_TWO_ARGUMENT_SUSER, 1,
+ [define if suser takes two arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-func-vfs-getnewfsid.m4 b/usr.sbin/afs/src/cf/bsd-func-vfs-getnewfsid.m4
new file mode 100644
index 00000000000..f47531501c9
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-func-vfs-getnewfsid.m4
@@ -0,0 +1,27 @@
+dnl
+dnl $Id: bsd-func-vfs-getnewfsid.m4,v 1.1 2000/09/11 14:40:44 art Exp $
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_VFS_GETNEWFSID, [
+AC_CHECK_KERNEL_FUNCS(vfs_getnewfsid)
+if test "$ac_cv_kernel_func_vfs_getnewfsid" = "yes"; then
+AC_CACHE_CHECK(if vfs_getnewfsid takes two arguments,
+ac_cv_func_vfs_getnewfsid_two_args,
+AC_TRY_COMPILE_KERNEL([
+#include <sys/types.h>
+#include <sys/param.h>
+#ifdef HAVE_SYS_MODULE_H
+#include <sys/module.h>
+#endif
+#include <sys/mount.h>
+#include <sys/vnode.h>
+],
+[vfs_getnewfsid(NULL, 0);],
+ac_cv_func_vfs_getnewfsid_two_args=yes,
+ac_cv_func_vfs_getnewfsid_two_args=no))
+if test "$ac_cv_func_vfs_getnewfsid_two_args" = yes; then
+ AC_DEFINE(HAVE_TWO_ARGUMENT_VFS_GETNEWFSID, 1,
+ [define if vfs_getnewfsid takes two arguments])
+fi
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-header-vnode-if-h.m4 b/usr.sbin/afs/src/cf/bsd-header-vnode-if-h.m4
new file mode 100644
index 00000000000..03279217378
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-header-vnode-if-h.m4
@@ -0,0 +1,41 @@
+dnl
+dnl $Id: bsd-header-vnode-if-h.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+AC_DEFUN(AC_BSD_HEADER_VNODE_IF_H, [
+AC_MSG_CHECKING(if vnode_if.h needs to be built)
+changequote(, )dnl
+rm -f vnode_if.[ch]
+changequote([,])dnl
+AC_TRY_CPP_KERNEL([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/vnode.h>
+], ac_cv_header_vnode_if_h=no,
+ac_cv_header_vnode_if_h=yes)
+dnl
+if test "$ac_cv_header_vnode_if_h" = "yes"; then
+test -d ../sys || mkdir ../sys
+if test -f $SYS/kern/vnode_if.pl; then
+ perl $SYS/kern/vnode_if.pl -h $SYS/kern/vnode_if.src
+elif test -f $SYS/kern/vnode_if.sh; then
+ /bin/sh $SYS/kern/vnode_if.sh $SYS/kern/vnode_if.src
+else
+ AC_MSG_ERROR(unable to find any vnode_if script)
+fi
+if test -f vnode_if.h; then
+ :
+else
+ AC_MSG_ERROR(failed to create vnode_if.h)
+fi
+AC_TRY_CPP_KERNEL([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/vnode.h>
+], ac_cv_header_vnode_if_h=yes; VNODE_IF_H=vnode_if.h,
+AC_MSG_ERROR(tried creating vnode_if.h but still could not include vnode.h))
+fi
+AC_MSG_RESULT($ac_cv_header_vnode_if_h)
+AC_SUBST(VNODE_IF_H)])
diff --git a/usr.sbin/afs/src/cf/bsd-vfs-busy.m4 b/usr.sbin/afs/src/cf/bsd-vfs-busy.m4
new file mode 100644
index 00000000000..15ef052ec3b
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-vfs-busy.m4
@@ -0,0 +1,47 @@
+dnl
+dnl $Id: bsd-vfs-busy.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+dnl
+dnl try to find out if vfs_busy takes three/four arguments
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_VFS_BUSY,[
+AC_CACHE_CHECK(if vfs_busy takes three arguments, ac_cv_func_vfs_busy_three_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#ifdef HAVE_SYS_MODULE_H
+#include <sys/module.h>
+#endif
+#include <sys/mount.h>],[vfs_busy(0, 0, 0)],
+ac_cv_func_vfs_busy_three_args=yes,
+ac_cv_func_vfs_busy_three_args=no))
+if test "$ac_cv_func_vfs_busy_three_args" = yes; then
+ AC_DEFINE(HAVE_THREE_ARGUMENT_VFS_BUSY, 1,
+ [define if vfs_busy takes three arguments])
+fi
+
+AC_CACHE_CHECK(if vfs_busy takes four arguments, ac_cv_func_vfs_busy_four_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#ifdef HAVE_SYS_MODULE_H
+#include <sys/module.h>
+#endif
+#include <sys/mount.h>],[vfs_busy(0, 0, 0, 0)],
+ac_cv_func_vfs_busy_four_args=yes,
+ac_cv_func_vfs_busy_four_args=no))
+if test "$ac_cv_func_vfs_busy_four_args" = yes; then
+ AC_DEFINE(HAVE_FOUR_ARGUMENT_VFS_BUSY, 1,
+ [define if vfs_busy takes four arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-vfs-object-create.m4 b/usr.sbin/afs/src/cf/bsd-vfs-object-create.m4
new file mode 100644
index 00000000000..8b338060047
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-vfs-object-create.m4
@@ -0,0 +1,28 @@
+dnl
+dnl $Id: bsd-vfs-object-create.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+dnl
+dnl check for number of arguments to vfs_object_create
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_VFS_OBJECT_CREATE, [
+AC_CHECK_KERNEL_FUNCS(vfs_object_create)
+if test "$ac_cv_kernel_func_vfs_object_create" = "yes"; then
+AC_CACHE_CHECK(if vfs_object_create takes four arguments,
+ac_cv_func_vfs_object_create_four_args,
+AC_TRY_COMPILE_KERNEL([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/vnode.h>
+],
+[vfs_object_create(0, 0, 0, 0);],
+ac_cv_func_vfs_object_create_four_args=yes,
+ac_cv_func_vfs_object_create_four_args=no))
+if test "$ac_cv_func_vfs_object_create_four_args" = "yes"; then
+ ac_foo=
+ AC_DEFINE(HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE, 1,
+ [if vfs_object_create takes four arguments])
+fi
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-vget.m4 b/usr.sbin/afs/src/cf/bsd-vget.m4
new file mode 100644
index 00000000000..f6f40a6a0eb
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-vget.m4
@@ -0,0 +1,66 @@
+dnl
+dnl $Id: bsd-vget.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_VGET, [
+AC_CACHE_CHECK(if vget takes one argument, ac_cv_func_vget_one_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if defined(__osf__) && defined(__GNUC__)
+#define asm __foo_asm
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+],[vget(0)],
+ac_cv_func_vget_one_args=yes,
+ac_cv_func_vget_one_args=no))
+if test "$ac_cv_func_vget_one_args" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_ONE_ARGUMENT_VGET, 1,
+ [define if vget takes one argument])
+fi
+
+AC_CACHE_CHECK(if vget takes two arguments, ac_cv_func_vget_two_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+],[vget(0, 0)],
+ac_cv_func_vget_two_args=yes,
+ac_cv_func_vget_two_args=no))
+if test "$ac_cv_func_vget_two_args" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_TWO_ARGUMENT_VGET, 1,
+ [define if vget takes two arguments])
+fi
+
+AC_CACHE_CHECK(if vget takes three arguments, ac_cv_func_vget_three_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+],[vget(0, 0, 0)],
+ac_cv_func_vget_three_args=yes,
+ac_cv_func_vget_three_args=no))
+if test "$ac_cv_func_vget_three_args" = yes; then
+ AC_DEFINE(HAVE_THREE_ARGUMENT_VGET, 1,
+ [define if vget takes three arguments])
+fi
+
+if test "$ac_cv_func_vget_one_args" = "no" -a "$ac_cv_func_vget_two_args" = "no" -a "$ac_cv_func_vget_three_args" = "no"; then
+ AC_MSG_ERROR([test for number of arguments of vget failed])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/bsd-vop-lock.m4 b/usr.sbin/afs/src/cf/bsd-vop-lock.m4
new file mode 100644
index 00000000000..31155761d32
--- /dev/null
+++ b/usr.sbin/afs/src/cf/bsd-vop-lock.m4
@@ -0,0 +1,63 @@
+dnl
+dnl $Id: bsd-vop-lock.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+dnl
+dnl Find out if VOP_LOCK takes one, two, or three arguments
+dnl
+
+AC_DEFUN(AC_BSD_FUNC_VOP_LOCK, [
+AC_CACHE_CHECK(if VOP_LOCK takes one argument, ac_cv_func_vop_lock_one_arg,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+],[VOP_LOCK(0)],
+ac_cv_func_vop_lock_one_arg=yes,
+ac_cv_func_vop_lock_one_arg=no))
+if test "$ac_cv_func_vop_lock_one_arg" = yes; then
+ AC_DEFINE_UNQUOTED(HAVE_ONE_ARGUMENT_VOP_LOCK, 1,
+ [define if VOP_LOCK takes one argument])
+fi
+
+AC_CACHE_CHECK(if VOP_LOCK takes two arguments, ac_cv_func_vop_lock_two_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+],[VOP_LOCK(0, 0)],
+ac_cv_func_vop_lock_two_args=yes,
+ac_cv_func_vop_lock_two_args=no))
+if test "$ac_cv_func_vop_lock_two_args" = yes; then
+ AC_DEFINE(HAVE_TWO_ARGUMENT_VOP_LOCK, 1,
+ [define if VOP_LOCK takes two arguments])
+fi
+
+AC_CACHE_CHECK(if VOP_LOCK takes three arguments, ac_cv_func_vop_lock_three_args,
+AC_TRY_COMPILE_KERNEL([
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/vnode.h>
+],[VOP_LOCK(0, 0, 0)],
+ac_cv_func_vop_lock_three_args=yes,
+ac_cv_func_vop_lock_three_args=no))
+if test "$ac_cv_func_vop_lock_three_args" = yes; then
+ AC_DEFINE(HAVE_THREE_ARGUMENT_VOP_LOCK, 1,
+ [define if VOP_LOCK takes three arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/c-attribute.m4 b/usr.sbin/afs/src/cf/c-attribute.m4
new file mode 100644
index 00000000000..39d5b3a1f00
--- /dev/null
+++ b/usr.sbin/afs/src/cf/c-attribute.m4
@@ -0,0 +1,39 @@
+dnl
+dnl $Id: c-attribute.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN(AC_C___ATTRIBUTE__, [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+
+/* Check for old gcc */
+static void __attribute__ ((unused))
+bar(void)
+{
+ exit (1);
+}
+
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+ AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
diff --git a/usr.sbin/afs/src/cf/c-function.m4 b/usr.sbin/afs/src/cf/c-function.m4
new file mode 100644
index 00000000000..50660b16f5b
--- /dev/null
+++ b/usr.sbin/afs/src/cf/c-function.m4
@@ -0,0 +1,33 @@
+dnl
+dnl $Id: c-function.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+dnl
+dnl Test for __FUNCTION__
+dnl
+
+AC_DEFUN(AC_C___FUNCTION__, [
+AC_MSG_CHECKING(for __FUNCTION__)
+AC_CACHE_VAL(ac_cv___function__, [
+AC_TRY_RUN([
+#include <string.h>
+
+static char *foo()
+{
+ return __FUNCTION__;
+}
+
+int main()
+{
+ return strcmp(foo(), "foo") != 0;
+}
+],
+ac_cv___function__=yes,
+ac_cv___function__=no,
+ac_cv___function__=no)])
+if test "$ac_cv___function__" = "yes"; then
+ AC_DEFINE(HAVE___FUNCTION__, 1, [define if your compiler has __FUNCTION__])
+fi
+AC_MSG_RESULT($ac_cv___function__)
+])
+
diff --git a/usr.sbin/afs/src/cf/check-declaration.m4 b/usr.sbin/afs/src/cf/check-declaration.m4
new file mode 100644
index 00000000000..e6203a8e181
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-declaration.m4
@@ -0,0 +1,25 @@
+dnl $Id: check-declaration.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+dnl
+dnl Check if we need the declaration of a variable
+dnl
+
+dnl AC_CHECK_DECLARATION(includes, variable)
+AC_DEFUN(AC_CHECK_DECLARATION, [
+AC_MSG_CHECKING([if $2 is properly declared])
+AC_CACHE_VAL(ac_cv_var_$2_declaration, [
+AC_TRY_COMPILE([$1
+extern struct { int foo; } $2;],
+[$2.foo = 1;],
+eval "ac_cv_var_$2_declaration=no",
+eval "ac_cv_var_$2_declaration=yes")
+])
+
+define(foo, [HAVE_]translit($2, [a-z], [A-Z])[_DECLARATION])
+
+AC_MSG_RESULT($ac_cv_var_$2_declaration)
+if eval "test \"\$ac_cv_var_$2_declaration\" = yes"; then
+ AC_DEFINE(foo, 1, [define if your system declares $2])
+fi
+undefine([foo])
+])
diff --git a/usr.sbin/afs/src/cf/check-dirsiz.m4 b/usr.sbin/afs/src/cf/check-dirsiz.m4
new file mode 100644
index 00000000000..0589a6244e5
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-dirsiz.m4
@@ -0,0 +1,45 @@
+dnl
+dnl $Id: check-dirsiz.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+
+dnl
+dnl Check where DIRSIZ lives
+dnl
+
+AC_DEFUN(AC_CHECK_DIRSIZ, [
+
+AC_CACHE_CHECK([if DIRSIZ lives in dirent.h], ac_cv_dirsiz_in_dirent,
+AC_EGREP_CPP(yes,[#include <dirent.h>
+#ifdef DIRSIZE
+yes
+#endif],
+eval "ac_cv_dirsiz_in_dirent=yes",
+eval "ac_cv_dirsiz_in_dirent=no"))
+if test "$ac_cv_dirsiz_in_dirent" = "yes"; then
+ AC_DEFINE(DIRSIZ_IN_DIRENT_H, 1, [define if DIRSIZ is defined in dirent.h])
+fi
+
+AC_CACHE_CHECK([if DIRSIZ lives in sys/dir.h], ac_cv_dirsiz_in_sys_dir,
+AC_EGREP_CPP(yes,[#include <sys/dir.h>
+#ifdef DIRSIZ
+yes
+#endif],
+eval "ac_cv_dirsiz_in_sys_dir=yes",
+eval "ac_cv_dirsiz_in_sys_dir=no"))
+if test "$ac_cv_dirsiz_in_sys_dir" = "yes"; then
+ AC_DEFINE(DIRSIZ_IN_SYS_DIR_H, 1, [define if DIRSIZ is defined in sys/dir.h])
+fi
+
+AC_CACHE_CHECK([if _GENERIC_DIRSIZ lives in sys/dirent.h],
+ac_cv_generic_dirsiz_in_sys_dirent,
+AC_EGREP_CPP(yes,[#include <sys/dirent.h>
+#ifdef _GENERIC_DIRSIZ
+yes
+#endif],
+eval "ac_cv_generic_dirsiz_in_sys_dirent=yes",
+eval "ac_cv_generic_dirsiz_in_sys_dirent=no"))
+if test "$ac_cv_generic_dirsiz_in_sys_dirent" = "yes"; then
+ AC_DEFINE(GENERIC_DIRSIZ_IN_SYS_DIRENT_H, 1,
+ [define if DIRSIZ is defined in sys/dirent.h])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/check-getpwnam_r-posix.m4 b/usr.sbin/afs/src/cf/check-getpwnam_r-posix.m4
new file mode 100644
index 00000000000..cc70e9549bc
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-getpwnam_r-posix.m4
@@ -0,0 +1,24 @@
+dnl $Id: check-getpwnam_r-posix.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+dnl check for getpwnam_r, and if it's posix or not
+
+AC_DEFUN(AC_CHECK_GETPWNAM_R_POSIX,[
+AC_FIND_FUNC_NO_LIBS(getpwnam_r,c_r)
+if test "$ac_cv_func_getpwnam_r" = yes; then
+ AC_CACHE_CHECK(if getpwnam_r is posix,ac_cv_func_getpwnam_r_posix,
+ ac_libs="$LIBS"
+ LIBS="$LIBS $LIB_getpwnam_r"
+ AC_TRY_RUN([
+#include <pwd.h>
+int main()
+{
+ struct passwd pw, *pwd;
+ return getpwnam_r("", &pw, NULL, 0, &pwd) < 0;
+}
+],ac_cv_func_getpwnam_r_posix=yes,ac_cv_func_getpwnam_r_posix=no,:)
+LIBS="$ac_libs")
+if test "$ac_cv_func_getpwnam_r_posix" = yes; then
+ AC_DEFINE(POSIX_GETPWNAM_R, 1, [Define if getpwnam_r has POSIX flavour.])
+fi
+fi
+]) \ No newline at end of file
diff --git a/usr.sbin/afs/src/cf/check-glibc.m4 b/usr.sbin/afs/src/cf/check-glibc.m4
new file mode 100644
index 00000000000..5a825b2a499
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-glibc.m4
@@ -0,0 +1,22 @@
+dnl
+dnl $Id: check-glibc.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+dnl
+dnl test for GNU libc
+dnl
+
+AC_DEFUN(AC_CHECK_GLIBC,[
+AC_CACHE_CHECK([for glibc],ac_cv_libc_glibc,[
+AC_EGREP_CPP(yes,
+[#include <features.h>
+#ifdef __GLIBC__
+yes
+#endif
+],
+eval "ac_cv_libc_glibc=yes",
+eval "ac_cv_libc_glibc=no")])
+if test "$ac_cv_libc_glibc" = "yes";then
+ AC_DEFINE(HAVE_GLIBC, 1,
+ [define if you have a glibc-based system])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/check-kafs.m4 b/usr.sbin/afs/src/cf/check-kafs.m4
new file mode 100644
index 00000000000..5f5871e6f7d
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kafs.m4
@@ -0,0 +1,47 @@
+dnl
+dnl $Id: check-kafs.m4,v 1.1 2000/09/11 14:40:45 art Exp $
+dnl
+dnl check for libkafs/krbafs
+dnl
+
+AC_DEFUN(AC_CHECK_KAFS,[
+
+AC_ARG_WITH(krbafs,
+[ --with-krbafs=dir use libkrbafs (from cmu, extracted from kth-krb) in dir],
+
+[if test "$with_krbafs" = "yes"; then
+ AC_MSG_ERROR([You have to give the path to krbafs lib])
+elif test "$with_krbafs" = "no"; then
+ ac_cv_funclib_k_hasafs=no
+else
+ KAFS_LIBS_FLAGS="-L${with_krbafs}/lib"
+fi])
+
+AC_CACHE_CHECK([for libkafs/libkrbafs],
+[ac_cv_funclib_k_hasafs],[
+
+saved_LIBS="$LIBS"
+
+for a in "$KRB4_LIB_FLAGS" \
+ "$KRB5_LIB_FLAGS" \
+ "$KRB5_LIB_FLAGS $KRB4_LIB_FLAGS" ; do
+ for b in "kafs" "krbafs"; do
+ LIBS="$saved_LIBS ${KAFS_LIBS_FLAGS} $a -l$b"
+ AC_TRY_LINK([],
+ [k_hasafs();],
+ [ac_cv_funclib_k_hasafs=yes
+ ac_cv_libkafs_flags="$KAFS_LIBS_FLAGS $a -l$b"
+ break 2],
+ [ac_cv_funclib_k_hasafs=no])
+ done
+done
+
+LIBS="$saved_LIBS"])
+
+if test "X$ac_cv_funclib_k_hasafs" != "Xno"; then
+ KAFS_LIBS="$ac_cv_libkafs_flags"
+fi
+
+AC_SUBST(KAFS_LIBS)dnl
+
+])dnl
diff --git a/usr.sbin/afs/src/cf/check-kerberos.m4 b/usr.sbin/afs/src/cf/check-kerberos.m4
new file mode 100644
index 00000000000..fe343e6928e
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kerberos.m4
@@ -0,0 +1,478 @@
+dnl
+dnl $Id: check-kerberos.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+dnl Check if the dog is alive
+dnl
+dnl Arguments:
+dnl
+dnl AC_CHECK_KERBEROS(4):
+dnl check for krb4 libs and krb5 krb4 compat libs
+dnl AC_CHECK_KERBEROS(45):
+dnl check for krb4 libs and krb5 libs
+dnl AC_CHECK_KERBEROS(5):
+dnl check for krb5 libs
+dnl AC_CHECK_KERBEROS([45]auto):
+dnl check for kerberos without a --with-krbN
+dnl
+dnl Set:
+dnl ac_cv_found_krb4=[yes|no]
+dnl KRB4_{LIB|INC}_DIR
+dnl KRB4_{LIB,INC}_FLAGS
+dnl
+dnl ac_cv_found_krb5=[yes|no]
+dnl KRB5_{LIB|INC}_DIR
+dnl KRB5_{LIB,INC}_FLAGS
+dnl
+dnl
+dnl Check order
+dnl krb5
+dnl include testing of libk5crypto/libcrypto
+dnl krb4
+dnl krb5 compat if needed (included in krb4 test)
+dnl this is the reson krb5 is tested first
+dnl
+
+AC_DEFUN(AC_CHECK_KERBEROS,[
+
+dnl
+dnl Parse args for kerberos4
+dnl
+
+ifelse(-1,regexp($1,[[45]]),[
+ errprint(__file__:__line__: [CHECK_KERBEROS: have to give at lease 4 or 5
+])
+ m4exit(1)
+])
+
+ifelse(-1,regexp($1,4),[with_krb4=no],[ dnl WITHOUT KERBEROS4 (1)
+
+AC_ARG_WITH(krb4,
+[ --with-krb4=dir use kerberos 4 in dir],
+[if test "X$withval" = "X"; then
+ ifelse(-1,regexp($1,[auto]),[
+ AC_MSG_ERROR([You have to give a dir to --with-krb4])],
+ [:])
+fi],
+[ifelse(-1,regexp($1,auto),[with_krb4=no],[with_krb4=yes])])
+
+AC_ARG_WITH(krb4-lib,
+[ --with-krb4-lib=dir use kerberos 4 libraries in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-krb4-lib])
+fi])
+
+AC_ARG_WITH(krb4-include,
+[ --with-krb4-include=dir use kerberos 4 headers in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-krb4-include])
+fi])
+
+]) dnl WITHOUT KERBEROS4 (1)
+
+dnl
+dnl Parse args for kerberos5
+dnl
+
+AC_ARG_WITH(krb5,
+[ --with-krb5=dir use ]dnl
+ifelse(-1,regexp($1,5),[kerberos 4 compat from ])[kerberos 5 in dir],
+[
+if test "X$withval" = "X"; then
+ ifelse(-1,regexp($1,[auto]),[
+ AC_MSG_ERROR([You have to give a dir to --with-krb5])],
+ [:])
+ ifelse(-1,regexp($1,5),[
+ if test "X$with_krb4" != "Xno"; then
+ AC_MSG_ERROR([Already specified kerberos 4 with --with-krb4])
+ fi])
+elif test "$withval" = "no"; then
+ifelse(-1,regexp($1,4),[with_krb5=no],
+[if test "$with_krb4" = "yes"; then
+ with_krb5=compat
+else
+ with_krb5=no
+fi])
+fi
+],
+[ifelse(-1,regexp($1,auto),[with_krb5=compat],[with_krb5=yes])])
+
+AC_ARG_WITH(krb5-include,
+[ --with-krb5-include=dir use ]dnl
+ifelse(-1,regexp($1,5),[kerberos 4 compat from ])[kerberos 5 headers in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-krb5-include])
+fi
+ifelse(-1,regexp($1,5),[
+if test "X$with_krb4_include" != "X"; then
+ AC_MSG_ERROR([Already specified kerberos 4 headers with --with-krb4-include])
+fi])])
+
+AC_ARG_WITH(krb5-lib,
+[ --with-krb5-lib=dir use kerberos 5 libraries in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-krb5-lib])
+fi
+ifelse(-1,regexp($1,5),[
+if test "X$with_krb4_lib" != "X"; then
+ AC_MSG_ERROR([Already specified kerberos 4 libraries with --with-krb4-lib])
+fi])])
+
+
+dnl
+dnl Check for kerberos5
+dnl
+
+case X"$with_krb5" in
+ Xyes|Xno|Xcompat)
+ ;;
+ *)
+ ac_cv_krb5_where_lib="$with_krb5/lib"
+ ac_cv_krb5_where_inc="$with_krb5/include"
+ ac_cv_found_krb5=yes
+ ;;
+esac
+
+if test "X$with_krb5_include" != "X"; then
+ ac_cv_krb4_where_inc=$with_krb5_include
+ ac_cv_found_krb5=yes
+fi
+
+if test "X$with_krb5_lib" != "X"; then
+ ac_cv_krb5_where_lib=$with_krb5_lib
+ with_krb5=yes
+fi
+
+ifelse(-1,regexp($1,auto),[],[
+if test "$with_krb5" != "no"; then
+ if test "$ac_cv_krb5_where_lib" = ""; then
+ AC_KRB5_LIB_WHERE(["" /usr/heimdal/lib /usr/athena/lib /usr/kerberos/lib /usr/local/lib])
+ else
+ AC_KRB5_LIB_WHERE($ac_cv_krb5_where_lib)
+ fi
+fi
+])
+
+if test "X$with_krb5_include" != "X"; then
+ ac_cv_krb5_where_inc=$with_krb5_include
+ ac_cv_found_krb5=yes
+ with_krb5=yes
+fi
+
+ifelse(-1,regexp($1,auto),[],[ dnl KRB5-AUTO
+if test "$with_krb5" != "no"; then
+ if test "$ac_cv_krb5_where_inc" = ""; then
+ AC_KRB5_INC_WHERE(["" /usr/heimdal/include /usr/athena/include /usr/kerberos/include /usr/include/kerberosV /usr/include/kerberos /usr/include/krb5 /usr/local/include])
+ else
+ AC_KRB5_INC_WHERE($ac_cv_krb5_where_inc)
+ fi
+fi
+]) dnl KRB5-AUTO
+
+ifelse(-1,regexp($1,4),[],[ dnl WITHOUT KERBEROS4 (2)
+
+dnl
+dnl Check for kerberos4
+dnl
+
+if test "X$with_krb4" != "Xyes" -a "X$with_krb4" != "Xno"; then
+ ac_cv_krb4_where_lib=$with_krb4/lib
+ ac_cv_krb4_where_inc=$with_krb4/include
+ ac_cv_found_krb4=yes
+ ifelse(-1,regexp($1,5),[ac_cv_found_krb5=no])
+fi
+
+if test "X$with_krb4_lib" != "X"; then
+ ac_cv_krb4_where_lib=$with_krb4_lib
+ ac_cv_found_krb4=yes
+fi
+
+ifelse(-1,regexp($1,auto),[],[
+if test "$with_krb4" != "no"; then
+ if test "$ac_cv_krb4_where_lib" = ""; then
+ AC_KRB4_LIB_WHERE(["" /usr/athena/lib /usr/kerberos/lib /usr/lib /usr/local/lib])
+ else
+ AC_KRB4_LIB_WHERE($ac_cv_krb4_where_lib)
+ fi
+fi
+])
+
+if test "X$with_krb4_include" != "X"; then
+ ac_cv_krb4_where_inc=$with_krb4_include
+ ac_cv_found_krb4=yes
+fi
+
+ifelse(-1,regexp($1,auto),[],[
+if test "$with_krb4" != "no"; then
+ if test "$ac_cv_krb4_where_inc" = ""; then
+ AC_KRB4_INC_WHERE(["" /usr/include /usr/athena/include /usr/kerberos/include /usr/include/kerberos /usr/local/include])
+ else
+ AC_KRB4_INC_WHERE($ac_cv_krb4_where_inc)
+ fi
+fi
+])
+
+]) dnl WITHOUT KERBEROS4 (2)
+
+
+dnl
+dnl
+dnl
+
+ifelse(-1,regexp($1,5),[],[ dnl KRB5 VARS
+
+if test "X$ac_cv_found_krb5" = "Xyes"; then
+ KRB5_INC_DIR=$ac_cv_krb5_where_inc
+ KRB5_LIB_DIR=$ac_cv_krb5_where_lib
+ KRB5_INC_FLAGS=
+ if test "X$KRB5_INC_DIR" != "X" ; then
+ KRB5_INC_FLAGS="-I${KRB5_INC_DIR}"
+ fi
+ KRB5_LIB_FLAGS=
+ if test "X$KRB5_LIB_DIR" != "X" ; then
+ KRB5_LIB_FLAGS="-L${KRB5_LIB_DIR}"
+ fi
+ KRB5_LIB_FLAGS="$KRB5_LIB_FLAGS -lkrb5 -lcom_err $ac_cv_krb5_extralib"
+fi
+
+]) dnl KRB5 VARS
+
+ifelse(-1,regexp($1,4),[],[ dnl KRB4 VARS
+
+if test "X$ac_cv_found_krb4" = "Xyes"; then
+ KRB4_INC_DIR=$ac_cv_krb4_where_inc
+ KRB4_LIB_DIR=$ac_cv_krb4_where_lib
+ KRB4_INC_FLAGS=
+ if test "X$KRB4_INC_DIR" != "X" ; then
+ KRB4_INC_FLAGS="-I${KRB4_INC_DIR}"
+ fi
+ KRB4_LIB_FLAGS="$ac_cv_krb4_extralib"
+ if test "X$KRB4_LIB_DIR" != "X" ; then
+ KRB4_LIB_FLAGS="-L${KRB4_LIB_DIR} ${KRB4_LIB_FLAGS}"
+ fi
+
+fi
+
+]) dnl KRB4 VARS
+
+
+dnl
+dnl Export variables, but only we have want it
+dnl
+
+dnl KRB 5 - export
+
+if test "X$ac_cv_found_krb5" = "Xyes"; then
+ if test "X$ac_cv_found_krb4_lib" = "Xcompat"; then
+ ac_cv_found_krb4=yes
+ with_krb4=yes
+ ifelse(-1,regexp($1,5),[ dnl 5
+ ac_cv_found_krb5=no
+ ],[
+ AC_DEFINE(HAVE_KRB5_COMPAT_KRB4, 1,
+ [define if you have kerberos 4 compat])
+ ]) dnl END 5
+ fi
+ ifelse(-1,regexp($1,5),[],[
+ with_krb5=yes
+ AC_DEFINE(HAVE_KRB5, 1, [define if you have kerberos 5])
+ ])
+ AC_DEFINE(KERBEROS, 1, [define if you have kerberos])
+fi
+
+ifelse(-1,regexp($1,5),[],[
+AC_SUBST(KRB5_LIB_DIR)
+AC_SUBST(KRB5_INC_DIR)
+AC_SUBST(KRB5_INC_FLAGS)
+AC_SUBST(KRB5_LIB_FLAGS)]) dnl END KRB5 - export
+
+dnl KRB 4 - export
+
+ifelse(-1,regexp($1,4),[],[
+
+if test "$ac_cv_found_krb4" = "yes"; then
+ with_krb4=yes
+ AC_DEFINE(KERBEROS, 1, [define if you have kerberos])
+ AC_DEFINE(HAVE_KRB4, 1, [define if you have kerberos 4])
+fi
+
+AC_SUBST(KRB4_LIB_DIR)
+AC_SUBST(KRB4_INC_DIR)
+AC_SUBST(KRB4_INC_FLAGS)
+AC_SUBST(KRB4_LIB_FLAGS)]) dnl END KRB4 - export
+
+]) dnl END AC_CHECK_KERBEROS end of this short function
+
+dnl
+dnl KRB4 tests
+dnl
+
+AC_DEFUN(AC_KRB4_INC_WHERE1, [
+saved_CPPFLAGS="${CPPFLAGS}"
+if test -n "$1"; then
+ CPPFLAGS="$saved_CPPFLAGS -I$1"
+fi
+AC_TRY_COMPILE([#include <krb.h>],
+[struct ktext foo;],
+[ac_cv_found_krb4=yes
+ac_cv_found_krb4_inc=yes],
+ac_cv_found_krb4_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN(AC_KRB4_INC_WHERE, [
+ for i in $1; do
+ for j in "" kerberos "kerberosIV"; do
+ if test -n "$i"; then
+ if test -n "$j"; then
+ d="$i/$j"
+ else
+ d="$i"
+ fi
+ else
+ d="$j"
+ fi
+ AC_MSG_CHECKING(for kerberos4 headers in $d)
+ AC_KRB4_INC_WHERE1($d)
+ if test "$ac_cv_found_krb4_inc" = "yes"; then
+ ac_cv_krb4_where_inc=$d
+ AC_MSG_RESULT(found)
+ break 2
+ else
+ AC_MSG_RESULT(not found)
+ fi
+ done
+ done
+])
+
+dnl
+dnl
+dnl
+
+
+AC_DEFUN(AC_KRB4_LIB_WHERE1, [
+saved_LIBS=$LIBS
+for a in "-lkrb -ldes" dnl kth-krb && mit-krb
+ "-lkrb -ldes -lroken" dnl kth-krb in nbsd
+ "-lkrb -ldes -lroken -lcom_err" dnl kth-krb in nbsd for real
+ "-lkrb -ldes -lcom_err" dnl kth-krb in fbsd
+ "-lkrb -ldes -lcom_err -lcrypt" dnl CNS q96 à la SCS
+ ; do
+ LIBS="$saved_LIBS"
+ if test "X$1" != "X"; then
+ LIBS="$LIBS -L$1"
+ fi
+ LIBS="$LIBS $a"
+ AC_TRY_LINK([],
+ [dest_tkt();],
+ [ac_cv_found_krb4_lib=yes
+ ac_cv_krb4_extralib="$a"
+ ac_cv_found_krb4=yes
+ break],
+ [ac_cv_found_krb4_lib=no
+ if test "$ac_cv_found_krb4_lib" = "no"; then
+ if test "X$1" != "X"; then
+ LIBS="$saved_LIBS -L$1"
+ fi
+ LIBS="$LIBS -lkrb4 -ldes425 -lkrb5 -lcom_err $ac_cv_krb5_extralib"
+ AC_TRY_LINK([],
+ [dest_tkt();],
+ [ac_cv_found_krb4_lib=compat
+ ac_cv_krb4_extralib="-lkrb4 -ldes425 -lkrb5 -lcom_err $ac_cv_krb5_extralib"
+ break],
+ [ac_cv_found_krb4_lib=no])
+ fi])
+done
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN(AC_KRB4_LIB_WHERE, [
+ for i in $1; do
+ AC_MSG_CHECKING(for kerberos4 libraries in $i)
+ AC_KRB4_LIB_WHERE1($i)
+ if test "$ac_cv_found_krb4_lib" != "no" ; then
+ ac_cv_krb4_where_lib=$i
+ AC_MSG_RESULT(found)
+ break
+ else
+ AC_MSG_RESULT(not found)
+ fi
+ done
+])
+
+dnl
+dnl KRB5 tests
+dnl
+
+AC_DEFUN(AC_KRB5_INC_WHERE1, [
+saved_CPPFLAGS=$CPPFLAGS
+if test "X$1" != "X" ; then
+ CPPFLAGS="$saved_CPPFLAGS -I$1"
+fi
+AC_TRY_COMPILE([#include <krb5.h>],
+[krb5_kvno foo;],
+ac_cv_found_krb5_inc=yes,
+ac_cv_found_krb5_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN(AC_KRB5_INC_WHERE, [
+ for i in $1; do
+ AC_MSG_CHECKING(for kerberos5 headers in $i)
+ AC_KRB5_INC_WHERE1($i)
+ if test "$ac_cv_found_krb5_inc" = "yes"; then
+ ac_cv_krb5_where_inc=$i
+ AC_MSG_RESULT(found)
+ break
+ else
+ AC_MSG_RESULT(not found)
+ fi
+ done
+])
+
+
+dnl
+dnl
+dnl
+
+AC_DEFUN(AC_KRB5_LIB_WHERE1, [
+saved_LIBS=$LIBS
+for a in "-lk5crypto -lcom_err" dnl new mit krb
+ "-lcrypto -lcom_err" dnl old mit krb
+ "-lasn1 -ldes -lroken" dnl heimdal w/ roken w/o dep on db
+ "-lasn1 -ldes -lroken -lresolv" dnl heimdal w/ roken w/o dep on db w/ dep on resolv
+ "-lasn1 -lcrypto -lcom_err -lroken" dnl heimdal-BSD w/ roken w/o dep on db
+ "-lasn1 -ldes -lroken -ldb" dnl heimdal w/ roken w/ dep on db
+ "-lasn1 -ldes -lroken -ldb -lresolv" dnl heimdal w/ roken w/ dep on db w/ dep on resolv
+ "-lasn1 -lcrypto -lcom_err -lroken -ldb" dnl heimdal-BSD w/ roken w/ dep on db
+ ; do
+ LIBS="$saved_LIBS"
+ if test "X$1" != "X"; then
+ LIBS="$LIBS -L$1"
+ fi
+ LIBS="$LIBS -lkrb5 $a"
+ AC_TRY_LINK([],
+ [krb5_init_context();],
+ [ac_cv_found_krb5_lib=yes
+ ac_cv_found_krb5=yes
+ ac_cv_krb5_extralib=$a
+ break],
+ ac_cv_found_krb5_lib=no)
+done
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN(AC_KRB5_LIB_WHERE, [
+ for i in $1; do
+ AC_MSG_CHECKING(for kerberos5 libraries in $i)
+ AC_KRB5_LIB_WHERE1($i)
+ if test "$ac_cv_found_krb5_lib" != "no" ; then
+ ac_cv_krb5_where_lib=$i
+ AC_MSG_RESULT(found)
+ break
+ else
+ AC_MSG_RESULT(not found)
+ fi
+ done
+])
+
+
diff --git a/usr.sbin/afs/src/cf/check-kernel-func.m4 b/usr.sbin/afs/src/cf/check-kernel-func.m4
new file mode 100644
index 00000000000..bcf2bc814f8
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kernel-func.m4
@@ -0,0 +1,11 @@
+dnl
+dnl $Id: check-kernel-func.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+
+dnl AC_CHECK_KERNEL_FUNC(func, param, [includes])
+AC_DEFUN(AC_CHECK_KERNEL_FUNC,
+AC_CHECK_KERNEL($1, ac_cv_kernel_func_$1, [$1]([$2]), $4)
+: << END
+@@@funcs="$funcs [patsubst([$1], [\w+], [kernel_\&])]"@@@
+END
+)
diff --git a/usr.sbin/afs/src/cf/check-kernel-funcs.m4 b/usr.sbin/afs/src/cf/check-kernel-funcs.m4
new file mode 100644
index 00000000000..56ada315768
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kernel-funcs.m4
@@ -0,0 +1,15 @@
+dnl
+dnl $Id: check-kernel-funcs.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+
+dnl AC_CHECK_KERNEL_FUNCS(functions...)
+AC_DEFUN(AC_CHECK_KERNEL_FUNCS,
+[for ac_func in $1
+do
+AC_CHECK_KERNEL($ac_func, ac_cv_kernel_func_$ac_func, [$ac_func]())
+done
+]
+: << END
+@@@funcs="$funcs [patsubst([$1], [\w+], [kernel_\&])]"@@@
+END
+)
diff --git a/usr.sbin/afs/src/cf/check-kernel-var.m4 b/usr.sbin/afs/src/cf/check-kernel-var.m4
new file mode 100644
index 00000000000..2775fdf1244
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kernel-var.m4
@@ -0,0 +1,11 @@
+dnl
+dnl $Id: check-kernel-var.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+
+dnl AC_CHECK_KERNEL_VAR(var, type, [includes])
+AC_DEFUN(AC_CHECK_KERNEL_VAR,
+AC_CHECK_KERNEL($1, ac_cv_kernel_var_$1, [extern $2 $1; return $1], $4)
+: << END
+@@@funcs="$funcs kernel_$1"@@@
+END
+)
diff --git a/usr.sbin/afs/src/cf/check-kernel-vop-t.m4 b/usr.sbin/afs/src/cf/check-kernel-vop-t.m4
new file mode 100644
index 00000000000..16c44da5e6e
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kernel-vop-t.m4
@@ -0,0 +1,17 @@
+dnl
+dnl $Id: check-kernel-vop-t.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+
+dnl
+dnl try to find out if we have a vop_t
+dnl
+
+AC_DEFUN(AC_CHECK_KERNEL_VOP_T, [
+
+AC_CACHE_CHECK(for vop_t, ac_cv_type_vop_t,
+AC_EGREP_HEADER(vop_t, sys/vnode.h, ac_cv_type_vop_t=yes, ac_cv_type_vop_t=no))
+
+if test "$ac_cv_type_vop_t" = "yes"; then
+ AC_DEFINE(HAVE_VOP_T, 1, [define if you have a vop_t])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/check-kernel.m4 b/usr.sbin/afs/src/cf/check-kernel.m4
new file mode 100644
index 00000000000..179f772ab2a
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-kernel.m4
@@ -0,0 +1,60 @@
+dnl
+dnl $Id: check-kernel.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+
+dnl there are two different heuristics for doing the kernel tests
+dnl a) running nm and greping the output
+dnl b) trying linking against the kernel
+
+dnl AC_CHECK_KERNEL(name, cv, magic, [includes])
+AC_DEFUN(AC_CHECK_KERNEL,
+[AC_MSG_CHECKING([for $1 in kernel])
+AC_CACHE_VAL($2,
+[
+if test "$target_os" = "macos10.0"; then
+ if nm $KERNEL | egrep "\\<_?$1\\>" >/dev/null 2>&1; then
+ eval "$2=yes"
+ else
+ eval "$2=no"
+ fi
+else
+cat > conftest.$ac_ext <<EOF
+dnl This sometimes fails to find confdefs.h, for some reason.
+dnl [#]line __oline__ "[$]0"
+[#]line __oline__ "configure"
+#include "confdefs.h"
+[$4]
+int _foo() {
+return foo();
+}
+int foo() {
+[$3];
+return 0; }
+EOF
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $test_KERNEL_CFLAGS $KERNEL_CPPFLAGS"
+if AC_TRY_EVAL(ac_compile) && AC_TRY_EVAL(ac_kernel_ld) && test -s conftest; then
+ eval "$2=yes"
+else
+ eval "$2=no"
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&AC_FD_CC
+fi
+CFLAGS="$save_CFLAGS"
+rm -f conftest*
+fi])
+changequote(, )dnl
+eval "ac_tr_var=HAVE_KERNEL_`echo $1 | tr '[a-z]' '[A-Z]'`"
+changequote([, ])dnl
+
+AC_MSG_RESULT(`eval echo \\${$2}`)
+if test `eval echo \\${$2}` = yes; then
+ AC_DEFINE_UNQUOTED($ac_tr_var, 1)
+fi
+])
+
+dnl define([foo], [[HAVE_KERNEL_]translit($1, [a-z], [A-Z])])
+dnl : << END
+dnl @@@syms="$syms foo"@@@
+dnl END
+dnl undefine([foo])
diff --git a/usr.sbin/afs/src/cf/check-lfs.m4 b/usr.sbin/afs/src/cf/check-lfs.m4
new file mode 100644
index 00000000000..cceac950592
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-lfs.m4
@@ -0,0 +1,31 @@
+dnl
+dnl $Id: check-lfs.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+
+AC_DEFUN(AC_HAVE_GETCONF, [
+AC_CHECK_PROG(ac_cv_prog_getconf,[getconf],yes)
+])
+
+AC_DEFUN(AC_GETCONF_FLAGS,[
+if test "$ac_cv_prog_getconf" = "yes";then
+AC_MSG_CHECKING([if we have $1])
+FOO="`getconf $1 2>/dev/null >/dev/null`"
+if test $? = 0 ;then
+$2="[$]$2 $FOO"
+AC_MSG_RESULT([yes $FOO])
+else
+AC_MSG_RESULT(no)
+fi
+fi
+
+])
+
+AC_DEFUN(AC_CHECK_LFS, [
+if test "${ac_cv_prog_getconf-set}" = set ;then
+AC_HAVE_GETCONF
+fi
+AC_GETCONF_FLAGS(LFS_CFLAGS, CFLAGS)
+AC_GETCONF_FLAGS(LFS_LDFLAGS, LDFLAGS)
+])
+
+
diff --git a/usr.sbin/afs/src/cf/check-man.m4 b/usr.sbin/afs/src/cf/check-man.m4
new file mode 100644
index 00000000000..7b1c7e020d3
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-man.m4
@@ -0,0 +1,59 @@
+dnl $Id: check-man.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl check how to format manual pages
+dnl
+
+AC_DEFUN(AC_CHECK_MAN,
+[AC_PATH_PROG(NROFF, nroff)
+AC_PATH_PROG(GROFF, groff)
+AC_CACHE_CHECK(how to format man pages,ac_cv_sys_man_format,
+[cat > conftest.1 << END
+.Dd January 1, 1970
+.Dt CONFTEST 1
+.Sh NAME
+.Nm conftest
+.Nd
+foobar
+END
+
+if test "$NROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$NROFF" $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$NROFF $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format" = "" -a "$GROFF" ; then
+ for i in "-mdoc" "-mandoc"; do
+ if "$GROFF" -Tascii $i conftest.1 2> /dev/null | \
+ grep Jan > /dev/null 2>&1 ; then
+ ac_cv_sys_man_format="$GROFF -Tascii $i"
+ break
+ fi
+ done
+fi
+if test "$ac_cv_sys_man_format"; then
+ ac_cv_sys_man_format="$ac_cv_sys_man_format \[$]< > \[$]@"
+fi
+])
+if test "$ac_cv_sys_man_format"; then
+ CATMAN="$ac_cv_sys_man_format"
+ AC_SUBST(CATMAN)
+fi
+AM_CONDITIONAL(CATMAN, test "$CATMAN")
+AC_CACHE_CHECK(extension of pre-formatted manual pages,ac_cv_sys_catman_ext,
+[if grep _suffix /etc/man.conf > /dev/null 2>&1; then
+ ac_cv_sys_catman_ext=0
+else
+ ac_cv_sys_catman_ext=number
+fi
+])
+if test "$ac_cv_sys_catman_ext" = number; then
+ CATMANEXT='$$ext'
+else
+ CATMANEXT=0
+fi
+AC_SUBST(CATMANEXT)
+
+]) \ No newline at end of file
diff --git a/usr.sbin/afs/src/cf/check-type-extra.m4 b/usr.sbin/afs/src/cf/check-type-extra.m4
new file mode 100644
index 00000000000..90466c22584
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-type-extra.m4
@@ -0,0 +1,23 @@
+dnl $Id: check-type-extra.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+dnl ac_check_type + extra headers
+
+dnl AC_CHECK_TYPE_EXTRA(TYPE, DEFAULT, HEADERS)
+AC_DEFUN(AC_CHECK_TYPE_EXTRA,
+[AC_REQUIRE([AC_HEADER_STDC])dnl
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(ac_cv_type_$1,
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<$1[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$3], ac_cv_type_$1=yes, ac_cv_type_$1=no)])dnl
+AC_MSG_RESULT($ac_cv_type_$1)
+if test $ac_cv_type_$1 = no; then
+ AC_DEFINE($1, $2, [Define this to what the type $1 should be.])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/check-var.m4 b/usr.sbin/afs/src/cf/check-var.m4
new file mode 100644
index 00000000000..060229cd688
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-var.m4
@@ -0,0 +1,20 @@
+dnl $Id: check-var.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+dnl AC_CHECK_VAR(includes, variable)
+AC_DEFUN(AC_CHECK_VAR, [
+AC_MSG_CHECKING(for $2)
+AC_CACHE_VAL(ac_cv_var_$2, [
+AC_TRY_LINK([extern int $2;
+int foo() { return $2; }],
+ [foo()],
+ ac_cv_var_$2=yes, ac_cv_var_$2=no)
+])
+define([foo], [HAVE_]translit($2, [a-z], [A-Z]))
+
+AC_MSG_RESULT(`eval echo \\$ac_cv_var_$2`)
+if test `eval echo \\$ac_cv_var_$2` = yes; then
+ AC_DEFINE_UNQUOTED(foo, 1, [define if you have $2])
+ AC_CHECK_DECLARATION([$1],[$2])
+fi
+undefine([foo])
+])
diff --git a/usr.sbin/afs/src/cf/check-x.m4 b/usr.sbin/afs/src/cf/check-x.m4
new file mode 100644
index 00000000000..2b74b5554db
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-x.m4
@@ -0,0 +1,52 @@
+dnl
+dnl See if there is any X11 present
+dnl
+dnl $Id: check-x.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+
+AC_DEFUN(KRB_CHECK_X,[
+AC_PATH_XTRA
+
+# try to figure out if we need any additional ld flags, like -R
+# and yes, the autoconf X test is utterly broken
+if test "$no_x" != yes; then
+ AC_CACHE_CHECK(for special X linker flags,krb_cv_sys_x_libs_rpath,[
+ ac_save_libs="$LIBS"
+ ac_save_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $X_CFLAGS"
+ krb_cv_sys_x_libs_rpath=""
+ krb_cv_sys_x_libs=""
+ for rflag in "" "-R" "-R " "-rpath "; do
+ if test "$rflag" = ""; then
+ foo="$X_LIBS"
+ else
+ foo=""
+ for flag in $X_LIBS; do
+ case $flag in
+ -L*)
+ foo="$foo $flag `echo $flag | sed \"s/-L/$rflag/\"`"
+ ;;
+ *)
+ foo="$foo $flag"
+ ;;
+ esac
+ done
+ fi
+ LIBS="$ac_save_libs $foo -lX11"
+ AC_TRY_RUN([
+ #include <X11/Xlib.h>
+ foo()
+ {
+ XOpenDisplay(NULL);
+ }
+ main()
+ {
+ return 0;
+ }
+ ], krb_cv_sys_x_libs_rpath="$rflag"; krb_cv_sys_x_libs="$foo"; break,:)
+ done
+ LIBS="$ac_save_libs"
+ CFLAGS="$ac_save_cflags"
+ ])
+ X_LIBS="$krb_cv_sys_x_libs"
+fi
+])
diff --git a/usr.sbin/afs/src/cf/check-xau.m4 b/usr.sbin/afs/src/cf/check-xau.m4
new file mode 100644
index 00000000000..7e142b7ca6b
--- /dev/null
+++ b/usr.sbin/afs/src/cf/check-xau.m4
@@ -0,0 +1,54 @@
+dnl $Id: check-xau.m4,v 1.1 2000/09/11 14:40:46 art Exp $
+dnl
+dnl check for Xau{Read,Write}Auth
+dnl
+AC_DEFUN(AC_CHECK_XAU,[
+save_CFLAGS="$CFLAGS"
+CFLAGS="$X_CFLAGS $CFLAGS"
+save_LIBS="$LIBS"
+dnl LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+LIBS="$X_PRE_LIBS $X_EXTRA_LIBS $LIBS"
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $X_LIBS"
+
+## check for XauWriteAuth first, so we detect the case where
+## XauReadAuth is in -lX11, but XauWriteAuth is only in -lXau this
+## could be done by checking for XauReadAuth in -lXau first, but this
+## breaks in IRIX 6.5
+
+AC_FIND_FUNC_NO_LIBS(XauWriteAuth, X11 Xau)
+ac_xxx="$LIBS"
+LIBS="$LIB_XauWriteAuth $LIBS"
+AC_FIND_FUNC_NO_LIBS(XauReadAuth, X11 Xau)
+LIBS="$ac_xxx"
+
+## set LIB_XauReadAuth to union of these tests, since this is what the
+## Makefiles are using
+case "$ac_cv_funclib_XauWriteAuth" in
+yes) ;;
+no) ;;
+*) if test "$ac_cv_funclib_XauReadAuth" = yes; then
+ LIB_XauReadAuth="$LIB_XauWriteAuth"
+ else
+ LIB_XauReadAuth="$LIB_XauReadAuth $LIB_XauWriteAuth"
+ fi
+ ;;
+esac
+
+if test "$AUTOMAKE" != ""; then
+ AM_CONDITIONAL(NEED_WRITEAUTH, test "$ac_cv_func_XauWriteAuth" != "yes")
+else
+ AC_SUBST(NEED_WRITEAUTH_TRUE)
+ AC_SUBST(NEED_WRITEAUTH_FALSE)
+ if test "$ac_cv_func_XauWriteAuth" != "yes"; then
+ NEED_WRITEAUTH_TRUE=
+ NEED_WRITEAUTH_FALSE='#'
+ else
+ NEED_WRITEAUTH_TRUE='#'
+ NEED_WRITEAUTH_FALSE=
+ fi
+fi
+CFLAGS=$save_CFLAGS
+LIBS=$save_LIBS
+LDFLAGS=$save_LDFLAGS
+])
diff --git a/usr.sbin/afs/src/cf/elf-object-format.m4 b/usr.sbin/afs/src/cf/elf-object-format.m4
new file mode 100644
index 00000000000..1bc51b44a53
--- /dev/null
+++ b/usr.sbin/afs/src/cf/elf-object-format.m4
@@ -0,0 +1,15 @@
+dnl
+dnl $Id: elf-object-format.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl test for ELF
+
+AC_DEFUN(AC_ELF_OBJECT_FORMAT,[
+AC_CACHE_CHECK([for ELF object format], ac_cv_sys_elf_object_format,[
+ac_cv_sys_elf_object_format=no
+echo 'int foo;' > conftest.$ac_ext
+if AC_TRY_EVAL(ac_compile); then
+ case `file conftest.o 2> /dev/null` in
+ *ELF*) ac_cv_sys_elf_object_format=yes ;;
+ esac
+fi
+rm -f conftest*])])
diff --git a/usr.sbin/afs/src/cf/find-func-no-libs.m4 b/usr.sbin/afs/src/cf/find-func-no-libs.m4
new file mode 100644
index 00000000000..cf70a7a34ac
--- /dev/null
+++ b/usr.sbin/afs/src/cf/find-func-no-libs.m4
@@ -0,0 +1,9 @@
+dnl $Id: find-func-no-libs.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN(AC_FIND_FUNC_NO_LIBS, [
+AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
diff --git a/usr.sbin/afs/src/cf/find-func-no-libs2.m4 b/usr.sbin/afs/src/cf/find-func-no-libs2.m4
new file mode 100644
index 00000000000..4c57fd432d4
--- /dev/null
+++ b/usr.sbin/afs/src/cf/find-func-no-libs2.m4
@@ -0,0 +1,63 @@
+dnl $Id: find-func-no-libs2.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN(AC_FIND_FUNC_NO_LIBS2, [
+
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(ac_cv_funclib_$1,
+[
+if eval "test \"\$ac_cv_func_$1\" != yes" ; then
+ ac_save_LIBS="$LIBS"
+ for ac_lib in $2; do
+ if test -n "$ac_lib"; then
+ ac_lib="-l$ac_lib"
+ else
+ ac_lib=""
+ fi
+ LIBS="$6 $ac_lib $5 $ac_save_LIBS"
+ AC_TRY_LINK([$3],[$1($4)],eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break)
+ done
+ eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
+ LIBS="$ac_save_LIBS"
+fi
+])
+
+eval "ac_res=\$ac_cv_funclib_$1"
+
+dnl autoheader tricks *sigh*
+: << END
+@@@funcs="$funcs $1"@@@
+@@@libs="$libs $2"@@@
+END
+
+# $1
+eval "ac_tr_func=HAVE_[]upcase($1)"
+eval "ac_tr_lib=HAVE_LIB[]upcase($ac_res | sed -e 's/-l//')"
+eval "LIB_$1=$ac_res"
+
+case "$ac_res" in
+ yes)
+ eval "ac_cv_func_$1=yes"
+ eval "LIB_$1="
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ AC_MSG_RESULT([yes])
+ ;;
+ no)
+ eval "ac_cv_func_$1=no"
+ eval "LIB_$1="
+ AC_MSG_RESULT([no])
+ ;;
+ *)
+ eval "ac_cv_func_$1=yes"
+ eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+ AC_DEFINE_UNQUOTED($ac_tr_func)
+ AC_DEFINE_UNQUOTED($ac_tr_lib)
+ AC_MSG_RESULT([yes, in $ac_res])
+ ;;
+esac
+AC_SUBST(LIB_$1)
+])
diff --git a/usr.sbin/afs/src/cf/find-func.m4 b/usr.sbin/afs/src/cf/find-func.m4
new file mode 100644
index 00000000000..9f41a9d1364
--- /dev/null
+++ b/usr.sbin/afs/src/cf/find-func.m4
@@ -0,0 +1,9 @@
+dnl $Id: find-func.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl AC_FIND_FUNC(func, libraries, includes, arguments)
+AC_DEFUN(AC_FIND_FUNC, [
+AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
+if test -n "$LIB_$1"; then
+ LIBS="$LIB_$1 $LIBS"
+fi
+])
diff --git a/usr.sbin/afs/src/cf/find-if-not-broken.m4 b/usr.sbin/afs/src/cf/find-if-not-broken.m4
new file mode 100644
index 00000000000..29e57d9c7e2
--- /dev/null
+++ b/usr.sbin/afs/src/cf/find-if-not-broken.m4
@@ -0,0 +1,13 @@
+dnl $Id: find-if-not-broken.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl
+dnl Mix between AC_FIND_FUNC and AC_BROKEN
+dnl
+
+AC_DEFUN(AC_FIND_IF_NOT_BROKEN,
+[AC_FIND_FUNC([$1], [$2], [$3], [$4])
+if eval "test \"$ac_cv_func_$1\" != yes"; then
+LIBOBJS[]="$LIBOBJS $1.o"
+fi
+AC_SUBST(LIBOBJS)dnl
+])
diff --git a/usr.sbin/afs/src/cf/func-hstrerror-const.m4 b/usr.sbin/afs/src/cf/func-hstrerror-const.m4
new file mode 100644
index 00000000000..c7dad234061
--- /dev/null
+++ b/usr.sbin/afs/src/cf/func-hstrerror-const.m4
@@ -0,0 +1,18 @@
+dnl
+dnl $Id: func-hstrerror-const.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl Test if hstrerror wants const or not
+dnl
+
+dnl AC_FUNC_HSTRERROR_CONST(includes, function)
+
+AC_DEFUN(AC_FUNC_HSTRERROR_CONST, [
+AC_CACHE_CHECK([if hstrerror needs const], ac_cv_func_hstrerror_const,
+AC_TRY_COMPILE([netdb.h],
+[const char *hstrerror(int);],
+ac_cv_func_hstrerror_const=no,
+ac_cv_func_hstrerror_const=yes))
+if test "$ac_cv_func_hstrerror_const" = "yes"; then
+ AC_DEFINE(NEED_HSTRERROR_CONST, 1, [define if hstrerror is const])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/func-krb-get-default-tkt-root.m4 b/usr.sbin/afs/src/cf/func-krb-get-default-tkt-root.m4
new file mode 100644
index 00000000000..0760a082389
--- /dev/null
+++ b/usr.sbin/afs/src/cf/func-krb-get-default-tkt-root.m4
@@ -0,0 +1,31 @@
+dnl
+dnl $Id: func-krb-get-default-tkt-root.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+
+dnl
+dnl Check for krb_get_default_tkt_root
+dnl
+
+AC_DEFUN(AC_FUNC_KRB_GET_DEFAULT_TKT_ROOT, [
+
+AC_CACHE_CHECK(for krb_get_default_tkt_root, ac_cv_func_krb_get_default_tkt_root, [
+if test "$ac_cv_found_krb4" = "yes"; then
+save_CPPFLAGS="${CPPFLAGS}"
+save_LIBS="${LIBS}"
+CPPFLAGS="${KRB4_INC_FLAGS} ${CPPFLAGS}"
+LIBS="${KRB4_LIB_FLAGS} ${LIBS}"
+AC_TRY_LINK([#include <krb.h>],
+[krb_get_default_tkt_root();],
+ac_cv_func_krb_get_default_tkt_root=yes,
+ac_cv_func_krb_get_default_tkt_root=no)
+CPPFLAGS="${save_CPPFLAGS}"
+LIBS="${save_LIBS}"
+else
+dnl Make it say no
+eval "ac_cv_func_krb_get_default_tkt_root=no"
+fi
+])
+if test "$ac_cv_func_krb_get_default_tkt_root" = "yes"; then
+ AC_DEFINE(HAVE_KRB_GET_DEFAULT_TKT_ROOT, 1, [define if you have krb_get_default_tkt_root])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/func-krb-get-err-text.m4 b/usr.sbin/afs/src/cf/func-krb-get-err-text.m4
new file mode 100644
index 00000000000..619a6a9a56d
--- /dev/null
+++ b/usr.sbin/afs/src/cf/func-krb-get-err-text.m4
@@ -0,0 +1,28 @@
+dnl
+dnl $Id: func-krb-get-err-text.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+
+dnl
+dnl Check for krb_get_err_text
+dnl
+
+AC_DEFUN(AC_FUNC_KRB_GET_ERR_TEXT, [
+
+AC_CACHE_CHECK(for krb_get_err_text, ac_cv_func_krb_get_err_text, [
+if test "$ac_cv_found_krb4" = "yes"; then
+save_CPPFLAGS="${CPPFLAGS}"
+save_LIBS="${LIBS}"
+CPPFLAGS="${KRB4_INC_FLAGS} ${CPPFLAGS}"
+LIBS="${KRB4_LIB_FLAGS} ${LIBS}"
+AC_TRY_LINK([#include <krb.h>],
+[krb_get_err_text(0);],
+ac_cv_func_krb_get_err_text=yes,
+ac_cv_func_krb_get_err_text=no)
+CPPFLAGS="${save_CPPFLAGS}"
+LIBS="${save_LIBS}"
+fi
+])
+if test "$ac_cv_func_krb_get_err_text" = "yes"; then
+ AC_DEFINE(HAVE_KRB_GET_ERR_TEXT, 1, [define if you have krb_get_err_text])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/func-krb-kdctimeofday.m4 b/usr.sbin/afs/src/cf/func-krb-kdctimeofday.m4
new file mode 100644
index 00000000000..446577aa856
--- /dev/null
+++ b/usr.sbin/afs/src/cf/func-krb-kdctimeofday.m4
@@ -0,0 +1,31 @@
+dnl
+dnl $Id: func-krb-kdctimeofday.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+
+dnl
+dnl Check for krb_kdctimeofday
+dnl
+
+AC_DEFUN(AC_FUNC_KRB_KDCTIMEOFDAY, [
+
+AC_CACHE_CHECK(for krb_kdctimeofday, ac_cv_func_krb_kdctimeofday, [
+if test "$ac_cv_found_krb4" = "yes"; then
+save_CPPFLAGS="${CPPFLAGS}"
+save_LIBS="${LIBS}"
+CPPFLAGS="${KRB4_INC_FLAGS} ${CPPFLAGS}"
+LIBS="${KRB4_LIB_FLAGS} ${LIBS}"
+AC_TRY_LINK([#include <krb.h>],
+[krb_kdctimeofday(0);],
+ac_cv_func_krb_kdctimeofday=yes,
+ac_cv_func_krb_kdctimeofday=no)
+CPPFLAGS="${save_CPPFLAGS}"
+LIBS="${save_LIBS}"
+else
+dnl Make it say no
+eval "ac_cv_func_krb_kdctimeofday=no"
+fi
+])
+if test "$ac_cv_func_krb_kdctimeofday" = "yes"; then
+ AC_DEFINE(HAVE_KRB_KDCTIMEOFDAY, 1, [define if you have krb_kdctimeofday])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/func-ntohl.m4 b/usr.sbin/afs/src/cf/func-ntohl.m4
new file mode 100644
index 00000000000..b2c001097f5
--- /dev/null
+++ b/usr.sbin/afs/src/cf/func-ntohl.m4
@@ -0,0 +1,38 @@
+dnl
+dnl $Id: func-ntohl.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+dnl test for how to do ntohl
+dnl
+
+AC_DEFUN(AC_FUNC_NTOHL, [
+AC_REQUIRE([AC_CANONICAL_TARGET])
+AC_MSG_CHECKING(for efficient ntohl)
+AC_CACHE_VAL(ac_cv_func_ntohl, [
+case "$target_cpu" in
+changequote(, )dnl
+i[3-9]86) AC_TRY_RUN(
+changequote([, ])dnl
+[
+#if defined(__GNUC__) && defined(i386)
+unsigned long foo(unsigned long x)
+{
+ asm("bswap %0" : "=r" (x) : "0" (x));
+ return x;
+}
+#endif
+
+int main(void)
+{
+ return foo(0x12345678) != 0x78563412;
+}
+],
+ac_cv_func_ntohl="bswap",
+ac_cv_func_ntohl="ntohl",
+ac_cv_func_ntohl="ntohl") ;;
+alpha) ac_cv_func_ntohl="bswap32" ;;
+*) ac_cv_func_ntohl="ntohl" ;;
+esac
+])
+AC_MSG_RESULT($ac_cv_func_ntohl)
+AC_DEFINE_UNQUOTED(EFF_NTOHL, $ac_cv_func_ntohl, [how should ntohl be done?])
+])
diff --git a/usr.sbin/afs/src/cf/grok-type.m4 b/usr.sbin/afs/src/cf/grok-type.m4
new file mode 100644
index 00000000000..7d840bac619
--- /dev/null
+++ b/usr.sbin/afs/src/cf/grok-type.m4
@@ -0,0 +1,35 @@
+dnl $Id: grok-type.m4,v 1.1 2000/09/11 14:40:47 art Exp $
+dnl
+AC_DEFUN(AC_GROK_TYPE, [
+AC_CACHE_VAL(ac_cv_type_$1,
+AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_BIND_BITYPES_H
+#include <bind/bitypes.h>
+#endif
+#ifdef HAVE_NETINET_IN6_MACHTYPES_H
+#include <netinet/in6_machtypes.h>
+#endif
+],
+$i x;
+,
+eval ac_cv_type_$1=yes,
+eval ac_cv_type_$1=no))])
+
+AC_DEFUN(AC_GROK_TYPES, [
+for i in $1; do
+ AC_MSG_CHECKING(for $i)
+ AC_GROK_TYPE($i)
+ eval ac_res=\$ac_cv_type_$i
+ if test "$ac_res" = yes; then
+ type=HAVE_[]upcase($i)
+ AC_DEFINE_UNQUOTED($type)
+ fi
+ AC_MSG_RESULT($ac_res)
+done
+])
diff --git a/usr.sbin/afs/src/cf/have-def.m4 b/usr.sbin/afs/src/cf/have-def.m4
new file mode 100644
index 00000000000..3bd7ab3aa7e
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-def.m4
@@ -0,0 +1,19 @@
+dnl
+dnl $Id: have-def.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+
+dnl AC_HAVE_DEF(includes, [struct|typedef])
+AC_DEFUN(AC_HAVE_DEF, [
+define(cache_val, translit(ac_cv_have_def_$2, [A-Z ], [a-z_]))
+AC_CACHE_CHECK([if $2 exists], cache_val, [
+AC_TRY_COMPILE([$1],
+[$2 foo],
+cache_val=yes,
+cache_val=no)])
+if test "$cache_val" = yes; then
+ define(foo, translit(HAVE_DEF_$2, [a-z ], [A-Z_]))
+ AC_DEFINE(foo, 1, [Define if you have $2])
+ undefine(foo)
+fi
+undefine([cache_val])
+])
diff --git a/usr.sbin/afs/src/cf/have-kernel-struct-field.m4 b/usr.sbin/afs/src/cf/have-kernel-struct-field.m4
new file mode 100644
index 00000000000..fa85b6b13e1
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-kernel-struct-field.m4
@@ -0,0 +1,19 @@
+dnl
+dnl $Id: have-kernel-struct-field.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+
+dnl AC_HAVE_KERNEL_STRUCT_FIELD(includes, struct, type, field)
+AC_DEFUN(AC_HAVE_KERNEL_STRUCT_FIELD, [
+define(cache_val, translit(ac_cv_struct_$2_$4, [A-Z ], [a-z_]))
+AC_CACHE_CHECK([if struct $2 has a field $4], cache_val, [
+AC_TRY_COMPILE_KERNEL([$1],
+[struct $2 foo; $3 bar = foo.$4; ],
+cache_val=yes,
+cache_val=no)])
+if test "$cache_val" = yes; then
+ define(foo, translit(HAVE_STRUCT_$2_$4, [a-z ], [A-Z_]))
+ AC_DEFINE(foo, 1, [Define if struct $2 has field $4])
+ undefine(foo)
+fi
+undefine(cache_val)
+])
diff --git a/usr.sbin/afs/src/cf/have-linux-kernel-type.m4 b/usr.sbin/afs/src/cf/have-linux-kernel-type.m4
new file mode 100644
index 00000000000..66409dd66ba
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-linux-kernel-type.m4
@@ -0,0 +1,24 @@
+dnl
+dnl $Id: have-linux-kernel-type.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+dnl Check for types in the Linux kernel
+dnl
+
+dnl AC_HAVE_LINUX_KERNEL_TYPE(type)
+AC_DEFUN(AC_HAVE_LINUX_KERNEL_TYPE, [
+cv=`echo "$1" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+AC_MSG_CHECKING(for $i in the linux kernel)
+AC_CACHE_VAL(ac_cv_linux_kernel_type_$cv,
+AC_TRY_COMPILE_KERNEL([
+#define __KERNEL__
+#include <linux/types.h>
+],
+[$1 x;],
+eval "ac_cv_linux_kernel_type_$cv=yes",
+eval "ac_cv_linux_kernel_type_$cv=no"))dnl
+AC_MSG_RESULT(`eval echo \\$ac_cv_linux_kernel_type_$cv`)
+if test `eval echo \\$ac_cv_linux_kernel_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_LINUX_KERNEL_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ AC_DEFINE_UNQUOTED($ac_tr_hdr, 1)
+fi
+])
diff --git a/usr.sbin/afs/src/cf/have-linux-kernel-types.m4 b/usr.sbin/afs/src/cf/have-linux-kernel-types.m4
new file mode 100644
index 00000000000..b3d1b3a8a1a
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-linux-kernel-types.m4
@@ -0,0 +1,14 @@
+dnl
+dnl $Id: have-linux-kernel-types.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+dnl Check for types in the Linux kernel
+dnl
+
+AC_DEFUN(AC_HAVE_LINUX_KERNEL_TYPES, [
+for i in $1; do
+ AC_HAVE_LINUX_KERNEL_TYPE($i)
+done
+: << END
+@@@funcs="$funcs patsubst([$1], [\w+], [linux_kernel_\&])"@@@
+END
+])
diff --git a/usr.sbin/afs/src/cf/have-pragma-weak.m4 b/usr.sbin/afs/src/cf/have-pragma-weak.m4
new file mode 100644
index 00000000000..fe5a42b1ab3
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-pragma-weak.m4
@@ -0,0 +1,37 @@
+dnl $Id: have-pragma-weak.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+AC_DEFUN(AC_HAVE_PRAGMA_WEAK, [
+if test "${enable_shared}" = "yes"; then
+AC_MSG_CHECKING(for pragma weak)
+AC_CACHE_VAL(ac_have_pragma_weak, [
+ac_have_pragma_weak=no
+cat > conftest_foo.$ac_ext <<'EOF'
+[#]line __oline__ "configure"
+#include "confdefs.h"
+#pragma weak foo = _foo
+int _foo = 17;
+EOF
+cat > conftest_bar.$ac_ext <<'EOF'
+[#]line __oline__ "configure"
+#include "confdefs.h"
+extern int foo;
+
+int t() {
+ return foo;
+}
+
+int main() {
+ return t();
+}
+EOF
+if AC_TRY_EVAL('CC -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest_foo.$ac_ext conftest_bar.$ac_ext 1>&AC_FD_CC'); then
+ac_have_pragma_weak=yes
+fi
+rm -rf conftest*
+])
+if test "$ac_have_pragma_weak" = "yes"; then
+ AC_DEFINE(HAVE_PRAGMA_WEAK, 1, [Define this if your compiler supports \`#pragma weak.'])dnl
+fi
+AC_MSG_RESULT($ac_have_pragma_weak)
+fi
+])
diff --git a/usr.sbin/afs/src/cf/have-struct-field.m4 b/usr.sbin/afs/src/cf/have-struct-field.m4
new file mode 100644
index 00000000000..5bd77468597
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-struct-field.m4
@@ -0,0 +1,19 @@
+dnl $Id: have-struct-field.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+dnl check for fields in a structure
+dnl
+dnl AC_HAVE_STRUCT_FIELD(struct, field, headers)
+
+AC_DEFUN(AC_HAVE_STRUCT_FIELD, [
+define(cache_val, translit(ac_cv_type_$1_$2, [A-Z ], [a-z_]))
+AC_CACHE_CHECK([for $2 in $1], cache_val,[
+AC_TRY_COMPILE([$3],[$1 x; x.$2;],
+cache_val=yes,
+cache_val=no)])
+if test "$cache_val" = yes; then
+ define(foo, translit(HAVE_$1_$2, [a-z ], [A-Z_]))
+ AC_DEFINE(foo, 1, [Define if $1 has field $2.])
+ undefine(foo)
+fi
+undefine(cache_val)
+])
diff --git a/usr.sbin/afs/src/cf/have-type.m4 b/usr.sbin/afs/src/cf/have-type.m4
new file mode 100644
index 00000000000..c0e069ca77a
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-type.m4
@@ -0,0 +1,32 @@
+dnl $Id: have-type.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+dnl check for existance of a type
+
+dnl AC_HAVE_TYPE(TYPE,INCLUDES)
+AC_DEFUN(AC_HAVE_TYPE, [
+AC_REQUIRE([AC_HEADER_STDC])
+cv=`echo "$1" | sed 'y%./+- %__p__%'`
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL([ac_cv_type_$cv],
+AC_TRY_COMPILE(
+[#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$2],
+[$1 foo;],
+eval "ac_cv_type_$cv=yes",
+eval "ac_cv_type_$cv=no"))dnl
+AC_MSG_RESULT(`eval echo \\$ac_cv_type_$cv`)
+if test `eval echo \\$ac_cv_type_$cv` = yes; then
+ ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
+dnl autoheader tricks *sigh*
+define(foo,translit($1, [ ], [_]))
+: << END
+@@@funcs="$funcs foo"@@@
+END
+undefine([foo])
+ AC_DEFINE_UNQUOTED($ac_tr_hdr, 1)
+fi
+])
diff --git a/usr.sbin/afs/src/cf/have-types.m4 b/usr.sbin/afs/src/cf/have-types.m4
new file mode 100644
index 00000000000..dee39577292
--- /dev/null
+++ b/usr.sbin/afs/src/cf/have-types.m4
@@ -0,0 +1,14 @@
+dnl
+dnl $Id: have-types.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+
+AC_DEFUN(AC_HAVE_TYPES, [
+for i in $1; do
+ AC_HAVE_TYPE($i)
+done
+: << END
+changequote(`,')dnl
+@@@funcs="$funcs $1"@@@
+changequote([,])dnl
+END
+])
diff --git a/usr.sbin/afs/src/cf/header-dirent-dir-h.m4 b/usr.sbin/afs/src/cf/header-dirent-dir-h.m4
new file mode 100644
index 00000000000..338cd920472
--- /dev/null
+++ b/usr.sbin/afs/src/cf/header-dirent-dir-h.m4
@@ -0,0 +1,21 @@
+dnl $Id: header-dirent-dir-h.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+
+dnl
+dnl Check if we can include both dirent.h and sys/dir.h
+dnl
+
+AC_DEFUN(AC_DIRENT_SYS_DIR_H, [
+AC_CACHE_CHECK(if we can include both dirent.h and sys/dir.h,
+ac_cv_header_dirent_and_sys_dir,
+AC_TRY_CPP([
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/dir.h>
+],
+ac_cv_header_dirent_and_sys_dir=yes,
+ac_cv_header_dirent_and_sys_dir=no))
+if test "$ac_cv_header_dirent_and_sys_dir" = yes; then
+ AC_DEFINE(DIRENT_AND_SYS_DIR_H, 1,
+ [define if you can include both dirent.h and sys/dir.h])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/kernel-have-def.m4 b/usr.sbin/afs/src/cf/kernel-have-def.m4
new file mode 100644
index 00000000000..14eebecdfb3
--- /dev/null
+++ b/usr.sbin/afs/src/cf/kernel-have-def.m4
@@ -0,0 +1,19 @@
+dnl
+dnl $Id: kernel-have-def.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+
+dnl AC_HAVE_KERNEL_DEF(includes, [struct|typedef])
+AC_DEFUN(AC_HAVE_KERNEL_DEF, [
+define(cache_val, translit(ac_cv_have_def_$2, [A-Z ], [a-z_]))
+AC_CACHE_CHECK([if $2 exists], cache_val, [
+AC_TRY_COMPILE_KERNEL([$1],
+[$2 foo],
+cache_val=yes,
+cache_val=no)])
+if test "$cache_val" = yes; then
+ define(foo, translit(HAVE_DEF_$2, [a-z ], [A-Z_]))
+ AC_DEFINE(foo, 1, [Define if you have $2])
+ undefine(foo)
+fi
+undefine([cache_val])
+])
diff --git a/usr.sbin/afs/src/cf/kernel.m4 b/usr.sbin/afs/src/cf/kernel.m4
new file mode 100644
index 00000000000..8b9bda1d1a4
--- /dev/null
+++ b/usr.sbin/afs/src/cf/kernel.m4
@@ -0,0 +1,19 @@
+dnl
+dnl $Id: kernel.m4,v 1.1 2000/09/11 14:40:48 art Exp $
+dnl
+
+dnl
+dnl Check for where the kernel is stored
+dnl
+
+AC_DEFUN(AC_KERNEL,
+[
+dnl XXX XXX XXX *** this test sucks *** XXX XXX XXX
+if test "$ac_kernel_ld" = ""; then
+if test "$ac_cv_sys_elf_object_format" = yes; then
+ac_kernel_ld='${LD-ld} -o conftest $LDFLAGS -R $KERNEL conftest.o -e _foo 1>&AC_FD_CC'
+else
+ac_kernel_ld='${LD-ld} -o conftest $LDFLAGS -A $KERNEL conftest.o -e _foo 1>&AC_FD_CC'
+fi
+fi
+])
diff --git a/usr.sbin/afs/src/cf/krb-bigendian.m4 b/usr.sbin/afs/src/cf/krb-bigendian.m4
new file mode 100644
index 00000000000..89a395c2430
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-bigendian.m4
@@ -0,0 +1,53 @@
+dnl
+dnl $Id: krb-bigendian.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+
+dnl check if this computer is little or big-endian
+dnl if we can figure it out at compile-time then don't define the cpp symbol
+dnl otherwise test for it and define it. also allow options for overriding
+dnl it when cross-compiling
+
+AC_DEFUN(KRB_C_BIGENDIAN, [
+AC_ARG_ENABLE(bigendian,
+[ --enable-bigendian the target is big endian],
+krb_cv_c_bigendian=yes)
+AC_ARG_ENABLE(littleendian,
+[ --enable-littleendian the target is little endian],
+krb_cv_c_bigendian=no)
+AC_CACHE_CHECK(whether byte order is known at compile time,
+krb_cv_c_bigendian_compile,
+[AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/param.h>],[
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif], krb_cv_c_bigendian_compile=yes, krb_cv_c_bigendian_compile=no)])
+AC_CACHE_CHECK(whether byte ordering is bigendian, krb_cv_c_bigendian,[
+ if test "$krb_cv_c_bigendian_compile" = "yes"; then
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/param.h>],[
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif], krb_cv_c_bigendian=yes, krb_cv_c_bigendian=no)
+ else
+ AC_TRY_RUN([main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+ }], krb_cv_c_bigendian=no, krb_cv_c_bigendian=yes,
+ AC_MSG_ERROR([specify either --enable-bigendian or --enable-littleendian]))
+ fi
+])
+if test "$krb_cv_c_bigendian" = "yes"; then
+ AC_DEFINE(WORDS_BIGENDIAN, 1, [define if target is big endian])dnl
+fi
+if test "$krb_cv_c_bigendian_compile" = "yes"; then
+ AC_DEFINE(ENDIANESS_IN_SYS_PARAM_H, 1, [define if sys/param.h defines the endiness])dnl
+fi
+])
diff --git a/usr.sbin/afs/src/cf/krb-find-db.m4 b/usr.sbin/afs/src/cf/krb-find-db.m4
new file mode 100644
index 00000000000..f79088035af
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-find-db.m4
@@ -0,0 +1,89 @@
+dnl $Id: krb-find-db.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl find a suitable database library
+dnl
+dnl AC_FIND_DB(libraries)
+AC_DEFUN(KRB_FIND_DB, [
+
+lib_dbm=no
+lib_db=no
+
+for i in $1; do
+
+ if test "$i"; then
+ m="lib$i"
+ l="-l$i"
+ else
+ m="libc"
+ l=""
+ fi
+
+ AC_MSG_CHECKING(for dbm_open in $m)
+ AC_CACHE_VAL(ac_cv_krb_dbm_open_$m, [
+
+ save_LIBS="$LIBS"
+ LIBS="$l $LIBS"
+ AC_TRY_RUN([
+#include <unistd.h>
+#include <fcntl.h>
+#include <ndbm.h>
+int main()
+{
+ DBM *d;
+
+ d = dbm_open("conftest", O_RDWR | O_CREAT, 0666);
+ if(d == NULL)
+ return 1;
+ dbm_close(d);
+ return 0;
+}], [
+ if test -f conftest.db; then
+ ac_res=db
+ else
+ ac_res=dbm
+ fi], ac_res=no, ac_res=no)
+
+ LIBS="$save_LIBS"
+
+ eval ac_cv_krb_dbm_open_$m=$ac_res])
+ eval ac_res=\$ac_cv_krb_dbm_open_$m
+ AC_MSG_RESULT($ac_res)
+
+ if test "$lib_dbm" = no -a $ac_res = dbm; then
+ lib_dbm="$l"
+ elif test "$lib_db" = no -a $ac_res = db; then
+ lib_db="$l"
+ break
+ fi
+done
+
+AC_MSG_CHECKING(for NDBM library)
+ac_ndbm=no
+if test "$lib_db" != no; then
+ LIB_DBM="$lib_db"
+ ac_ndbm=yes
+ AC_DEFINE(HAVE_NEW_DB, 1, [Define if NDBM really is DB (creates files ending in .db).])
+ if test "$LIB_DBM"; then
+ ac_res="yes, $LIB_DBM"
+ else
+ ac_res=yes
+ fi
+elif test "$lib_dbm" != no; then
+ LIB_DBM="$lib_dbm"
+ ac_ndbm=yes
+ if test "$LIB_DBM"; then
+ ac_res="yes, $LIB_DBM"
+ else
+ ac_res=yes
+ fi
+else
+ LIB_DBM=""
+ ac_res=no
+fi
+test "$ac_ndbm" = yes && AC_DEFINE(NDBM, 1, [Define if you have NDBM (and not DBM)])dnl
+AC_SUBST(LIB_DBM)
+DBLIB="$LIB_DBM"
+AC_SUBST(DBLIB)
+AC_MSG_RESULT($ac_res)
+
+])
diff --git a/usr.sbin/afs/src/cf/krb-func-getcwd-broken.m4 b/usr.sbin/afs/src/cf/krb-func-getcwd-broken.m4
new file mode 100644
index 00000000000..55dffc73e86
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-func-getcwd-broken.m4
@@ -0,0 +1,42 @@
+dnl $Id: krb-func-getcwd-broken.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl test for broken getcwd in (SunOS braindamage)
+dnl
+
+AC_DEFUN(AC_KRB_FUNC_GETCWD_BROKEN, [
+if test "$ac_cv_func_getcwd" = yes; then
+AC_MSG_CHECKING(if getcwd is broken)
+AC_CACHE_VAL(ac_cv_func_getcwd_broken, [
+ac_cv_func_getcwd_broken=no
+
+AC_TRY_RUN([
+#include <errno.h>
+char *getcwd(char*, int);
+
+void *popen(char *cmd, char *mode)
+{
+ errno = ENOTTY;
+ return 0;
+}
+
+int main()
+{
+ char *ret;
+ ret = getcwd(0, 1024);
+ if(ret == 0 && errno == ENOTTY)
+ return 0;
+ return 1;
+}
+], ac_cv_func_getcwd_broken=yes,:,:)
+])
+if test "$ac_cv_func_getcwd_broken" = yes; then
+ AC_DEFINE(BROKEN_GETCWD, 1, [Define if getcwd is broken (like in SunOS 4).])dnl
+ LIBOBJS="$LIBOBJS getcwd.o"
+ AC_SUBST(LIBOBJS)dnl
+ AC_MSG_RESULT($ac_cv_func_getcwd_broken)
+else
+ AC_MSG_RESULT([seems ok])
+fi
+fi
+])
diff --git a/usr.sbin/afs/src/cf/krb-ipv6.m4 b/usr.sbin/afs/src/cf/krb-ipv6.m4
new file mode 100644
index 00000000000..70641511ddc
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-ipv6.m4
@@ -0,0 +1,130 @@
+dnl $Id: krb-ipv6.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl test for IPv6
+dnl
+AC_DEFUN(AC_KRB_IPV6, [
+AC_CACHE_CHECK(for IPv6,ac_cv_lib_ipv6,
+AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+],
+[
+#if defined(IN6ADDR_ANY_INIT)
+struct in6_addr any = IN6ADDR_ANY_INIT;
+#elif defined(IPV6ADDR_ANY_INIT)
+struct in6_addr any = IPV6ADDR_ANY_INIT;
+#else
+#error no any?
+#endif
+ struct sockaddr_in6 sin6;
+ int s;
+
+ s = socket(AF_INET6, SOCK_DGRAM, 0);
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(17);
+ sin6.sin6_addr = any;
+ bind(s, (struct sockaddr *)&sin6, sizeof(sin6));
+],
+ac_cv_lib_ipv6=yes,
+ac_cv_lib_ipv6=no))
+if test "$ac_cv_lib_ipv6" = yes; then
+ AC_DEFINE(HAVE_IPV6, 1, [Define if you have IPv6.])
+
+ dnl check for different v6 implementations (by itojun)
+ v6type=unknown
+ v6lib=none
+
+ AC_MSG_CHECKING([ipv6 stack type])
+ for i in v6d toshiba kame inria zeta linux; do
+ case $i in
+ v6d)
+ AC_EGREP_CPP(yes, [dnl
+#include </usr/local/v6/include/sys/types.h>
+#ifdef __V6D__
+yes
+#endif],
+ [v6type=$i; v6lib=v6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-I/usr/local/v6/include $CFLAGS"])
+ ;;
+ toshiba)
+ AC_EGREP_CPP(yes, [dnl
+#include <sys/param.h>
+#ifdef _TOSHIBA_INET6
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ kame)
+ AC_EGREP_CPP(yes, [dnl
+#include <netinet/in.h>
+#ifdef __KAME__
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ inria)
+ AC_EGREP_CPP(yes, [dnl
+#include <netinet/in.h>
+#ifdef IPV6_INRIA_VERSION
+yes
+#endif],
+ [v6type=$i; CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ zeta)
+ AC_EGREP_CPP(yes, [dnl
+#include <sys/param.h>
+#ifdef _ZETA_MINAMI_INET6
+yes
+#endif],
+ [v6type=$i; v6lib=inet6;
+ v6libdir=/usr/local/v6/lib;
+ CFLAGS="-DINET6 $CFLAGS"])
+ ;;
+ linux)
+ if test -d /usr/inet6; then
+ v6type=$i
+ v6lib=inet6
+ v6libdir=/usr/inet6
+ CFLAGS="-DINET6 $CFLAGS"
+ fi
+ ;;
+ esac
+ if test "$v6type" != "unknown"; then
+ break
+ fi
+ done
+ AC_MSG_RESULT($v6type)
+
+ if test "$v6lib" != "none"; then
+ for dir in $v6libdir /usr/local/v6/lib /usr/local/lib; do
+ if test -d $dir -a -f $dir/lib$v6lib.a; then
+ LIBS="-L$dir -l$v6lib $LIBS"
+ break
+ fi
+ done
+dnl AC_CHECK_LIB($v6lib, getaddrinfo,
+dnl [SERVER_LIBS="-l$v6lib $SERVER_LIBS"],
+dnl [dnl
+dnl echo "Fatal: no $v6lib library found. cannot continue."
+dnl echo "You need to fetch lib$v6lib.a from appropriate v6 kit and"
+dnl echo 'compile beforehand.'
+dnl exit 1])
+ fi
+fi
+])
diff --git a/usr.sbin/afs/src/cf/krb-prog-ln-s.m4 b/usr.sbin/afs/src/cf/krb-prog-ln-s.m4
new file mode 100644
index 00000000000..b80095b445e
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-prog-ln-s.m4
@@ -0,0 +1,28 @@
+dnl $Id: krb-prog-ln-s.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl Better test for ln -s, ln or cp
+dnl
+
+AC_DEFUN(AC_KRB_PROG_LN_S,
+[AC_MSG_CHECKING(for ln -s or something else)
+AC_CACHE_VAL(ac_cv_prog_LN_S,
+[rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ touch conftestdata1
+ if ln conftestdata1 conftestdata2; then
+ rm -f conftestdata*
+ ac_cv_prog_LN_S=ln
+ else
+ ac_cv_prog_LN_S=cp
+ fi
+fi])dnl
+LN_S="$ac_cv_prog_LN_S"
+AC_MSG_RESULT($ac_cv_prog_LN_S)
+AC_SUBST(LN_S)dnl
+])
+
diff --git a/usr.sbin/afs/src/cf/krb-prog-ranlib.m4 b/usr.sbin/afs/src/cf/krb-prog-ranlib.m4
new file mode 100644
index 00000000000..ea7fcc9703d
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-prog-ranlib.m4
@@ -0,0 +1,8 @@
+dnl $Id: krb-prog-ranlib.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl Also look for EMXOMF for OS/2
+dnl
+
+AC_DEFUN(AC_KRB_PROG_RANLIB,
+[AC_CHECK_PROGS(RANLIB, ranlib EMXOMF, :)])
diff --git a/usr.sbin/afs/src/cf/krb-prog-yacc.m4 b/usr.sbin/afs/src/cf/krb-prog-yacc.m4
new file mode 100644
index 00000000000..c9fbee93e31
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-prog-yacc.m4
@@ -0,0 +1,8 @@
+dnl $Id: krb-prog-yacc.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl We prefer byacc or yacc because they do not use `alloca'
+dnl
+
+AC_DEFUN(AC_KRB_PROG_YACC,
+[AC_CHECK_PROGS(YACC, byacc yacc 'bison -y')])
diff --git a/usr.sbin/afs/src/cf/krb-struct-sockaddr-sa-len.m4 b/usr.sbin/afs/src/cf/krb-struct-sockaddr-sa-len.m4
new file mode 100644
index 00000000000..c5e5f9a0234
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-struct-sockaddr-sa-len.m4
@@ -0,0 +1,22 @@
+dnl $Id: krb-struct-sockaddr-sa-len.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl Check for sa_len in sys/socket.h
+dnl
+
+AC_DEFUN(AC_KRB_STRUCT_SOCKADDR_SA_LEN, [
+AC_MSG_CHECKING(for sa_len in struct sockaddr)
+AC_CACHE_VAL(ac_cv_struct_sockaddr_sa_len, [
+AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <sys/socket.h>],
+[struct sockaddr sa;
+int foo = sa.sa_len;],
+ac_cv_struct_sockaddr_sa_len=yes,
+ac_cv_struct_sockaddr_sa_len=no)
+])
+if test "$ac_cv_struct_sockaddr_sa_len" = yes; then
+ AC_DEFINE(SOCKADDR_HAS_SA_LEN)dnl
+fi
+AC_MSG_RESULT($ac_cv_struct_sockaddr_sa_len)
+])
diff --git a/usr.sbin/afs/src/cf/krb-struct-spwd.m4 b/usr.sbin/afs/src/cf/krb-struct-spwd.m4
new file mode 100644
index 00000000000..e319f36e82f
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-struct-spwd.m4
@@ -0,0 +1,22 @@
+dnl $Id: krb-struct-spwd.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl Test for `struct spwd'
+
+AC_DEFUN(AC_KRB_STRUCT_SPWD, [
+AC_MSG_CHECKING(for struct spwd)
+AC_CACHE_VAL(ac_cv_type_struct_spwd, [
+AC_TRY_COMPILE(
+[#include <pwd.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif],
+[struct spwd foo;],
+ac_cv_struct_spwd=yes,
+ac_cv_struct_spwd=no)
+])
+AC_MSG_RESULT($ac_cv_struct_spwd)
+
+if test "$ac_cv_struct_spwd" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_SPWD, 1, [define if you have struct spwd])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/krb-struct-winsize.m4 b/usr.sbin/afs/src/cf/krb-struct-winsize.m4
new file mode 100644
index 00000000000..72d0a4c7418
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-struct-winsize.m4
@@ -0,0 +1,27 @@
+dnl $Id: krb-struct-winsize.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl Search for struct winsize
+dnl
+
+AC_DEFUN(AC_KRB_STRUCT_WINSIZE, [
+AC_MSG_CHECKING(for struct winsize)
+AC_CACHE_VAL(ac_cv_struct_winsize, [
+ac_cv_struct_winsize=no
+for i in sys/termios.h sys/ioctl.h; do
+AC_EGREP_HEADER(
+changequote(, )dnl
+struct[ ]*winsize,dnl
+changequote([,])dnl
+$i, ac_cv_struct_winsize=yes; break)dnl
+done
+])
+if test "$ac_cv_struct_winsize" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_WINSIZE, 1, [define if struct winsize is declared in sys/termios.h])
+fi
+AC_MSG_RESULT($ac_cv_struct_winsize)
+AC_EGREP_HEADER(ws_xpixel, termios.h,
+ AC_DEFINE(HAVE_WS_XPIXEL, 1, [define if struct winsize has ws_xpixel]))
+AC_EGREP_HEADER(ws_ypixel, termios.h,
+ AC_DEFINE(HAVE_WS_YPIXEL, 1, [define if struct winsize has ws_ypixel]))
+])
diff --git a/usr.sbin/afs/src/cf/krb-sys-aix.m4 b/usr.sbin/afs/src/cf/krb-sys-aix.m4
new file mode 100644
index 00000000000..8fc3c27ae22
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-sys-aix.m4
@@ -0,0 +1,15 @@
+dnl $Id: krb-sys-aix.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl AIX have a very different syscall convention
+dnl
+AC_DEFUN(AC_KRB_SYS_AIX, [
+AC_MSG_CHECKING(for AIX)
+AC_CACHE_VAL(krb_cv_sys_aix,
+AC_EGREP_CPP(yes,
+[#ifdef _AIX
+ yes
+#endif
+], krb_cv_sys_aix=yes, krb_cv_sys_aix=no) )
+AC_MSG_RESULT($krb_cv_sys_aix)
+])
diff --git a/usr.sbin/afs/src/cf/krb-sys-nextstep.m4 b/usr.sbin/afs/src/cf/krb-sys-nextstep.m4
new file mode 100644
index 00000000000..fb2ac40d866
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-sys-nextstep.m4
@@ -0,0 +1,22 @@
+dnl $Id: krb-sys-nextstep.m4,v 1.1 2000/09/11 14:40:49 art Exp $
+dnl
+dnl
+dnl NEXTSTEP is not posix compliant by default,
+dnl you need a switch -posix to the compiler
+dnl
+
+AC_DEFUN(AC_KRB_SYS_NEXTSTEP, [
+AC_MSG_CHECKING(for NEXTSTEP)
+AC_CACHE_VAL(krb_cv_sys_nextstep,
+AC_EGREP_CPP(yes,
+[#if defined(NeXT) && !defined(__APPLE__)
+ yes
+#endif
+], krb_cv_sys_nextstep=yes, krb_cv_sys_nextstep=no) )
+if test "$krb_cv_sys_nextstep" = "yes"; then
+ CFLAGS="$CFLAGS -posix"
+ CPPFLAGS="$CPPFLAGS -posix"
+ LIBS="$LIBS -posix"
+fi
+AC_MSG_RESULT($krb_cv_sys_nextstep)
+])
diff --git a/usr.sbin/afs/src/cf/krb-version.m4 b/usr.sbin/afs/src/cf/krb-version.m4
new file mode 100644
index 00000000000..a83327198bd
--- /dev/null
+++ b/usr.sbin/afs/src/cf/krb-version.m4
@@ -0,0 +1,25 @@
+dnl $Id: krb-version.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+dnl
+dnl output a C header-file with some version strings
+dnl
+AC_DEFUN(AC_KRB_VERSION,[
+dnl AC_OUTPUT_COMMANDS([
+cat > include/${PACKAGE}-newversion.h.in <<FOOBAR
+char *${PACKAGE}_long_version = "@(#)\$Version: $PACKAGE-$VERSION by @USER@ on @HOST@ ($host) @DATE@ \$";
+char *${PACKAGE}_version = "$PACKAGE-$VERSION";
+FOOBAR
+
+if test -f include/${PACKAGE}-version.h && cmp -s include/${PACKAGE}-newversion.h.in include/${PACKAGE}-version.h.in; then
+ echo "include/${PACKAGE}-version.h is unchanged"
+ rm -f include/${PACKAGE}-newversion.h.in
+else
+ echo "creating include/${PACKAGE}-version.h"
+ User=${USER-${LOGNAME}}
+ Host=`(hostname || uname -n) 2>/dev/null | sed 1q`
+ Date=`date`
+ mv -f include/${PACKAGE}-newversion.h.in include/${PACKAGE}-version.h.in
+ sed -e "s/@USER@/$User/" -e "s/@HOST@/$Host/" -e "s/@DATE@/$Date/" include/${PACKAGE}-version.h.in > include/${PACKAGE}-version.h
+fi
+dnl ],host=$host PACKAGE=$PACKAGE VERSION=$VERSION)
+])
diff --git a/usr.sbin/afs/src/cf/linux-func-d_alloc_root-two_args.m4 b/usr.sbin/afs/src/cf/linux-func-d_alloc_root-two_args.m4
new file mode 100644
index 00000000000..f6cfe4323a0
--- /dev/null
+++ b/usr.sbin/afs/src/cf/linux-func-d_alloc_root-two_args.m4
@@ -0,0 +1,21 @@
+dnl
+dnl $Id: linux-func-d_alloc_root-two_args.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+
+AC_DEFUN(AC_LINUX_FUNC_D_ALLOC_ROOT_TWO_ARGS, [
+AC_CACHE_CHECK(if d_alloc_root takes two arguments,
+ac_cv_func_d_alloc_root_two_args,
+AC_TRY_COMPILE_KERNEL([#include <asm/current.h>
+#include <linux/fs.h>
+#include <linux/dcache.h>],
+[
+d_alloc_root(NULL, NULL)
+],
+ac_cv_func_d_alloc_root_two_args=yes,
+ac_cv_func_d_alloc_root_two_args=no))
+
+if test "$ac_cv_func_d_alloc_root_two_args" = "yes"; then
+ AC_DEFINE(HAVE_D_ALLOC_ROOT_TWO_ARGS, 1,
+ [define if d_alloc_root takes two arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/linux-func-devfs-register-eleven-args.m4 b/usr.sbin/afs/src/cf/linux-func-devfs-register-eleven-args.m4
new file mode 100644
index 00000000000..9f610c30165
--- /dev/null
+++ b/usr.sbin/afs/src/cf/linux-func-devfs-register-eleven-args.m4
@@ -0,0 +1,19 @@
+dnl
+dnl $Id: linux-func-devfs-register-eleven-args.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+
+AC_DEFUN(AC_LINUX_FUNC_DEVFS_REGISTER_ELEVEN_ARGS, [
+
+AC_CACHE_CHECK(if devfs_register takes the dir argument,
+ac_cv_func_devfs_register_eleven_args,
+AC_TRY_COMPILE_KERNEL([#include <linux/devfs_fs_kernel.h>
+],[devfs_handle_t de;
+devfs_register(de, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL);
+],
+ac_cv_func_devfs_register_eleven_args=yes,
+ac_cv_func_devfs_register_eleven_args=no))
+if test "$ac_cv_func_devfs_register_eleven_args" = "yes"; then
+ AC_DEFINE(HAVE_DEVFS_REGISTER_ELEVEN_ARGS, 1,
+ [define if devfs_register takes eleven arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/linux-func-init-mutex.m4 b/usr.sbin/afs/src/cf/linux-func-init-mutex.m4
new file mode 100644
index 00000000000..d8973cd85cf
--- /dev/null
+++ b/usr.sbin/afs/src/cf/linux-func-init-mutex.m4
@@ -0,0 +1,20 @@
+dnl
+dnl $Id: linux-func-init-mutex.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+
+AC_DEFUN(AC_LINUX_FUNC_INIT_MUTEX, [
+AC_CACHE_CHECK([for init_MUTEX],
+ac_cv_func_init_mutex, [
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $test_KERNEL_CFLAGS $KERNEL_CPPFLAGS"
+AC_EGREP_CPP([init_MUTEX],
+[#include <asm/semaphore.h>],
+ac_cv_func_init_mutex=yes,
+ac_cv_func_init_mutex=no)]
+CPPFLAGS="$save_CPPFLAGS"
+)
+if test "$ac_cv_func_init_mutex" = "yes"; then
+ AC_DEFINE(HAVE_INIT_MUTEX, 1,
+ [define if you have a function init_MUTEX])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/linux-func-init-wait-queue-head.m4 b/usr.sbin/afs/src/cf/linux-func-init-wait-queue-head.m4
new file mode 100644
index 00000000000..a845c1b83e3
--- /dev/null
+++ b/usr.sbin/afs/src/cf/linux-func-init-wait-queue-head.m4
@@ -0,0 +1,17 @@
+dnl
+dnl $Id: linux-func-init-wait-queue-head.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+
+AC_DEFUN(AC_LINUX_FUNC_INIT_WAITQUEUE_HEAD, [
+AC_CACHE_CHECK([for init_waitqueue_head],
+ac_cv_func_init_waitqueue_head,[
+AC_TRY_COMPILE_KERNEL([#include <linux/wait.h>],
+[wait_queue_head_t foo;
+init_waitqueue_head(&foo)],
+ac_cv_func_init_waitqueue_head=yes,
+ac_cv_func_init_waitqueue_head=no)])
+if test "$ac_cv_func_init_waitqueue_head" = "yes"; then
+ AC_DEFINE(HAVE_INIT_WAITQUEUE_HEAD, 1,
+ [define if you have a init_waitqueue_head])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/linux-type-wait-queue-head.m4 b/usr.sbin/afs/src/cf/linux-type-wait-queue-head.m4
new file mode 100644
index 00000000000..175db4bdfc3
--- /dev/null
+++ b/usr.sbin/afs/src/cf/linux-type-wait-queue-head.m4
@@ -0,0 +1,16 @@
+dnl
+dnl $Id: linux-type-wait-queue-head.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+
+AC_DEFUN(AC_LINUX_TYPE_WAIT_QUEUE_HEAD_T, [
+AC_CACHE_CHECK([for wait_queue_head_t],
+ac_cv_type_wait_queue_head_t,[
+AC_TRY_COMPILE_KERNEL([#include <linux/wait.h>],
+[wait_queue_head_t foo;],
+ac_cv_type_wait_queue_head_t=yes,
+ac_cv_type_wait_queue_head_t=no)])
+if test "$ac_cv_type_wait_queue_head_t" = "yes"; then
+ AC_DEFINE(HAVE_WAIT_QUEUE_HEAD_T, 1,
+ [define if you have a wait_queue_head_t])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/mips-abi.m4 b/usr.sbin/afs/src/cf/mips-abi.m4
new file mode 100644
index 00000000000..4b00d838b50
--- /dev/null
+++ b/usr.sbin/afs/src/cf/mips-abi.m4
@@ -0,0 +1,87 @@
+dnl $Id: mips-abi.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+dnl
+dnl Check for MIPS/IRIX ABI flags. Sets $abi and $abilibdirext to some
+dnl value.
+
+AC_DEFUN(AC_MIPS_ABI, [
+AC_ARG_WITH(mips_abi,
+[ --with-mips-abi=abi ABI to use for IRIX (32, n32, or 64)])
+
+case "$host_os" in
+irix*)
+with_mips_abi="${with_mips_abi:-yes}"
+if test -n "$GCC"; then
+
+# GCC < 2.8 only supports the O32 ABI. GCC >= 2.8 has a flag to select
+# which ABI to use, but only supports (as of 2.8.1) the N32 and 64 ABIs.
+#
+# Default to N32, but if GCC doesn't grok -mabi=n32, we assume an old
+# GCC and revert back to O32. The same goes if O32 is asked for - old
+# GCCs doesn't like the -mabi option, and new GCCs can't output O32.
+#
+# Don't you just love *all* the different SGI ABIs?
+
+case "${with_mips_abi}" in
+ 32|o32) abi='-mabi=32'; abilibdirext='' ;;
+ n32|yes) abi='-mabi=n32'; abilibdirext='32' ;;
+ 64) abi='-mabi=64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) AC_ERROR("Invalid ABI specified") ;;
+esac
+if test -n "$abi" ; then
+ac_foo=krb_cv_gcc_`echo $abi | tr =- __`
+dnl
+dnl can't use AC_CACHE_CHECK here, since it doesn't quote CACHE-ID to
+dnl AC_MSG_RESULT
+dnl
+AC_MSG_CHECKING([if $CC supports the $abi option])
+AC_CACHE_VAL($ac_foo, [
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $abi"
+AC_TRY_COMPILE(,int x;, eval $ac_foo=yes, eval $ac_foo=no)
+CFLAGS="$save_CFLAGS"
+])
+ac_res=`eval echo \\\$$ac_foo`
+AC_MSG_RESULT($ac_res)
+if test $ac_res = no; then
+# Try to figure out why that failed...
+case $abi in
+ -mabi=32)
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mabi=n32"
+ AC_TRY_COMPILE(,int x;, ac_res=yes, ac_res=no)
+ CLAGS="$save_CFLAGS"
+ if test $ac_res = yes; then
+ # New GCC
+ AC_ERROR([$CC does not support the $with_mips_abi ABI])
+ fi
+ # Old GCC
+ abi=''
+ abilibdirext=''
+ ;;
+ -mabi=n32|-mabi=64)
+ if test $with_mips_abi = yes; then
+ # Old GCC, default to O32
+ abi=''
+ abilibdirext=''
+ else
+ # Some broken GCC
+ AC_ERROR([$CC does not support the $with_mips_abi ABI])
+ fi
+ ;;
+esac
+fi #if test $ac_res = no; then
+fi #if test -n "$abi" ; then
+else
+case "${with_mips_abi}" in
+ 32|o32) abi='-32'; abilibdirext='' ;;
+ n32|yes) abi='-n32'; abilibdirext='32' ;;
+ 64) abi='-64'; abilibdirext='64' ;;
+ no) abi=''; abilibdirext='';;
+ *) AC_ERROR("Invalid ABI specified") ;;
+esac
+fi #if test -n "$GCC"; then
+;;
+esac
+])
diff --git a/usr.sbin/afs/src/cf/misc.m4 b/usr.sbin/afs/src/cf/misc.m4
new file mode 100644
index 00000000000..82991737922
--- /dev/null
+++ b/usr.sbin/afs/src/cf/misc.m4
@@ -0,0 +1,3 @@
+dnl $Id: misc.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+define(upcase,`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`)dnl
diff --git a/usr.sbin/afs/src/cf/need-proto.m4 b/usr.sbin/afs/src/cf/need-proto.m4
new file mode 100644
index 00000000000..b634b4433b3
--- /dev/null
+++ b/usr.sbin/afs/src/cf/need-proto.m4
@@ -0,0 +1,25 @@
+dnl $Id: need-proto.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+dnl
+dnl Check if we need the prototype for a function
+dnl
+
+dnl AC_NEED_PROTO(includes, function)
+
+AC_DEFUN(AC_NEED_PROTO, [
+if test "$ac_cv_func_$2+set" != set -o "$ac_cv_func_$2" = yes; then
+AC_CACHE_CHECK([if $2 needs a prototype], ac_cv_func_$2_noproto,
+AC_TRY_COMPILE([$1],
+[struct foo { int foo; } xx;
+extern int $2 (struct foo*);
+$2(&xx);
+],
+eval "ac_cv_func_$2_noproto=yes",
+eval "ac_cv_func_$2_noproto=no"))
+define([foo], [NEED_]translit($2, [a-z], [A-Z])[_PROTO])
+if test "$ac_cv_func_$2_noproto" = yes; then
+ AC_DEFINE(foo, 1, [define if the system is missing a prototype for $2()])
+fi
+undefine([foo])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/osf-func-ubc-lookup.m4 b/usr.sbin/afs/src/cf/osf-func-ubc-lookup.m4
new file mode 100644
index 00000000000..2a56dab5a9d
--- /dev/null
+++ b/usr.sbin/afs/src/cf/osf-func-ubc-lookup.m4
@@ -0,0 +1,24 @@
+dnl
+dnl $Id: osf-func-ubc-lookup.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+
+AC_DEFUN(AC_OSF_FUNC_UBC_LOOKUP, [
+AC_CACHE_CHECK(if ubc_lookup takes six arguments,
+ac_cv_func_ubc_lookup_six_args,
+AC_TRY_COMPILE_KERNEL([
+#if defined(__osf__) && defined(__GNUC__)
+#define asm __foo_asm
+#endif
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <vm/vm_ubc.h>
+], [ubc_lookup(NULL, 0, 0, 0, NULL, NULL)],
+ac_cv_func_ubc_lookup_six_args=yes,
+ac_cv_func_ubc_lookup_six_args=no))
+if test "$ac_cv_func_ubc_lookup_six_args" = yes; then
+ AC_DEFINE(HAVE_SIX_ARGUMENT_UBC_LOOKUP, 1,
+ [define if ubc_lookup takes six arguments])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/osfc2.m4 b/usr.sbin/afs/src/cf/osfc2.m4
new file mode 100644
index 00000000000..f9eb15398f2
--- /dev/null
+++ b/usr.sbin/afs/src/cf/osfc2.m4
@@ -0,0 +1,14 @@
+dnl $Id: osfc2.m4,v 1.1 2000/09/11 14:40:50 art Exp $
+dnl
+dnl enable OSF C2 stuff
+
+AC_DEFUN(AC_CHECK_OSFC2,[
+AC_ARG_ENABLE(osfc2,
+[ --enable-osfc2 enable some OSF C2 support])
+LIB_security=
+if test "$enable_osfc2" = yes; then
+ AC_DEFINE(HAVE_OSFC2, 1, [Define to enable basic OSF C2 support.])
+ LIB_security=-lsecurity
+fi
+AC_SUBST(LIB_security)
+])
diff --git a/usr.sbin/afs/src/cf/prog-cc-flags.m4 b/usr.sbin/afs/src/cf/prog-cc-flags.m4
new file mode 100644
index 00000000000..0ccd68f9fd1
--- /dev/null
+++ b/usr.sbin/afs/src/cf/prog-cc-flags.m4
@@ -0,0 +1,15 @@
+dnl
+dnl $Id: prog-cc-flags.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+
+AC_DEFUN(AC_PROG_CC_FLAGS, [
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_MSG_CHECKING(for $CC warning options)
+if test "$GCC" = "yes"; then
+ extra_flags="-Wall -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast -Wmissing-declarations -Wnested-externs"
+ CFLAGS="$CFLAGS $extra_flags"
+ AC_MSG_RESULT($extra_flags)
+else
+ AC_MSG_RESULT(none)
+fi
+])
diff --git a/usr.sbin/afs/src/cf/proto-compat.m4 b/usr.sbin/afs/src/cf/proto-compat.m4
new file mode 100644
index 00000000000..1c67050f4b8
--- /dev/null
+++ b/usr.sbin/afs/src/cf/proto-compat.m4
@@ -0,0 +1,22 @@
+dnl $Id: proto-compat.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+dnl
+dnl Check if the prototype of a function is compatible with another one
+dnl
+
+dnl AC_PROTO_COMPAT(includes, function, prototype)
+
+AC_DEFUN(AC_PROTO_COMPAT, [
+AC_CACHE_CHECK([if $2 is compatible with system prototype],
+ac_cv_func_$2_proto_compat,
+AC_TRY_COMPILE([$1],
+[$3;],
+eval "ac_cv_func_$2_proto_compat=yes",
+eval "ac_cv_func_$2_proto_compat=no"))
+define([foo], translit($2, [a-z], [A-Z])[_PROTO_COMPATIBLE])
+if test "$ac_cv_func_$2_proto_compat" = yes; then
+ AC_DEFINE(foo, 1, [define if prototype of $2 is compatible with
+ $3])
+fi
+undefine([foo])
+]) \ No newline at end of file
diff --git a/usr.sbin/afs/src/cf/shared-libs.m4 b/usr.sbin/afs/src/cf/shared-libs.m4
new file mode 100644
index 00000000000..69060f1dc8e
--- /dev/null
+++ b/usr.sbin/afs/src/cf/shared-libs.m4
@@ -0,0 +1,186 @@
+dnl
+dnl $Id: shared-libs.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+dnl Shared library stuff has to be different everywhere
+dnl
+
+AC_DEFUN(AC_SHARED_LIBS, [
+
+dnl Check if we want to use shared libraries
+AC_ARG_ENABLE(shared,
+[ --enable-shared create shared libraries for Kerberos])
+
+AC_SUBST(CFLAGS)dnl
+AC_SUBST(LDFLAGS)dnl
+
+case ${enable_shared} in
+ yes ) enable_shared=yes;;
+ no ) enable_shared=no;;
+ * ) enable_shared=no;;
+esac
+
+# NOTE: Building shared libraries may not work if you do not use gcc!
+#
+# OS $SHLIBEXT
+# HP-UX sl
+# Linux so
+# NetBSD so
+# FreeBSD so
+# OSF so
+# SunOS5 so
+# SunOS4 so.0.5
+# Irix so
+#
+# LIBEXT is the extension we should build (.a or $SHLIBEXT)
+LINK='$(CC)'
+AC_SUBST(LINK)
+lib_deps=yes
+REAL_PICFLAGS="-fpic"
+LDSHARED='$(CC) $(PICFLAGS) -shared'
+LIBPREFIX=lib
+build_symlink_command=@true
+install_symlink_command=@true
+install_symlink_command2=@true
+REAL_SHLIBEXT=so
+changequote({,})dnl
+SHLIB_VERSION=`echo $VERSION | sed 's/\([0-9.]*\).*/\1/'`
+SHLIB_SONAME=`echo $VERSION | sed 's/\([0-9]*\).*/\1/'`
+changequote([,])dnl
+case "${host}" in
+*-*-hpux*)
+ REAL_SHLIBEXT=sl
+ REAL_LD_FLAGS='-Wl,+b$(libdir)'
+ if test -z "$GCC"; then
+ LDSHARED="ld -b"
+ REAL_PICFLAGS="+z"
+ fi
+ lib_deps=no
+ ;;
+*-*-linux*)
+ LDSHARED='$(CC) -shared -Wl,-soname,$(LIBNAME).so.'"${SHLIB_SONAME}"
+ REAL_LD_FLAGS='-Wl,-rpath,$(libdir)'
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ build_symlink_command='$(LN_S) -f [$][@] $(LIBNAME).so'
+ install_symlink_command='$(LN_S) -f $(LIB) $(DESTDIR)$(libdir)/$(LIBNAME).so.'"${SHLIB_SONAME}"';$(LN_S) -f $(LIB) $(DESTDIR)$(libdir)/$(LIBNAME).so'
+ install_symlink_command2='$(LN_S) -f $(LIB2) $(DESTDIR)$(libdir)/$(LIBNAME2).so.'"${SHLIB_SONAME}"';$(LN_S) -f $(LIB2) $(DESTDIR)$(libdir)/$(LIBNAME2).so'
+ ;;
+*-*-freebsd3*)
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ LDSHARED='ld -Bshareable'
+ REAL_LD_FLAGS='-Wl,-R$(libdir)'
+ build_symlink_command='$(LN_S) -f [$][@] $(LIBNAME).so'
+ install_symlink_command='$(LN_S) -f $(LIB) $(DESTDIR)$(libdir)/$(LIBNAME).so'
+ install_symlink_command2='$(LN_S) -f $(LIB2) $(DESTDIR)$(libdir)/$(LIBNAME2).so'
+ ;;
+*-*-*bsd*)
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ LDSHARED='ld -Bshareable'
+ REAL_LD_FLAGS='-Wl,-R$(libdir)'
+ ;;
+*-*-osf*)
+ REAL_LD_FLAGS='-Wl,-rpath,$(libdir)'
+ REAL_PICFLAGS=
+ LDSHARED='ld -shared -expect_unresolved \*'
+ ;;
+*-*-solaris2*)
+ REAL_LD_FLAGS='-Wl,-R$(libdir)'
+ if test -z "$GCC"; then
+ LDSHARED='$(CC) -G'
+ REAL_PICFLAGS="-Kpic"
+ fi
+ ;;
+*-fujitsu-uxpv*)
+ REAL_LD_FLAGS='' # really: LD_RUN_PATH=$(libdir) cc -o ...
+ REAL_LINK='LD_RUN_PATH=$(libdir) $(CC)'
+ LDSHARED='$(CC) -G'
+ REAL_PICFLAGS="-Kpic"
+ lib_deps=no # fails in mysterious ways
+ ;;
+*-*-sunos*)
+ REAL_SHLIBEXT=so.$SHLIB_VERSION
+ REAL_LD_FLAGS='-Wl,-L$(libdir)'
+ lib_deps=no
+ ;;
+*-*-irix*)
+ libdir="${libdir}${abilibdirext}"
+ REAL_LD_FLAGS="${abi} -Wl,-rpath,\$(libdir)"
+ LD_FLAGS="${abi} -Wl,-rpath,\$(libdir)"
+ LDSHARED="\$(CC) -shared ${abi}"
+ REAL_PICFLAGS=
+ CFLAGS="${abi} ${CFLAGS}"
+ ;;
+*-*-os2*)
+ LIBPREFIX=
+ EXECSUFFIX='.exe'
+ RANLIB=EMXOMF
+ LD_FLAGS=-Zcrtdll
+ REAL_SHLIBEXT=nobuild
+ ;;
+*-*-cygwin32*)
+ EXECSUFFIX='.exe'
+ REAL_SHLIBEXT=nobuild
+ ;;
+*) REAL_SHLIBEXT=nobuild
+ REAL_PICFLAGS=
+ ;;
+esac
+
+if test "${enable_shared}" != "yes" ; then
+ PICFLAGS=""
+ SHLIBEXT="nobuild"
+ LIBEXT="a"
+ build_symlink_command=@true
+ install_symlink_command=@true
+ install_symlink_command2=@true
+else
+ PICFLAGS="$REAL_PICFLAGS"
+ SHLIBEXT="$REAL_SHLIBEXT"
+ LIBEXT="$SHLIBEXT"
+ AC_MSG_CHECKING(whether to use -rpath)
+ case "$libdir" in
+ /lib | /usr/lib | /usr/local/lib)
+ AC_MSG_RESULT(no)
+ REAL_LD_FLAGS=
+ LD_FLAGS=
+ ;;
+ *)
+ LD_FLAGS="$REAL_LD_FLAGS"
+ test "$REAL_LINK" && LINK="$REAL_LINK"
+ AC_MSG_RESULT($LD_FLAGS)
+ ;;
+ esac
+fi
+
+if test "$lib_deps" = yes; then
+ lib_deps_yes=""
+ lib_deps_no="# "
+else
+ lib_deps_yes="# "
+ lib_deps_no=""
+fi
+AC_SUBST(lib_deps_yes)
+AC_SUBST(lib_deps_no)
+
+# use supplied ld-flags, or none if `no'
+if test "$with_ld_flags" = no; then
+ LD_FLAGS=
+elif test -n "$with_ld_flags"; then
+ LD_FLAGS="$with_ld_flags"
+fi
+
+AC_SUBST(REAL_PICFLAGS) dnl
+AC_SUBST(REAL_SHLIBEXT) dnl
+AC_SUBST(REAL_LD_FLAGS) dnl
+
+AC_SUBST(PICFLAGS) dnl
+AC_SUBST(SHLIBEXT) dnl
+AC_SUBST(LDSHARED) dnl
+AC_SUBST(LD_FLAGS) dnl
+AC_SUBST(LIBEXT) dnl
+AC_SUBST(LIBPREFIX) dnl
+AC_SUBST(EXECSUFFIX) dnl
+
+AC_SUBST(build_symlink_command)dnl
+AC_SUBST(install_symlink_command)dnl
+AC_SUBST(install_symlink_command2)dnl
+])
diff --git a/usr.sbin/afs/src/cf/test-package.m4 b/usr.sbin/afs/src/cf/test-package.m4
new file mode 100644
index 00000000000..bc21ee90c7f
--- /dev/null
+++ b/usr.sbin/afs/src/cf/test-package.m4
@@ -0,0 +1,88 @@
+dnl $Id: test-package.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+dnl AC_TEST_PACKAGE_NEW(package,headers,libraries,extra libs,default locations)
+
+AC_DEFUN(AC_TEST_PACKAGE,[AC_TEST_PACKAGE_NEW($1,[#include <$2>],$4,,$5)])
+
+AC_DEFUN(AC_TEST_PACKAGE_NEW,[
+AC_ARG_WITH($1,
+[ --with-$1=dir use $1 in dir])
+AC_ARG_WITH($1-lib,
+[ --with-$1-lib=dir use $1 libraries in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-$1-lib])
+elif test "X$with_$1" = "X"; then
+ with_$1=yes
+fi])
+AC_ARG_WITH($1-include,
+[ --with-$1-include=dir use $1 headers in dir],
+[if test "$withval" = "yes" -o "$withval" = "no"; then
+ AC_MSG_ERROR([No argument for --with-$1-include])
+elif test "X$with_$1" = "X"; then
+ with_$1=yes
+fi])
+
+AC_MSG_CHECKING(for $1)
+
+case "$with_$1" in
+yes) ;;
+no) ;;
+"") ;;
+*) if test "$with_$1_include" = ""; then
+ with_$1_include="$with_$1/include"
+ fi
+ if test "$with_$1_lib" = ""; then
+ with_$1_lib="$with_$1/lib$abilibdirext"
+ fi
+ ;;
+esac
+header_dirs=
+lib_dirs=
+d='$5'
+for i in $d; do
+ header_dirs="$header_dirs $i/include"
+ lib_dirs="$lib_dirs $i/lib$abilibdirext"
+done
+
+case "$with_$1_include" in
+yes) ;;
+no) ;;
+*) header_dirs="$with_$1_include $header_dirs";;
+esac
+case "$with_$1_lib" in
+yes) ;;
+no) ;;
+*) lib_dirs="$with_$1_lib $lib_dirs";;
+esac
+
+save_CFLAGS="$CFLAGS"
+save_LIBS="$LIBS"
+ires= lres=
+for i in $header_dirs; do
+ CFLAGS="-I$i $save_CFLAGS"
+ AC_TRY_COMPILE([$2],,ires=$i;break)
+done
+for i in $lib_dirs; do
+ LIBS="-L$i $3 $4 $save_LIBS"
+ AC_TRY_LINK([$2],,lres=$i;break)
+done
+CFLAGS="$save_CFLAGS"
+LIBS="$save_LIBS"
+
+if test "$ires" -a "$lres"; then
+ $1_includedir="$ires"
+ $1_libdir="$lres"
+ INCLUDE_$1="-I$$1_includedir"
+ LIB_$1="-L$$1_libdir $3"
+ AC_DEFINE_UNQUOTED(upcase($1),1,[Define if you have the $1 package.])
+ with_$1=yes
+ AC_MSG_RESULT([headers $ires, libraries $lres])
+else
+ INCLUDE_$1=
+ LIB_$1=
+ with_$1=no
+ AC_MSG_RESULT($with_$1)
+fi
+AC_SUBST(INCLUDE_$1)
+AC_SUBST(LIB_$1)
+])
diff --git a/usr.sbin/afs/src/cf/try-compile-kernel.m4 b/usr.sbin/afs/src/cf/try-compile-kernel.m4
new file mode 100644
index 00000000000..537b258f628
--- /dev/null
+++ b/usr.sbin/afs/src/cf/try-compile-kernel.m4
@@ -0,0 +1,10 @@
+dnl
+dnl $Id: try-compile-kernel.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+
+AC_DEFUN(AC_TRY_COMPILE_KERNEL,[
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $test_KERNEL_CFLAGS $KERNEL_CPPFLAGS"
+AC_TRY_COMPILE([$1], [$2], [$3], [$4])
+CFLAGS="$save_CFLAGS"
+])
diff --git a/usr.sbin/afs/src/cf/try-cpp-kernel.m4 b/usr.sbin/afs/src/cf/try-cpp-kernel.m4
new file mode 100644
index 00000000000..93a7996a14c
--- /dev/null
+++ b/usr.sbin/afs/src/cf/try-cpp-kernel.m4
@@ -0,0 +1,10 @@
+dnl
+dnl $Id: try-cpp-kernel.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+
+AC_DEFUN(AC_TRY_CPP_KERNEL,[
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $KERNEL_CPPFLAGS"
+AC_TRY_CPP([$1], [$2], [$3])
+CPPFLAGS="$save_CPPFLAGS"
+])
diff --git a/usr.sbin/afs/src/cf/type-iovec.m4 b/usr.sbin/afs/src/cf/type-iovec.m4
new file mode 100644
index 00000000000..31fb323826a
--- /dev/null
+++ b/usr.sbin/afs/src/cf/type-iovec.m4
@@ -0,0 +1,23 @@
+dnl
+dnl $Id: type-iovec.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+
+dnl
+dnl Check for struct iovec
+dnl
+
+AC_DEFUN(AC_TYPE_IOVEC, [
+
+AC_CACHE_CHECK(for struct iovec, ac_cv_struct_iovec, [
+AC_EGREP_HEADER(
+changequote(, )dnl
+struct[ ]*iovec,
+changequote([,])dnl
+sys/uio.h,
+ac_cv_struct_iovec=yes,
+ac_cv_struct_iovec=no)
+])
+if test "$ac_cv_struct_iovec" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_IOVEC, 1, [define if you have struct iovec])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/type-krb-principal.m4 b/usr.sbin/afs/src/cf/type-krb-principal.m4
new file mode 100644
index 00000000000..adfe69d0ccc
--- /dev/null
+++ b/usr.sbin/afs/src/cf/type-krb-principal.m4
@@ -0,0 +1,26 @@
+dnl
+dnl $Id: type-krb-principal.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+
+dnl
+dnl Check for struct krb_principal
+dnl
+
+AC_DEFUN(AC_TYPE_KRB_PRINCIPAL, [
+
+AC_CACHE_CHECK(for krb_principal, ac_cv_struct_krb_principal, [
+if test "$ac_cv_found_krb4" = "yes"; then
+save_CPPFLAGS="${CPPFLAGS}"
+CPPFLAGS="${KRB4_INC_FLAGS} $CPPFLAGS"
+AC_EGREP_HEADER(krb_principal, krb.h,ac_cv_struct_krb_principal=yes)
+CPPFLAGS="${save_CPPFLAGS}"
+eval "ac_cv_struct_krb_principal=${ac_cv_struct_krb_principal-no}"
+else
+dnl Gross hack to avoid struct krb_principal get defined when we don't have krb
+eval "ac_cv_struct_krb_principal=no"
+fi
+])
+if test "$ac_cv_struct_krb_principal" = "yes"; then
+ AC_DEFINE(HAVE_KRB_PRINCIPAL, 1, [define if you have a struct krb_principal])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/type-msghdr.m4 b/usr.sbin/afs/src/cf/type-msghdr.m4
new file mode 100644
index 00000000000..b14e096c188
--- /dev/null
+++ b/usr.sbin/afs/src/cf/type-msghdr.m4
@@ -0,0 +1,19 @@
+dnl
+dnl $Id: type-msghdr.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+
+dnl
+dnl Check for struct msghdr
+dnl
+
+AC_DEFUN(AC_TYPE_MSGHDR, [
+
+AC_CACHE_CHECK(for struct msghdr, ac_cv_struct_msghdr, [
+AC_EGREP_HEADER([struct msghdr], sys/socket.h,
+ac_cv_struct_msghdr=yes,
+ac_cv_struct_msghdr=no)
+])
+if test "$ac_cv_struct_msghdr" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_MSGHDR, 1, [define if you have struct msghdr])
+fi
+])
diff --git a/usr.sbin/afs/src/cf/wflags.m4 b/usr.sbin/afs/src/cf/wflags.m4
new file mode 100644
index 00000000000..321023b420d
--- /dev/null
+++ b/usr.sbin/afs/src/cf/wflags.m4
@@ -0,0 +1,21 @@
+dnl $Id: wflags.m4,v 1.1 2000/09/11 14:40:51 art Exp $
+dnl
+dnl set WFLAGS
+
+AC_DEFUN(AC_WFLAGS,[
+WFLAGS_NOUNUSED=""
+WFLAGS_NOIMPLICITINT=""
+if test -z "$WFLAGS" -a "$GCC" = "yes"; then
+ # -Wno-implicit-int for broken X11 headers
+ # leave these out for now:
+ # -Wcast-align doesn't work well on alpha osf/1
+ # -Wmissing-prototypes -Wpointer-arith -Wbad-function-cast
+ # -Wmissing-declarations -Wnested-externs
+ WFLAGS="ifelse($#, 0,-Wall, $1)"
+ WFLAGS_NOUNUSED="-Wno-unused"
+ WFLAGS_NOIMPLICITINT="-Wno-implicit-int"
+fi
+AC_SUBST(WFLAGS)dnl
+AC_SUBST(WFLAGS_NOUNUSED)dnl
+AC_SUBST(WFLAGS_NOIMPLICITINT)dnl
+])
diff --git a/usr.sbin/afs/src/conf/Makefile.in b/usr.sbin/afs/src/conf/Makefile.in
new file mode 100644
index 00000000000..484d6da4dfb
--- /dev/null
+++ b/usr.sbin/afs/src/conf/Makefile.in
@@ -0,0 +1,59 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:52 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+ARLACACHEDIR = @ARLACACHEDIR@
+CHMOD = @chmod@
+
+prefix = @prefix@
+sysconfdir = @sysconfdir@
+
+CONF_FILES = CellServDB ThisCell arla.conf SuidCells
+
+all: arla.spec
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(ARLACACHEDIR)
+ $(CHMOD) 700 $(DESTDIR)$(ARLACACHEDIR)
+ $(MKINSTALLDIRS) $(DESTDIR)$(sysconfdir)
+ @CONF_FILES='$(CONF_FILES)'; \
+ for x in $$CONF_FILES; do \
+ echo $(INSTALL_DATA) $(srcdir)/$$x $(DESTDIR)$(sysconfdir)/$$x.default; \
+ $(INSTALL_DATA) $(srcdir)/$$x $(DESTDIR)$(sysconfdir)/$$x.default; \
+ if test -f $(DESTDIR)$(sysconfdir)/$$x; then \
+ echo "$@ will not overwrite $(DESTDIR)$(sysconfdir)/$$x"; \
+ else \
+ echo $(INSTALL_DATA) $(srcdir)/$$x $(DESTDIR)$(sysconfdir)/$$x; \
+ $(INSTALL_DATA) $(srcdir)/$$x $(DESTDIR)$(sysconfdir)/$$x; \
+ fi; \
+ done
+
+uninstall:
+ CONF_FILES='$(CONF_FILES)'; \
+ for x in $$CONF_FILES; do \
+ rm -f $(DESTDIR)$(sysconfdir)/$$x.default; \
+ rm -f $(DESTDIR)$(sysconfdir)/$$x; \
+ done
+
+clean :
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile
+
+realclean: distclean
+
+arla.spec: arla.spec.in ../config.status
+ (cd .. ; CONFIG_FILES=conf/arla.spec CONFIG_HEADERS= $(SHELL) ./config.status)
+
+Makefile: Makefile.in ../config.status
+ (cd .. ; CONFIG_FILES=conf/Makefile CONFIG_HEADERS= $(SHELL) ./config.status)
+
+.PHONY: all install uninstall clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/conf/SuidCells b/usr.sbin/afs/src/conf/SuidCells
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/usr.sbin/afs/src/conf/SuidCells
diff --git a/usr.sbin/afs/src/conf/arla.spec.in b/usr.sbin/afs/src/conf/arla.spec.in
new file mode 100644
index 00000000000..e51990ee3b5
--- /dev/null
+++ b/usr.sbin/afs/src/conf/arla.spec.in
@@ -0,0 +1,133 @@
+#
+# $Id: arla.spec.in,v 1.1 2000/09/11 14:40:52 art Exp $
+#
+# A spec file for build a arla rpm
+#
+# Build both smp and up modules for the current kernel
+#
+# Puts the configurationfiles in /etc/arla
+#
+# Note: it doesn't create the ThisCell file you have to
+# do that yourself.
+#
+#
+%define version @VERSION@
+%define prefix @prefix@
+
+Summary: A free AFS clone
+Name: arla
+
+Version: %{version}
+Release: 1
+Copyright: BSD
+
+Source: ftp.stacken.kth.se:/pub/arla/snap/arla-%{version}.tar.gz
+Group: System Environment/Daemons
+Distribution: Arla
+Vendor: KTH
+URL: http://www.stacken.kth.se/projekt/arla/
+
+BuildRoot: /var/tmp/arla-%{version}-%{release}-root
+Prefix: %{prefix}
+
+Provides: arla
+Requires: krb4
+
+%description
+A free implementation of AFS
+
+%changelog
+
+* Thu Jan 21 2000 <lha@s3.kth.se>
+ Added to distribution
+
+* Thu Jan 21 2000 <lha@s3.kth.se>
+ arla 0.30
+
+* Thu Dec 16 1999 <lha@s3.kth.se>
+ arla 0.29.2
+
+* Mon Dec 13 1999 <lha@s3.kth.se>
+ arla 0.29.1
+
+* Thu Nov 25 1999 <lha@s3.kth.se>
+ arla 0.28
+
+* Mon Nov 8 1999 <lha@s3.kth.se>
+ Build a up and smp module, don't install ThisCell its up to the
+ admin to do right, patch startarla to find what module to use.
+ Do relocateable. Added krb4 requirement.
+
+* Fri Nov 5 1999 <lha@s3.kth.se>
+ First spec with a ChangeLog-entry
+
+%prep
+%setup
+%build
+
+rm -rf ${RPM_BUILD_ROOT}
+
+mkdir ${RPM_BUILD_ROOT}
+
+CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --sysconfdir=/etc/arla
+make
+
+cd xfs/linux
+make clean
+CPPFLAGS="-D__BOOT_KERNEL_SMP=1 -D__BOOT_KERNEL_UP=0" make
+mv xfs.o xfs.smp.o.save
+
+make clean
+CPPFLAGS="-D__BOOT_KERNEL_SMP=0 -D__BOOT_KERNEL_UP=1" make
+mv xfs.o xfs.up.o.save
+
+
+
+echo "dummy file, to be removed later" > xfs.o
+
+mv xfs.up.o.save xfs.up.o
+mv xfs.smp.o.save xfs.smp.o
+
+%install
+
+mkdir ${RPM_BUILD_ROOT}/etc
+make prefix=$RPM_BUILD_ROOT%{prefix} install
+rm $RPM_BUILD_ROOT%{prefix}/bin/xfs.o
+
+
+KERNEL_VERSION=$(uname -r | sed 's/smp$//')
+
+cp xfs/linux/xfs.{smp,up}.o $RPM_BUILD_ROOT%{prefix}/bin
+
+mkdir -p $RPM_BUILD_ROOT/lib/modules/${KERNEL_VERSION}/fs
+cp xfs/linux/xfs.up.o \
+ $RPM_BUILD_ROOT/lib/modules/${KERNEL_VERSION}/fs/xfs.o
+mkdir -p $RPM_BUILD_ROOT/lib/modules/${KERNEL_VERSION}smp/fs
+cp xfs/linux/xfs.smp.o \
+ $RPM_BUILD_ROOT/lib/modules/${KERNEL_VERSION}smp/fs/xfs.o
+
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
+cp xfs/linux/bin/arla $RPM_BUILD_ROOT/etc/rc.d/init.d/arla
+chmod 555 $RPM_BUILD_ROOT/etc/rc.d/init.d/arla
+
+cp xfs/linux/libgetcwd.so $RPM_BUILD_ROOT%{prefix}/lib
+chmod 555 $RPM_BUILD_ROOT%{prefix}/lib/libgetcwd.so
+
+%post
+
+depmod -a
+
+%files
+
+%doc README NEWS ChangeLog
+
+%config /etc/arla/CellServDB
+%config /etc/arla/arla.conf
+%config /etc/arla/SuidCells
+
+%{prefix}/bin
+%{prefix}/lib
+%{prefix}/include
+%{prefix}/cache
+/etc/rc.d/init.d
+/lib/modules
diff --git a/usr.sbin/afs/src/conf/bos.conf b/usr.sbin/afs/src/conf/bos.conf
new file mode 100644
index 00000000000..89ea13a2024
--- /dev/null
+++ b/usr.sbin/afs/src/conf/bos.conf
@@ -0,0 +1,21 @@
+#
+# $Id: bos.conf,v 1.1 2000/09/11 14:40:52 art Exp $
+#
+# Syntax:
+#
+# nodetype [node-specific]
+#
+# Node types and their arguments:
+#
+# program executablefile bos-flags core-dir [one flag to executable]
+# email admin@example.org
+#
+# Where bos-flags are:
+#
+# e - mail
+# c - save coredump from `core-dir' XXX
+# d - try to debug corefile :) XXX
+# - - the nop flag
+#
+email example.adress@example.org
+program /usr/arla/bin/arlad e /usr/arla/cache -nz
diff --git a/usr.sbin/afs/src/conf/services b/usr.sbin/afs/src/conf/services
new file mode 100644
index 00000000000..db78eaf0f20
--- /dev/null
+++ b/usr.sbin/afs/src/conf/services
@@ -0,0 +1,13 @@
+#
+# AFS Services
+#
+afs3-fileserver 7000/udp # Fileserver
+afs3-callback 7001/udp # Callback server
+afs3-prserver 7002/udp # Protection server
+afs3-vlserver 7003/udp # Volumelocation server
+afs3-kaserver 7004/udp # Kerberos authenication server
+afs3-volser 7005/udp # Volume server
+afs3-errors 7006/udp # Error server ?
+afs3-bos 7007/udp # Basic over-see server ?
+afs3-update 7008/udp # ?
+afs3-rmtsys 7009/udp # ?
diff --git a/usr.sbin/afs/src/config.guess b/usr.sbin/afs/src/config.guess
new file mode 100644
index 00000000000..20c971aae9a
--- /dev/null
+++ b/usr.sbin/afs/src/config.guess
@@ -0,0 +1,1171 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+ if test x"$HOST_CC" != x; then
+ CC_FOR_BUILD="$HOST_CC"
+ else
+ if test x"$CC" != x; then
+ CC_FOR_BUILD="$CC"
+ else
+ CC_FOR_BUILD=cc
+ fi
+ fi
+fi
+
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # Netbsd (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ # Determine the machine/vendor (is the vendor relevant).
+ case "${UNAME_MACHINE}" in
+ amiga) machine=m68k-cbm ;;
+ arm32) machine=arm-unknown ;;
+ atari*) machine=m68k-atari ;;
+ sun3*) machine=m68k-sun ;;
+ mac68k) machine=m68k-apple ;;
+ macppc) machine=powerpc-apple ;;
+ hp3[0-9][05]) machine=m68k-hp ;;
+ ibmrt|romp-ibm) machine=romp-ibm ;;
+ *) machine=${UNAME_MACHINE}-unknown ;;
+ esac
+ # The Operating System including object format.
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ sed 's/^ //' << EOF >$dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ rm -f $dummy.c $dummy
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ if test -x /usr/bin/objformat; then
+ if test "elf" = "`/usr/bin/objformat`"; then
+ echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+ exit 0
+ fi
+ fi
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ ld_help_string=`cd /; ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ *ia64)
+ echo "${UNAME_MACHINE}-unknown-linux"
+ exit 0
+ ;;
+ i?86linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0
+ ;;
+ i?86coff)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0
+ ;;
+ sparclinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ armlinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ elf32arm*)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
+ exit 0
+ ;;
+ armelf_linux*)
+ echo "${UNAME_MACHINE}-unknown-linux-gnu"
+ exit 0
+ ;;
+ m68klinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ elf32ppc | elf32ppclinux)
+ # Determine Lib Version
+ cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.c $dummy
+ echo powerpc-unknown-linux-gnu${LIBC}
+ exit 0
+ ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ cat <<EOF >$dummy.s
+ .data
+ \$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+ main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ esac
+
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >$dummy.c <<EOF
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ elif test "${UNAME_MACHINE}" = "s390"; then
+ echo s390-ibm-linux && exit 0
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i?86:*:5:7*)
+ # Fixed at (any) Pentium or better
+ UNAME_MACHINE=i586
+ if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
+ echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i?86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Mac*OS:*:*)
+ echo powerpc-apple-macos${UNAME_RELEASE}
+ exit 0 ;;
+ *:Mac*OS:*:*)
+ echo ${UNAME_MACHINE}-apple-macos${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-qnx-qnx${UNAME_VERSION}
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/usr.sbin/afs/src/config.sub b/usr.sbin/afs/src/config.sub
new file mode 100644
index 00000000000..00b90f8841c
--- /dev/null
+++ b/usr.sbin/afs/src/config.sub
@@ -0,0 +1,1256 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+#
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+ | alphaev6[78] \
+ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+ | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+ | mips64vr5000 | miprs64vr5000el | mcore \
+ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+ | thumb | d10v | fr30 | avr)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ # FIXME: clean up the formatting here.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+ | xmp-* | ymp-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+ | alphaev6[78]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+ | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+ | mipstx39-* | mipstx39el-* | mcore-* \
+ | f301-* | armv*-* | s390-* | sv1-* | t3e-* \
+ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+ | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* )
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ i386-go32 | go32)
+ basic_machine=i386-unknown
+ os=-go32
+ ;;
+ i386-mingw32 | mingw32)
+ basic_machine=i386-unknown
+ os=-mingw32
+ ;;
+ i386-qnx | qnx)
+ basic_machine=i386-qnx
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos)
+ basic_machine=i386-unknown
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=t3e-cray
+ os=-unicos
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc | sparcv9)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -opened* | -openstep* | -oskit*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -qnx)
+ os=-qnx4
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -*MiNT)
+ os=-mint
+ ;;
+ -neutrino* | -nto*)
+ os=-neutrino
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -*MiNT)
+ vendor=atari
+ ;;
+ -neutrino* | -nto*)
+ vendor=qnx
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/usr.sbin/afs/src/configure.in b/usr.sbin/afs/src/configure.in
new file mode 100644
index 00000000000..ed27a142816
--- /dev/null
+++ b/usr.sbin/afs/src/configure.in
@@ -0,0 +1,1611 @@
+dnl Process this file with autoconf to produce a configure script
+dnl This requires autoconf 2.13
+AC_REVISION($Revision: 1.1 $)dnl
+AC_PREREQ(2.13)
+AC_INIT(arlad/arla.c)
+AC_CONFIG_HEADER(include/config.h)
+
+dnl
+dnl definitions
+dnl
+
+PACKAGE=arla
+AC_SUBST(PACKAGE)dnl
+VERSION=0.35pre
+AC_SUBST(VERSION)dnl
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [what package is this?])dnl
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [and what version?])dnl
+
+# This may be overridden using --prefix=/usr to configure
+AC_PREFIX_DEFAULT(/usr/arla)
+
+CFLAGS="-g ${CFLAGS}"
+
+if test "$AS" = ""; then
+ AS=as
+fi
+AC_SUBST(AS)dnl
+
+AC_PROG_CC
+AC_PROG_CC_FLAGS
+AC_PROG_CPP
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+AC_PROG_LN_S
+AC_PROG_LEX
+AC_PROG_YACC
+AC_CANONICAL_HOST
+CANONICAL_HOST=$host
+AC_SUBST(CANONICAL_HOST)
+AC_CHECK_PROGS(SYMORDER, symorder, :)
+AC_CHECK_PROGS(MAKEINFO, makeinfo, :)
+AC_CHECK_PROGS(DVI2PS, dvi2ps, :)
+AC_CHECK_PROGS(TEXI2DVI, texi2dvi, :)
+AC_CHECK_PROGS(TEXI2PDF, texi2pdf, :)
+AC_CHECK_PROGS(TEXI2HTML, texi2html, :)
+AC_CHECK_PROGS(DVIPS, dvips, :)
+AC_CHECK_PROGS(chmod, chmod, :)
+AC_PATH_PROGS(GUILE_GTK, guile-gtk, /bin/false)
+
+dnl
+dnl See if there is any X11 present
+dnl
+KRB_CHECK_X
+if test "$no_x" = "yes" ; then
+ MAKE_X_PROGS_BIN=""
+else
+ MAKE_X_PROGS_BIN='$(X_PROGS_BIN)'
+fi
+AC_SUBST(MAKE_X_PROGS_BIN)dnl
+
+
+AC_FUNC_NTOHL
+
+AC_ARG_ENABLE(smp,
+[ --enable-smp compile for SMP (for Linux and FreeBSD)],
+[if test "$enableval" = "yes"; then
+ smp="-DSMP -D__SMP__"
+else
+ smp="no"
+fi
+])
+
+AC_ARG_ENABLE(kld,
+[ --enable-kld build kld modules (only FreeBSD 3.0)],
+[if test "$enableval" = "yes"; then
+ kld="yes"
+else
+ kld="no"
+fi
+])
+
+# what kind of lwp
+
+LWP_PROCESS="process.o"
+LWP_C="lwp_asm.c"
+LWP_O="lwp_asm.o"
+LWP_H="lwp_asm.h"
+PLWP_LIB_FLAGS=""
+PLWP_INC_FLAGS=""
+
+AC_ARG_WITH(pthreads,
+[ --with-pthreads=dir compile liblwp as pthreads wrapper using pthreads in dir],
+[if test "$with_pthreads" = "windows"; then
+ with_pthreads=win
+elif test "$with_pthreads" != "no"; then
+ LWP_PROCESS=""
+ LWP_C="plwp.c"
+ LWP_O="plwp.o"
+ LWP_H="plwp.h"
+ PLWP_INC_FLAGS="-DPTHREADS_LWP"
+ if test "$with_pthreads" != "yes"; then
+ PLWP_LIB_FLAGS="-L${with_pthreads}/lib -lpthread"
+ PLWP_INC_FLAGS="-I${with_pthreads}/include -DPTHREADS_LWP"
+ else
+ PLWP_LIB_FLAGS="-lpthread"
+ PLWP_INC_FLAGS="-DPTHREADS_LWP"
+ fi
+fi],[with_pthreads=no])
+
+# where the source tree is located
+
+case "$target_os" in
+ linux*)
+ default_sys=/usr/src/linux
+ ;;
+ *)
+ default_sys=/sys
+ ;;
+esac
+AC_ARG_WITH(sys,
+[ --with-sys=dir use dir as your kernel source code directory
+ default $default_sys],
+[SYS=$withval],
+[SYS="$default_sys"])
+AC_SUBST(SYS)
+
+xfs_target="$target_os"
+AC_ARG_ENABLE(xfs,
+[ --disable-xfs build arla w/o xfs],
+[if test "$enableval" = "no" ; then
+ xfs_target="without_xfs";
+fi])
+
+AC_MSG_CHECKING(for kernel stuff)
+case "$xfs_target" in
+sunos4.1*)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/sunos
+ KERNEL_SRCS='sunos-subr.c'
+ KERNEL_HDRS=''
+ XFS_SUBDIR=sunos
+ KERNEL=/vmunix
+ AC_MSG_RESULT(SunOS 4.1.x)
+ ;;
+solaris*)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/solaris
+ KERNEL_SRCS='solaris-subr.c'
+ KERNEL_HDRS=''
+ XFS_SUBDIR=solaris
+ KERNEL=/dev/ksyms
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -D_KERNEL"
+ AC_MSG_RESULT(Solaris)
+ case "$target_cpu" in
+ sparc64) AC_DEFINE(NEED_VICEIOCTL32, 1,
+ [define if you need 32 bit compat pioctl])
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -D_SYSCALL32 -D_SYSCALL32_IMPL"
+ ;;
+ esac
+ ;;
+irix*)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/irix
+ KERNEL_SRCS='irix-subr.c'
+ KERNEL_HDRS=''
+ ip=`hinv -c processor | awk '$4 ~ /IP/ { print $4}'`
+ cpu=`hinv -t cpu | awk '{print $3}'`
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -D$ip -D$cpu -DR4000"
+ XFS_SUBDIR=irix
+ KERNEL=/unix
+ case "$target_os" in
+changequote(, )dnl
+ irix6.[4-9])
+changequote([,])dnl
+ AC_DEFINE(IRIX_64, 1, [define this if on Irix6.4 or higher]) ;;
+ esac
+ AC_MSG_RESULT(Irix)
+ ;;
+hpux*)
+ KERNEL_SRCS='hpux-subr.c'
+ AC_MSG_RESULT(hp-ux)
+ KERNEL=/hp-ux
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/unknown
+ AC_MSG_WARN(No kernel support for $target_os, compiling only user-level stuff)
+ ;;
+aix*)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/aix
+ KERNEL_SRCS='aix-subr.c'
+ KERNEL_HDRS=''
+ XFS_SUBDIR=aix
+ AC_MSG_RESULT(AIX)
+ ;;
+openbsd*)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/bsd
+ KERNEL_SRCS='bsd-subr.c'
+ KERNEL_HDRS=''
+ MODULE=xfs_mod.o
+ cat > conftest.mk << END
+.include <bsd.lkm.mk>
+.if defined(UVM) && (\${UVM} != "no")
+CFLAGS+=-DUVM
+.endif
+.if PMAP_NEW
+CFLAGS+=-DPMAP_NEW
+.endif
+echo:
+ @echo \$(CFLAGS)
+END
+ ac_out=`/usr/bin/make S=$SYS -f conftest.mk echo 2> /dev/null`
+ incl= defs= flags=
+ for i in $ac_out; do
+ case "$i" in
+ -I*) if test "$i" != -I. -a "$i" != "-I`pwd`"; then
+ incl="$incl${incl:+ }$i"
+ fi
+ ;;
+ -D*) defs="$defs${defs:+ }$i" ;;
+ -m*) flags="$flags${flags:+ }$i" ;;
+ *) ;;
+ esac
+ done
+## -DKERNEL -DLKM -DACTUALLY_LKM_NOT_KERNEL ??
+ # make sure we compile with -mno-fp-regs on alpha
+ if test `uname -m` = alpha -a `expr "$flags" : ".*-mno-fp-regs"` -eq 0
+ then
+ flags="$flags${flags:+ }-mno-fp-regs"
+ fi
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -D_LKM"
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} $defs${defs:+ }$flags${flags:+ }$incl"
+ test_KERNEL_CFLAGS="${KERNEL_CFLAGS}"
+ KERNEL_LD='ld'
+ XFS_SRCS='xfs_wrap-bsd.c xfs_common-bsd.c xfs_dev-common.c xfs_dev-bsd.c xfs_syscalls-common.c xfs_syscalls-wrap-bsd.c xfs_node-bsd.c xfs_vfsops-common.c xfs_vfsops-bsd.c xfs_vfsops-openbsd.c xfs_vnodeops-common.c xfs_vnodeops-bsd.c'
+ XFS_SUBDIR=bsd
+ KERNEL=/bsd
+ MODLOAD=modload
+ MODUNLOAD=modunload
+ AC_MSG_RESULT(OpenBSD)
+ ;;
+netbsd* | netbsdelf*)
+ dnl There is a nasty bug in 1.4.2 that make shared libs
+ dnl together with syscall(2) fail with bus error.
+ case "$target_os" in
+ netbsd1.4.2)
+ if test X"$GCC" = Xyes ; then
+ CC="$CC -static"
+ else
+ AC_MSG_WARN([There is a problem with netbsd 1.4.2, you should build it static])
+ fi
+ ;;
+ esac
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/bsd
+ KERNEL_SRCS='bsd-subr.c'
+ KERNEL_HDRS=''
+ MODULE=xfs_mod.o
+ cat > conftest.mk << END
+.include <bsd.kmod.mk>
+.if UVM
+CFLAGS+=-DUVM
+.endif
+.if PMAP_NEW
+CFLAGS+=-DPMAP_NEW
+.endif
+echo:
+ @echo \$(CFLAGS)
+END
+ ac_out=`/usr/bin/make S=$SYS -f conftest.mk echo 2> /dev/null`
+ incl= defs= flags=
+ for i in $ac_out; do
+ case "$i" in
+ -I*) if test "$i" != -I. -a "$i" != "-I`pwd`"; then
+ incl="$incl${incl:+ }$i"
+ fi
+ ;;
+ -D*) defs="$defs${defs:+ }$i" ;;
+ -m*) flags="$flags${flags:+ }$i" ;;
+ *) ;;
+ esac
+ done
+## -DKERNEL -DLKM -DACTUALLY_LKM_NOT_KERNEL ??
+ # make sure we compile with -mno-fp-regs on alpha
+ if test `uname -m` = alpha -a `expr "$flags" : ".*-mno-fp-regs"` -eq 0
+ then
+ flags="$flags${flags:+ }-mno-fp-regs"
+ fi
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} $defs${defs:+ }$flags${flags:+ }$incl"
+ test_KERNEL_CFLAGS="${KERNEL_CFLAGS}"
+ KERNEL_LD='ld'
+ XFS_SRCS='xfs_wrap-bsd.c xfs_common-bsd.c xfs_dev-common.c xfs_dev-bsd.c xfs_syscalls-common.c xfs_syscalls-wrap-bsd.c xfs_node-bsd.c xfs_vfsops-common.c xfs_vfsops-bsd.c xfs_vfsops-netbsd.c xfs_vnodeops-common.c xfs_vnodeops-bsd.c'
+ XFS_SUBDIR=bsd
+ KERNEL=/netbsd
+ MODLOAD=modload
+ MODUNLOAD=modunload
+ AC_MSG_RESULT(NetBSD)
+ ;;
+changequote(, )dnl
+freebsd[345]* | freebsdelf[345]*)
+ AC_MSG_RESULT(FreeBSD [345].x)
+changequote([,])dnl
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/bsd
+ KERNEL_SRCS='bsd-subr.c'
+ KERNEL_HDRS=''
+ KERNEL=`sysctl -n kern.bootfile`
+ AC_MSG_CHECKING(for kernel object format)
+ kernobjformat=aout
+ case `file $KERNEL 2>/dev/null` in
+ *ELF*) kernobjformat=elf ;;
+ esac
+ AC_MSG_RESULT($kernobjformat)
+
+ AC_MSG_CHECKING(for kld)
+ dnl Default to kld if freebsd4.0
+ case "$target_os" in
+changequote(, )dnl
+ freebsd[45]*)
+changequote([,])dnl
+ if test "X$kld" = "X"; then
+ kld="yes";
+ fi
+ ;;
+ esac
+ dnl Or if the kernel is ELF
+ case "$kernobjformat" in
+ elf*)
+ if test "X$kld" = "X"; then
+ kld=yes;
+ fi
+ ;;
+ esac
+ KERNEL_CFLAGS="${KERNEL_CFLAGS}${KERNEL_CFLAGS:+ }-O"
+ if test `uname -m` = alpha -a `expr "$KERNEL_CFLAGS" : ".*-mno-fp-regs"` -eq 0
+ then
+ KERNEL_CFLAGS="${KERNEL_CFLAGS}${KERNEL_CFLAGS:+ }-mno-fp-regs"
+ fi
+ if test "$kld" = "yes"; then
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} $smp -DKERNEL -D_KERNEL -DVFS_KLD -DKLD_MODULE -I$SYS/arch -I$SYS -I."
+ test_KERNEL_CFLAGS="-$kernobjformat ${KERNEL_CFLAGS}"
+ KERNEL_LD='ld'
+ case "$kernobjformat" in
+ aout) extra_LDFLAGS="-A" ;;
+ elf) extra_LDFLAGS="-R" ;;
+ *) AC_MSG_ERROR([Unknown object format $kernobjformat])
+ esac
+ ac_kernel_ld='${LD-ld} -$kernobjformat -o conftest $LDFLAGS $extra_LDFLAGS $KERNEL conftest.o -e _foo 1>&AC_FD_CC'
+ MODULE=xfs.ko
+ AC_MSG_RESULT(yes)
+ else
+ if test "$kernobjformat" != "aout"; then
+ AC_MSG_WARN([You cannot build LKMs against $kernobjformat kernels])
+ fi
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} $smp -DKERNEL -D_KERNEL -DLKM -D_LKM -DVFS_LKM -DACTUALLY_LKM_NOT_KERNEL -I$SYS/arch -I$SYS -I."
+ test_KERNEL_CFLAGS="-aout ${KERNEL_CFLAGS}"
+ KERNEL_LD='ld -aout'
+ ac_kernel_ld='${LD-ld} -aout -o conftest $LDFLAGS -A $KERNEL conftest.o -e _foo 1>&AC_FD_CC'
+ MODULE=xfs_mod.o
+ AC_MSG_RESULT(no)
+ fi
+
+ XFS_SUBDIR=bsd
+ XFS_SRCS='xfs_wrap-bsd.c xfs_common-bsd.c xfs_dev-common.c xfs_dev-bsd.c xfs_syscalls-common.c xfs_syscalls-wrap-freebsd.c xfs_node-bsd.c xfs_vfsops-common.c xfs_vfsops-bsd.c xfs_vfsops-freebsd.c xfs_vnodeops-common.c xfs_vnodeops-bsd.c'
+ MODLOAD=modload
+ MODUNLOAD=modunload
+
+ ;;
+macos*|darwin*)
+ AC_MSG_RESULT(MacOS)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/bsd
+ KERNEL_SRCS='bsd-subr.c'
+ KERNEL_HDRS=''
+ KERNEL=/mach
+
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -DKERNEL -D_KERNEL -I/System/Library/Frameworks/Kernel.framework/Headers -static -DKERNEL_PRIVATE -DDIAGNOSTIC -DUSE_SELECT -DMACH_USER_API"
+ KERNEL_CFLAGS="${KERNEL_CFLAGS} -fno-common -Wno-format -pipe -finline -fno-keep-inline-functions -force_cpusubtype_ALL -msoft-float -mlong-branch"
+ test_KERNEL_CFLAGS="${KERNEL_CFLAGS}"
+ KERNEL_LD='ld'
+ MODULE=xfs_mod.o
+
+ MODLOAD=kmodload
+ MODUNLOAD=kmodunload
+
+ XFS_SUBDIR=bsd
+ XFS_SRCS='xfs_wrap-bsd.c xfs_common-bsd.c xfs_dev-common.c xfs_dev-bsd.c xfs_syscalls-common.c xfs_syscalls-wrap-bsd.c xfs_node-bsd.c xfs_vfsops-common.c xfs_vfsops-bsd.c xfs_vfsops-macos.c xfs_vnodeops-common.c xfs_vnodeops-bsd.c xfs_info.c'
+
+ ;;
+linux*)
+ AC_MSG_RESULT(Linux)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/linux
+ KERNEL_SRCS='bsd-subr.c'
+ KERNEL_HDRS=''
+ AC_MSG_CHECKING(for smp)
+if test "X$smp" = "Xno"; then
+ smp=
+elif test "X$smp" = "X"; then
+ AC_EGREP_CPP(
+changequote(, )dnl
+smp_[0-9a-z_]*,dnl
+changequote([,])dnl
+[#include <linux/config.h>
+#ifdef CONFIG_MODVERSIONS
+#define MODVERSIONS
+#include <linux/modversions.h>
+#endif
+__ver_get_module_symbol], smp='-D__SMP__', [
+changequote(, )dnl
+if grep 'smp_[0-9a-zA-Z_]*\>' /proc/ksyms >/dev/null || test `grep -c '^processor' /proc/cpuinfo` -gt 1; then
+ smp='-D__SMP__'
+fi
+changequote([,])dnl
+fi
+])
+ if test "X$smp" = "X"; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(yes)
+ fi
+ KERNEL_CPPFLAGS="-I$SYS/include -DMODULE -D__KERNEL__ $smp ${KERNEL_CPPFLAGS} "
+ KERNEL_CC="$CC"
+ case "$target_cpu" in
+ alpha*)
+ KERNEL_CFLAGS="${KERNEL_CFLAGS} -mno-fp-regs -ffixed-8" ;;
+ sparc64*)
+ KERNEL_CFLAGS="${KERNEL_CFLAGS} -mno-fpu -ffixed-g4 -fcall-used-g5 -fcall-used-g7"
+ KERNEL_LDFLAGS="-m elf64_sparc"
+ KERNEL_CC=sparc64-linux-gcc
+ AC_DEFINE(NEED_VICEIOCTL32, 1,
+ [define if you need 32 bit compat pioctl]);;
+ esac
+ test_KERNEL_CFLAGS="${KERNEL_CFLAGS}"
+ XFS_SUBDIR=linux
+ KERNEL=/dev/null
+ ;;
+osf*)
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/bsd
+ KERNEL_SRCS=bsd-subr.c
+ KERNEL_HDRS=
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -DKERNEL -D_KERNEL -DMACH"
+ XFS_SRCS='xfs_wrap-osf.c xfs_common-osf.c xfs_dev-common.c xfs_dev-osf.c xfs_syscalls-common.c xfs_syscalls-wrap-osf.c xfs_node-osf.c xfs_vfsops-common.c xfs_vfsops-osf.c xfs_vnodeops-common.c xfs_vnodeops-osf.c'
+ # XXX find kernel include dir
+ nodename=`hostname | sed 's/\..*//' | tr 'a-z' 'A-Z'`
+ foo=`ls $SYS/inet.h $SYS/GENERIC/inet.h $SYS/$nodename/inet.h $SYS/*/inet.h 2> /dev/null | head -1 | sed -e 's,/inet.h,,'`
+ KERNEL_CPPFLAGS="${KERNEL_CPPFLAGS} -I/usr/sys/include -I$foo"
+ test_KERNEL_CFLAGS="${KERNEL_CFLAGS}"
+ KERNEL_LD='ld'
+ XFS_SUBDIR=bsd
+ AC_MSG_RESULT(osf/1)
+ KERNEL=/vmunix
+ case "$CC" in
+ cc)
+ CC="$CC -std1"
+ ;;
+ esac
+ MODLOAD=modload
+ MODUNLOAD=modunload
+ ;;
+cygwin*)
+ AC_MSG_RESULT(cygwin/VC)
+ AC_MSG_WARN([Only kernel support for NT])
+ if test "$with_pthreads" = "windows"; then
+ AC_MSG_WARN([Using LWP on windows native threads])
+ LWP_PROCESS=""
+ LWP_C="plwp.c"
+ LWP_O="plwp.o"
+ LWP_H="plwp.h"
+ PLWP_INC_FLAGS="-DWINDOWS_THREADS_LWP"
+ else
+ AC_MSG_WARN([Using LWP on asm threads or pthreads])
+ fi
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/unknown
+ KERNEL_SRCS=unknown-subr.c
+ KERNEL_HDRS=
+ KERNEL=/dev/null
+ XFS_SUBDIR=
+ ;;
+*)
+ AC_MSG_RESULT(none)
+ if test "$xfs_target" != "without_xfs"; then
+ AC_MSG_WARN([No kernel support for $target_os, compiling only user-level stuff])
+ fi
+ KERNEL_INCLUDE=-I`(cd $srcdir; pwd)`/xfs/unknown
+ KERNEL_SRCS=unknown-subr.c
+ KERNEL_HDRS=
+ KERNEL=/dev/null
+ XFS_SUBDIR=
+ ;;
+esac
+if test "$XFS_SUBDIR" != ""; then
+ XFS_SUBDIR_Makefile=xfs/$XFS_SUBDIR/Makefile
+ XFS_SUBDIR_BIN_Makefile=xfs/$XFS_SUBDIR/bin/Makefile
+fi
+
+AM_CONDITIONAL(OSF1, test "`uname`" = OSF1)dnl
+
+# Check where to put the cache
+
+AC_ARG_WITH(arlacachedir,
+[ --with-arlacachedir=dir use dir as cachedir instead of \$prefix/cache],
+[ARLACACHEDIR=$withval],
+[ARLACACHEDIR='${prefix}/cache'])
+
+# Check where to find the configuration
+
+AC_ARG_WITH(arlaconffile,
+[ --with-arlaconffile=file use file for configuration instead of \$prefix/etc/arla.conf],
+[ARLACONFFILE=$withval],
+[ARLACONFFILE='${sysconfdir}/arla.conf'])
+
+# Do we want knfs ?
+
+ARLA_KNFS=""
+AC_ARG_ENABLE(knfs,
+[ --enable-knfs make afs nfs-mountable],
+[ARLA_KNFS="-DARLA_KNFS"])
+AC_SUBST(ARLA_KNFS)
+
+dnl
+dnl If we want to use pthreads
+dnl
+
+AC_SUBST(LWP_PROCESS)
+AC_SUBST(PLWP_LIB_FLAGS)
+AC_SUBST(PLWP_INC_FLAGS)
+AC_SUBST(LWP_C)
+AC_SUBST(LWP_O)
+AC_SUBST(LWP_H)
+
+AC_CHECK_KERBEROS(45auto)
+AC_CHECK_KAFS
+
+if test "X$ac_cv_found_krb4" = "Xyes"; then
+ RXKAD="rxkad"
+ RXKAD_MAKEFILE="rxkad/Makefile"
+ RXKAD_LIBS="-L../rxkad -lrxkad $KRB4_LIB_FLAGS"
+ MILKO_RXKAD_LIBS=`echo $RXKAD_LIBS | sed s,\.\./,\.\./\.\./,`
+ MILKO_RXKAD_LIBS2=`echo $MILKO_RXKAD_LIBS | sed s,\.\./,\.\./\.\./,`
+ APPL_SUBDIRS='afsutils amon fs'
+else
+ APPL_SUBDIRS=
+fi
+
+AC_SUBST(APPL_SUBDIRS)dnl
+
+AC_TYPE_MSGHDR
+AC_TYPE_IOVEC
+AC_TYPE_KRB_PRINCIPAL
+AC_FUNC_KRB_GET_ERR_TEXT
+AC_FUNC_KRB_GET_DEFAULT_TKT_ROOT
+AC_FUNC_KRB_KDCTIMEOFDAY
+
+dnl AC_TYPE_MODE_T
+dnl AC_CHECK_TYPE(nlink_t, int)
+
+dnl
+dnl Tests for readline/editline
+dnl
+
+AC_TEST_PACKAGE_NEW(readline,[
+#include <stdio.h>
+#include <readline.h>
+],-lreadline)
+
+if test "$with_readline" = "no"; then
+ AC_FIND_FUNC_NO_LIBS(tgetent, termcap ncurses curses)
+ if test "$ac_cv_funclib_tgetent" = "no"; then
+ AC_MSG_ERROR([Could not find tgetent, needed by edit/editline])
+ fi
+ AC_FIND_FUNC_NO_LIBS(readline, editline edit readline, [], [], [$LIB_tgetent])
+ if test "$ac_cv_func_readline" = "no"; then
+ AC_FIND_FUNC_NO_LIBS(el_init, edit, [], [], [$LIB_tgetent])
+ if test "$ac_cv_func_el_init" = yes; then
+ editline_OBJS=edit_compat.o
+ LIB_readline='-L'`pwd`'/lib/editline -leditline '"$LIB_el_init";
+ INCLUDE_readline='-I'`pwd`'/lib/editline -I$(top_srcdir)/lib/editline'
+ else
+ editline_OBJS="editline.o complete.o sysunix.o"
+ LIB_readline='-L'`pwd`'/lib/editline -leditline'
+ INCLUDE_readline='-I'`pwd`'/lib/editline -I$(top_srcdir)/lib/editline'
+ fi
+ fi
+fi
+AC_DEFINE(HAVE_READLINE, 1, [define if you have a function readline])dnl
+LIB_readline="$LIB_readline \$(LIB_tgetent)"
+
+AC_ARG_ENABLE(mmap,
+[ --disable-mmap don't use mmap],
+[if test "$enableval" = "no"; then
+ ac_cv_func_mmap_fixed_mapped=no
+ fi])
+
+AC_ARG_ENABLE(mmaptime,
+[ --enable-mmaptime use mmaptime time, read the README before use (disable by default)],
+[if test "$enableval" = "yes" -o "X$enableval" = "X"; then
+ AC_DEFINE(USE_MMAPTIME, 1, [define if you want to use mmaptime])
+fi])
+
+aix_dynamic_afs=yes
+AC_ARG_ENABLE(dynamic-afs,
+[ --disable-dynamic-afs don't use loaded AFS library with AIX],[
+if test "$enableval" = "no"; then
+ aix_dynamic_afs=no
+fi
+])
+
+AC_CHECK_LFS
+AC_CHECK_GLIBC
+
+AC_SUBST(LIB_readline)
+AC_SUBST(INCLUDE_readline)
+AC_SUBST(editline_OBJS)dnl
+if test "$editline_OBJS" != ""; then
+ editline_dir=editline
+fi
+AC_SUBST(editline_dir)
+
+AC_SUBST(GCC)
+AC_SUBST(CFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(KERNEL_INCLUDE)
+AC_SUBST(KERNEL_SRCS)
+AC_SUBST(KERNEL_HDRS)
+AC_SUBST(KERNEL_CPPFLAGS)
+AC_SUBST(KERNEL_CFLAGS)
+AC_SUBST(KERNEL_LDFLAGS)
+AC_SUBST(KERNEL_CC)
+AC_SUBST(KERNEL_LD)
+AC_SUBST(MODLOAD)
+AC_SUBST(MODUNLOAD)
+AC_SUBST(MODULE)
+AC_SUBST(XFS_SUBDIR)
+AC_SUBST(XFS_SRCS)
+AC_SUBST(RXKAD)
+AC_SUBST(MILKO_RXKAD_LIBS)
+AC_SUBST(MILKO_RXKAD_LIBS2)
+AC_SUBST(RXKAD_LIBS)
+AC_SUBST(ARLACACHEDIR)
+AC_SUBST(ARLACONFFILE)
+AC_FUNC_MMAP
+
+dnl
+dnl Various checks for headers and their contents
+dnl
+
+AC_HEADER_STDC
+AC_HEADER_TIME
+
+AC_CHECK_HEADERS([ \
+ arpa/inet.h \
+ arpa/nameser.h \
+ crypt.h \
+ dbm.h \
+ dirent.h \
+ errno.h \
+ fcntl.h \
+ grp.h \
+ inttypes.h \
+ kvm.h \
+ libelf/nlist.h \
+ machine/alpha/asm.h \
+ machine/asm.h \
+ machine/endian.h \
+ machine/regdef.h \
+ miscfs/genfs/genfs.h \
+ ndbm.h \
+ netdb.h \
+ netinet/in.h \
+ netinet/in6.h \
+ netinet/in6_machtypes.h \
+ netinet6/in6.h \
+ nlist.h \
+ paths.h \
+ pwd.h \
+ regdef.h \
+ resolv.h \
+ rpcsvc/dbm.h \
+ shadow.h \
+ sys/attr.h \
+ sys/bitypes.h \
+ sys/cdefs.h \
+ sys/dir.h \
+ sys/filedesc.h \
+ sys/ioccom.h \
+ sys/ioctl.h \
+ sys/lkm.h \
+ sys/mman.h \
+ sys/module.h \
+ sys/mount.h \
+ sys/param.h \
+ sys/poll.h \
+ sys/proc.h \
+ sys/queue.h \
+ sys/resource.h \
+ sys/select.h \
+ sys/signalvar.h \
+ sys/socket.h \
+ sys/sockio.h \
+ sys/stat.h \
+ sys/syscallargs.h \
+ sys/sysconfig.h \
+ sys/sysctl.h \
+ sys/sysent.h \
+ sys/sysproto.h \
+ sys/time.h \
+ sys/tty.h \
+ sys/types.h \
+ sys/uio.h \
+ sys/user.h \
+ sys/utsname.h \
+ sys/vfs.h \
+ sys/wait.h \
+ syslog.h \
+ termios.h \
+ unistd.h \
+ uvm/uvm_extern.h \
+ vm/vm.h \
+ vm/vm_extern.h \
+ vm/vm_object.h \
+ vm/vm_pager.h \
+ vm/vm_zone.h \
+ vm/vnode_pager.h \
+])
+
+dnl
+dnl Check for endian-ness
+dnl
+KRB_C_BIGENDIAN
+
+dnl
+dnl check for const
+dnl
+
+AC_C_CONST
+
+dnl
+dnl Check for inline
+dnl
+
+AC_C_INLINE
+
+dnl
+dnl Check for __FUNCTION__
+dnl
+
+AC_C___FUNCTION__
+
+dnl
+dnl Check for __attribute__
+dnl
+
+AC_C___ATTRIBUTE__
+
+dnl
+dnl Look for berkeley db, gdbm, and ndbm in that order.
+dnl
+
+KRB_FIND_DB("" $berkeley_db gdbm ndbm)
+
+dnl
+dnl Check for strange operating systems that you need to handle differently
+dnl
+
+AC_KRB_SYS_NEXTSTEP
+AC_KRB_SYS_AIX
+
+if test "$krb_cv_sys_aix" = yes ;then
+ if test "$aix_dynamic_afs" = yes; then
+ AFS_EXTRA_OBJS='$(srcdir)/afsl.exp dlfcn.o'
+ AFS_EXTRA_LIBS=afslib.so
+ # this works differently in AIX <=3 and 4
+ if test `uname -v` = 4 ; then
+ AFS_EXTRA_LD="-bnoentry"
+ else
+ AFS_EXTRA_LD="-e _nostart"
+ fi
+ AFS_EXTRA_DEFS=
+ AIX_EXTRA_KAFS="-lld"
+ else
+ AFS_EXTRA_OBJS='$(srcdir)/afsl.exp afslib.o'
+ AFS_EXTRA_LIBS=
+ AFS_EXTRA_DEFS='-DSTATIC_AFS_SYSCALLS'
+ AIX_EXTRA_KAFS=
+ fi
+ AC_SUBST(AFS_EXTRA_OBJS)dnl
+ AC_SUBST(AFS_EXTRA_LIBS)dnl
+ AC_SUBST(AFS_EXTRA_LD)dnl
+ AC_SUBST(AFS_EXTRA_DEFS)dnl
+ AC_SUBST(AIX_EXTRA_KAFS)dnl
+fi
+
+dnl
+dnl Check for struct winsize
+dnl
+
+AC_KRB_STRUCT_WINSIZE
+
+dnl
+dnl Various checks for libraries and their contents
+dnl
+
+AC_FIND_FUNC(syslog, syslog)
+
+dnl
+dnl System V is have misplaced the socket routines, should really be in libc
+dnl
+
+AC_FIND_FUNC(socket, socket,
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif],
+[0,0,0])
+AC_FIND_FUNC(gethostbyname, nsl,
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif],
+"foo")
+
+AC_FIND_FUNC(res_search, resolv,
+[
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+],
+[0,0,0,0,0])
+
+AC_FIND_FUNC(dn_expand, resolv,
+[
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+],
+[0,0,0,0,0])
+
+AC_BROKEN_SNPRINTF
+
+AC_CHECK_FUNCS(asnprintf asprintf vasprintf vasnprintf vsnprintf)
+
+AC_CHECK_FUNCS(thr_yield)
+
+AC_EGREP_HEADER(sigaction, signal.h,
+ AC_DEFINE(HAVE_POSIX_SIGNALS, 1, [define if you have sigaction]))
+
+save_CPPFLAGS="${CPPFLAGS}"
+if test "$KRB4_INC_DIR"; then
+ CPPFLAGS="-I${KRB4_INC_DIR} $CPPFLAGS"
+fi
+AC_HAVE_TYPES(int8_t int16_t int32_t int64_t)
+AC_HAVE_TYPES(int16 int32)
+AC_HAVE_TYPES(u_int8_t u_int16_t u_int32_t u_int64_t)
+AC_HAVE_TYPES(u_int16 u_int32)
+AC_HAVE_TYPES(bool ssize_t)
+AC_HAVE_TYPES(register_t)
+AC_HAVE_TYPES(intptr_t)
+AC_HAVE_TYPES(off64_t)
+AC_CHECK_HEADERS(ktypes.h com_err.h et/com_err.h)
+CPPFLAGS="${save_CPPFLAGS}"
+
+AC_TYPE_SIGNAL
+
+#
+# Check if we have _res
+#
+
+AC_CHECK_VAR([#include <resolv.h>], res)
+
+dnl
+dnl check for old libkafs
+dnl
+
+AC_FIND_FUNC_NO_LIBS2(krb_afslog_uid, "", , , [$KAFS_LIBS $KRB4_LIB_FLAGS])
+
+#
+# libroken
+#
+
+AC_FIND_IF_NOT_BROKEN(hstrerror, resolv,
+[#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+17)
+AC_NEED_PROTO([
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+hstrerror)
+AC_FUNC_HSTRERROR_CONST
+
+AC_BROKEN(chown daemon err errx fchown flock getcwd getdtablesize getopt)
+AC_BROKEN(getusershell inet_aton initgroups lstat memmove mkstemp)
+AC_BROKEN(putenv rcmd readv recvmsg sendmsg setegid setenv seteuid)
+AC_BROKEN(strcasecmp strdup strerror strftime strlcat strlcpy strlwr)
+AC_BROKEN(strnlen strsep strsep_copy strptime strtok_r strupr unsetenv)
+AC_BROKEN(verr verrx vsyslog vwarn vwarnx warn warnx writev)
+
+if test "$ac_cv_func_inet_aton" = "yes"; then
+AC_NEED_PROTO([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif],
+inet_aton)
+fi
+
+AC_CHECK_FUNCS(fcntl getrlimit getspnam getspuid mktime setregid)
+AC_CHECK_FUNCS(setresuid setreuid setsid setsockopt sysconf sysctl)
+
+AC_CHECK_FUNCS(getitimer)
+
+AC_CHECK_FUNCS(vfsisloadable vfsload)
+
+AC_CHECK_FUNCS(getfh fhopen)
+
+AC_FUNC_GETVFSBYNAME
+
+AC_CHECK_VAR([#include <stdlib.h>], optreset)dnl
+if test "$ac_cv_var_optreset" = yes; then
+ AC_CHECK_DECLARATION([#include <stdlib.h>], optreset)dnl
+fi
+
+dnl
+dnl Test if hstrerror needs const (like on SunOS 5.6)
+dnl
+
+dnl XXX - AC_HSTRERROR_CONST
+
+dnl
+dnl Test if we can mmap time, speed hack
+dnl
+
+AC_FIND_FUNC(kvm_open, kvm)
+AC_FIND_FUNC(kvm_nlist, kvm)
+#AC_MMAP_TIME($with_mmap_time)
+
+dnl
+dnl prototypes
+dnl
+
+AC_NEED_PROTO([
+#include <string.h>
+],
+strtok_r)
+
+AC_NEED_PROTO([
+#include <sys/types.h>
+#include <sys/time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],
+select)
+
+AC_DIRENT_SYS_DIR_H
+
+AC_HAVE_STRUCT_FIELD(struct dirent, d_type,
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <dirent.h>
+])
+
+dnl
+dnl Check for sa_len in sys/socket.h
+dnl
+
+AC_HAVE_STRUCT_FIELD(struct sockaddr,
+sa_len,
+[#include <sys/types.h>
+#include <sys/socket.h>])
+
+dnl
+dnl variable checks
+dnl
+
+AC_CHECK_VAR([#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+h_errno)
+
+AC_CHECK_VAR([#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+h_errlist)
+
+AC_CHECK_VAR([#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif],
+h_nerr)
+
+dnl
+dnl check for strange as stuff on solaris
+dnl
+
+case "$target_os" in
+solaris*)
+ AC_CACHE_CHECK(if as supports .register, ac_cv_prog_as_register,[
+ cat > conftest.s <<EOF
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+ .register %g7, #scratch
+EOF
+ if $AS conftest.s >/dev/null 2>&1; then
+ ac_cv_prog_as_register=yes
+ else
+ ac_cv_prog_as_register=no
+ fi
+ rm -f conftest.s a.out
+])
+ if test "$ac_cv_prog_as_register" = "yes"; then
+ AC_DEFINE(AS_UNDERSTANDS_REGISTER, 1,
+ [define this if your as understands .register])
+ fi
+esac
+
+dnl
+dnl kernel checks
+dnl
+
+dnl
+dnl bsd style
+dnl
+
+if test "$XFS_SUBDIR" = "bsd"; then
+
+AC_ELF_OBJECT_FORMAT
+AC_KERNEL
+AC_CHECK_KERNEL_FUNCS( \
+cdevsw_add \
+debuglockmgr \
+lockmgr \
+make_dev \
+vop_revoke \
+genfs_revoke \
+vfs_opv_init \
+vfs_opv_init_default \
+vfs_opv_init_explicit \
+vfs_add_vnodeops \
+vfs_attach \
+vfs_register \
+vfs_getvfs \
+vgonel \
+zfreei \
+vfs_cache_lookup \
+vnode_pager_generic_putpages \
+vnode_pager_generic_getpages \
+vnode_pager_setsize \
+devtoname \
+udev2dev \
+snprintf \
+nosys \
+sys_nosys \
+sys_lkmnosys \
+)
+AC_CHECK_KERNEL_FUNC(memcpy, [0,0,0])
+
+AC_BSD_HEADER_VNODE_IF_H
+
+AC_CHECK_KERNEL_VAR(doforce, int)
+AC_CHECK_KERNEL_VAR(aout_sysent, struct sysent*,[#include <sys/systm.h>])
+AC_CHECK_KERNEL_VOP_T
+AC_BSD_FUNC_VFS_OBJECT_CREATE
+AC_BSD_FUNC_VOP_LOCK
+AC_BSD_FUNC_VFS_BUSY
+AC_BSD_FUNC_VGET
+AC_BSD_FUNC_SUSER
+AC_BSD_FUNC_VFS_GETNEWFSID
+AC_BSD_FUNC_LOCKMGR
+AC_BSD_FUNC_LOCKSTATUS
+case "$target_os" in
+osf*)
+AC_OSF_FUNC_UBC_LOOKUP ;;
+esac
+
+AC_CHECK_DIRSIZ
+
+dnl
+dnl Find out if have have proc.p_sigmask
+dnl
+
+AC_HAVE_STRUCT_FIELD(
+struct proc,
+p_sigmask,
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif])
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+#ifdef HAVE_SYS_VNODE_H
+#include <sys/vnode.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+],
+mount,
+struct vnode *,
+mnt_syncer)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+#ifdef HAVE_SYS_VNODE_H
+#include <sys/vnode.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+],
+mount,
+qaddr_t,
+m_info)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsconf,
+int,
+vfc_refcount)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsconf,
+int (*)(void),
+vfc_mountroot)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/uio.h>
+],
+uio,
+struct proc *,
+uio_procp)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsops,
+struct vnodeopv_desc **,
+vfs_opv_descs)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsops,
+char *,
+vfs_name)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsops,
+void *,
+vfs_uninit)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsops,
+struct sysctl_oid *,
+vfs_oid)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsops,
+int,
+vfs_done)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+],
+vfsops,
+void *,
+vfs_checkexp)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/vnode.h>
+#include <sys/vnode_if.h>
+],
+vop_fsync_args,
+int,
+a_flags)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+],
+proc,
+register_t *,
+p_retval)
+
+
+AC_HAVE_KERNEL_DEF([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+#ifdef HAVE_SYS_SYSPROTO_H
+#include <sys/sysproto.h>
+#endif
+#ifdef HAVE_SYS_SYSCALLARGS_H
+#include <sys/syscallargs.h>
+#endif
+],
+struct setgroups_args)
+
+AC_HAVE_KERNEL_DEF([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+#ifdef HAVE_SYS_SYSPROTO_H
+#include <sys/sysproto.h>
+#endif
+#ifdef HAVE_SYS_SYSCALLARGS_H
+#include <sys/syscallargs.h>
+#endif
+],
+struct sys_setgroups_args)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+d_stop_t *,
+d_stop)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+d_reset_t *,
+d_reset)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+d_reset_t *,
+d_bogoreset)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+d_devtotty_t *,
+d_devtotty)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+d_parms_t *,
+d_bogoparms)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+void *,
+d_spare)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/conf.h>
+],
+cdevsw,
+int,
+d_maxio)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#include <sys/uio.h>
+#include <sys/namei.h>
+],
+componentname,
+u_long,
+cn_hash)
+
+dnl
+dnl linux
+dnl
+
+elif test "$XFS_SUBDIR" = "linux"; then
+
+dnl Linux devfs check
+AC_CHECK_HEADERS(linux/devfs_fs.h linux/devfs_fs_kernel.h)
+
+AC_LINUX_FUNC_D_ALLOC_ROOT_TWO_ARGS
+AC_LINUX_FUNC_DEVFS_REGISTER_ELEVEN_ARGS
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#define __KERNEL__
+#include <asm/current.h>
+#include <linux/fs.h>
+],
+ViceIoctl,
+caddr_t,
+in)
+
+AC_HAVE_LINUX_KERNEL_TYPES(int8_t int16_t int32_t int64_t)
+AC_HAVE_LINUX_KERNEL_TYPES(u_int8_t u_int16_t u_int32_t u_int64_t)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <asm/current.h>
+#include <linux/fs.h>
+typedef int (*notify_change_type)(struct dentry *, struct iattr *);
+],
+super_operations,
+notify_change_type,
+notify_change)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <asm/current.h>
+#include <linux/fs.h>
+],
+inode_operations,
+struct file_operations *,
+default_file_ops)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <asm/current.h>
+#include <linux/fs.h>
+typedef int (*updatepage_type)(struct file *, struct page *, unsigned long, unsigned int, int);
+],
+inode_operations,
+updatepage_type,
+updatepage)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <asm/current.h>
+#include <linux/fs.h>
+typedef int (*bmap_type)(struct inode *,int);
+],
+inode_operations,
+bmap_type,
+bmap)
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <asm/current.h>
+#include <linux/fs.h>
+typedef int (*smap_type)(struct inode *,int);
+],
+inode_operations,
+smap_type,
+smap)
+
+AC_LINUX_TYPE_WAIT_QUEUE_HEAD_T
+AC_LINUX_FUNC_INIT_WAITQUEUE_HEAD
+AC_LINUX_FUNC_INIT_MUTEX
+
+elif test "$XFS_SUBDIR" = "solaris"; then
+
+AC_HAVE_KERNEL_STRUCT_FIELD([
+#include <sys/types.h>
+#include <sys/vfs.h>
+typedef void (*freevfs_type)(struct vfs *);
+],
+vfsops,
+freevfs_type,
+vfs_freevfs)
+
+fi # end of OS-specific tests
+
+AC_MSG_CHECKING(for working htonl)
+AC_CACHE_VAL(ac_cv_htonl_works, [
+AC_TRY_LINK([#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],
+[htonl(0);],
+ac_cv_htonl_works=yes,
+ac_cv_htonl_works=no)])
+AC_MSG_RESULT($ac_cv_htonl_works)
+
+if test "$ac_cv_htonl_works" = "no"; then
+AC_MSG_CHECKING(if htonl is repairable)
+AC_CACHE_VAL(ac_cv_htonl_hack_works, [
+AC_TRY_LINK(
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#define htonl(x) __cpu_to_be32(x)
+],
+[htonl(0);],
+ac_cv_htonl_hack_works=yes,
+ac_cv_htonl_hack_works=no)])
+AC_MSG_RESULT($ac_cv_htonl_hack_works)
+
+if test "$ac_cv_htonl_hack_works" = "no"; then
+AC_MSG_ERROR([Cannot repair htonl])
+else
+ AC_DEFINE(HAVE_REPAIRABLE_HTONL, 1, [define?])
+fi
+
+fi
+
+# Almost done....
+
+AC_OUTPUT(Makefile \
+ include/Makefile \
+ arlad/Makefile \
+ lwp/Makefile \
+ xfs/Makefile \
+ $XFS_SUBDIR_Makefile \
+ $XFS_SUBDIR_BIN_Makefile \
+ rx/Makefile \
+ $RXKAD_MAKEFILE \
+ rxdef/Makefile \
+ appl/Makefile \
+ appl/lib/Makefile \
+ appl/asrvutil/Makefile \
+ appl/afsmgr/Makefile \
+ appl/afsutils/Makefile \
+ appl/amon/Makefile \
+ appl/fs/Makefile \
+ appl/pts/Makefile \
+ appl/udebug/Makefile \
+ appl/vos/Makefile \
+ appl/bos/Makefile \
+ doc/Makefile \
+ lib/Makefile \
+ lib/roken/Makefile \
+ lib/sl/Makefile \
+ lib/cmd/Makefile \
+ lib/editline/Makefile \
+ lib/ko/Makefile \
+ lib/acl/Makefile \
+ lib/bufdir/Makefile \
+ util/Makefile \
+ ydr/Makefile \
+ conf/Makefile \
+ conf/arla.spec \
+ milko/Makefile \
+ milko/lib/Makefile \
+ milko/lib/vstatus/Makefile \
+ milko/lib/dpart/Makefile \
+ milko/lib/voldb/Makefile \
+ milko/lib/vld/Makefile \
+ milko/lib/ropa/Makefile \
+ milko/lib/msecurity/Makefile \
+ milko/lib/mlog/Makefile \
+ milko/appl/Makefile \
+ milko/appl/sked/Makefile \
+ milko/appl/perf/Makefile \
+ milko/appl/bootstrap/Makefile \
+ milko/fs/Makefile \
+ milko/vldb/Makefile \
+ milko/pts/Makefile \
+ milko/bos/Makefile \
+ tests/Makefile)
+
+AC_KRB_VERSION
diff --git a/usr.sbin/afs/src/doc/Makefile.in b/usr.sbin/afs/src/doc/Makefile.in
new file mode 100644
index 00000000000..7c8286f9c98
--- /dev/null
+++ b/usr.sbin/afs/src/doc/Makefile.in
@@ -0,0 +1,189 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:52 art Exp $
+#
+
+SHELL = /bin/sh
+ED = ed
+AWK = awk
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+infodir = @infodir@
+mandir = @mandir@
+
+DISTDIR =
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+info_TEXINFOS = arla.texi
+arla_TEXINFOS = ack.texi \
+ intro.texi \
+ partsofarla.texi \
+ tools.texi \
+ debugging.texi \
+ authors.texi \
+ storage.texi \
+ timeline.texi \
+ afs-basics.texi
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+TEXI2DVI = @TEXI2DVI@
+TEXI2PDF = @TEXI2PDF@
+TEXI2HTML = @TEXI2HTML@
+TEXINFO_TEX = $(srcdir)/texinfo.tex
+INFO_DEPS = arla.info
+DVIS = arla.dvi
+MAKEINFO = @MAKEINFO@
+TEXINFOS = arla.texi
+DIST_COMMON = $(arla_TEXINFOS) Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+all: Makefile
+
+.SUFFIXES:
+.SUFFIXES: .dvi .info .ps .texi .texinfo .txi .pdf .html
+
+Makefile: Makefile.in ../config.status
+ cd .. && CONFIG_FILES=doc/Makefile CONFIG_HEADERS= $(SHELL) ./config.status
+
+arla.info: arla.texi $(arla_TEXINFOS)
+arla.dvi: arla.texi $(arla_TEXINFOS)
+
+ack.texi: ack.texi.in Makefile.in
+ rm -f tempfile
+ $(AWK) 'BEGIN { FS="|";foo=0;printf("/%%THANKS%%\nd\ni\n"); } \
+ /@/ { if (foo) { \
+ printf("@item %s\n\n",$$1);\
+ } \
+ } /expect you to/ { foo=1; } \
+ END { printf(".\n1,$$s/<.*@/&@/g\n1,$$s/</\\\n@email{/g\n1,$$s/>/}/g\nw %s\nq\n", "$(srcdir)/ack.texi") ;} ' < $(srcdir)/../THANKS > tempfile
+ $(ED) $(srcdir)/ack.texi.in < tempfile
+ rm -f tempfile
+
+DVIPS = @DVIPS@
+
+.texi.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texi.dvi:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi.pdf:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2PDF) --language=Texinfo $<
+
+.texi.html:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2HTML) -split_chapter -split_node $< && ln -s $*_toc.html $*.html
+
+.texi:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.dvi:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.txi.dvi:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install:
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @for file in $(INFO_DEPS); do \
+ d=$(srcdir); \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo "$(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+
+uninstall:
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ for file in $(INFO_DEPS); do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ for file in $(INFO_DEPS); do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ for base in $(INFO_DEPS); do \
+ d=$(srcdir); \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+ $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+info: $(INFO_DEPS)
+dvi: $(DVIS)
+
+clean:
+ rm -f arla.aux arla.cp arla.cps arla.dvi arla.fn arla.fns arla.ky \
+ arla.kys arla.ps arla.log arla.pg arla.toc arla.tp arla.tps \
+ arla.vr arla.vrs arla.op arla.tr arla.cv arla.cn
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/usr.sbin/afs/src/doc/ack.texi b/usr.sbin/afs/src/doc/ack.texi
new file mode 100644
index 00000000000..0bbeccb3353
--- /dev/null
+++ b/usr.sbin/afs/src/doc/ack.texi
@@ -0,0 +1,145 @@
+@c $Id: ack.texi,v 1.1 2000/09/11 14:40:52 art Exp $
+
+@node Acknowledgments, , Authors, Top
+@comment node-name, next, previous, up
+@appendix Acknowledgments
+
+lwp and rx are copyrighted by IBM. We're grateful to Derrick J
+Brashear @email{shadow@@dementia.org} and Jim Doyle @email{jrd@@bu.edu}
+for making them available.
+
+the @code{rxkad} implementation was written by Björn Grönvall
+@email{bg@@sics.se} and is also part of the kth-krb distribution.
+
+Some of the files in @file{libroken} come from Berkeley by the way of
+NetBSD/FreeBSD
+
+@code{editline} was written by Simmule Turner and Rich Salz.
+
+The code for gluing these together were written by ourselves.
+
+Bugfixes, documentation, encouragement, and code has been contributed by:
+@table @asis
+
+@item Aaron M. Ucko
+@email{amu@@MIT.EDU}
+
+@item Alec Wolman
+@email{wolman@@cs.washington.edu}
+
+@item Alexandra Ellwood
+@email{lxs@@MIT.EDU}
+
+@item Brad Keryan
+@email{keryan@@andrew.cmu.edu}
+
+@item Constantine Sapuntzakis
+@email{csapuntz@@openbsd.org}
+
+@item Dan Winship
+@email{danw@@MIT.EDU}
+
+@item Derrick J Brashear
+@email{shadow@@dementia.org}
+
+@item Harald Barth
+@email{haba@@pdc.kth.se}
+
+@item Jim Doyle
+@email{jrd@@bu.edu}
+
+@item John Davison
+@email{davisoja@@clarkson.edu}
+
+@item John Hawkinson
+@email{jhawk@@MIT.EDU}
+
+@item Karl Ramm
+@email{kcr@@MIT.EDU}
+
+@item Mark Eichin
+@email{eichin@@kitten.gen.ma.us}
+
+@item Per Boussard T/ED
+@email{Per.Boussard@@era-t.ericsson.se}
+
+@item Dima Ruban
+@email{dima@@best.net}
+
+@item Max
+@email{davros@@cyclone.Stanford.EDU}
+
+@item Andrzej Filinski
+@email{andrzej@@daimi.aau.dk}
+
+@item Chuck Lever
+@email{chuckl@@netscape.com}
+
+@item WUWEI SHEN
+@email{wwshen@@engin.umich.edu}
+
+@item Cheng Jin
+@email{chengjin@@eecs.umich.edu}
+
+@item Paul Callaway
+@email{pcallawa@@umich.edu}
+
+@item Brandon S. Allbery
+@email{allbery@@ece.cmu.edu}
+
+@item Ken Raeburn
+@email{raeburn@@raeburn.org}
+
+@item Jeffrey Hutzelman
+@email{jhutz+@@cmu.edu}
+
+@item Hee-Seok Heo
+@email{hsheo@@postech.ac.kr}
+
+@item Paul Ewing Jr.
+@email{ewing@@ima.umn.edu}
+
+@item Niklas Hallqvist
+@email{niklas@@appli.se}
+
+@item Marko Asplund
+@email{aspa@@hip.fi}
+
+@item Chris Wing
+@email{wingc@@engin.umich.edu}
+
+@item Simon Josefsson
+@email{jas@@pdc.kth.se}
+
+@item Magnus Lindström
+@email{magnus.lindstrom@@s3.kth.se}
+
+@item Greg Stark
+@email{gsstark@@mit.edu}
+
+@item Matt
+@email{deberg@@mit.edu}
+
+@item Björn Grönvall
+@email{bg@@sics.se}
+
+@item Tino Schwarze
+@email{tino.schwarze@@informatik.tu-chemnitz.de}
+
+@item David Sanderson
+@email{david@@transarc.ibm.com}
+
+@item Roman Hodek
+@email{Roman.Hodek@@informatik.uni-erlangen.de}
+
+
+@end table
+
+If you have done something and are not mentioned here, please send
+mail to @email{arla-drinkers@@stacken.kth.se}.
+
+If you are mentioned here and have not contributed, that's because we
+expect you to.
+
+
+
diff --git a/usr.sbin/afs/src/doc/ack.texi.in b/usr.sbin/afs/src/doc/ack.texi.in
new file mode 100644
index 00000000000..c83ead9b9ec
--- /dev/null
+++ b/usr.sbin/afs/src/doc/ack.texi.in
@@ -0,0 +1,35 @@
+@c $Id: ack.texi.in,v 1.1 2000/09/11 14:40:52 art Exp $
+
+@node Acknowledgments, , Authors, Top
+@comment node-name, next, previous, up
+@appendix Acknowledgments
+
+lwp and rx are copyrighted by IBM. We're grateful to Derrick J
+Brashear @email{shadow@@dementia.org} and Jim Doyle @email{jrd@@bu.edu}
+for making them available.
+
+the @code{rxkad} implementation was written by Björn Grönvall
+@email{bg@@sics.se} and is also part of the kth-krb distribution.
+
+Some of the files in @file{libroken} come from Berkeley by the way of
+NetBSD/FreeBSD
+
+@code{editline} was written by Simmule Turner and Rich Salz.
+
+The code for gluing these together were written by ourselves.
+
+Bugfixes, documentation, encouragement, and code has been contributed by:
+@table @asis
+
+%THANKS%
+
+@end table
+
+If you have done something and are not mentioned here, please send
+mail to @email{arla-drinkers@@stacken.kth.se}.
+
+If you are mentioned here and have not contributed, that's because we
+expect you to.
+
+
+
diff --git a/usr.sbin/afs/src/doc/afs-basics.texi b/usr.sbin/afs/src/doc/afs-basics.texi
new file mode 100644
index 00000000000..4fec475b9ca
--- /dev/null
+++ b/usr.sbin/afs/src/doc/afs-basics.texi
@@ -0,0 +1,176 @@
+@c $Id: afs-basics.texi,v 1.1 2000/09/11 14:40:52 art Exp $
+
+@node Description of AFS infrastructure, Organization of data, Introduction, Top
+@comment node-name, next, previous, up
+@chapter Description of AFS infrastructure
+
+This is an overview of the AFS infrastructure as viewed from a Transarc
+perspective, since most people still run Transarc cells.
+
+@heading Server overview
+
+AFS filespace is split up in smaller parts called cells. These cells are
+usually listed under @file{/afs}. A cell is usually a whole organization
+or an adminstative unit within an organization. An example is e.kth.se
+(with the path @file{/afs/e.kth.se}), that is the department of
+electrical engineering at KTH, which obviously has the @file{e.kth.se}
+domain in DNS. Using DNS domains for cell names is the typical and most
+convenient way.
+
+All cells (and their db-servers) in the AFS world are listed in a file
+named @file{CellServDB}. There is a central copy that is maintained by
+Transarc at @file{/afs/transarc.com/service/etc/CellServDB}. In
+addition Arla can use DNS to find the db-servers of a cell. The DNS
+resource record that is used is the AFSDB. It tells you what machines
+are db servers for a particular cell. The AFSDB resource record is also
+used for DCE/DFS. An example (the 1 means AFS, 2 is used for DCE):
+
+@example
+e.kth.se. 1D IN AFSDB 1 sonen.e.kth.se.
+e.kth.se. 1D IN AFSDB 1 anden.e.kth.se.
+e.kth.se. 1D IN AFSDB 1 fadern.e.kth.se.
+@end example
+
+Some cells use the abbreviated version
+@file{/afs/<word-before-first-dot>} (in the example above that would be
+@file{/afs/e/}. This might be convenient when typing them, but is a bad
+idea, because it does not create the same name space everywhere. If you
+create a symbolic link to @file{/afs/e/foo/bar}, it will not work for
+people in other cells.
+
+Note that cell names are written in lowercase by convention.
+
+There are several servers running in an AFS cell. For performance and
+redundancy reasons, these servers are often run on different hosts.
+There is a built in hierarchy within the servers (in two different
+dimensions).
+
+There is one server that keeps track of the other servers within a host,
+restart them when they die, make sure they run in the correct order,
+save their core-files when they crash, and provide an interface for the
+sysadmin to start/stop/restart the servers. This server is called
+bos-server (Basic Overseer Server).
+
+Another hierarchy is the one who keeps track of data (volumes, users,
+passwords, etc) and who is performing the real hard work (serving files)
+There is the the database server that keeps the database (obviously),
+and keeps several database copies on different hosts relpicated with
+Ubik (see below). The fileserver and the client software (like the
+afsd/arlad, pts and, vos) are pulling meta-data out of the dbserver to
+find where to find user-privileges and where volumes resides.
+
+@heading Basic overseer - boserver
+
+The Bos server is making sure the servers are running. If they crash, it
+saves the corefile, and starts a new server. It also makes sure that
+servers/services that are not supposted to run at the same time do not.
+An example of this is the fileserver/volserver and salvage. It would be
+devastating if salvage tried to correct data that the fileserver is
+changing. The salvager is run before the fileserver starts. The
+administrator can also force a file server to run through salvage again.
+
+@heading Ubik
+
+Ubik is a distributed database. It is really a (distributed) flat file
+that you can perform read/write/lseek operation on. The important
+property of Ubik is that it provides a way to make sure that updates are
+done once (transactions), and that the database is kept consistent. It
+also provides read-only access to the database when there is one (or
+more) available database-server(s).
+
+This works the following way: A newly booted server sends out a message
+to all other servers that tells them that it believes that it is the new
+master server. If the server gets a notice back from an other server
+that tells it that the other server believes that it (or a third server)
+is the master, depending on how long it has been masterserver it will
+switch to the new server. If they can't agree, the one with the lowest
+ip-address is supposed to win the argument. If the server is a slave it
+still updates the database to the current version of the database.
+
+A update to the database can only be done if more than half of the
+servers are available and vote for the master. A update is first
+propaged to all servers, then after that is done, and if all servers
+agree with the change, a commit message is sent out from the server, and
+the update is written to disk and the serial number of the database is
+increased.
+
+All servers in AFS use Ubik to store their data.
+
+@heading Volume Location database server - vlserver
+
+The vldb-server is resposible for the information on what fileserver
+every volume resides and of what kind of volumes exists on each
+fileserver.
+
+To confuse you even more there are three types of support for the
+clients. Basically there is AFS 3.3, 3.4, and 3.6 support. The different
+interfaces look the same for the system administrator, but there are
+some important differences.
+
+AFS 3.3 is the classic interface. 3.4 adds the possibility of multihomed
+servers for the client to talk to, and that introduces the N interface.
+To deal with multihomed clients AFS 3.5 was introduced. This we call the
+U interface.
+
+The N interface added more replication-sites in the database-entry
+structure. The U interface changed the server and clients in two ways.
+
+Now a server registers all its ip-addresses when it boots. This means
+that a server can add (or remove) an network interface without
+rebooting. When registering at the vldb server, the file server presents
+itself with an UUID, an unique identifier. This UUID will be stored in a
+file so the UUID keeps constant even when network addresses are changed,
+added, or removed.
+
+@heading Protection server - ptserver
+
+The protection server keeps track of all users and groups. It's used a
+lot by the file servers.
+
+@heading Kerberos server - kaserver
+
+The kaserver is a Kerberos server, but in other clothes. There is a new
+RPC interface to get tickets (tokens) and administer the server. The
+old Kerberos v4 interface is also implemented, and can be used by
+ordinary Kerberos v4 clients.
+
+You can replace this server with an Heimdal kdc, since it provides a
+superset of the functionality.
+
+@heading Backup server - buserver
+
+The backup server keeps the backup database that is used when backing up
+and restoring volumes. The backup server is not used by other servers,
+only operators.
+
+@heading Update server - upserver
+
+With the update server its possible to automagicly update configuration
+files, server binaries. You keep masters that are supposed to contain the
+correct copy of all the files and then other servers can fetch them from there.
+
+@heading Fileserver and Volume Server - fs and volser
+
+The file server serves data to the clients, keeps track of callbacks,
+and breaks callbacks when needed. Volser is the administative interface
+where you add, move, change, and delete volumes from the server.
+
+The volume server and file server are ran at the same time and they sync
+with each other to make sure that fileserver does not access a volume
+that volser is about to change.
+
+@heading Salvage
+
+Salvage is not a real server. It is run before the fileserver and volser
+are started to make sure the partitions are consistent.
+
+It's imperative that salvager is NOT run at the same time as the
+fileserver/volser is running.
+
+@heading Things that milko does differently.
+
+Fileserver, volumeserver, and salvage are all in one program.
+
+There is no bu nor ka-server. The ka-server is replaced by kth-krb or
+Heimdal. Heimdal's kdc even implements a ka-server readonly interface,
+so your users can keep using programs like klog.
diff --git a/usr.sbin/afs/src/doc/arla.info b/usr.sbin/afs/src/doc/arla.info
new file mode 100644
index 00000000000..681ba046700
--- /dev/null
+++ b/usr.sbin/afs/src/doc/arla.info
@@ -0,0 +1,1332 @@
+This is Info file arla.info, produced by Makeinfo version 1.68 from the
+input file arla.texi.
+
+INFO-DIR-SECTION Arla
+START-INFO-DIR-ENTRY
+* Arla: (arla). Arla - The Free AFS Clone
+END-INFO-DIR-ENTRY
+
+
+File: arla.info, Node: Top, Prev: (dir), Up: (dir)
+
+Arla
+****
+
+Arla is a free AFS implementation from KTH.
+
+* Menu:
+
+* Introduction::
+* Description of AFS infrastructure::
+* Organization of data::
+* Parts of Arla::
+* Debugging::
+* Porting::
+* Authors::
+* Oddities::
+* Arla timeline::
+* Acknowledgments::
+
+
+File: arla.info, Node: Introduction, Next: Description of AFS infrastructure, Prev: Top, Up: Top
+
+Introduction
+************
+
+ *Caution:* Parts of this package are not yet stable software. If
+ something doesn't work, it's probably because it doesn't. If you
+ don't have backup of your data, take backup.
+
+What is Arla?
+=============
+
+Arla is a free AFS implementation. Some of the goals are:
+
+ * to have an implementation that is free and can be used for adding
+ and playing with cool stuff, like support for disconnected-mode.
+ Implement features you can't get from commercial AFS.
+
+ * to provide an alternative to Transarc's AFS-client and server
+ implementations.
+
+ * to add support for platfroms that don't have AFS support from
+ Transarc today.
+
+This release is known to work on the following platforms: NetBSD,
+OpenBSD, FreeBSD, Linux, Solaris, Darwin/MacOS X.
+
+Earlier releases are known to work on current or earlier versions of the
+following platforms: SunOS, AIX, IRIX, Digital UNIX. Some fixes might
+be necessary to make Arla work.
+
+There is or has been done work to support the following platforms: HPUX,
+Fujitsu UXP/V, . Some development is necessary to make Arla work.
+
+There is work going on to support the following platform: Windows
+NT/2000. Contributions are very welcome.
+
+Status
+======
+
+Arla has the following features (quality varies between stable and not
+implemented):
+
+ * a rxgen implementation called ydr (stable).
+
+ * a cache manager replacing Transarc's afsd. The cache managers
+ quality depends on platform: *BSD, Linux i386 and Solaris are
+ stable, others platforms are not as tested ane therefore not as
+ stable.
+
+ * partly implemented fs, vos, pts commands. Commands typically issued
+ by users are stable, commands issued by administrators may return
+ unmotivated errors or are not implemented yet.
+
+ * an implementaion of rxkad written outside USA without any export
+ restrictions (stable).
+
+ * a server implementation called milko, containing file server,
+ volume server and protection server. The file server has an API to
+ the storage backend(s). Milko is still unstable and not fit for
+ production yet.
+
+Bug reports
+===========
+
+If you find bugs in this software, make sure it is a genuine bug and not
+just a part of the code that isn't implemented.
+
+Bug reports should be sent to <arla-drinkers@stacken.kth.se>. Please
+include information on what machine and operating system (including
+version) you are running, what you are trying to do, what happens, what
+you think should have happened, an example for us to repeat, the output
+you get when trying the example, and a patch for the problem if you have
+one. Please make any patches with `diff -u' or `diff -c'.
+
+Suggestions, comments and other non bug reports are also welcome.
+
+Mailing list
+============
+
+There are two mailing lists with talk about Arla.
+<arla-announce@stacken.kth.se> is a low-volume announcement list, while
+<arla-drinkers@stacken.kth.se> is for general discussion. There is
+also commit list <arla-commit@stacken.kth.se>. Send a message to
+<LIST-request@stacken.kth.se> to subscribe.
+
+
+File: arla.info, Node: Description of AFS infrastructure, Next: Organization of data, Prev: Introduction, Up: Top
+
+Description of AFS infrastructure
+*********************************
+
+This is an overview of the AFS infrastructure as viewed from a Transarc
+perspective, since most people still run Transarc cells.
+
+Server overview
+===============
+
+AFS filespace is split up in smaller parts called cells. These cells are
+usually listed under `/afs'. A cell is usually a whole organization or
+an adminstative unit within an organization. An example is e.kth.se
+(with the path `/afs/e.kth.se'), that is the department of electrical
+engineering at KTH, which obviously has the `e.kth.se' domain in DNS.
+Using DNS domains for cell names is the typical and most convenient way.
+
+All cells (and their db-servers) in the AFS world are listed in a file
+named `CellServDB'. There is a central copy that is maintained by
+Transarc at `/afs/transarc.com/service/etc/CellServDB'. In addition
+Arla can use DNS to find the db-servers of a cell. The DNS resource
+record that is used is the AFSDB. It tells you what machines are db
+servers for a particular cell. The AFSDB resource record is also used
+for DCE/DFS. An example (the 1 means AFS, 2 is used for DCE):
+
+ e.kth.se. 1D IN AFSDB 1 sonen.e.kth.se.
+ e.kth.se. 1D IN AFSDB 1 anden.e.kth.se.
+ e.kth.se. 1D IN AFSDB 1 fadern.e.kth.se.
+
+Some cells use the abbreviated version `/afs/<word-before-first-dot>'
+(in the example above that would be `/afs/e/'. This might be
+convenient when typing them, but is a bad idea, because it does not
+create the same name space everywhere. If you create a symbolic link
+to `/afs/e/foo/bar', it will not work for people in other cells.
+
+Note that cell names are written in lowercase by convention.
+
+There are several servers running in an AFS cell. For performance and
+redundancy reasons, these servers are often run on different hosts.
+There is a built in hierarchy within the servers (in two different
+dimensions).
+
+There is one server that keeps track of the other servers within a host,
+restart them when they die, make sure they run in the correct order,
+save their core-files when they crash, and provide an interface for the
+sysadmin to start/stop/restart the servers. This server is called
+bos-server (Basic Overseer Server).
+
+Another hierarchy is the one who keeps track of data (volumes, users,
+passwords, etc) and who is performing the real hard work (serving files)
+There is the the database server that keeps the database (obviously),
+and keeps several database copies on different hosts relpicated with
+Ubik (see below). The fileserver and the client software (like the
+afsd/arlad, pts and, vos) are pulling meta-data out of the dbserver to
+find where to find user-privileges and where volumes resides.
+
+Basic overseer - boserver
+=========================
+
+The Bos server is making sure the servers are running. If they crash, it
+saves the corefile, and starts a new server. It also makes sure that
+servers/services that are not supposted to run at the same time do not.
+An example of this is the fileserver/volserver and salvage. It would be
+devastating if salvage tried to correct data that the fileserver is
+changing. The salvager is run before the fileserver starts. The
+administrator can also force a file server to run through salvage again.
+
+Ubik
+====
+
+Ubik is a distributed database. It is really a (distributed) flat file
+that you can perform read/write/lseek operation on. The important
+property of Ubik is that it provides a way to make sure that updates are
+done once (transactions), and that the database is kept consistent. It
+also provides read-only access to the database when there is one (or
+more) available database-server(s).
+
+This works the following way: A newly booted server sends out a message
+to all other servers that tells them that it believes that it is the new
+master server. If the server gets a notice back from an other server
+that tells it that the other server believes that it (or a third server)
+is the master, depending on how long it has been masterserver it will
+switch to the new server. If they can't agree, the one with the lowest
+ip-address is supposed to win the argument. If the server is a slave it
+still updates the database to the current version of the database.
+
+A update to the database can only be done if more than half of the
+servers are available and vote for the master. A update is first
+propaged to all servers, then after that is done, and if all servers
+agree with the change, a commit message is sent out from the server, and
+the update is written to disk and the serial number of the database is
+increased.
+
+All servers in AFS use Ubik to store their data.
+
+Volume Location database server - vlserver
+==========================================
+
+The vldb-server is resposible for the information on what fileserver
+every volume resides and of what kind of volumes exists on each
+fileserver.
+
+To confuse you even more there are three types of support for the
+clients. Basically there is AFS 3.3, 3.4, and 3.6 support. The different
+interfaces look the same for the system administrator, but there are
+some important differences.
+
+AFS 3.3 is the classic interface. 3.4 adds the possibility of multihomed
+servers for the client to talk to, and that introduces the N interface.
+To deal with multihomed clients AFS 3.5 was introduced. This we call the
+U interface.
+
+The N interface added more replication-sites in the database-entry
+structure. The U interface changed the server and clients in two ways.
+
+Now a server registers all its ip-addresses when it boots. This means
+that a server can add (or remove) an network interface without
+rebooting. When registering at the vldb server, the file server presents
+itself with an UUID, an unique identifier. This UUID will be stored in a
+file so the UUID keeps constant even when network addresses are changed,
+added, or removed.
+
+Protection server - ptserver
+============================
+
+The protection server keeps track of all users and groups. It's used a
+lot by the file servers.
+
+Kerberos server - kaserver
+==========================
+
+The kaserver is a Kerberos server, but in other clothes. There is a new
+RPC interface to get tickets (tokens) and administer the server. The
+old Kerberos v4 interface is also implemented, and can be used by
+ordinary Kerberos v4 clients.
+
+You can replace this server with an Heimdal kdc, since it provides a
+superset of the functionality.
+
+Backup server - buserver
+========================
+
+The backup server keeps the backup database that is used when backing up
+and restoring volumes. The backup server is not used by other servers,
+only operators.
+
+Update server - upserver
+========================
+
+With the update server its possible to automagicly update configuration
+files, server binaries. You keep masters that are supposed to contain
+the correct copy of all the files and then other servers can fetch them
+from there.
+
+Fileserver and Volume Server - fs and volser
+============================================
+
+The file server serves data to the clients, keeps track of callbacks,
+and breaks callbacks when needed. Volser is the administative interface
+where you add, move, change, and delete volumes from the server.
+
+The volume server and file server are ran at the same time and they sync
+with each other to make sure that fileserver does not access a volume
+that volser is about to change.
+
+Salvage
+=======
+
+Salvage is not a real server. It is run before the fileserver and volser
+are started to make sure the partitions are consistent.
+
+It's imperative that salvager is NOT run at the same time as the
+fileserver/volser is running.
+
+Things that milko does differently.
+===================================
+
+Fileserver, volumeserver, and salvage are all in one program.
+
+There is no bu nor ka-server. The ka-server is replaced by kth-krb or
+Heimdal. Heimdal's kdc even implements a ka-server readonly interface,
+so your users can keep using programs like klog.
+
+
+File: arla.info, Node: Organization of data, Next: Parts of Arla, Prev: Description of AFS infrastructure, Up: Top
+
+Organization of data
+********************
+
+This chapter how data is stored and how AFS diffrent from, for example,
+NFS. It also describes how data kept consistent and what the
+requirements was and how that inpacted on the design.
+
+* Menu:
+
+* Requirements::
+* Data organization::
+* Callbacks::
+* Volume management::
+
+
+File: arla.info, Node: Requirements, Next: Data organization, Prev: Organization of data, Up: Organization of data
+
+Requirements
+============
+
+ * Scalability
+
+ It should be possible to use AFS with hundred-thousands of users
+ without problems.
+
+ Writes that are done to diffrent parts of the filesystem should not
+ affect each other. It should be possible to distribute out the
+ reads and writes over many file-servers. So if you have a file
+ that is accessed by many clients, it should be possible to
+ distribute out the load.
+
+ If there is multiple writes to the same file, are you sure that
+ isn't a database.
+
+ * Transparent to users
+
+ Users should not need to know where their files are stored. It
+ should be possible to move their files while they are using their
+ files.
+
+ * Easy to admin
+
+ It should be easy for a administrator to make changes to the
+ filesystem. For example to change quota for a user or project. It
+ should also be possible to move the users data for a fileserver to
+ a less loaded one, or one with more diskspace available.
+
+ Some benefits of using AFS is:
+
+ * user-transparent data migration
+
+ * an ability for on-line backups;
+
+ * data replication that provides both load balancing and
+ robustness of critical data
+
+ * global name space without automounters and other add-ons;
+
+ * @sys variables for platform-independent paths to binary
+ location;
+
+ * enhanced security;
+
+ * client-side caching;
+
+Anti-requirements
+=================
+
+ * No databases
+
+ AFS isn't constructed for storing databases. It would be possible
+ to use AFS for storing a database if a layer above provided
+ locking and synchronizing of data.
+
+ One of the problems is that AFS doesn't include mandatory
+ byte-range locks. AFS uses advisory locking on whole files.
+
+ If you need a real database, use one, they are much more efficent
+ on solving a database problem. Don't use AFS.
+
+
+File: arla.info, Node: Data organization, Next: Callbacks, Prev: Requirements, Up: Organization of data
+
+Volume
+======
+
+A volume is a unit that is smaller then a partition. Its usually (should
+be) a well defined area, like a user's home directory, a project work
+area, or a program distribution.
+
+Quota is controlled on volume-level. All day-to-day management are done
+on volumes.
+
+Partition
+=========
+
+In AFS a partition is what normally is named a partition. All partions
+that afs isusing is named a special way, `/vicepNN', where NN is ranged
+from a to z, continuing with aa to zz. The fileserver (and volser)
+automaticly picks upp all partition starting with `/vicep'
+
+Volumes are stored in a partition. Volumes can't overlap partitions.
+Partitions are added when the fileserver is created or when a new disk
+is added to a filesystem.
+
+Volume cloning and read-only clones
+===================================
+
+A clone of volume is often needed for the volume operations. A clone is
+copy-on-write copy of a volume, the clone is the read-only version.
+
+A two special versions of a clone is the read-only volume and the backup
+volume. The read-only volume is a snapshot of a read-write volume (that
+is what a clone is) that can be replicated to several fileserver to
+distribute the load. Each fileserver plus partition where the read-only
+is located is called a replication-site.
+
+The backup volume is a clone that typically is made each night to enable
+the user to retrieve yestoday's data when they happen to remove a file.
+This is a very useful feature, since it lessen the load on the
+system-administrators to restore files from backup.
+
+Mountpoints
+===========
+
+The volumes are independent of each other. To clue the together there is
+a `mountpoint's. Mountpoints are really symlink that is formated a
+special way that points out a volume (and a optional cell). A
+AFS-cache-manager will show a mountpoint as directory, in fact it will
+be the root directory of the target volume.
+
+
+File: arla.info, Node: Callbacks, Next: Volume management, Prev: Data organization, Up: Organization of data
+
+Callbacks
+=========
+
+Callbacks are what enable the AFS-cache-manager to keep the files
+without asking the server if there is newer version of the file.
+
+A callback is a promise from the fileserver that it will notify the
+client if the file (or directory) changes within the timelimit of the
+callback.
+
+For read-only callbacks there is only callback given its called a volume
+callback and it will be broken when the read-only volume is updated.
+
+
+File: arla.info, Node: Volume management, Prev: Callbacks, Up: Organization of data
+
+Volume management
+=================
+
+ * Create
+
+ * Replicate
+
+ * Release
+
+ * Delete
+
+ * Backup
+
+
+File: arla.info, Node: Parts of Arla, Next: Debugging, Prev: Organization of data, Up: Top
+
+Parts of Arla
+*************
+
+ *Caution:* This text just tries to give a general picture. For
+ real info read the code. If you have any questions, mail
+ <arla-drinkers@stacken.kth.se>.
+
+* Menu:
+
+* How arla works::
+* The relation between Arlad and XFS::
+* The life of a file::
+* Tools and libs::
+* The files in arlad/::
+* pioctl and kafs::
+
+
+File: arla.info, Node: How arla works, Next: The relation between Arlad and XFS, Prev: Parts of Arla, Up: Parts of Arla
+
+How does arla work
+==================
+
+Arla consists of two parts, a userland process (arlad) and the
+kernel-module (xfs).
+
+Arlad is written in user-space for simpler debugging (and less
+rebooting). As a uset space program arlad does not have the same
+limitations as if it would be written in the kernel. To avoid
+performance loss as much as possible, xfs is caching data.
+
+xfs and arlad communicate with each other via a char-device-driver.
+There is a rpc-protocol currenly used specially written for this
+(`arlad/message.c')
+
+xfs is written to be as simple as possible. Theoretically, xfs could be
+used by other user-space daemons to implement a file system. Some
+parts, such as syscalls, are arla-specific. These parts are designed to
+be as general as possible.
+
+For example, xfs does not recognize which pioctl the user-level program
+calls, it just passes this information on to arlad.
+
+
+File: arla.info, Node: The relation between Arlad and XFS, Next: The life of a file, Prev: How arla works, Up: Parts of Arla
+
+The relation between Arlad and XFS
+==================================
+
+ Userland
+
+ ---------
+ Edit file | Arlad | ------> Network
+ | ---------
+ ----|-----------------|[1]----
+ ------- -------
+ Kernel | VFS | <--[2]--> | XFS |
+ ------- -------
+
+[1] A char device (/dev/xfs0)
+
+[2] Xfs provides a filesystem for the vfs-layer in
+ the operating system.
+
+
+File: arla.info, Node: The life of a file, Next: Tools and libs, Prev: The relation between Arlad and XFS, Up: Parts of Arla
+
+The life of a file
+==================
+
+Step by step description of what happens during the creation of a file.
+The names are inspired of BSD-style VFS-layer but the idea is the same
+in most operating systems.
+
+ * The user decides to open a file.
+
+ * open(2) syscall is issued.
+
+ * The vfslayer sends a VOP_LOOKUP to xfs that is forwarded to arlad
+ with a getnode() (seq-num 1).
+
+ * arlad tries to find the requested file and then, if found, sends an
+ install_node to xfs by writing to the xfs character device.
+
+ * xfs inserts the node into the cache and returns from the device
+ write.
+
+ * arlad sends a wakeup rpc message (seq-num 1) to xfs. If the
+ return value is zero xfs tries to find the node in the cache, if
+ not found it might have been flushed out of the cache and the whole
+ thing is repeated.
+
+ * If a none-zero return value is returned, this value is sent as
+ reply to the user. This way arla can decide what error message is
+ returned, without xfs having support for each error.
+
+ * xfs now checks if it has the valid attributes. If the attributes
+ are invalid, xfs will send a rpc message to arlad to refresh it.
+
+ * Since the user wanted to open the file, a getdata rpc message is
+ sent from xfs to arlad. Now arlad fetches the files from the afs
+ file server.
+
+ * Arlad stores the file in the file cache. All vnode operations will
+ be done on this file. Now arlad sends a installdata to xfs.
+
+ * When xfs recives the installdata it looks up the node in the cache,
+ and then it does a VOP_LOOKUP to find a vnode to the cachefile
+ (and store it to keep it for future use).
+
+ * The same thing is done when the file is a directory, except that
+ the directory is converted from the afs directory format to an
+ operating system dependent format and stored in a file. xfs reads
+ this file instead.
+
+ * If the directory is modified locally, write operations are done on
+ the file obtained from the afs-server, and when done the newly
+ changed file is converted and reinstalled.
+
+ * Now the user wants to read a file.
+
+ * read(2) system call is issued.
+
+ * A VOP_READ is sent to the from the vfs-layer to xfs.
+
+ * xfs checks if it has valid attributes/and data (and updates if
+ needed). Now VOP_READ is simply performed on the stored vnode of
+ the cachefile.
+
+
+File: arla.info, Node: Tools and libs, Next: The files in arlad/, Prev: The life of a file, Up: Parts of Arla
+
+Tools and libs
+==============
+
+What other tools does the arla suite consists of
+
+libutil: `util/libutil.a' - A library for the most often used
+ modules like hashtable, double-linked list, logging functions,
+ date-parsing, etc
+
+rx: `rx/librx.a' - The library for the rx protocol
+ (*note Rx protocol::.).
+
+lwp: `lwp/liblwp.a' - The library for the lwp thread-package
+ (*note LWP::.).
+
+ydr: `ydr/ydr' - A stub generator that replaces rxgen.
+
+rxkad: `rxkad/librxkad.a' - The rx Kerberos authentication package.
+
+roken: `lib/roken/libroken.a' - The library that will unbreak
+ things that are missing or broken.
+
+ko: `lib/ko/libko.a' - A library of functions that are arlad-core
+ related but also are useful for programs like vos, pts, fs, etc.
+
+arlalib: `appl/lib/libarlalib.a' - A broken library that does all
+ the hard work with connections etc.
+
+fs: `appl/fs/fs' - The fs util, extra feature
+ (amongst others): getfid.
+
+vos: `appl/vos/vos' - The vos util.
+
+pts: `appl/pts/pts' - The pts util, extra feature: dump.
+
+udebug: `appl/udebug/udebug' - Debug your ubik server.
+
+File: arla.info, Node: Rx protocol, Next: LWP, Up: Tools and libs
+
+Rx protocol
+===========
+
+Rx is run over UDP.
+
+One of rxgen or ydr is used to generate stub-files, ydr is better since
+it generates prototypes, too.
+
+The current implemetation of rx it not that beautiful.
+
+
+File: arla.info, Node: LWP, Prev: Rx protocol, Up: Tools and libs
+
+LWP
+===
+
+LWP is a preepmtive thread package. It does it's context-switching by
+creating a private stack for each thread. The heart of the package is
+select(2).
+
+The core of the package is `process.S'. Its currenty built with a
+bourne-shell file. `Process.s' is preprocessed with `cpp' and then
+given to (g)as. The magic how to build this file a portable way is not
+fun.
+
+The stack is checked for overruns in context-switches, but that is often
+too late. It might be an idea to add a `red zone' at the top of the
+stack to be able to detect overruns.
+
+For architectures not supported by LWP, it can be exchanged with the
+pthreads pakage.
+
+
+File: arla.info, Node: The files in arlad/, Next: pioctl and kafs, Prev: Tools and libs, Up: Parts of Arla
+
+The files in arlad/
+===================
+
+This is a short describtion of the files to bring new deveplopers up to
+speed.
+
+The core of arlad
+-----------------
+
+`adir.c' - contains all functions needed to to operations
+ on afs-directory files.
+
+`afsdir_check.c' - check if an AFS-directory looks sane.
+
+`arla.c' - The startup and the standalone (-t) code.
+
+`arladeb.c' - The logging code specific to arla, like aliases
+ for debugging masks.
+
+`cmcb.c' - The callback-server that is contacted by the
+ server when a callback expires or a server wants to send an
+ InitCallBackState.
+
+`conn.c' - The connection cache, responsible for caching connection
+ based on pag and security index. It will also create new
+ connection when needed.
+
+`cred.c' - Keep track of all credentials that all users have
+ inserted. Indexed on pag.
+
+`fbuf.c' - An interface between rx and filedescriptors. It is also
+ used to mmap files. Used by `adir.c'.
+
+`fcache.c' - Responsible for keeping track of files in the cache.
+ Also fetches files from the afs-server.
+
+`fprio.c' - Tries to give files priority. These files are
+ therefore not garbarge-collected as fast as they would be
+ otherwise. If you wonder what this is for, think of the
+ disconnected mode.
+
+`inter.c' - An interface to hide all junk in fcache, just give
+ the items a VenusFid and you can access them this way.
+
+`kernel.c' - The interface between arlad and the char-device.
+
+`messages.c' - The rpc interface between arlad and xfs.
+
+`volcache.c' - Cache for all volumes.
+Operating system specific files
+-------------------------------
+
+These are the files that contain operating specific functions. Today
+it's just conv_dir().
+
+`aix-subr.c' - AIX
+
+`bsd-subr.c' - FreeBSD 2.2.6, OpenBSD 2.2, 2.3, NetBSD 1.3.x
+
+`hpux-subr.c' - HPUX
+
+`irix-subr.c' - Irix
+
+`linux-subr.c' - Linux 2.0.x, 2.1.x, 2.2
+
+`solaris-subr.c' - Solaris 2.5.x, 2.6, 7
+
+`sunos-subr.c' - SunOS
+
+`unknown-subr.c' - Stub used when compiled on a unknown OS.
+
+File: arla.info, Node: pioctl and kafs, Prev: The files in arlad/, Up: Parts of Arla
+
+pioctl and kafs
+===============
+
+The pioctl interface is the only part of xfs that is afs related.
+
+pioctl is a ioctl but called with a path instead of a filedescriptor.
+When you probe if there is a live afsclient you first run `k_hasafs()'
+that probes if there is an afsclient around. It also sets up some
+static variables in the library. So if you start to do `pioctl()' w/o
+running `k_hasafs()', you're up to funny errors, and/or get a corefile.
+
+`k_hasafs()' does an `AFSCALL_PIOCTL' with opcode `VIOCSETTOK' and
+insize == 0, ie you try to set a token (ticket) that is 0 bytes long.
+This is cleary invalid and kafs expects to find an `EINVAL' returned
+from `syscall(2)'.
+
+The pioctl is used more then just for `AFSCALL_PIOCTL', an other use is
+`AFSCALL_SETPAG' (setting pag). It has also been in use for setting xfs
+debugging levels.
+
+When xfs discovers that a path is given in the `pioctl()' it does a
+`VOP_LOOKUP' on the path and if the returned value is a vnode that
+resides in afs then it extracts the xfs-handle for that node (that just
+happens to be the VenusFid) and passes that on to arlad.
+
+The only ugly thing about the current implentation is that the syscall
+code assumes that the arlad on "xfs-fd" is the arlad that should get
+this syscall.
+
+An example of using `pioctl()':
+
+ 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 (k_pioctl(path,VIOC_FILE_CELL_NAME,&a_params,1) == -1)
+ return errno;
+
+ return 0;
+ }
+
+ int
+ main (int argc, char **argv)
+ {
+ char cell[100];
+
+ if (!k_hasafs())
+ errx (1, "there is no afs");
+
+ if (fs_getfilecellname (".", cell, sizeof(cell)))
+ errx (1, "fs_getfilecellname failed");
+
+ printf ("cell for `.' is %s", cell);
+ return 0;
+ }
+
+
+File: arla.info, Node: Debugging, Next: Porting, Prev: Parts of Arla, Up: Top
+
+Debugging
+*********
+
+Arlad
+=====
+
+If arlad is run without any arguments arlad will fork(2) and log to
+syslog(3). To disable forking use the -no-fork (-n) switch. In the
+current state of the code, arlad is allways to be started with the
+recover (-z) switch. This will invalidate your cache at startup. This
+restriction may be dropped in the future.
+
+To enable more debuggning run arla with the switch
+-debug=module1,module2,... One useful combination is
+ --debug=all,-cleaner
+The cleaner output is usully not that intresting and can be ignored.
+
+A convenient way to debug arlad is to start it inside gdb.
+ datan:~# gdb /usr/arla/bin/arlad
+ (gdb) run -z -n
+This gives you the opportunity to examine a crashed arlad.
+ (gdb) bt
+The arla team appreciates cut and paste information from the beginning
+to the end of the bt output from such a gdb run.
+
+To set the debugging with a running arlad use `fs arladeb' as root.
+
+ datan:~# fs arladeb
+ arladebug is: none
+ datan:~# fs arladeb almost-all
+ datan:~#
+
+By default, arlad logs through syslog if running as a daemon and to
+stderr when running in the foreground (with `--no-fork').
+
+xfs
+===
+
+XFS debugging does almost look the same on all platforms. They all
+share same debugging flags, but not all are enabled on all platforms.
+
+Change the debugging with the `fs xfsdebug' command.
+
+ datan:~# fs xfsdebug
+ xfsdebug is: none
+ datan:~# fs xfsdebug almost-all
+ datan:~#
+
+If it crashes before you have an opportunity to set the debug level, you
+will have to edit `xfs/YOUR-OS/xfs_deb.c' and recompile.
+
+The logging of xfs ends up in your syslog. Syslog usully logs to
+/var/log or /var/adm (look in /etc/syslog.conf).
+
+When reporting problems
+=======================
+
+Please do not include a whole log in a email. Most people on the list
+doesn't want to read this. Instead send a pointer to a URL (http or
+ftp).
+
+xfs on linux
+============
+
+There is a problem with klogd, it's too slow. Cat the `/proc/kmsg' file
+instead. Remember to kill klogd, since the reader will delete the text
+from the ring-bufer, and you will only get some of the message in your
+cat.
+
+
+File: arla.info, Node: Porting, Next: Oddities, Prev: Debugging, Up: Top
+
+Porting
+*******
+
+The largest part of the work needed to port Arla to a new operating
+system is in porting xfs, as kernel programming always is harder, less
+portable and messier than user-space dito. Arlad in test mode (`arlad
+--test') should work without any porting on any system that's not very
+far away from Unix and that provides berkeley sockets (including
+cygwin32). Therefore we will concern ourselves mostly with how to port
+the XFS module.
+
+XFS
+===
+
+ 1. It helps to have source code for your operating system.
+
+ In theory, if stuff was documented well enough, you wouldn't need
+ it. In practice it never is, so you find out interfaces specs and
+ how stuff works by reading the source code. If you're unable to
+ find source code for your OS, try finding source for the closest
+ match. If your OS is based on BSD, try the appropriate version of
+ BSD, for example.
+
+ 2. If you don't have source, try second best, include files.
+
+ You can usually gather quite a lot of information on the workings
+ of the kernel by reading the includes files in `<sys/*.h>'.
+
+ 3. Be lazy
+
+ Try to find out what other XFS port is most similar to your OS and
+ start with that code.
+
+ 4. Figure out how your kernel works.
+
+ You need to figure out how a few things work in your kernel:
+
+ 1. Loading/unloading kernel modules
+
+ That varies quite a lot but it's probably easy to figure out
+ if you have the source code for some other loadable module.
+ Sometimes you can get the kernel to add your cdev, system
+ call and file system automatically but usually you have to
+ write code in your `entry-point' to add these to the
+ appropriate tables.
+
+ 2. Adding a new character device driver
+
+ The kernel has a table of all known device drivers, ordered
+ by major number. Some kernels have one for block devices and
+ one for character devices and some have a common one. That
+ entry usually consists of a number of function pointers that
+ perform the operations (open, close, read, write, ...), and
+ possible a name and some flags. It could look something like
+ the following:
+
+ struct cdevsw {
+ int (*d_open)();
+ int (*d_close)();
+ ...
+ };
+
+ struct cdevsw cdevsw[];
+
+ These are then usually stored in a table `cdevsw' indexed by
+ the major device number. If you're really lucky there's a new
+ way to get the kernel to add your `struct cdevsw' to the
+ global table when loading the module or a function that does
+ the addition for you. If not, you'll have to fallback on
+ looking for a free slot in the table and putting your struct
+ cdevsw there. In some cases, this is not stored in a table but
+ then there'll be a way of adding entries to the new data
+ structure so you don't need to worry about it.
+
+ 3. Adding a new system call
+
+ This is quite similar to adding a new cdev but the table is
+ usually called `sysent' instead.
+
+ 4. Adding a new file system
+
+ Once again, quite similar in principle. The names of the
+ structures tend to vary quite a lot more.
+
+ 5. Finding out how the VFS/Vnode switch works
+
+ The structure vfsops contains function pointers for all of
+ the file system operations. You need to figure out what
+ operations you need to implement (usually at least mount,
+ unmount, root, sync, and statfs).
+
+ The operations that are performed on files are vnode
+ operations (usually stored in a struct vnodeops), and you
+ need to figure which of these you need and how they should
+ work. Also, which is not as explicit, how vnodes are
+ supposed to be allocated and freed and such.
+
+
+ 5. Suggested plan of action
+
+ 1. Start by writing a minimal hello-world module and make sure
+ you can load and unload it properly.
+
+ 2. Then add a device driver to the module which dummy functions
+ and verify that works.
+
+ 3. Try to fit the device driver functions in `xfs_dev.c' into the
+ device driver.
+
+ 4. Do a dummy module with a system call and verify that you can
+ call it.
+
+ 5. Start trying to add enough of the vfs/vnode operations from
+ `xfs_vfsops.c' and `xfs_vnodeops.c' so that you can build it.
+
+ 6. Debug it.
+
+ 7. Send us patches
+
+
+
+
+File: arla.info, Node: Oddities, Next: Arla timeline, Prev: Porting, Up: Top
+
+Oddities
+********
+
+AFS
+===
+
+ * Directories - UnixModeBits are ignored when the vnode is a
+ directory.
+
+ * Errnos are sent over the network. Like Solaris ENOTEMPTY(93)
+ doesn't even map to an error on sunos4 where ENOTEMPTY is 66.
+
+ * Mountpoints have the mode-bits 0644, if they don't they are
+ symlinks (and have the mode-bits 0755).
+
+Operating systems
+=================
+
+ * On Irix 6.5 you have to build the dirents depending on what ABI
+ of the binary you are currently running.
+
+ * . and .. need to be first in directories, this is needed since some
+ programs (like make) "knows" that the two first entries are . and
+ .. and thus can be skiped.
+
+ * Reclen (in struct dirent) shouldn't be too large. When its larger
+ then the buffer used in opendir/readdir/closedir, you loose.
+
+
+File: arla.info, Node: Arla timeline, Next: Authors, Prev: Oddities, Up: Top
+
+Arla timeline
+=============
+
+Arla have existed for quite some years.
+
+Development started around XXX by Björn Grönvall <bg@nada.kth.se>,
+quick followers was Assar <assar@sics.se> (at that time
+<assar@pdc.kth.se>) and Johan Danielsson <joda@pdc.kth.se>. The
+platform that was chosen was Sparc SunOS4 (the OS that NADA, KTH was
+using).
+
+Some work was being done by Patrik Stymne <patriks@e.kth.se> in porting
+arla to Ultrix, but this work was never finished.
+
+At this time there was no free rx, lwp or rxkad. A basic rx
+implementation was written, and the threading problem was solved by
+using pthreads.
+
+The Arla development started to slow down around 11 April 1995.
+
+In about Mar-Jun 1996 rx and lwp was released by Transarc, this was made
+possible by Jim Doyle <jrd@bu.edu>, and Derrick J. Brashear
+<shadow@dementia.org>.
+
+In September 1997, an rxkad implementation was written by Björn. At the
+same time, a need for an AFS client for OpenBSD rose at the Stacken,
+the local computer club at KTH. Other free OS:es, as NetBSD, FreeBSD
+and Linux(primarily sparc) were also in need of AFS clients.
+
+In TokKOM, a local communications system using LysKOM
+(`http://www.lysator.liu.se/lyskom/'), Assar suggested to some club
+members that it would be a nice thing to resume the arla development.
+
+Some people suggested that it would be less trouble having someone with
+access to the Transarc AFS source code port the code to the relevent
+platforms. Assar then ported xfs to FreeBSD 2.2.x in notime, just to
+show the high portability.
+
+People started to understand that arla was a concept that would work,
+and first out was Love Hörnqvist-Åstrand <lha@stacken.kth.se> to join.
+Development was primarily aimed at OpenBSD and NetBSD at the moment,
+and Arla lived for at least 2-3 weeks in /var/tmp on a host named
+yakko.stacken.kth.se.
+
+Magnus Ahltorp <map@stacken.kth.se> joined shortly thereafter, spending
+the rest of the year reading about the Linux VFS, and after a while,
+Artur Grabowski <art@stacken.kth.se> also started to work on arla,
+concentrating on OpenBSD kernel stuff.
+
+The first entry in ChangeLog is dated Fri Oct 24 17:20:40 1997. Around
+this time arla was given a CVS tree, to ease development. Now you could
+also mount the xfs-device and get the root-directory out of it.
+
+The Linux port was done in a few weeks in the beginning of 1998. Only
+the Linux 2.0 kernel was supported at this time.
+
+In April 1998 Assar hade a Arla paper presented at Freenix. Linux 2.1
+support was written also written around this time. This was a major
+work since there was a lot of stuff that had changed (namely the
+dcache).
+
+The first milko entry is dated Thu Oct 30 01:46:51 1997. Note that this
+milko in a sense "worked". You could get files out from it and store
+them.
+
+There was from this point a lot of work being done and quite a lot of
+studies was "wasted". We learned a lot, but not the stuff we were
+expected too.
+
+In Mars 2000 preliminary support for MacOS X/Darwin 1.0 was merged in
+by Magnus and Assar.
+
+Around the same time there we hacked in support for Solaris 8 (beta2)
+There was also some work being done on Windows 2000 native driver at
+same time.
+
+In June 2000 there was a presentation on MADE2000 in Gothenburg, Sweden.
+
+This just includes some milestones, for more information se Changelog.*
+and NEWS files in the distribution.
+
+
+File: arla.info, Node: Authors, Next: Acknowledgments, Prev: Arla timeline, Up: Top
+
+Authors
+*******
+
+Currently writing on arla are
+
+Assar Westerlund, Everything
+
+Magnus Ahltorp, Everything
+
+Artur Grabowski, BSD xfs, OpenBSD maintainer
+
+Love Hörnquist-Åstrand, Everything
+
+Robert Burgess, fs, Solaris xfs
+
+Johan Danielsson, OSF/1 xfs
+
+Hans Insulander, pts, OpenBSD maintainer
+
+Mattias Amnefelt, vos, milko
+
+Harald Barth, doc
+
+Tomas Olsson, milko
+
+Mikael Vidstedt (userland, some milko stuff)
+
+Jimmy Engelbercht (bos)
+Rhapsody xfs port was contributed by Alexandra Ellwood <lxs@MIT.EDU>
+Previously, Rhapsody named Darwin.
+
+Disconnected code is written by:
+
+WUWEI SHEN <wwshen@engin.umich.edu>
+
+Cheng Jin <chengjin@eecs.umich.edu>
+
+Paul Callaway <pcallawa@umich.edu>
+For more contributors look in the THANKS file in the distribution on
+`ftp://ftp.stacken.kth.se/pub/arla/'.
+
+
+File: arla.info, Node: Acknowledgments, Prev: Authors, Up: Top
+
+Acknowledgments
+***************
+
+lwp and rx are copyrighted by IBM. We're grateful to Derrick J
+Brashear <shadow@dementia.org> and Jim Doyle <jrd@bu.edu> for making
+them available.
+
+the `rxkad' implementation was written by Björn Grönvall <bg@sics.se>
+and is also part of the kth-krb distribution.
+
+Some of the files in `libroken' come from Berkeley by the way of
+NetBSD/FreeBSD
+
+`editline' was written by Simmule Turner and Rich Salz.
+
+The code for gluing these together were written by ourselves.
+
+Bugfixes, documentation, encouragement, and code has been contributed
+by:
+Aaron M. Ucko
+ <amu@MIT.EDU>
+
+Alec Wolman
+ <wolman@cs.washington.edu>
+
+Alexandra Ellwood
+ <lxs@MIT.EDU>
+
+Brad Keryan
+ <keryan@andrew.cmu.edu>
+
+Constantine Sapuntzakis
+ <csapuntz@openbsd.org>
+
+Dan Winship
+ <danw@MIT.EDU>
+
+Derrick J Brashear
+ <shadow@dementia.org>
+
+Harald Barth
+ <haba@pdc.kth.se>
+
+Jim Doyle
+ <jrd@bu.edu>
+
+John Davison
+ <davisoja@clarkson.edu>
+
+John Hawkinson
+ <jhawk@MIT.EDU>
+
+Karl Ramm
+ <kcr@MIT.EDU>
+
+Mark Eichin
+ <eichin@kitten.gen.ma.us>
+
+Per Boussard T/ED
+ <Per.Boussard@era-t.ericsson.se>
+
+Dima Ruban
+ <dima@best.net>
+
+Max
+ <davros@cyclone.Stanford.EDU>
+
+Andrzej Filinski
+ <andrzej@daimi.aau.dk>
+
+Chuck Lever
+ <chuckl@netscape.com>
+
+WUWEI SHEN
+ <wwshen@engin.umich.edu>
+
+Cheng Jin
+ <chengjin@eecs.umich.edu>
+
+Paul Callaway
+ <pcallawa@umich.edu>
+
+Brandon S. Allbery
+ <allbery@ece.cmu.edu>
+
+Ken Raeburn
+ <raeburn@raeburn.org>
+
+Jeffrey Hutzelman
+ <jhutz+@cmu.edu>
+
+Hee-Seok Heo
+ <hsheo@postech.ac.kr>
+
+Paul Ewing Jr.
+ <ewing@ima.umn.edu>
+
+Niklas Hallqvist
+ <niklas@appli.se>
+
+Marko Asplund
+ <aspa@hip.fi>
+
+Chris Wing
+ <wingc@engin.umich.edu>
+
+Simon Josefsson
+ <jas@pdc.kth.se>
+
+Magnus Lindström
+ <magnus.lindstrom@s3.kth.se>
+
+Greg Stark
+ <gsstark@mit.edu>
+
+Matt
+ <deberg@mit.edu>
+
+Björn Grönvall
+ <bg@sics.se>
+
+Tino Schwarze
+ <tino.schwarze@informatik.tu-chemnitz.de>
+
+David Sanderson
+ <david@transarc.ibm.com>
+
+Roman Hodek
+ <Roman.Hodek@informatik.uni-erlangen.de>
+
+If you have done something and are not mentioned here, please send mail
+to <arla-drinkers@stacken.kth.se>.
+
+If you are mentioned here and have not contributed, that's because we
+expect you to.
+
+
+
+Tag Table:
+Node: Top210
+Node: Introduction520
+Node: Description of AFS infrastructure3701
+Node: Organization of data11783
+Node: Requirements12221
+Node: Data organization14280
+Node: Callbacks16271
+Node: Volume management16832
+Node: Parts of Arla17028
+Node: How arla works17478
+Node: The relation between Arlad and XFS18497
+Node: The life of a file19156
+Node: Tools and libs21677
+Node: Rx protocol22894
+Node: LWP23171
+Node: The files in arlad/23880
+Node: pioctl and kafs26005
+Node: Debugging28104
+Node: Porting30341
+Node: Oddities35036
+Node: Arla timeline35943
+Node: Authors39368
+Node: Acknowledgments40247
+
+End Tag Table
diff --git a/usr.sbin/afs/src/doc/arla.texi b/usr.sbin/afs/src/doc/arla.texi
new file mode 100644
index 00000000000..05264ed4302
--- /dev/null
+++ b/usr.sbin/afs/src/doc/arla.texi
@@ -0,0 +1,222 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@c $Id: arla.texi,v 1.1 2000/09/11 14:40:52 art Exp $
+@setfilename arla.info
+@settitle ARLA
+@iftex
+@afourpaper
+@end iftex
+@c some sensible characters, please?
+@tex
+\input latin1.tex
+@end tex
+@setchapternewpage on
+@syncodeindex pg cp
+@c %**end of header
+
+@ifinfo
+@dircategory Arla
+@direntry
+* Arla: (arla). Arla - The Free AFS Clone
+@end direntry
+@end ifinfo
+
+@c title page
+@titlepage
+@title Arla
+@subtitle A Free AFS Clone from KTH
+@subtitle Edition 0.1, for version 0.34
+@subtitle 1999 - 2000
+@author Love Hörnquist-Åstrand
+@author Assar Westerlund
+@author Harald Barth
+@author last updated $Date: 2000/09/11 14:40:52 $
+
+@comment This text will show up in the output of texi2html
+@def@fnotsupported{THIS TEXT MAY CONTAIN GARBLED OUTPUT BECAUSE THIS VIEW FORMAT DOES NOT SUPPORT TEXI FUNCTIONS}
+
+@def@copynext{@vskip 20pt plus 1fil@penalty-1000}
+@def@copyrightstart{}
+@def@copyrightend{}
+@page
+@copyrightstart
+Copyright (c) 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. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Kungliga Tekniska
+ Högskolan and its contributors.
+
+4. 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.
+
+@copynext
+
+Copyright (c) 1988, 1990, 1993
+ The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+
+4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+
+@copynext
+
+Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
+
+This software is not subject to any license of the American Telephone
+and Telegraph Company or of the Regents of the University of California.
+
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it freely, subject
+to the following restrictions:
+
+1. The authors are not responsible for the consequences of use of this
+ software, no matter how awful, even if they arise from flaws in it.
+
+2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. Since few users ever read sources,
+ credits must appear in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software. Since few users
+ ever read sources, credits must appear in the documentation.
+
+4. This notice may not be removed or altered.
+
+@copynext
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+@copyrightend
+@end titlepage
+
+@c Less filling! Tastes great!
+@iftex
+@parindent=0pt
+@global@parskip 6pt plus 1pt
+@global@chapheadingskip = 15pt plus 4pt minus 2pt
+@global@secheadingskip = 12pt plus 3pt minus 2pt
+@global@subsecheadingskip = 9pt plus 2pt minus 2pt
+@end iftex
+@ifinfo
+@paragraphindent 0
+@end ifinfo
+
+@ifinfo
+@node Top, , (dir), (dir)
+@comment node-name, next, previous, up
+@top Arla
+
+Arla is a free AFS implementation from KTH.
+
+@end ifinfo
+
+@menu
+* Introduction::
+* Description of AFS infrastructure::
+* Organization of data::
+* Parts of Arla::
+* Debugging::
+* Porting::
+* Authors::
+* Oddities::
+* Arla timeline::
+* Acknowledgments::
+@end menu
+@c * What is AFS::
+@c * Building and Installing::
+@c * Unreleased parts of the arla suite::
+@c * Things that might be done better::
+
+@include intro.texi
+@c @include whatisafs.texi
+@c @include install.texi
+@include afs-basics.texi
+@include storage.texi
+@include partsofarla.texi
+@c @include milko.texi
+@include debugging.texi
+@include porting.texi
+@include oddities.texi
+@include timeline.texi
+@include authors.texi
+@include ack.texi
+
+@c @shortcontents
+@contents
+
+@bye
+
diff --git a/usr.sbin/afs/src/doc/authors.texi b/usr.sbin/afs/src/doc/authors.texi
new file mode 100644
index 00000000000..26bbf18b0e8
--- /dev/null
+++ b/usr.sbin/afs/src/doc/authors.texi
@@ -0,0 +1,36 @@
+@c $Id: authors.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Authors, Acknowledgments, Arla timeline, Top
+@chapter Authors
+
+Currently writing on arla are
+
+@table @asis
+@item Assar Westerlund, Everything
+@item Magnus Ahltorp, Everything
+@item Artur Grabowski, BSD xfs, OpenBSD maintainer
+@item Love Hörnquist-Åstrand, Everything
+@item Robert Burgess, fs, Solaris xfs
+@item Johan Danielsson, OSF/1 xfs
+@item Hans Insulander, pts, OpenBSD maintainer
+@item Mattias Amnefelt, vos, milko
+@item Harald Barth, doc
+@item Tomas Olsson, milko
+@item Mikael Vidstedt (userland, some milko stuff)
+@item Jimmy Engelbercht (bos)
+@end table
+
+Rhapsody xfs port was contributed by Alexandra Ellwood <lxs@@MIT.EDU>
+Previously, Rhapsody named Darwin.
+
+Disconnected code is written by:
+
+@table @asis
+@item WUWEI SHEN <wwshen@@engin.umich.edu>
+@item Cheng Jin <chengjin@@eecs.umich.edu>
+@item Paul Callaway <pcallawa@@umich.edu>
+@end table
+
+For more contributors look in the THANKS file in the distribution on
+@url{ftp://ftp.stacken.kth.se/pub/arla/}.
+
diff --git a/usr.sbin/afs/src/doc/debugging.texi b/usr.sbin/afs/src/doc/debugging.texi
new file mode 100644
index 00000000000..a699a26d624
--- /dev/null
+++ b/usr.sbin/afs/src/doc/debugging.texi
@@ -0,0 +1,78 @@
+@c $Id: debugging.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Debugging, Porting, Parts of Arla, Top
+@chapter Debugging
+
+@section Arlad
+
+If arlad is run without any arguments arlad will fork(2) and log to
+syslog(3). To disable forking use the --no-fork (-n) switch. In the
+current state of the code, arlad is allways to be started with
+the recover (-z) switch. This will invalidate your cache at startup.
+This restriction may be dropped in the future.
+
+To enable more debuggning run arla with the switch --debug=module1,module2,...
+One useful combination is
+@example
+ --debug=all,-cleaner
+@end example
+The cleaner output is usully not that intresting and can be ignored.
+
+A convenient way to debug arlad is to start it inside gdb.
+@example
+datan:~# gdb /usr/arla/bin/arlad
+(gdb) run -z -n
+@end example
+This gives you the opportunity to examine a crashed arlad.
+@example
+(gdb) bt
+@end example
+The arla team appreciates cut and paste information from
+the beginning to the end of the bt output from such a gdb run.
+
+To set the debugging with a running arlad use @code{fs arladeb} as root.
+
+@example
+datan:~# fs arladeb
+arladebug is: none
+datan:~# fs arladeb almost-all
+datan:~#
+@end example
+
+By default, arlad logs through syslog if running as a daemon and to
+stderr when running in the foreground (with @kbd{--no-fork}).
+
+@section xfs
+
+XFS debugging does almost look the same on all platforms. They
+all share same debugging flags, but not all are enabled on all
+platforms.
+
+Change the debugging with the @kbd{fs xfsdebug} command.
+
+@example
+datan:~# fs xfsdebug
+xfsdebug is: none
+datan:~# fs xfsdebug almost-all
+datan:~#
+@end example
+
+If it crashes before you have an opportunity to set the debug level, you
+will have to edit @file{xfs/@var{your-os}/xfs_deb.c} and recompile.
+
+The logging of xfs ends up in your syslog. Syslog usully logs to /var/log
+or /var/adm (look in /etc/syslog.conf).
+
+@section When reporting problems
+
+Please do not include a whole log in a email. Most people on the list
+doesn't want to read this. Instead send a pointer to a URL (http or
+ftp).
+
+@section xfs on linux
+
+There is a problem with klogd, it's too slow. Cat the @file{/proc/kmsg}
+file instead. Remember to kill klogd, since the reader will delete the
+text from the ring-bufer, and you will only get some of the message in
+your cat.
+
diff --git a/usr.sbin/afs/src/doc/intro.texi b/usr.sbin/afs/src/doc/intro.texi
new file mode 100644
index 00000000000..be3da30c1df
--- /dev/null
+++ b/usr.sbin/afs/src/doc/intro.texi
@@ -0,0 +1,89 @@
+@c $Id: intro.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Introduction, Description of AFS infrastructure, Top, Top
+@comment node-name, next, previous, up
+@chapter Introduction
+
+@quotation
+@strong{Caution:} Parts of this package are not yet stable software.
+If something doesn't work, it's probably because it doesn't. If you
+don't have backup of your data, take backup.
+@end quotation
+
+@heading What is Arla?
+
+Arla is a free AFS implementation. Some of the goals are:
+
+@itemize @bullet
+@item
+to have an implementation that is free and can be used for adding and
+playing with cool stuff, like support for disconnected-mode. Implement
+features you can't get from commercial AFS.
+@item
+to provide an alternative to Transarc's AFS-client and server implementations.
+@item
+to add support for platfroms that don't have AFS support from Transarc today.
+@end itemize
+
+This release is known to work on the following platforms: NetBSD,
+OpenBSD, FreeBSD, Linux, Solaris, Darwin/MacOS X.
+
+Earlier releases are known to work on current or earlier versions of the
+following platforms: SunOS, AIX, IRIX, Digital UNIX. Some fixes might
+be necessary to make Arla work.
+
+There is or has been done work to support the following platforms: HPUX,
+Fujitsu UXP/V, . Some development is necessary to make Arla work.
+
+There is work going on to support the following platform: Windows
+NT/2000. Contributions are very welcome.
+
+@heading Status
+
+Arla has the following features (quality varies between
+stable and not implemented):
+
+@itemize @bullet
+@item
+a rxgen implementation called ydr (stable).
+@item
+a cache manager replacing Transarc's afsd. The cache managers
+quality depends on platform: *BSD, Linux i386 and Solaris are stable,
+others platforms are not as tested ane therefore not as stable.
+@item
+partly implemented fs, vos, pts commands. Commands typically issued
+by users are stable, commands issued by administrators may return
+unmotivated errors or are not implemented yet.
+@item
+an implementaion of rxkad written outside USA without any export
+restrictions (stable).
+@item
+a server implementation called milko, containing file server,
+volume server and protection server. The file server has an
+API to the storage backend(s). Milko is still unstable and
+not fit for production yet.
+@end itemize
+
+@heading Bug reports
+
+If you find bugs in this software, make sure it is a genuine bug and not
+just a part of the code that isn't implemented.
+
+Bug reports should be sent to @email{arla-drinkers@@stacken.kth.se}. Please
+include information on what machine and operating system (including
+version) you are running, what you are trying to do, what happens, what
+you think should have happened, an example for us to repeat, the output
+you get when trying the example, and a patch for the problem if you have
+one. Please make any patches with @code{diff -u} or @code{diff -c}.
+
+Suggestions, comments and other non bug reports are also welcome.
+
+@heading Mailing list
+
+There are two mailing lists with talk about
+Arla. @email{arla-announce@@stacken.kth.se} is a low-volume announcement
+list, while @email{arla-drinkers@@stacken.kth.se} is for general
+discussion. There is also commit list
+@email{arla-commit@@stacken.kth.se}. Send a message to
+@email{LIST-request@@stacken.kth.se} to subscribe.
+
diff --git a/usr.sbin/afs/src/doc/latin1.tex b/usr.sbin/afs/src/doc/latin1.tex
new file mode 100644
index 00000000000..e683dd271dc
--- /dev/null
+++ b/usr.sbin/afs/src/doc/latin1.tex
@@ -0,0 +1,95 @@
+% ISO Latin 1 (ISO 8859/1) encoding for Computer Modern fonts.
+% Jan Michael Rynning <jmr@nada.kth.se> 1990-10-12
+\def\inmathmode#1{\relax\ifmmode#1\else$#1$\fi}
+\global\catcode`\^^a0=\active \global\let^^a0=~ % no-break space
+\global\catcode`\^^a1=\active \global\def^^a1{!`} % inverted exclamation mark
+\global\catcode`\^^a2=\active \global\def^^a2{{\rm\rlap/c}} % cent sign
+\global\catcode`\^^a3=\active \global\def^^a3{{\it\$}} % pound sign
+% currency sign, yen sign, broken bar
+\global\catcode`\^^a7=\active \global\let^^a7=\S % section sign
+\global\catcode`\^^a8=\active \global\def^^a8{\"{}} % diaeresis
+\global\catcode`\^^a9=\active \global\let^^a9=\copyright % copyright sign
+% feminine ordinal indicator, left angle quotation mark
+\global\catcode`\^^ac=\active \global\def^^ac{\inmathmode\neg}% not sign
+\global\catcode`\^^ad=\active \global\let^^ad=\- % soft hyphen
+% registered trade mark sign
+\global\catcode`\^^af=\active \global\def^^af{\={}} % macron
+% ...
+\global\catcode`\^^b1=\active \global\def^^b1{\inmathmode\pm} % plus minus
+\global\catcode`\^^b2=\active \global\def^^b2{\inmathmode{{^2}}}
+\global\catcode`\^^b3=\active \global\def^^b3{\inmathmode{{^3}}}
+\global\catcode`\^^b4=\active \global\def^^b4{\'{}} % acute accent
+\global\catcode`\^^b5=\active \global\def^^b5{\inmathmode\mu} % mu
+\global\catcode`\^^b6=\active \global\let^^b6=\P % pilcroy
+\global\catcode`\^^b7=\active \global\def^^b7{\inmathmode{{\cdot}}}
+\global\catcode`\^^b8=\active \global\def^^b8{\c{}} % cedilla
+\global\catcode`\^^b9=\active \global\def^^b9{\inmathmode{{^1}}}
+% ...
+\global\catcode`\^^bc=\active \global\def^^bc{\inmathmode{{1\over4}}}
+\global\catcode`\^^bd=\active \global\def^^bd{\inmathmode{{1\over2}}}
+\global\catcode`\^^be=\active \global\def^^be{\inmathmode{{3\over4}}}
+\global\catcode`\^^bf=\active \global\def^^bf{?`} % inverted question mark
+\global\catcode`\^^c0=\active \global\def^^c0{\`A}
+\global\catcode`\^^c1=\active \global\def^^c1{\'A}
+\global\catcode`\^^c2=\active \global\def^^c2{\^A}
+\global\catcode`\^^c3=\active \global\def^^c3{\~A}
+\global\catcode`\^^c4=\active \global\def^^c4{\"A} % capital a with diaeresis
+\global\catcode`\^^c5=\active \global\let^^c5=\AA % capital a with ring above
+\global\catcode`\^^c6=\active \global\let^^c6=\AE
+\global\catcode`\^^c7=\active \global\def^^c7{\c C}
+\global\catcode`\^^c8=\active \global\def^^c8{\`E}
+\global\catcode`\^^c9=\active \global\def^^c9{\'E}
+\global\catcode`\^^ca=\active \global\def^^ca{\^E}
+\global\catcode`\^^cb=\active \global\def^^cb{\"E}
+\global\catcode`\^^cc=\active \global\def^^cc{\`I}
+\global\catcode`\^^cd=\active \global\def^^cd{\'I}
+\global\catcode`\^^ce=\active \global\def^^ce{\^I}
+\global\catcode`\^^cf=\active \global\def^^cf{\"I}
+% capital eth
+\global\catcode`\^^d1=\active \global\def^^d1{\~N}
+\global\catcode`\^^d2=\active \global\def^^d2{\`O}
+\global\catcode`\^^d3=\active \global\def^^d3{\'O}
+\global\catcode`\^^d4=\active \global\def^^d4{\^O}
+\global\catcode`\^^d5=\active \global\def^^d5{\~O}
+\global\catcode`\^^d6=\active \global\def^^d6{\"O} % capital o with diaeresis
+\global\catcode`\^^d7=\active \global\def^^d7{\inmathmode\times}% multiplication sign
+\global\catcode`\^^d8=\active \global\let^^d8=\O
+\global\catcode`\^^d9=\active \global\def^^d9{\`U}
+\global\catcode`\^^da=\active \global\def^^da{\'U}
+\global\catcode`\^^db=\active \global\def^^db{\^U}
+\global\catcode`\^^dc=\active \global\def^^dc{\"U}
+\global\catcode`\^^dd=\active \global\def^^dd{\'Y}
+% capital thorn
+\global\catcode`\^^df=\active \global\def^^df{\ss}
+\global\catcode`\^^e0=\active \global\def^^e0{\`a}
+\global\catcode`\^^e1=\active \global\def^^e1{\'a}
+\global\catcode`\^^e2=\active \global\def^^e2{\^a}
+\global\catcode`\^^e3=\active \global\def^^e3{\~a}
+\global\catcode`\^^e4=\active \global\def^^e4{\"a} % small a with diaeresis
+\global\catcode`\^^e5=\active \global\let^^e5=\aa % small a with ring above
+\global\catcode`\^^e6=\active \global\let^^e6=\ae
+\global\catcode`\^^e7=\active \global\def^^e7{\c c}
+\global\catcode`\^^e8=\active \global\def^^e8{\`e}
+\global\catcode`\^^e9=\active \global\def^^e9{\'e}
+\global\catcode`\^^ea=\active \global\def^^ea{\^e}
+\global\catcode`\^^eb=\active \global\def^^eb{\"e}
+\global\catcode`\^^ec=\active \global\def^^ec{\`\i}
+\global\catcode`\^^ed=\active \global\def^^ed{\'\i}
+\global\catcode`\^^ee=\active \global\def^^ee{\^\i}
+\global\catcode`\^^ef=\active \global\def^^ef{\"\i}
+% small eth
+\global\catcode`\^^f1=\active \global\def^^f1{\~n}
+\global\catcode`\^^f2=\active \global\def^^f2{\`o}
+\global\catcode`\^^f3=\active \global\def^^f3{\'o}
+\global\catcode`\^^f4=\active \global\def^^f4{\^o}
+\global\catcode`\^^f5=\active \global\def^^f5{\~o}
+\global\catcode`\^^f6=\active \global\def^^f6{\"o} % small o with diaeresis
+\global\catcode`\^^f7=\active \global\def^^f7{\inmathmode\div}% division sign
+\global\catcode`\^^f8=\active \global\let^^f8=\o
+\global\catcode`\^^f9=\active \global\def^^f9{\`u}
+\global\catcode`\^^fa=\active \global\def^^fa{\'u}
+\global\catcode`\^^fb=\active \global\def^^fb{\^u}
+\global\catcode`\^^fc=\active \global\def^^fc{\"u}
+\global\catcode`\^^fd=\active \global\def^^fd{\'y}
+% capital thorn
+\global\catcode`\^^ff=\active \global\def^^ff{\"y}
diff --git a/usr.sbin/afs/src/doc/milko1.fig b/usr.sbin/afs/src/doc/milko1.fig
new file mode 100644
index 00000000000..2429ad87c29
--- /dev/null
+++ b/usr.sbin/afs/src/doc/milko1.fig
@@ -0,0 +1,111 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.00
+Single
+-2
+1200 2
+6 525 3900 1275 4275
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 525 3900 1275 3900 1275 4275 525 4275 525 3900
+4 0 0 100 0 0 12 0.0000 4 180 360 750 4125 dpart\001
+-6
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1725 1200 2925 1200 2925 1500 1725 1500 1725 1200
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 4050 1050 4500 1050 4500 1425 4050 1425 4050 1050
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1050 2325 1725 2325 1725 2775 1050 2775 1050 2325
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 3075 3300 3525 3300 3525 3675 3075 3675 3075 3300
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 3525 4500 4200 4500 4200 4800 3525 4800 3525 4500
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1800 4575 2400 4575 2400 4875 1800 4875 1800 4575
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 1350 5400 2100 5400 2100 5700 1350 5700 1350 5400
+2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5
+ 2325 5400 3000 5400 3000 5700 2325 5700 2325 5400
+2 2 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5
+ 4650 5475 5100 5475 5100 5775 4650 5775 4650 5475
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 1725 1575 1425 2250
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 4200 1500 1800 2475
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 2400 1575 3150 3225
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 4
+ 2250 1575 2475 3375 2400 4050 2175 4500
+ 0.000 1.000 1.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 3150 3750 2400 4500
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 3375 3750 3750 4425
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 2025 4875 1800 5400
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 2250 4875 2625 5400
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 7
+ 3600 3525 3975 3600 4275 3900 4725 4425 4800 4800 4875 5175
+ 4875 5325
+ 0.000 1.000 1.000 1.000 1.000 1.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 4350 1500 3450 3225
+ 0.000 0.000
+3 0 0 1 0 7 100 0 -1 0.000 0 0 0 2
+ 3000 3525 1425 3975
+ 0.000 0.000
+3 1 0 1 0 7 100 0 -1 0.000 0 0 0 10
+ 4500 4725 5250 4650 5625 4950 5850 5850 5325 6225 4650 6225
+ 4275 5850 4200 5250 4350 4950 4500 4725
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000
+3 0 1 1 0 7 100 0 -1 4.000 0 0 0 2
+ 3150 5550 4500 5625
+ 0.000 0.000
+3 1 0 1 0 7 100 0 -1 0.000 0 0 0 10
+ 1650 4275 2325 4200 3000 4425 3300 5250 3225 5925 2100 6300
+ 1200 6000 1050 5400 1200 4650 1650 4275
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000
+3 0 0 1 4 7 100 0 -1 4.000 0 0 0 16
+ 225 3825 750 3675 1200 3750 1650 4050 1950 4425 2325 4350
+ 2625 4200 2700 3900 2850 3525 3150 3375 3300 3225 3675 2925
+ 4125 2700 4800 2475 4950 2250 5025 1950
+ 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 0.000
+3 0 0 1 14 7 100 0 -1 0.000 0 0 0 37
+ 3975 1350 3900 1650 3600 2175 3375 2625 3225 3000 3150 3075
+ 3000 3450 2850 3900 2775 4275 2250 4575 1800 4725 1650 4950
+ 1500 5625 1800 5925 2025 5625 2100 5175 2100 5025 2700 4575
+ 3000 4350 3225 3750 3825 3600 4200 3900 4500 4425 4650 5250
+ 4725 5775 4875 6000 5100 5850 5175 5550 5250 4950 4950 4050
+ 4500 3675 4050 3450 3525 2850 3600 2475 3900 1950 4125 1650
+ 4200 1500
+ 0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
+ 1.000 1.000 1.000 1.000 0.000
+4 0 0 100 0 0 12 0.0000 4 165 1035 1800 1425 sked/volserver\001
+4 0 0 100 0 0 12 0.0000 4 165 585 1425 5625 vdb_flat\001
+4 0 0 100 0 0 12 0.0000 4 135 300 2550 5625 ? db\001
+4 0 0 100 0 0 12 0.0000 4 120 495 3600 4725 vstatus\001
+4 0 0 100 0 0 12 0.0000 4 165 510 1125 2625 [fm]dir\001
+4 0 0 100 0 0 12 0.0000 4 135 300 4725 5700 svol\001
+4 0 0 100 0 0 12 0.0000 4 135 135 4200 1350 fs\001
+4 0 0 100 0 0 12 0.0000 4 135 225 3150 3600 vld\001
+4 0 0 100 0 0 12 0.0000 4 135 405 1875 4800 voldb\001
+4 0 4 100 0 0 12 0.0000 4 135 345 5100 1950 AFS\001
+4 0 14 100 0 0 12 0.0000 4 135 180 3300 2475 32\001
+4 0 14 100 0 0 12 0.0000 4 135 510 3075 4200 opaque\001
+4 0 14 100 0 0 12 0.0000 4 135 435 4650 3750 vnode\001
diff --git a/usr.sbin/afs/src/doc/oddities.texi b/usr.sbin/afs/src/doc/oddities.texi
new file mode 100644
index 00000000000..4127a748c12
--- /dev/null
+++ b/usr.sbin/afs/src/doc/oddities.texi
@@ -0,0 +1,40 @@
+@c $Id: oddities.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Oddities, Arla timeline, Porting, Top
+@chapter Oddities
+
+@c ----------------------------------------------------
+
+@section AFS
+
+@itemize @bullet
+
+@item Directories - UnixModeBits are ignored when the vnode is a directory.
+
+@item Errnos are sent over the network. Like Solaris ENOTEMPTY(93) doesn't
+ even map to an error on sunos4 where ENOTEMPTY is 66.
+
+@item Mountpoints have the mode-bits 0644, if they don't they are symlinks
+(and have the mode-bits 0755).
+
+@end itemize
+
+@c ----------------------------------------------------
+
+@section Operating systems
+
+@itemize @bullet
+
+@item On Irix 6.5 you have to build the dirents depending on what ABI
+ of the binary you are currently running.
+
+@item . and .. need to be first in directories, this is needed since some
+programs (like make) "knows" that the two first entries are . and .. and
+thus can be skiped.
+
+@item Reclen (in struct dirent) shouldn't be too large. When its
+larger then the buffer used in opendir/readdir/closedir, you loose.
+
+@end itemize
+
+@c ----------------------------------------------------
diff --git a/usr.sbin/afs/src/doc/partsofarla.texi b/usr.sbin/afs/src/doc/partsofarla.texi
new file mode 100644
index 00000000000..c349dd5b4f4
--- /dev/null
+++ b/usr.sbin/afs/src/doc/partsofarla.texi
@@ -0,0 +1,347 @@
+@c $Id: partsofarla.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Parts of Arla, Debugging, Organization of data, Top
+@comment node-name, next, previous, up
+@chapter Parts of Arla
+
+@quotation
+@strong{Caution:} This text just tries to give a general picture.
+For real info read the code. If you have any questions, mail
+@email{arla-drinkers@@stacken.kth.se}.
+@end quotation
+
+
+@menu
+* How arla works::
+* The relation between Arlad and XFS::
+* The life of a file::
+* Tools and libs::
+* The files in arlad/::
+* pioctl and kafs::
+@end menu
+
+@comment -----------------------------------------------------
+@node How arla works, The relation between Arlad and XFS, Parts of Arla, Parts of Arla
+@heading How does arla work
+
+Arla consists of two parts, a userland process (arlad) and the
+kernel-module (xfs).
+
+Arlad is written in user-space for simpler debugging (and less rebooting).
+As a uset space program arlad does not have the same limitations as if it
+would be written in the kernel. To avoid performance loss as much as possible,
+xfs is caching data.
+
+@c XXX ptr to coda and arla-usenix paper
+
+xfs and arlad communicate with each other via a char-device-driver.
+There is a rpc-protocol currenly used specially written for this
+(@file{arlad/message.c})
+
+xfs is written to be as simple as possible. Theoretically, xfs could
+be used by other user-space daemons to implement a file system. Some
+parts, such as syscalls, are arla-specific. These parts are designed
+to be as general as possible.
+
+For example, xfs does not recognize which pioctl the user-level
+program calls, it just passes this information on to arlad.
+
+@comment -----------------------------------------------------
+@node The relation between Arlad and XFS, The life of a file, How arla works, Parts of Arla
+@heading The relation between Arlad and XFS
+
+@example
+Userland
+
+ ---------
+ Edit file | Arlad | ------> Network
+ | ---------
+ ----|-----------------|[1]----
+ ------- -------
+Kernel | VFS | <--[2]--> | XFS |
+ ------- -------
+
+@end example
+
+@table @asis
+@item [1] A char device (/dev/xfs0)
+@item [2] Xfs provides a filesystem for the vfs-layer in
+the operating system.
+@end table
+
+@comment -----------------------------------------------------
+@node The life of a file, Tools and libs, The relation between Arlad and XFS, Parts of Arla
+@section The life of a file
+
+@comment This a rough description of the life of a file.
+
+Step by step description of what happens during the creation of a file.
+The names are inspired of BSD-style VFS-layer but the idea is the same
+in most operating systems.
+
+@itemize @bullet
+
+@item The user decides to open a file.
+
+@item open(2) syscall is issued.
+
+@item The vfslayer sends a VOP_LOOKUP to xfs that is forwarded
+to arlad with a getnode() (seq-num 1).
+
+@item arlad tries to find the requested file and then, if found, sends an
+install_node to xfs by writing to the xfs character device.
+
+@item xfs inserts the node into the cache and returns from the device write.
+
+@item arlad sends a wakeup rpc message (seq-num 1) to xfs.
+If the return value is zero xfs tries to find the node in the cache, if
+not found it might have been flushed out of the cache and the whole
+thing is repeated.
+
+@item If a none-zero return value is returned, this value is sent
+as reply to the user. This way arla can decide what error message
+is returned, without xfs having support for each error.
+
+@item xfs now checks if it has the valid attributes. If the attributes
+are invalid, xfs will send a rpc message to arlad to refresh it.
+
+@item Since the user wanted to open the file, a getdata rpc message is
+sent from xfs to arlad. Now arlad fetches the files from the
+afs file server.
+
+@item Arlad stores the file in the file cache. All vnode operations will
+be done on this file. Now arlad sends a installdata to xfs.
+
+@item When xfs recives the installdata it looks up the node in the cache,
+and then it does a VOP_LOOKUP to find a vnode to the cachefile (and store
+it to keep it for future use).
+
+@item The same thing is done when the file is a directory, except that
+the directory is converted from the afs directory format to an operating
+system dependent format and stored in a file. xfs reads this file
+instead.
+
+@item If the directory is modified locally, write operations are
+done on the file obtained from the afs-server, and when done the newly
+changed file is converted and reinstalled.
+
+@item Now the user wants to read a file.
+
+@item read(2) system call is issued.
+
+@item A VOP_READ is sent to the from the vfs-layer to xfs.
+
+@item xfs checks if it has valid attributes/and data (and updates if needed).
+Now VOP_READ is simply performed on the stored vnode of the cachefile.
+
+@end itemize
+
+@comment -----------------------------------------------------
+@node Tools and libs, The files in arlad/, The life of a file, Parts of Arla
+@heading Tools and libs
+
+What other tools does the arla suite consists of
+
+@table @asis
+
+@item libutil: @code{util/libutil.a} - A library for the most often used
+modules like hashtable, double-linked list, logging functions,
+date-parsing, etc
+
+@item rx: @code{rx/librx.a} - The library for the rx protocol
+ (@pxref{Rx protocol}).
+
+@item lwp: @code{lwp/liblwp.a} - The library for the lwp thread-package
+ (@pxref{LWP}).
+
+@item ydr: @code{ydr/ydr} - A stub generator that replaces rxgen.
+
+@item rxkad: @code{rxkad/librxkad.a} - The rx Kerberos authentication package.
+
+@item roken: @code{lib/roken/libroken.a} - The library that will unbreak
+things that are missing or broken.
+
+@item ko: @code{lib/ko/libko.a} - A library of functions that are arlad-core
+related but also are useful for programs like vos, pts, fs, etc.
+
+@item arlalib: @code{appl/lib/libarlalib.a} - A broken library that does all
+the hard work with connections etc.
+
+@item fs: @code{appl/fs/fs} - The fs util, extra feature
+(amongst others): getfid.
+
+@item vos: @code{appl/vos/vos} - The vos util.
+
+@item pts: @code{appl/pts/pts} - The pts util, extra feature: dump.
+
+@item udebug: @code{appl/udebug/udebug} - Debug your ubik server.
+
+@end table
+
+@include tools.texi
+
+@comment -----------------------------------------------------
+@node The files in arlad/, pioctl and kafs, Tools and libs, Parts of Arla
+@section The files in arlad/
+
+This is a short describtion of the files to bring new deveplopers
+up to speed.
+
+@subsection The core of arlad
+
+@table @asis
+
+@item @file{adir.c} - contains all functions needed to to operations
+on afs-directory files.
+
+@item @file{afsdir_check.c} - check if an AFS-directory looks sane.
+
+@item @file{arla.c} - The startup and the standalone (-t) code.
+
+@item @file{arladeb.c} - The logging code specific to arla, like aliases
+for debugging masks.
+
+@item @file{cmcb.c} - The callback-server that is contacted by the
+server when a callback expires or a server wants to send an InitCallBackState.
+
+@item @file{conn.c} - The connection cache, responsible for caching connection
+based on pag and security index. It will also create new connection when
+needed.
+
+@item @file{cred.c} - Keep track of all credentials that all users have
+inserted. Indexed on pag.
+
+@item @file{fbuf.c} - An interface between rx and filedescriptors. It is also
+used to mmap files. Used by @file{adir.c}.
+
+@item @file{fcache.c} - Responsible for keeping track of files in the cache.
+Also fetches files from the afs-server.
+
+@item @file{fprio.c} - Tries to give files priority. These files are
+therefore not garbarge-collected as fast as they would be otherwise.
+If you wonder what this is for, think of the disconnected mode.
+
+@item @file{inter.c} - An interface to hide all junk in fcache, just give
+the items a VenusFid and you can access them this way.
+
+@item @file{kernel.c} - The interface between arlad and the char-device.
+
+@item @file{messages.c} - The rpc interface between arlad and xfs.
+
+@item @file{volcache.c} - Cache for all volumes.
+
+@end table
+
+@subsection Operating system specific files
+
+These are the files that contain operating specific functions.
+Today it's just conv_dir().
+
+@table @asis
+
+@item @file{aix-subr.c} - AIX
+@item @file{bsd-subr.c} - FreeBSD 2.2.6, OpenBSD 2.2, 2.3, NetBSD 1.3.x
+@item @file{hpux-subr.c} - HPUX
+@item @file{irix-subr.c} - Irix
+@item @file{linux-subr.c} - Linux 2.0.x, 2.1.x, 2.2
+@item @file{solaris-subr.c} - Solaris 2.5.x, 2.6, 7
+@item @file{sunos-subr.c} - SunOS
+@item @file{unknown-subr.c} - Stub used when compiled on a unknown OS.
+
+@end table
+@comment -----------------------------------------------------
+
+@node pioctl and kafs, ,The files in arlad/, Parts of Arla
+@heading pioctl and kafs
+
+The pioctl interface is the only part of xfs that is afs related.
+
+pioctl is a ioctl but called with a path instead of a filedescriptor.
+When you probe if there is a live afsclient you first run
+@code{k_hasafs()} that probes if there is an afsclient around.
+It also sets up some static variables in the library. So if you
+start to do @code{pioctl()} w/o running @code{k_hasafs()}, you're
+up to funny errors, and/or get a corefile.
+
+@code{k_hasafs()} does an @code{AFSCALL_PIOCTL} with opcode
+@code{VIOCSETTOK} and insize == 0, ie you try to set a token
+(ticket) that is 0 bytes long. This is cleary invalid and kafs
+expects to find an @code{EINVAL} returned from @code{syscall(2)}.
+
+The pioctl is used more then just for @code{AFSCALL_PIOCTL}, an other
+use is @code{AFSCALL_SETPAG} (setting pag). It has also been in use for
+setting xfs debugging levels.
+
+When xfs discovers that a path is given in the @code{pioctl()} it does a
+@code{VOP_LOOKUP} on the path and if the returned value is a vnode that
+resides in afs then it extracts the xfs-handle for that node (that just
+happens to be the VenusFid) and passes that on to arlad.
+
+The only ugly thing about the current implentation is that
+the syscall code assumes that the arlad on "xfs-fd" is the
+arlad that should get this syscall.
+
+An example of using @code{pioctl()}:
+
+@example
+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 (k_pioctl(path,VIOC_FILE_CELL_NAME,&a_params,1) == -1)
+ return errno;
+
+ return 0;
+@}
+
+int
+main (int argc, char **argv)
+@{
+ char cell[100];
+
+ if (!k_hasafs())
+ errx (1, "there is no afs");
+
+ if (fs_getfilecellname (".", cell, sizeof(cell)))
+ errx (1, "fs_getfilecellname failed");
+
+ printf ("cell for `.' is %s", cell);
+ return 0;
+@}
+
+@end example
+
+@comment -----------------------------------------------------
+
+@c -----------------------------------------------------------
+@c Storybook
+@c -----------------------------------------------------------
+@c
+@c Assar Westerlund tells a story to the rest of the world:
+@c
+@c John Hawkinson <jhawk@MIT.EDU> writes:
+@c > What does sl stand for?
+@c
+@c The short answer is that you should ask Mark.
+@c
+@c The long answer is that it used to be this old library part of MIT
+@c krb4 that was called `ss' (that I believe is short for subsystem, and
+@c that was part of some unknown operating system a long time ago.
+@c (Again, ask Mark.)), for reading and handling command line loops and
+@c parsing. That wasn't IMHO optimal so we wrote a new library which we
+@c called `sl'. The reason for SL is that the local transport authority
+@c in Stockholm used to be called SS (Stockholms Sparvagar) but due to
+@c the bad PR this abbreviation got under the second world war and that
+@c they almost have abandoned trolleys (Sparvagnar) today, they renamed
+@c themselves to SL (Storstockholms Lokaltrafik).
+@c
+@c
+@c [ lha: Mark is only known to assar ]
+@c [ assar: Mark == Mark Eichin ]
+@c -----------------------------------------------------------
diff --git a/usr.sbin/afs/src/doc/porting.texi b/usr.sbin/afs/src/doc/porting.texi
new file mode 100644
index 00000000000..cd8d956796d
--- /dev/null
+++ b/usr.sbin/afs/src/doc/porting.texi
@@ -0,0 +1,142 @@
+@c $Id: porting.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Porting, Oddities, Debugging, Top
+@chapter Porting
+
+The largest part of the work needed to port Arla to a new operating
+system is in porting xfs, as kernel programming always is harder, less
+portable and messier than user-space dito. Arlad in test mode
+(@kbd{arlad --test}) should work without any porting on any system
+that's not very far away from Unix and that provides berkeley sockets
+(including cygwin32). Therefore we will concern ourselves mostly with
+how to port the XFS module.
+
+@section XFS
+
+@enumerate
+
+@item
+It helps to have source code for your operating system.
+
+In theory, if stuff was documented well enough, you wouldn't need it.
+In practice it never is, so you find out interfaces specs and how stuff
+works by reading the source code. If you're unable to find source code
+for your OS, try finding source for the closest match. If your OS is
+based on BSD, try the appropriate version of BSD, for example.
+
+@item
+If you don't have source, try second best, include files.
+
+You can usually gather quite a lot of information on the workings of the
+kernel by reading the includes files in @file{<sys/*.h>}.
+
+@item
+Be lazy
+
+Try to find out what other XFS port is most similar to your OS and start
+with that code.
+
+@item
+Figure out how your kernel works.
+
+You need to figure out how a few things work in your kernel:
+
+@enumerate
+
+@item
+Loading/unloading kernel modules
+
+That varies quite a lot but it's probably easy to figure out if you
+have the source code for some other loadable module. Sometimes you
+can get the kernel to add your cdev, system call and file system
+automatically but usually you have to write code in your `entry-point'
+to add these to the appropriate tables.
+
+@item
+Adding a new character device driver
+
+The kernel has a table of all known device drivers, ordered by major
+number. Some kernels have one for block devices and one for character
+devices and some have a common one. That entry usually consists of a
+number of function pointers that perform the operations (open, close,
+read, write, ...), and possible a name and some flags. It could look
+something like the following:
+
+@example
+struct cdevsw @{
+ int (*d_open)();
+ int (*d_close)();
+ ...
+@};
+
+struct cdevsw cdevsw[];
+@end example
+
+These are then usually stored in a table `cdevsw' indexed by the major
+device number. If you're really lucky there's a new way to get the
+kernel to add your `struct cdevsw' to the global table when loading the
+module or a function that does the addition for you. If not, you'll have
+to fallback on looking for a free slot in the table and putting your
+struct cdevsw there. In some cases, this is not stored in a table but
+then there'll be a way of adding entries to the new data structure so
+you don't need to worry about it.
+
+@item
+Adding a new system call
+
+This is quite similar to adding a new cdev but the table is usually
+called `sysent' instead.
+
+@item
+Adding a new file system
+
+Once again, quite similar in principle. The names of the structures
+tend to vary quite a lot more.
+
+@item
+Finding out how the VFS/Vnode switch works
+
+The structure vfsops contains function pointers for all of the file
+system operations. You need to figure out what operations you need to
+implement (usually at least mount, unmount, root, sync, and statfs).
+
+The operations that are performed on files are vnode operations
+(usually stored in a struct vnodeops), and you need to figure which of
+these you need and how they should work. Also, which is not as
+explicit, how vnodes are supposed to be allocated and freed and such.
+
+@end enumerate
+
+@item
+Suggested plan of action
+
+@enumerate
+
+@item
+Start by writing a minimal hello-world module and make sure you can load
+and unload it properly.
+
+@item
+Then add a device driver to the module which dummy functions and
+verify that works.
+
+@item
+Try to fit the device driver functions in @file{xfs_dev.c} into the
+device driver.
+
+@item
+Do a dummy module with a system call and verify that you can call it.
+
+@item
+Start trying to add enough of the vfs/vnode operations from
+@file{xfs_vfsops.c} and @file{xfs_vnodeops.c} so that you can build it.
+
+@item
+Debug it.
+
+@item
+Send us patches
+
+@end enumerate
+
+@end enumerate
diff --git a/usr.sbin/afs/src/doc/servers.texi b/usr.sbin/afs/src/doc/servers.texi
new file mode 100644
index 00000000000..93f68bc4fb9
--- /dev/null
+++ b/usr.sbin/afs/src/doc/servers.texi
@@ -0,0 +1,67 @@
+@c $Id: servers.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@c
+@c This file contain random junk that should be ordered some day
+@c
+
+
+@section YDR
+
+@code{Ydr} is a rxgen replacement that is generating a lot more stuff
+then rxgen (like headerfiles). It also does the same thing in one run
+instead of three (rxgen does one run for ss.c cs.c and .h, and each time
+passes the whole data thru cpp).
+
+@code{Ydr} was created when there was no free rx package.
+
+Things to remeber about ydr and ydr generated code:
+
+@itemize @bullet
+
+@item When a server function is done out mashalling and writing out data
+it will free all data that contains VARRAYs. The functions you are
+intressed in is @code{generate_server_stub} and @code{genfree}.
+
+@item When a server functions fail (ie returns != 0), mashalling of
+out-data is not done, and out-data is not freed, instead rx_Error() is
+called with that error (See @code{generate_server_stub}.
+
+@item To use ydr (to describe when is codeing a struct or running ydr on
+a file) is called ydra.
+
+@end itemize
+
+
+@section CellServDB
+
+Transarc users a flat file called @code{CellServDB} to distribute the
+knowledge of what cells exist in the world. There is a way to represent
+that kind of information in DNS, but Transarc never implemented that in
+their software. Arla uses both ways to build its view of the AFS world.
+In spite of being organized in IPnumber - name pairs, where the name
+parts resemble comments, both values are used by Transarc software and
+confusion may arise if they are not synchronized with each other.
+
+@example
+
+>stacken.kth.se # Stacken Computer Club, KTH, Sweden
+130.237.234.3 #milko.stacken.kth.se
+130.237.234.43 #hot.stacken.kth.se
+130.237.237.230 #fishburger.stacken.kth.se
+
+@end example
+
+Again, please note that the text after the # in the cell-name is a
+comment, @strong{but} the hostnames after the # on the rows of an
+IP-address is @strong{not} a comment. The host and the ip-address needs
+to point at the same computer.
+
+@c Creations of a volume
+@c VOLSER_ListPartions
+@c VL_GetEntryByNameN -> VL_NOENT
+@c VOLSER_CreateVolume
+@c VOLSER_SetFlags
+@c VOLSER_EndTrans (rcode ignored ?)
+@c VL_CreateEntryN
+
+
diff --git a/usr.sbin/afs/src/doc/storage.texi b/usr.sbin/afs/src/doc/storage.texi
new file mode 100644
index 00000000000..f45f37708ec
--- /dev/null
+++ b/usr.sbin/afs/src/doc/storage.texi
@@ -0,0 +1,150 @@
+@c $Id: storage.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Organization of data, Parts of Arla, Description of AFS infrastructure, Top
+@comment node-name, next, previous, up
+
+@chapter Organization of data
+
+This chapter how data is stored and how AFS diffrent from, for example,
+NFS. It also describes how data kept consistent and what the
+requirements was and how that inpacted on the design.
+
+@menu
+* Requirements::
+* Data organization::
+* Callbacks::
+* Volume management::
+@end menu
+
+@node Requirements, Data organization, Organization of data, Organization of data
+@comment node-name, next, previous, up
+@heading Requirements
+
+@itemize @bullet
+@item Scalability
+
+It should be possible to use AFS with hundred-thousands of users without
+problems.
+
+Writes that are done to diffrent parts of the filesystem should not
+affect each other. It should be possible to distribute out the reads and
+writes over many file-servers. So if you have a file that is accessed by
+many clients, it should be possible to distribute out the load.
+
+If there is multiple writes to the same file, are you sure that isn't a
+database.
+
+@item Transparent to users
+
+Users should not need to know where their files are stored. It should be
+possible to move their files while they are using their files.
+
+@item Easy to admin
+
+It should be easy for a administrator to make changes to the
+filesystem. For example to change quota for a user or project. It should
+also be possible to move the users data for a fileserver to a less
+loaded one, or one with more diskspace available.
+
+Some benefits of using AFS is:
+
+@itemize @bullet
+@item user-transparent data migration
+@item an ability for on-line backups;
+@item data replication that provides both load balancing and robustness of
+critical data
+@item global name space without automounters and other add-ons;
+@item @@sys variables for platform-independent paths to binary location;
+@item enhanced security;
+@item client-side caching;
+@end itemize
+@end itemize
+
+@heading Anti-requirements
+
+@itemize @bullet
+@item No databases
+
+AFS isn't constructed for storing databases. It would be possible to use
+AFS for storing a database if a layer above provided locking and
+synchronizing of data.
+
+One of the problems is that AFS doesn't include mandatory byte-range
+locks. AFS uses advisory locking on whole files.
+
+If you need a real database, use one, they are much more efficent on
+solving a database problem. Don't use AFS.
+
+@end itemize
+
+@node Data organization, Callbacks, Requirements, Organization of data
+@comment node-name, next, previous, up
+@heading Volume
+
+A volume is a unit that is smaller then a partition. Its usually (should
+be) a well defined area, like a user's home directory, a project work
+area, or a program distribution.
+
+Quota is controlled on volume-level. All day-to-day management are done
+on volumes.
+
+@heading Partition
+
+In AFS a partition is what normally is named a partition. All partions
+that afs isusing is named a special way, @file{/vicepNN}, where NN is
+ranged from a to z, continuing with aa to zz. The fileserver (and
+volser) automaticly picks upp all partition starting with @file{/vicep}
+
+Volumes are stored in a partition. Volumes can't overlap
+partitions. Partitions are added when the fileserver is created or when
+a new disk is added to a filesystem.
+
+@heading Volume cloning and read-only clones
+
+A clone of volume is often needed for the volume operations. A clone is
+copy-on-write copy of a volume, the clone is the read-only version.
+
+A two special versions of a clone is the read-only volume and the backup
+volume. The read-only volume is a snapshot of a read-write volume (that
+is what a clone is) that can be replicated to several fileserver to
+distribute the load. Each fileserver plus partition where the read-only
+is located is called a replication-site.
+
+The backup volume is a clone that typically is made each night to enable
+the user to retrieve yestoday's data when they happen to remove a
+file. This is a very useful feature, since it lessen the load on the
+system-administrators to restore files from backup.
+
+@heading Mountpoints
+
+The volumes are independent of each other. To clue the together there is
+a @samp{mountpoint}s. Mountpoints are really symlink that is formated a
+special way that points out a volume (and a optional cell). A
+AFS-cache-manager will show a mountpoint as directory, in fact it will
+be the root directory of the target volume.
+
+@node Callbacks, Volume management, Data organization, Organization of data
+@comment node-name, next, previous, up
+@heading Callbacks
+
+Callbacks are what enable the AFS-cache-manager to keep the files
+without asking the server if there is newer version of the file.
+
+A callback is a promise from the fileserver that it will notify the
+client if the file (or directory) changes within the timelimit of the
+callback.
+
+For read-only callbacks there is only callback given its called a volume
+callback and it will be broken when the read-only volume is updated.
+
+@node Volume management, , Callbacks, Organization of data
+@comment node-name, next, previous, up
+@heading Volume management
+
+@itemize @bullet
+@item Create
+@item Replicate
+@item Release
+@item Delete
+@item Backup
+@end itemize
diff --git a/usr.sbin/afs/src/doc/timeline.texi b/usr.sbin/afs/src/doc/timeline.texi
new file mode 100644
index 00000000000..9b6066c6545
--- /dev/null
+++ b/usr.sbin/afs/src/doc/timeline.texi
@@ -0,0 +1,84 @@
+@c $Id: timeline.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Arla timeline, Authors, Oddities, Top
+@comment node-name, next, previous, up
+@chapter Arla timeline
+
+Arla have existed for quite some years.
+
+Development started around XXX by Björn Grönvall
+@email{bg@@nada.kth.se}, quick followers was Assar
+@email{assar@@sics.se} (at that time @email{assar@@pdc.kth.se>) and
+Johan Danielsson <joda@@pdc.kth.se}. The platform that was chosen was
+Sparc SunOS4 (the OS that NADA, KTH was using).
+
+Some work was being done by Patrik Stymne @email{patriks@@e.kth.se} in
+porting arla to Ultrix, but this work was never finished.
+
+At this time there was no free rx, lwp or rxkad. A basic rx
+implementation was written, and the threading problem was solved by
+using pthreads.
+
+The Arla development started to slow down around 11 April 1995.
+
+In about Mar-Jun 1996 rx and lwp was released by Transarc, this was made
+possible by Jim Doyle @email{jrd@@bu.edu}, and Derrick J. Brashear
+@email{shadow@@dementia.org}.
+
+In September 1997, an rxkad implementation was written by Björn. At
+the same time, a need for an AFS client for OpenBSD rose at the
+Stacken, the local computer club at KTH. Other free OS:es, as NetBSD,
+FreeBSD and Linux(primarily sparc) were also in need of AFS clients.
+
+In TokKOM, a local communications system using LysKOM
+(@url{http://www.lysator.liu.se/lyskom/}), Assar suggested to some club
+members that it would be a nice thing to resume the arla
+development.
+
+Some people suggested that it would be less trouble having someone with
+access to the Transarc AFS source code port the code to the relevent
+platforms. Assar then ported xfs to FreeBSD 2.2.x in notime, just to
+show the high portability.
+
+People started to understand that arla was a concept that would work,
+and first out was Love Hörnqvist-Åstrand @email{lha@@stacken.kth.se} to
+join. Development was primarily aimed at OpenBSD and NetBSD at the
+moment, and Arla lived for at least 2-3 weeks in /var/tmp on a host
+named yakko.stacken.kth.se.
+
+Magnus Ahltorp @email{map@@stacken.kth.se} joined shortly thereafter,
+spending the rest of the year reading about the Linux VFS, and after a
+while, Artur Grabowski @email{art@@stacken.kth.se} also started to work
+on arla, concentrating on OpenBSD kernel stuff.
+
+The first entry in ChangeLog is dated Fri Oct 24 17:20:40 1997. Around
+this time arla was given a CVS tree, to ease development. Now you
+could also mount the xfs-device and get the root-directory out of it.
+
+The Linux port was done in a few weeks in the beginning of 1998. Only
+the Linux 2.0 kernel was supported at this time.
+
+In April 1998 Assar hade a Arla paper presented at Freenix. Linux 2.1
+support was written also written around this time. This was a major
+work since there was a lot of stuff that had changed (namely the
+dcache).
+
+The first milko entry is dated Thu Oct 30 01:46:51 1997. Note that
+this milko in a sense "worked". You could get files out from it and
+store them.
+
+There was from this point a lot of work being done and quite a lot of
+studies was "wasted". We learned a lot, but not the stuff we were
+expected too.
+
+In Mars 2000 preliminary support for MacOS X/Darwin 1.0 was merged in
+by Magnus and Assar.
+
+Around the same time there we hacked in support for Solaris 8 (beta2)
+There was also some work being done on Windows 2000 native driver at
+same time.
+
+In June 2000 there was a presentation on MADE2000 in Gothenburg, Sweden.
+
+This just includes some milestones, for more information se
+Changelog.* and NEWS files in the distribution.
diff --git a/usr.sbin/afs/src/doc/tools.texi b/usr.sbin/afs/src/doc/tools.texi
new file mode 100644
index 00000000000..a2005c9ae59
--- /dev/null
+++ b/usr.sbin/afs/src/doc/tools.texi
@@ -0,0 +1,34 @@
+@c $Id: tools.texi,v 1.1 2000/09/11 14:40:53 art Exp $
+
+@node Rx protocol, LWP, , Tools and libs
+@section Rx protocol
+
+@c XXX History of RX
+
+Rx is run over UDP.
+
+One of rxgen or ydr is used to generate stub-files, ydr is better since
+it generates prototypes, too.
+
+The current implemetation of rx it not that beautiful.
+
+@node LWP, , Rx protocol, Tools and libs
+@section LWP
+
+@c XXX History of LWP
+
+LWP is a preepmtive thread package. It does it's context-switching by
+creating a private stack for each thread. The heart of the package is
+select(2).
+
+The core of the package is @file{process.S}. Its currenty built with a
+bourne-shell file. @file{Process.s} is preprocessed with @code{cpp} and
+then given to (g)as. The magic how to build this file a portable way is
+not fun.
+
+The stack is checked for overruns in context-switches, but that is often
+too late. It might be an idea to add a @cite{red zone} at the top of the
+stack to be able to detect overruns.
+
+For architectures not supported by LWP, it can be exchanged with the
+pthreads pakage.
diff --git a/usr.sbin/afs/src/doc/xfs.txt b/usr.sbin/afs/src/doc/xfs.txt
new file mode 100644
index 00000000000..a305b55ec3d
--- /dev/null
+++ b/usr.sbin/afs/src/doc/xfs.txt
@@ -0,0 +1,380 @@
+
+XFS DOCUMENTATION
+=================
+
+$Id: xfs.txt,v 1.1 2000/09/11 14:40:53 art Exp $
+
+This is not the truth, but close too.
+
+
+TODO
+#include <xfs/xfs_attr.h>
+
+
+LIMITATIONS and CONSTANTS
+=========================
+
+You can install messages to xfs of maxsize ``MAX_XMSG_SIZE''.
+
+The kernel can at most hold rights of size ``MAXRIGHTS''.
+
+A xfs handle have the size of ``MAXHANDLE'', and that is at least 16bytes.
+
+The annonous user had id ``XFS_ANONYMOUSID''.
+
+The xfs-fh-open-handle have the size of ``CACHEHANDLESIZE'', and its
+a opaque data-structure.
+
+PAGS
+====
+
+Pags are a hack to separate processes of same UID to make them have
+diffrent access-rights. Pags are saved over setuid(2)/initgroups(2)
+calls. Xfs uses a struct ``xfs_cred'' to pass over the UID and the pag.
+
+
+TOKENS
+======
+
+Tokens are the rights the xfs have on the node and what parts of the
+node that is valid.
+
+XXX Insert descriptions of tokens here....
+
+
+MESSAGES
+========
+
+Are passed through the xfs device somehow.
+
+Each message is prepended by a header including the 32-bit fields
+`size'', ``opcode'', ``sequence_num'', ``pad1'' (in that
+order). ``Size'' is the size of the WHOLE message. ``Opcode'' is the
+opcode (described bellow). ``sequence_num'' is a messages specific field
+that is used for replying the the sender of the message (if so is
+needed).
+
+All messages (and the xfs_header) are padded to 64-bit boundery to
+avoid bit unaligned data in the kernel. The padding is called padN,
+where N is a number.
+
+Note that the total size of the message may be larger then one message,
+them its two or more message pasted together for preformance resons.
+
+The opcode has a value from 0 (zero) to XFS_MSG_COUNT - 1.
+
+The following opcodes are defined:
+
+XFS_MSG_VERSION (userland)
+
+ Used probe the kernelmodule to check some *basic* things that will change
+ the behavior of the userland module.
+
+ For each question XFS_MSG_VERSION can return XFS_VERSION_YES
+ or XFS_VERSION_NO.
+
+ If VERSION returns something else then XFS_VERSION_YES to
+ XFS_MSG_VERSION, its not supported.
+
+ ``probe'' is set to a query.
+
+ Queries that exist today is:
+ XFS_VERSION_VERSION - check if we have XFS_VERSION supporta
+ XFS_VERSION_FHGET - have we fhget support, or do we use pathnames
+ XFS_VERSION_FHGET_NATIVE- native fhget (not xfs-version ?)
+ XFS_VERSION_GC_NODES - we have gc-nodes xfs-call ?
+
+XFS_MSG_WAKEUP (userland|xfs)
+
+ Wakeup query ``sleepers_sequence_num'' with ``error'' (that is a
+ errno or userdefined error).
+
+ It may be called from both userland and the xfs-implementation.
+
+XFS_MSG_GETROOT (xfs)
+
+ GETROOT is called to get the root-node with the ``cred''
+
+ Its only called from xfs to get the root-node, this might be
+ serveral times per mount depending on filesystem.
+
+ Xfs is wake-up:ed by a XFS_MSG_WAKEUP message from userland
+ after a XFS_MSG_INSTALLROOT message has been sent or and error-code is
+ passed to the kernel with the wakeup-message.
+
+XFS_MSG_INSTALLROOT (userland)
+
+ INSTALLROOT is called insert a root.
+
+ INSTALLROOT MUST only be called on the request of GETROOT.
+
+ The node to install is in ``node''.
+
+ The only returnvalue of the message is the integer return value.
+
+ Multiple INSTALLROOT must be ignored by the xfs-implementation, and
+ the returnvalue EBUSY MUST be returned.
+
+XFS_MSG_GETNODE (xfs)
+
+ GETNODE is called to get the node named ``named'' in the
+ directory ``parent_handle'' with ``cred''.
+
+ While there is no error in the returning WAKEUP call and there
+ is corresponding node in cache the xfs-implemetation should
+ loop until there is an error.
+
+XFS_MSG_INSTALLNODE (userland)
+
+ Insert the ``node'' of ``name'' in the directory ``parent_handle''
+ into the cache.
+
+ The userland MUST NOT install the ``node'' yet onther time
+
+ The xfs-implemetation SHOULD NOT install same node several
+ times in the same ``parent_handle'', that is if ``node'' has
+ same parent and same name (observe that same handle can be
+ installed several times in the case of hardlinks).
+
+XFS_MSG_GETATTR (xfs)
+
+ Get the attributes for the node described by ``handle'' that
+ already have been installed by INSTALLNODE with the ``cred''.
+
+ The xfs-implemetation should loop until there is an error,
+ or the node is the cache with appropriate pag in the cred
+ part of the node.
+
+XFS_MSG_INSTALLATTR (userland)
+
+ Should update the preinstalled incache data with ``node''. If
+ the node found in ``node.handle'' isn't in the cache the
+ xfs-implementation MUST return 0 and MIGHT print a
+ debug-message. Note that this isn't error if the node isn't in
+ the xfs-cache since it might have fallen out before the
+ message was sent to xfs (that is, the invalidnode message is
+ still in the queue to userland).
+
+XFS_MSG_GETDATA (xfs)
+
+ Get data for the node described in ``handle''. Otherwise same
+ as GETATTR.
+
+XFS_MSG_INSTALLDATA (userland)
+
+ Install data for the node described by ``node.handle''. The
+ vnode/inode that contains the is pointed out by ``cache_handle''
+ the there is support for openfh/getfh. Its also pointed out
+ by the name ``cache_name'', and that name is relative to the
+ current process current working directory.
+
+ Installdata also updates the attributes of the node.
+
+ If the ``flag & XFS_ID_INVALID_DNLC'' is set the
+ xfs-implementation should flush all namecache related to this
+ node. The xfs-implementation SHOULD check that this is a
+ directory-node.
+
+XFS_MSG_INACTIVENODE (xfs)
+
+ The message that xfs sends to the userland daemon when
+ ``handle'' no longer exist in the cache.
+
+ To tell what state the node is in flag in set to appropiate
+ value. ``XFS_NOREFS'' tells the userland daemon that the xfs
+ still have the node cached but nothing is using it and it can
+ be removed at any time. ``XFS_DELETE'' mean that all this node
+ has been droped from the cache and can't be used anymore.
+
+XFS_MSG_INVALIDNODE (userland)
+
+ Used to hint the kernel that node described by `handle''
+ should be droped from the cache. Doesn't mean that the node
+ should be killed off, just that it should be that when it's no
+ longer used.
+
+ The userland MUST NOT remove the node from the cache until it
+ receives a XFS_MSG_INACTIVENODE.
+
+ XXX what is the diffrence to GC_NODE
+
+XFS_MSG_OPEN (xfs)
+
+ Passed up to the userland to inform that ``handle'' has been
+ opened with ``cred'' to do what is decribed in ``tokens''.
+
+ Can be the same as XFS_MSG_GETDATA if no locking is implemeted.
+
+XFS_MSG_PUTDATA (xfs)
+
+enum { XFS_READ = 1, XFS_WRITE = 2, XFS_NONBLOCK = 4, XFS_APPEND = 8};
+
+XFS_MSG_PUTATTR (xfs)
+
+/* Directory manipulating messages. */
+XFS_MSG_CREATE (xfs)
+XFS_MSG_MKDIR (xfs)
+XFS_MSG_LINK (xfs)
+XFS_MSG_SYMLINK (xfs)
+
+XFS_MSG_REMOVE (xfs)
+XFS_MSG_RMDIR (xfs)
+
+XFS_MSG_RENAME (xfs)
+
+XFS_MSG_PIOCTL (xfs)
+XFS_MSG_WAKEUP_DATA (userland)
+
+XFS_MSG_UPDATEFID (userland)
+
+XFS_MSG_ADVLOCK (xfs/userland)
+
+XFS_MSG_GC_NODES (userland)
+
+
+__END__;
+
+/* XFS_MSG_OPEN */
+struct xfs_message_open {
+ struct xfs_message_header header;
+ struct xfs_cred cred;
+ xfs_handle handle;
+ u_int32_t tokens;
+ u_int32_t pad1;
+};
+
+/* XFS_MSG_PUTDATA */
+struct xfs_message_putdata {
+ struct xfs_message_header header;
+ xfs_handle handle;
+ struct xfs_attr attr; /* XXX ??? */
+ struct xfs_cred cred;
+ u_int32_t flag;
+ u_int32_t pad1;
+};
+
+/* XFS_MSG_PUTATTR */
+struct xfs_message_putattr {
+ struct xfs_message_header header;
+ xfs_handle handle;
+ struct xfs_attr attr;
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_CREATE */
+struct xfs_message_create {
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_attr attr;
+ u_int32_t mode;
+ u_int32_t pad1;
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_MKDIR */
+struct xfs_message_mkdir {
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_attr attr;
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_LINK */
+struct xfs_message_link {
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ xfs_handle from_handle;
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_SYMLINK */
+struct xfs_message_symlink {
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ char contents[2048]; /* XXX */
+ struct xfs_attr attr;
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_REMOVE */
+struct xfs_message_remove {
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_RMDIR */
+struct xfs_message_rmdir {
+ struct xfs_message_header header;
+ xfs_handle parent_handle;
+ char name[256]; /* XXX */
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_RENAME */
+struct xfs_message_rename {
+ struct xfs_message_header header;
+ xfs_handle old_parent_handle;
+ char old_name[256]; /* XXX */
+ xfs_handle new_parent_handle;
+ char new_name[256]; /* XXX */
+ struct xfs_cred cred;
+};
+
+/* XFS_MSG_PIOCTL */
+struct xfs_message_pioctl {
+ struct xfs_message_header header;
+ u_int32_t opcode ;
+ u_int32_t pad1;
+ xfs_cred cred;
+ u_int32_t insize;
+ u_int32_t outsize;
+ char msg[2048] ; /* XXX */
+ xfs_handle handle;
+};
+
+
+/* XFS_MESSAGE_WAKEUP_DATA */
+struct xfs_message_wakeup_data {
+ struct xfs_message_header header;
+ u_int32_t sleepers_sequence_num; /* Where to send wakeup */
+ u_int32_t error; /* Return value */
+ u_int32_t len;
+ u_int32_t pad1;
+ char msg[2048] ; /* XXX */
+};
+
+/* XFS_MESSAGE_UPDATEFID */
+struct xfs_message_updatefid {
+ struct xfs_message_header header;
+ xfs_handle old_handle;
+ xfs_handle new_handle;
+};
+
+/* XFS_MESSAGE_ADVLOCK */
+struct xfs_message_advlock {
+ struct xfs_message_header header;
+ xfs_handle handle;
+ struct xfs_cred cred;
+ xfs_locktype_t locktype;
+#define XFS_WR_LOCK 1 /* Write lock */
+#define XFS_RD_LOCK 2 /* Read lock */
+#define XFS_UN_LOCK 3 /* Unlock */
+#define XFS_BR_LOCK 4 /* Break lock (inform that we don't want the lock) */
+ xfs_lockid_t lockid;
+};
+
+/* XFS_MESSAGE_GC_NODES */
+struct xfs_message_gc_nodes {
+ struct xfs_message_header header;
+#define XFS_GC_NODES_MAX_HANDLE 50
+ u_int32_t len;
+ u_int32_t pad1;
+ xfs_handle handle[XFS_GC_NODES_MAX_HANDLE];
+};
+#endif /* _xmsg_h */
diff --git a/usr.sbin/afs/src/include/Makefile.in b/usr.sbin/afs/src/include/Makefile.in
new file mode 100644
index 00000000000..6ee7114ad68
--- /dev/null
+++ b/usr.sbin/afs/src/include/Makefile.in
@@ -0,0 +1,132 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:53 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+CC = @CC@
+DEFS = @DEFS@ -DHOST=\"@CANONICAL_HOST@\"
+CFLAGS = @CFLAGS@ $(DEFS) -I. -I$(srcdir)
+
+LN_S = @LN_S@
+RM_F = rm -f
+MKDIR = mkdir
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+
+LOCL_HEADERS = roken.h ko.h sl.h part.h list.h \
+ bool.h log.h \
+ hash.h \
+ lwp.h lock.h getarg.h err.h parse_units.h \
+ resolve.h rxkad.h service.h mmaptime.h ports.h \
+ heap.h fbuf.h fdir.h afs_dir.h parse_time.h parse_bytes.h \
+ acl.h
+
+BUILDHEADERS = atypes.h fs_errors.h
+
+HEADERS = $(BUILDHEADERS)
+
+BITS_OBJECTS = bits.o
+
+SOURCES = bits.c
+
+all: $(LOCL_HEADERS) $(HEADERS)
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(includedir)
+ for x in $(HEADERS); \
+ do \
+ b=`basename $$x`; \
+ if test -f $$b; then \
+ $(INSTALL_DATA) $$b $(DESTDIR)$(includedir)/$$b; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$b $(DESTDIR)$(includedir)/$$b; \
+ fi; \
+ done
+
+uninstall:
+ for x in $(HEADERS); do \
+ $(RM_F) $(DESTDIR)$(includedir)/$$x; \
+ done
+
+bits: $(BITS_OBJECTS)
+ $(CC) -o $@ $(BITS_OBJECTS)
+
+bits.o: bits.c
+
+atypes.h: bits
+ ./bits $@
+
+clean:
+ rm -f bits *.o $(BUILDHEADERS) $(LOCL_HEADERS)
+
+distclean: clean
+ rm -f Makefile
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=include/Makefile CONFIG_HEADERS= ./config.status
+
+roken.h:
+ $(LN_S) $(srcdir)/../lib/roken/roken.h .
+sl.h:
+ $(LN_S) $(srcdir)/../lib/sl/sl.h .
+ko.h:
+ $(LN_S) $(srcdir)/../lib/ko/ko.h .
+part.h:
+ $(LN_S) $(srcdir)/../lib/ko/part.h .
+ports.h:
+ $(LN_S) $(srcdir)/../lib/ko/ports.h .
+atom.h:
+ $(LN_S) $(srcdir)/../util/atom.h .
+list.h:
+ $(LN_S) $(srcdir)/../util/list.h .
+bool.h:
+ $(LN_S) $(srcdir)/../util/bool.h .
+log.h:
+ $(LN_S) $(srcdir)/../util/log.h .
+hash.h:
+ $(LN_S) $(srcdir)/../util/hash.h .
+mmaptime.h:
+ $(LN_S) $(srcdir)/../util/mmaptime.h .
+lock.h:
+ $(LN_S) $(srcdir)/../lwp/lock.h .
+lwp.h:
+ $(LN_S) $(srcdir)/../lwp/@LWP_H@ ./lwp.h
+getarg.h:
+ $(LN_S) $(srcdir)/../lib/roken/getarg.h .
+parse_units.h:
+ $(LN_S) $(srcdir)/../lib/roken/parse_units.h .
+err.h:
+ $(LN_S) $(srcdir)/../lib/roken/err.h .
+resolve.h:
+ $(LN_S) $(srcdir)/../lib/roken/resolve.h .
+parse_time.h:
+ $(LN_S) $(srcdir)/../lib/roken/parse_time.h .
+parse_bytes.h:
+ $(LN_S) $(srcdir)/../lib/roken/parse_bytes.h .
+rxkad.h:
+ $(LN_S) $(srcdir)/../rxkad/rxkad.h .
+service.h:
+ $(LN_S) $(srcdir)/../arlad/service.h .
+heap.h:
+ $(LN_S) $(srcdir)/../util/heap.h .
+fs_errors.h:
+ $(LN_S) $(srcdir)/../arlad/fs_errors.h .
+fbuf.h:
+ $(LN_S) $(srcdir)/../lib/bufdir/fbuf.h .
+fdir.h:
+ $(LN_S) $(srcdir)/../lib/bufdir/fdir.h .
+afs_dir.h:
+ $(LN_S) $(srcdir)/../lib/bufdir/afs_dir.h .
+acl.h:
+ $(LN_S) $(srcdir)/../lib/acl/acl.h .
+
+.PHONY: all install uninstall clean distclean
diff --git a/usr.sbin/afs/src/install-sh b/usr.sbin/afs/src/install-sh
new file mode 100644
index 00000000000..ebc66913e94
--- /dev/null
+++ b/usr.sbin/afs/src/install-sh
@@ -0,0 +1,250 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/usr.sbin/afs/src/lib/Makefile.in b/usr.sbin/afs/src/lib/Makefile.in
new file mode 100644
index 00000000000..1b6961836b9
--- /dev/null
+++ b/usr.sbin/afs/src/lib/Makefile.in
@@ -0,0 +1,45 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:54 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+SUBDIRS = roken sl @editline_dir@ acl cmd
+
+all:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+install:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+uninstall:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+clean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+realclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+distclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+mostlyclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+.PHONY: all install uninstall clean realclean distclean mostlyclean
diff --git a/usr.sbin/afs/src/lib/acl/Makefile.in b/usr.sbin/afs/src/lib/acl/Makefile.in
new file mode 100644
index 00000000000..bd1a2bb52a6
--- /dev/null
+++ b/usr.sbin/afs/src/lib/acl/Makefile.in
@@ -0,0 +1,81 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:54 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+LN_S = @LN_S@
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+
+INCLUDES = -I../../include \
+ -I$(srcdir)/../../include \
+ -I$(srcdir) \
+ -I.
+
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(CFLAGS)
+LIBNAME = $(LIBPREFIX)acl
+LIBEXT = a
+LIBPREFIX = lib
+LIB = $(LIBNAME).$(LIBEXT)
+
+SOURCES = acl_files.c
+
+OBJECTS = acl_files.o
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(DEFS) $(REALCFLAGS) $(PICFLAGS) $(CPPFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) -m 0555 $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *.tab.c *~ roken_rename.h
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(OBJECTS)
+ -$(RANLIB) $@
+
+$(OBJECTS): ../../include/config.h
+
+Makefile: ../../config.status Makefile.in
+ cd ../.. ; CONFIG_FILES=lib/acl/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/lib/acl/acl.h b/usr.sbin/afs/src/lib/acl/acl.h
new file mode 100644
index 00000000000..20e28a42b00
--- /dev/null
+++ b/usr.sbin/afs/src/lib/acl/acl.h
@@ -0,0 +1,60 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: acl.h,v 1.1 2000/09/11 14:40:54 art Exp $ */
+
+#ifndef __ACL_H
+#define __ACL_H
+
+#include <atypes.h>
+#ifndef HAVE_KRB_PRINCIPAL
+#include <stds.h>
+#endif
+
+#ifndef __P
+#define __P(x) x
+#endif
+
+void acl_canonicalize_principal __P((char *principal, char *canon));
+int acl_initialize __P((char *acl_file, int perm));
+int acl_exact_match __P((char *acl, char *principal));
+int acl_check __P((char *acl, char *principal));
+int acl_add __P((char *acl, char *principal));
+int acl_delete __P((char *acl, char *principal));
+
+#endif /* __ACL_H */
diff --git a/usr.sbin/afs/src/lib/acl/acl_files.c b/usr.sbin/afs/src/lib/acl/acl_files.c
new file mode 100644
index 00000000000..9d35d34bd0d
--- /dev/null
+++ b/usr.sbin/afs/src/lib/acl/acl_files.c
@@ -0,0 +1,611 @@
+/*
+ Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+ Export of this software from the United States of America is assumed
+ to require a specific license from the United States Government.
+ It is the responsibility of any person or organization contemplating
+ export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+ */
+
+#include "config.h"
+
+RCSID("$Id: acl_files.c,v 1.1 2000/09/11 14:40:55 art Exp $");
+
+#ifdef KERBEROS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <time.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include <errno.h>
+#include <ctype.h>
+
+#include <roken.h>
+
+#include <krb.h>
+#include <acl.h>
+
+/*
+ * compat functions for different krb libraries
+ *
+ * this should either be moved somewhere else or compatability with
+ * other kerberos implementations should just be given up.
+ */
+
+#ifndef HAVE_KRB_PRINCIPAL
+
+int
+krb_parse_name (const char *fullname, krb_principal *principal)
+{
+ return kname_parse (principal->name,
+ principal->instance,
+ principal->realm,
+ fullname);
+}
+
+/* copied from unparse_name.c in krb4 */
+
+static void
+quote_string(char *quote, char *from, char *to)
+{
+ while(*from){
+ if(strchr(quote, *from))
+ *to++ = '\\';
+ *to++ = *from++;
+ }
+ *to = 0;
+}
+
+/* To be compatible with old functions, we quote differently in each
+ part of the principal*/
+
+char *
+krb_unparse_name_r(krb_principal *pr, char *fullname)
+{
+ quote_string("'@\\", pr->name, fullname);
+ if(pr->instance[0]){
+ strcat(fullname, ".");
+ quote_string("@\\", pr->instance, fullname + strlen(fullname));
+ }
+ if(pr->realm[0]){
+ strcat(fullname, "@");
+ quote_string("\\", pr->realm, fullname + strlen(fullname));
+ }
+ return fullname;
+}
+
+char *
+krb_unparse_name_long_r(char *name, char *instance, char *realm,
+ char *fullname)
+{
+ krb_principal pr;
+
+ memset(&pr, 0, sizeof(pr));
+ strncpy (pr.name, name, sizeof(pr.name));
+ pr.name[sizeof(pr.name) - 1] = '\0';
+ if(instance) {
+ strncpy (pr.instance, instance, sizeof(pr.instance));
+ pr.instance[sizeof(pr.instance) - 1] = '\0';
+ }
+ if(realm) {
+ strncpy (pr.realm, realm, sizeof(pr.realm));
+ pr.realm[sizeof(pr.realm) - 1] = '\0';
+ }
+ return krb_unparse_name_r(&pr, fullname);
+}
+
+char *
+krb_unparse_name(krb_principal *pr)
+{
+ static char principal[MAX_K_NAME_SZ];
+ krb_unparse_name_r(pr, principal);
+ return principal;
+}
+
+char *
+krb_unparse_name_long(char *name, char *instance, char *realm)
+{
+ krb_principal pr;
+
+ memset(&pr, 0, sizeof(pr));
+ strncpy(pr.name, name, sizeof(pr.name));
+ pr.name[sizeof(pr.name) - 1] = '\0';
+ if(instance) {
+ strncpy(pr.instance, instance, sizeof(pr.instance));
+ pr.instance[sizeof(pr.instance) - 1] = '\0';
+ }
+ if(realm) {
+ strncpy(pr.realm, realm, sizeof(pr.realm));
+ pr.realm[sizeof(pr.realm) - 1] = '\0';
+ }
+ return krb_unparse_name(&pr);
+}
+
+#endif /* HAVE_KRB_PRINCIPAL */
+
+/*** Routines for manipulating access control list files ***/
+
+/* "aname.inst@realm" */
+#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3)
+#define INST_SEP '.'
+#define REALM_SEP '@'
+
+#define LINESIZE 2048 /* Maximum line length in an acl file */
+
+#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */
+#define WAIT_TIME 300 /* Maximum time allowed write acl file */
+
+#define CACHED_ACLS 8 /* How many acls to cache */
+ /* Each acl costs 1 open file descriptor */
+#define ACL_LEN 16 /* Twice a reasonable acl length */
+
+#define COR(a,b) ((a!=NULL)?(a):(b))
+
+/*
+ * Canonicalize a principal name.
+ * If instance is missing, it becomes ""
+ * If realm is missing, it becomes the local realm
+ * Canonicalized form is put in canon, which must be big enough to
+ * hold MAX_PRINCIPAL_SIZE characters
+ *
+ */
+
+void
+acl_canonicalize_principal(char *principal, char *canon)
+{
+ krb_principal princ;
+ int ret;
+ ret = krb_parse_name(principal, &princ);
+ if(ret) { /* ? */
+ *canon = '\0';
+ return;
+ }
+ if(princ.realm[0] == '\0')
+ krb_get_lrealm(princ.realm, 1);
+ krb_unparse_name_r(&princ, canon);
+}
+
+/* Get a lock to modify acl_file */
+/* Return new FILE pointer */
+/* or NULL if file cannot be modified */
+/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */
+static
+FILE *acl_lock_file(char *acl_file)
+{
+ struct stat s;
+ char new[LINESIZE];
+ int nfd;
+ FILE *nf;
+ int mode;
+
+ if(stat(acl_file, &s) < 0) return(NULL);
+ mode = s.st_mode;
+ snprintf(new, sizeof(new), NEW_FILE, acl_file);
+ for(;;) {
+ /* Open the new file */
+ if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) {
+ if(errno == EEXIST) {
+ /* Maybe somebody got here already, maybe it's just old */
+ if(stat(new, &s) < 0) return(NULL);
+ if(time(0) - s.st_ctime > WAIT_TIME) {
+ /* File is stale, kill it */
+ unlink(new);
+ continue;
+ } else {
+ /* Wait and try again */
+ sleep(1);
+ continue;
+ }
+ } else {
+ /* Some other error, we lose */
+ return(NULL);
+ }
+ }
+
+ /* If we got to here, the lock file is ours and ok */
+ /* Reopen it under stdio */
+ if((nf = fdopen(nfd, "w")) == NULL) {
+ /* Oops, clean up */
+ unlink(new);
+ }
+ return(nf);
+ }
+}
+
+/* Abort changes to acl_file written onto FILE *f */
+/* Returns 0 if successful, < 0 otherwise */
+/* Closes f */
+static int
+acl_abort(char *acl_file, FILE *f)
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ /* make sure we aren't nuking someone else's file */
+ if(fstat(fileno(f), &s) < 0
+ || s.st_nlink == 0) {
+ fclose(f);
+ return(-1);
+ } else {
+ snprintf(new, sizeof(new), NEW_FILE, acl_file);
+ ret = unlink(new);
+ fclose(f);
+ return(ret);
+ }
+}
+
+/* Commit changes to acl_file written onto FILE *f */
+/* Returns zero if successful */
+/* Returns > 0 if lock was broken */
+/* Returns < 0 if some other error occurs */
+/* Closes f */
+static int
+acl_commit(char *acl_file, FILE *f)
+{
+ char new[LINESIZE];
+ int ret;
+ struct stat s;
+
+ snprintf(new, sizeof(new), NEW_FILE, acl_file);
+ if(fflush(f) < 0
+ || fstat(fileno(f), &s) < 0
+ || s.st_nlink == 0) {
+ acl_abort(acl_file, f);
+ return(-1);
+ }
+
+ ret = rename(new, acl_file);
+ fclose(f);
+ return(ret);
+}
+
+/* Initialize an acl_file */
+/* Creates the file with permissions perm if it does not exist */
+/* Erases it if it does */
+/* Returns return value of acl_commit */
+int
+acl_initialize(char *acl_file, int perm)
+{
+ FILE *new;
+ int fd;
+
+ /* Check if the file exists already */
+ if((new = acl_lock_file(acl_file)) != NULL) {
+ return(acl_commit(acl_file, new));
+ } else {
+ /* File must be readable and writable by owner */
+ if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) {
+ return(-1);
+ } else {
+ close(fd);
+ return(0);
+ }
+ }
+}
+
+/* Eliminate all whitespace character in buf */
+/* Modifies its argument */
+static void
+ nuke_whitespace(char *buf)
+{
+ char *pin, *pout;
+
+ for(pin = pout = buf; *pin != '\0'; pin++)
+ if(!isspace((unsigned char)*pin)) *pout++ = *pin;
+ *pout = '\0'; /* Terminate the string */
+}
+
+/* Hash table stuff */
+
+struct hashtbl {
+ int size; /* Max number of entries */
+ int entries; /* Actual number of entries */
+ char **tbl; /* Pointer to start of table */
+};
+
+/* Make an empty hash table of size s */
+static struct hashtbl *
+make_hash(int size)
+{
+ struct hashtbl *h;
+
+ if(size < 1) size = 1;
+ h = (struct hashtbl *) malloc(sizeof(struct hashtbl));
+ if (h == NULL)
+ return NULL;
+ h->size = size;
+ h->entries = 0;
+ h->tbl = (char **) calloc(size, sizeof(char *));
+ if (h->tbl == NULL) {
+ free (h);
+ return NULL;
+ }
+ return(h);
+}
+
+/* Destroy a hash table */
+static void
+destroy_hash(struct hashtbl *h)
+{
+ int i;
+
+ for(i = 0; i < h->size; i++) {
+ if(h->tbl[i] != NULL) free(h->tbl[i]);
+ }
+ free(h->tbl);
+ free(h);
+}
+
+/* Compute hash value for a string */
+static unsigned int
+hashval(char *s)
+{
+ unsigned hv;
+
+ for(hv = 0; *s != '\0'; s++) {
+ hv ^= ((hv << 3) ^ *s);
+ }
+ return(hv);
+}
+
+/* Add an element to a hash table */
+static void
+add_hash(struct hashtbl *h, char *el)
+{
+ unsigned hv;
+ char *s;
+ char **old;
+ int i;
+
+ /* Make space if it isn't there already */
+ if(h->entries + 1 > (h->size >> 1)) {
+ old = h->tbl;
+ h->tbl = (char **) calloc(h->size << 1, sizeof(char *));
+ for(i = 0; i < h->size; i++) {
+ if(old[i] != NULL) {
+ hv = hashval(old[i]) % (h->size << 1);
+ while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1);
+ h->tbl[hv] = old[i];
+ }
+ }
+ h->size = h->size << 1;
+ free(old);
+ }
+
+ hv = hashval(el) % h->size;
+ while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size;
+ s = strdup(el);
+ if (s != NULL) {
+ h->tbl[hv] = s;
+ h->entries++;
+ }
+}
+
+/* Returns nonzero if el is in h */
+static int
+check_hash(struct hashtbl *h, char *el)
+{
+ unsigned hv;
+
+ for(hv = hashval(el) % h->size;
+ h->tbl[hv] != NULL;
+ hv = (hv + 1) % h->size) {
+ if(!strcmp(h->tbl[hv], el)) return(1);
+ }
+ return(0);
+}
+
+struct acl {
+ char filename[LINESIZE]; /* Name of acl file */
+ int fd; /* File descriptor for acl file */
+ struct stat status; /* File status at last read */
+ struct hashtbl *acl; /* Acl entries */
+};
+
+static struct acl acl_cache[CACHED_ACLS];
+
+static int acl_cache_count = 0;
+static int acl_cache_next = 0;
+
+/* Returns < 0 if unsuccessful in loading acl */
+/* Returns index into acl_cache otherwise */
+/* Note that if acl is already loaded, this is just a lookup */
+static int
+acl_load(char *name)
+{
+ int i;
+ FILE *f;
+ struct stat s;
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ /* See if it's there already */
+ for(i = 0; i < acl_cache_count; i++) {
+ if(!strcmp(acl_cache[i].filename, name)
+ && acl_cache[i].fd >= 0) goto got_it;
+ }
+
+ /* It isn't, load it in */
+ /* maybe there's still room */
+ if(acl_cache_count < CACHED_ACLS) {
+ i = acl_cache_count++;
+ } else {
+ /* No room, clean one out */
+ i = acl_cache_next;
+ acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
+ close(acl_cache[i].fd);
+ if(acl_cache[i].acl) {
+ destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = (struct hashtbl *) 0;
+ }
+ }
+
+ /* Set up the acl */
+ strncpy(acl_cache[i].filename, name, LINESIZE);
+ acl_cache[i].filename[LINESIZE-1] = '\0';
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ /* Force reload */
+ acl_cache[i].acl = (struct hashtbl *) 0;
+
+ got_it:
+ /*
+ * See if the stat matches
+ *
+ * Use stat(), not fstat(), as the file may have been re-created by
+ * acl_add or acl_delete. If this happens, the old inode will have
+ * no changes in the mod-time and the following test will fail.
+ */
+ if(stat(acl_cache[i].filename, &s) < 0) return(-1);
+ if(acl_cache[i].acl == (struct hashtbl *) 0
+ || s.st_nlink != acl_cache[i].status.st_nlink
+ || s.st_mtime != acl_cache[i].status.st_mtime
+ || s.st_ctime != acl_cache[i].status.st_ctime) {
+ /* Gotta reload */
+ if(acl_cache[i].fd >= 0) close(acl_cache[i].fd);
+ if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1);
+ if((f = fdopen(acl_cache[i].fd, "r")) == NULL) return(-1);
+ if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = make_hash(ACL_LEN);
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ nuke_whitespace(buf);
+ acl_canonicalize_principal(buf, canon);
+ add_hash(acl_cache[i].acl, canon);
+ }
+ fclose(f);
+ acl_cache[i].status = s;
+ }
+ return(i);
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Principal is not canonicalized, and no wildcarding is done */
+int
+acl_exact_match(char *acl, char *principal)
+{
+ int idx;
+
+ return((idx = acl_load(acl)) >= 0
+ && check_hash(acl_cache[idx].acl, principal));
+}
+
+/* Returns nonzero if it can be determined that acl contains principal */
+/* Recognizes wildcards in acl of the form
+ name.*@realm, *.*@realm, and *.*@* */
+int
+acl_check(char *acl, char *principal)
+{
+ char buf[MAX_PRINCIPAL_SIZE];
+ char canon[MAX_PRINCIPAL_SIZE];
+ char *realm;
+
+ acl_canonicalize_principal(principal, canon);
+
+ /* Is it there? */
+ if(acl_exact_match(acl, canon)) return(1);
+
+ /* Try the wildcards */
+ realm = strchr(canon, REALM_SEP);
+ *strchr(canon, INST_SEP) = '\0'; /* Chuck the instance */
+
+ snprintf(buf, sizeof(buf), "%s.*%s", canon, realm);
+ if(acl_exact_match(acl, buf)) return(1);
+
+ snprintf(buf, sizeof(buf), "*.*%s", realm);
+ if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1);
+
+ return(0);
+}
+
+/* Adds principal to acl */
+/* Wildcards are interpreted literally */
+int
+acl_add(char *acl, char *principal)
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL) {
+ if(fputs(acl_cache[idx].acl->tbl[i], new) == EOF
+ || putc('\n', new) != '\n') {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ }
+ }
+ fputs(canon, new);
+ putc('\n', new);
+ return(acl_commit(acl, new));
+}
+
+/* Removes principal from acl */
+/* Wildcards are interpreted literally */
+int
+acl_delete(char *acl, char *principal)
+{
+ int idx;
+ int i;
+ FILE *new;
+ char canon[MAX_PRINCIPAL_SIZE];
+
+ acl_canonicalize_principal(principal, canon);
+
+ if((new = acl_lock_file(acl)) == NULL) return(-1);
+ if((!acl_exact_match(acl, canon))
+ || (idx = acl_load(acl)) < 0) {
+ acl_abort(acl, new);
+ return(-1);
+ }
+ /* It isn't there yet, copy the file and put it in */
+ for(i = 0; i < acl_cache[idx].acl->size; i++) {
+ if(acl_cache[idx].acl->tbl[i] != NULL
+ && strcmp(acl_cache[idx].acl->tbl[i], canon)) {
+ fputs(acl_cache[idx].acl->tbl[i], new);
+ putc('\n', new);
+ }
+ }
+ return(acl_commit(acl, new));
+}
+
+#endif /* KERBEROS */
diff --git a/usr.sbin/afs/src/lib/acl/acl_files.doc b/usr.sbin/afs/src/lib/acl/acl_files.doc
new file mode 100644
index 00000000000..78c448a6d69
--- /dev/null
+++ b/usr.sbin/afs/src/lib/acl/acl_files.doc
@@ -0,0 +1,107 @@
+PROTOTYPE ACL LIBRARY
+
+Introduction
+
+An access control list (ACL) is a list of principals, where each
+principal is is represented by a text string which cannot contain
+whitespace. The library allows application programs to refer to named
+access control lists to test membership and to atomically add and
+delete principals using a natural and intuitive interface. At
+present, the names of access control lists are required to be Unix
+filenames, and refer to human-readable Unix files; in the future, when
+a networked ACL server is implemented, the names may refer to a
+different namespace specific to the ACL service.
+
+
+Usage
+
+cc <files> -lacl -lkrb.
+
+
+
+Principal Names
+
+Principal names have the form
+
+<name>[.<instance>][@<realm>]
+
+e.g.
+
+asp
+asp.root
+asp@ATHENA.MIT.EDU
+asp.@ATHENA.MIT.EDU
+asp.root@ATHENA.MIT.EDU
+
+It is possible for principals to be underspecified. If instance is
+missing, it is assumed to be "". If realm is missing, it is assumed
+to be local_realm. The canonical form contains all of name, instance,
+and realm; the acl_add and acl_delete routines will always
+leave the file in that form. Note that the canonical form of
+asp@ATHENA.MIT.EDU is actually asp.@ATHENA.MIT.EDU.
+
+
+Routines
+
+acl_canonicalize_principal(principal, buf)
+char *principal;
+char *buf; /*RETVAL*/
+
+Store the canonical form of principal in buf. Buf must contain enough
+space to store a principal, given the limits on the sizes of name,
+instance, and realm specified in /usr/include/krb.h.
+
+acl_check(acl, principal)
+char *acl;
+char *principal;
+
+Returns nonzero if principal appears in acl. Returns 0 if principal
+does not appear in acl, or if an error occurs. Canonicalizes
+principal before checking, and allows the ACL to contain wildcards.
+
+acl_exact_match(acl, principal)
+char *acl;
+char *principal;
+
+Like acl_check, but does no canonicalization or wildcarding.
+
+acl_add(acl, principal)
+char *acl;
+char *principal;
+
+Atomically adds principal to acl. Returns 0 if successful, nonzero
+otherwise. It is considered a failure if principal is already in acl.
+This routine will canonicalize principal, but will treat wildcards
+literally.
+
+acl_delete(acl, principal)
+char *acl;
+char *principal;
+
+Atomically deletes principal from acl. Returns 0 if successful,
+nonzero otherwise. It is consider a failure if principal is not
+already in acl. This routine will canonicalize principal, but will
+treat wildcards literally.
+
+acl_initialize(acl, mode)
+char *acl;
+int mode;
+
+Initialize acl. If acl file does not exist, creates it with mode
+mode. If acl exists, removes all members. Returns 0 if successful,
+nonzero otherwise. WARNING: Mode argument is likely to change with
+the eventual introduction of an ACL service.
+
+
+Known problems
+
+In the presence of concurrency, there is a very small chance that
+acl_add or acl_delete could report success even though it would have
+had no effect. This is a necessary side effect of using lock files
+for concurrency control rather than flock(2), which is not supported
+by NFS.
+
+The current implementation caches ACLs in memory in a hash-table
+format for increased efficiency in checking membership; one effect of
+the caching scheme is that one file descriptor will be kept open for
+each ACL cached, up to a maximum of 8.
diff --git a/usr.sbin/afs/src/lib/bufdir/Makefile.in b/usr.sbin/afs/src/lib/bufdir/Makefile.in
new file mode 100644
index 00000000000..89382af0159
--- /dev/null
+++ b/usr.sbin/afs/src/lib/bufdir/Makefile.in
@@ -0,0 +1,95 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:55 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+INCLUDE=-I../../include -I$(srcdir) \
+ -I../../rxdef \
+ -I$(srcdir)/../roken \
+ @KRB4_INC_FLAGS@ \
+ -I$(srcdir)/../..
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)bufdir
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+PROGS =
+
+LIB_SOURCES = fbuf.c fdir.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = fbuf.o fdir.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB) $(PROGS)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDE) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+Makefile: ../../config.status Makefile.in
+ cd ../.. ; CONFIG_FILES=lib/bufdir/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../include/config.h
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/lib/bufdir/afs_dir.h b/usr.sbin/afs/src/lib/bufdir/afs_dir.h
new file mode 100644
index 00000000000..f10457a8dce
--- /dev/null
+++ b/usr.sbin/afs/src/lib/bufdir/afs_dir.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * The directory structure used by AFS.
+ */
+
+/* $Id: afs_dir.h,v 1.1 2000/09/11 14:40:55 art Exp $ */
+
+#ifndef _AFS_DIR_
+#define _AFS_DIR_
+
+#define AFSDIR_PAGESIZE 2048
+#define ADIRHASHSIZE 128
+#define ENTRIESPERPAGE 64
+
+/* number of pages in map */
+
+#define MAXPAGES 128
+
+/*
+ * We only save vnode and unique in the directory. Everything else is
+ * the same as in the parent directory.
+ */
+
+typedef struct {
+ u_int32_t Vnode;
+ u_int32_t Unique;
+} DirFid;
+
+typedef struct {
+ union {
+ struct {
+ u_int16_t pgcount;
+ u_int16_t tag; /* Should be 1234 in net-order */
+ u_int8_t freecount;
+ u_int8_t bitmap[ENTRIESPERPAGE / 8];
+ } s;
+ u_int8_t pad[32];
+ } u;
+} PageHeader;
+
+#define AFSDIRMAGIC 1234
+
+#define pg_tag u.s.tag
+#define pg_freecount u.s.freecount
+#define pg_pgcount u.s.pgcount
+#define pg_bitmap u.s.bitmap
+
+typedef struct {
+ u_int8_t map[MAXPAGES];
+ u_int16_t hash[ADIRHASHSIZE];
+} DirHeader;
+
+typedef struct {
+ u_int8_t flag;
+ u_int8_t length;
+ u_int16_t next;
+ DirFid fid;
+ char name[16]; /* If name overflows into fill, then we */
+ char fill[4]; /* should use next entry too. */
+} DirEntry;
+
+typedef struct {
+ PageHeader header;
+ DirHeader dheader;
+ DirEntry entry[1];
+} DirPage0;
+
+typedef struct {
+ PageHeader header;
+ DirEntry entry[1];
+} DirPage1;
+
+#endif /* _AFS_DIR_ */
diff --git a/usr.sbin/afs/src/lib/bufdir/fbuf.c b/usr.sbin/afs/src/lib/bufdir/fbuf.c
new file mode 100644
index 00000000000..597df986bfc
--- /dev/null
+++ b/usr.sbin/afs/src/lib/bufdir/fbuf.c
@@ -0,0 +1,485 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+
+RCSID("$Id: fbuf.c,v 1.1 2000/09/11 14:40:55 art Exp $") ;
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <unistd.h>
+
+#include <fs_errors.h>
+
+#include <roken.h>
+
+#include <fbuf.h>
+
+#ifdef HAVE_MMAP
+
+#if !defined(MAP_FAILED)
+#define MAP_FAILED ((void *)(-1))
+#endif
+
+/*
+ * Map fbuf_flags in `flags' to mmap dito
+ */
+
+static int
+mmap_flags (fbuf_flags flags)
+{
+ int ret = 0;
+
+ assert ((flags & (FBUF_PRIVATE | FBUF_SHARED)) == FBUF_PRIVATE
+ || (flags & (FBUF_PRIVATE | FBUF_SHARED)) == FBUF_SHARED);
+
+ if (flags & FBUF_PRIVATE)
+ ret = MAP_PRIVATE;
+ else if (flags & FBUF_SHARED)
+ ret = MAP_SHARED;
+ return ret;
+}
+
+/*
+ * Map fbuf_flags in `flags' to mmap prot
+ */
+
+static int
+mmap_prot (fbuf_flags flags)
+{
+ int ret = 0;
+
+ if (flags & FBUF_READ)
+ ret |= PROT_READ;
+ if (flags & FBUF_WRITE)
+ ret |= PROT_WRITE;
+ return ret;
+}
+
+/*
+ * Create a fbuf with (fd, len, flags).
+ * Returns 0 or error.
+ */
+
+static int
+mmap_create (fbuf *f, int fd, size_t len, fbuf_flags flags)
+{
+ void *buf;
+
+ if (len != 0) {
+ buf = mmap (0, len, mmap_prot(flags), mmap_flags(flags), fd, 0);
+ if (buf == (void *) MAP_FAILED)
+ return errno;
+ } else
+ buf = NULL;
+
+ f->buf = buf;
+ f->fd = fd;
+ f->len = len;
+ f->flags = flags;
+ return 0;
+}
+
+/*
+ * Change the size of the underlying file and the fbuf to `new_len'
+ * bytes.
+ * Returns 0 or error.
+ */
+
+static int
+mmap_truncate (fbuf *f, size_t new_len)
+{
+ int ret;
+
+ if (f->buf != NULL) {
+ ret = munmap (f->buf, f->len);
+ if (ret < 0)
+ return errno;
+ }
+ ret = ftruncate (f->fd, new_len);
+ if (ret < 0)
+ return errno;
+ return mmap_create (f, f->fd, new_len, f->flags);
+}
+
+/*
+ * End using `f'.
+ * Returns 0 or error.
+ */
+
+static int
+mmap_end (fbuf *f)
+{
+ int ret;
+
+ ret = munmap (f->buf, f->len);
+ if (ret < 0)
+ ret = errno;
+ return ret;
+}
+
+/*
+ * Copy `len' bytes from the rx call `call' to the file `fd'.
+ * Returns 0 or error
+ */
+
+static int
+mmap_copyrx2fd (struct rx_call *call, int fd, off_t off, size_t len)
+{
+ void *buf;
+ int r_len;
+ int ret = 0;
+
+ if (len == 0)
+ return 0;
+
+ buf = mmap (0, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, off);
+ if (buf == (void *) MAP_FAILED)
+ return errno;
+ r_len = rx_Read (call, buf, len);
+ if (r_len != len)
+ ret = conv_to_arla_errno(rx_Error(call));
+ munmap (buf, len);
+ return ret;
+}
+
+/*
+ * Copy `len' bytes from `fd' to `call'.
+ * Returns 0 or error.
+ */
+
+static int
+mmap_copyfd2rx (int fd, struct rx_call *call, off_t off, size_t len)
+{
+ void *buf;
+ int r_write;
+ int ret = 0;
+
+ if (len == 0)
+ return 0;
+
+ buf = mmap (0, len, PROT_READ, MAP_PRIVATE, fd, off);
+ if (buf == (void *) MAP_FAILED)
+ return errno;
+ r_write = rx_Write (call, buf, len);
+ if (r_write != len)
+ ret = conv_to_arla_errno(rx_Error(call));
+ munmap (buf, len);
+ return ret;
+}
+
+#else /* !HAVE_MMAP */
+
+/*
+ * Create a fbuf with (fd, len, flags).
+ * Returns 0 or error.
+ */
+
+static int
+malloc_create (fbuf *f, int fd, size_t len, fbuf_flags flags)
+{
+ void *buf;
+
+ buf = malloc (len);
+ if (buf == NULL)
+ return ENOMEM;
+ if (lseek(fd, 0, SEEK_SET) == -1 ||
+ read (fd, buf, len) != len) {
+ free(buf);
+ return errno;
+ }
+ f->buf = buf;
+ f->fd = fd;
+ f->len = len;
+ f->flags = flags;
+ return 0;
+}
+
+/*
+ * Write out the data of `f' to the file.
+ * Returns 0 or error.
+ */
+
+static int
+malloc_flush (fbuf *f)
+{
+ if ((f->flags & FBUF_WRITE) && (f->flags & FBUF_SHARED)) {
+ lseek (f->fd, 0, SEEK_SET);
+ if (write (f->fd, f->buf, f->len) != f->len)
+ return errno;
+ }
+ return 0;
+}
+
+/*
+ * End using `f'.
+ * Returns 0 or error.
+ */
+
+static int
+malloc_end (fbuf *f)
+{
+ int ret;
+
+ ret = malloc_flush (f);
+ free (f->buf);
+ return ret;
+}
+
+/*
+ * Change the size of the underlying file and the fbuf to `new_len'
+ * bytes.
+ * Returns 0 or error.
+ */
+
+static int
+malloc_truncate (fbuf *f, size_t new_len)
+{
+ void *buf;
+ int ret;
+
+ ret = malloc_flush (f);
+ if (ret)
+ goto fail;
+
+ ret = ftruncate (f->fd, new_len);
+ if (ret < 0) {
+ ret = errno;
+ goto fail;
+ }
+
+ buf = realloc (f->buf, new_len);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ f->buf = buf;
+ f->len = new_len;
+ return 0;
+
+fail:
+ free (f->buf);
+ return ret;
+}
+
+/*
+ * Copy `len' bytes from the rx call `call' to the file `fd'.
+ * Returns 0 or error
+ */
+
+static int
+malloc_copyrx2fd (struct rx_call *call, int fd, off_t off, size_t len)
+{
+ void *buf;
+ struct stat statbuf;
+ u_long bufsize;
+ u_long nread;
+ int ret = 0;
+
+ if (len == 0)
+ return 0;
+
+ if (lseek (fd, off, SEEK_SET) == -1)
+ return errno;
+
+ if (fstat (fd, &statbuf)) {
+/* arla_warn (ADEBFBUF, errno, "fstat"); */
+ bufsize = 1024;
+ } else
+ bufsize = statbuf.st_blksize;
+
+ buf = malloc (bufsize);
+ if (buf == NULL)
+ return ENOMEM;
+
+ while ( len && (nread = rx_Read (call, buf, min(bufsize,
+ len))) > 0) {
+ if (write (fd, buf, nread) != nread) {
+ ret = errno;
+ break;
+ }
+ len -= nread;
+ }
+ free (buf);
+ return ret;
+}
+
+/*
+ * Copy `len' bytes from at offset `off' in `fd' to `call'.
+ * Returns 0 or error.
+ */
+
+static int
+malloc_copyfd2rx (int fd, struct rx_call *call, off_t off, size_t len)
+{
+ void *buf;
+ struct stat statbuf;
+ u_long bufsize;
+ u_long nread;
+ int ret = 0;
+
+ if (len == 0)
+ return 0;
+
+ if (lseek (fd, off, SEEK_SET) < 0)
+ return errno;
+
+ if (fstat (fd, &statbuf)) {
+/* arla_warn (ADEBFBUF, errno, "fstat"); */
+ bufsize = 1024;
+ } else
+ bufsize = statbuf.st_blksize;
+
+ buf = malloc (bufsize);
+ if (buf == NULL)
+ return ENOMEM;
+
+ while (len
+ && (nread = read (fd, buf, min(bufsize, len))) > 0) {
+ if (rx_Write (call, buf, nread) != nread) {
+ ret = errno;
+ break;
+ }
+ len -= nread;
+ }
+ free (buf);
+ return ret;
+}
+#endif /* !HAVE_MMAP */
+
+/*
+ * Accessor functions.
+ */
+
+size_t
+fbuf_len (fbuf *f)
+{
+ return f->len;
+}
+
+/*
+ *
+ */
+
+void *
+fbuf_buf (fbuf *f)
+{
+ return f->buf;
+}
+
+/*
+ * Return a pointer to a copy of this file contents. If we have mmap,
+ * we use that, otherwise we have to allocate some memory and read it.
+ */
+
+int
+fbuf_create (fbuf *f, int fd, size_t len, fbuf_flags flags)
+{
+#ifdef HAVE_MMAP
+ return mmap_create (f, fd, len, flags);
+#else
+ return malloc_create (f, fd, len, flags);
+#endif
+}
+
+/*
+ * Undo everything we did in fbuf_create.
+ */
+
+int
+fbuf_end (fbuf *f)
+{
+#ifdef HAVE_MMAP
+ return mmap_end (f);
+#else
+ return malloc_end (f);
+#endif
+}
+
+/*
+ * Make the file (and the buffer) be `new_len' bytes.
+ */
+
+int
+fbuf_truncate (fbuf *f, size_t new_len)
+{
+#ifdef HAVE_MMAP
+ return mmap_truncate (f, new_len);
+#else
+ return malloc_truncate (f, new_len);
+#endif
+}
+
+/*
+ * Copy from a RX_call to a fd.
+ * The area between offset and len + offset should be present in the file.
+ */
+
+int
+copyrx2fd (struct rx_call *call, int fd, off_t off, size_t len)
+{
+#ifdef HAVE_MMAP
+ return mmap_copyrx2fd (call, fd, off, len);
+#else
+ return malloc_copyrx2fd (call, fd, off, len);
+#endif
+}
+
+/*
+ * Copy from a file descriptor to a RX call.
+ *
+ * Returns: error number if failed
+ */
+
+int
+copyfd2rx (int fd, struct rx_call *call, off_t off, size_t len)
+{
+#ifdef HAVE_MMAP
+ return mmap_copyfd2rx (fd, call, off, len);
+#else
+ return malloc_copyfd2rx (fd, call, off, len);
+#endif
+}
diff --git a/usr.sbin/afs/src/lib/bufdir/fbuf.h b/usr.sbin/afs/src/lib/bufdir/fbuf.h
new file mode 100644
index 00000000000..88e464f9160
--- /dev/null
+++ b/usr.sbin/afs/src/lib/bufdir/fbuf.h
@@ -0,0 +1,71 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: fbuf.h,v 1.1 2000/09/11 14:40:55 art Exp $ */
+
+#ifndef _FBUF_H_
+#define _FBUF_H_
+
+#include <rx/rx.h>
+
+typedef enum {
+ FBUF_READ = 0x01,
+ FBUF_WRITE = 0x02,
+ FBUF_PRIVATE = 0x04,
+ FBUF_SHARED = 0x08
+} fbuf_flags;
+
+struct fbuf {
+ void *buf;
+ int fd;
+ size_t len;
+ fbuf_flags flags;
+};
+
+typedef struct fbuf fbuf;
+
+int fbuf_create (fbuf *fbuf, int fd, size_t len, fbuf_flags flags);
+int fbuf_truncate (fbuf *fbuf, size_t new_len);
+int fbuf_end (fbuf *fbuf);
+size_t fbuf_len (fbuf *f);
+void *fbuf_buf (fbuf *f);
+
+int copyrx2fd (struct rx_call *call, int fd, off_t off, size_t len);
+int copyfd2rx (int fd, struct rx_call *call, off_t off, size_t len);
+
+#endif /* _FBUF_H_ */
diff --git a/usr.sbin/afs/src/lib/bufdir/fdir.c b/usr.sbin/afs/src/lib/bufdir/fdir.c
new file mode 100644
index 00000000000..86011d8b215
--- /dev/null
+++ b/usr.sbin/afs/src/lib/bufdir/fdir.c
@@ -0,0 +1,624 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * Routines for reading an AFS directory
+ */
+
+#include <config.h>
+
+RCSID("$Id: fdir.c,v 1.1 2000/09/11 14:40:55 art Exp $") ;
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+#include <rx/rx.h>
+#include <afs_dir.h>
+#include <fdir.h>
+
+/*
+ * Hash the filename of one entry.
+ */
+
+static unsigned
+hashentry (const char *sentry)
+{
+ int s = 0, h;
+ const unsigned char *entry = (const unsigned char *)sentry;
+
+ while (*entry)
+ s = s * 173 + *entry++;
+ h = s & (ADIRHASHSIZE - 1);
+ if (h == 0)
+ return h;
+ else if( s < 0 )
+ h = ADIRHASHSIZE - h;
+ return h;
+}
+
+/*
+ * Return the number of additional DirEntries used by an entry with
+ * the filename `name`.
+ */
+
+static unsigned
+additional_entries (const char *filename)
+{
+ static DirEntry dummy;
+
+ return (strlen(filename) - sizeof(dummy.name) + 1
+ + sizeof(DirEntry) - 1)
+ / sizeof(DirEntry);
+}
+
+/*
+ * Return a pointer to page number `pageno'.
+ */
+
+static DirPage1 *
+getpage (DirPage0 *page0, unsigned pageno)
+{
+ return (DirPage1 *)((char *)page0 + AFSDIR_PAGESIZE * pageno);
+}
+
+/*
+ * Return the entry `num' in the directory `page0'.
+ * The directory must be continuous in memory after page0.
+ */
+
+static DirEntry *
+getentry (DirPage0 *page0,
+ unsigned short num)
+{
+ DirPage1 *page = getpage (page0, num / ENTRIESPERPAGE);
+
+ assert (page->header.pg_tag == htons(AFSDIRMAGIC));
+ return &page->entry[num % ENTRIESPERPAGE];
+}
+
+/*
+ * Return a pointer to the entry with name `name' in the directory `page0'.
+ */
+
+static DirEntry *
+find_entry(DirPage0 *page0, const char *name)
+{
+ DirEntry *entry;
+ unsigned i;
+
+ for (i = ntohs(page0->dheader.hash[hashentry (name)]);
+ i != 0;
+ i = ntohs(entry->next)) {
+ entry = getentry (page0, i - 1);
+
+ if (strcmp (entry->name, name) == 0)
+ return entry;
+ }
+ return NULL;
+}
+
+/*
+ * Return the fid for the entry with `name' in `page0'. `fid' is set
+ * to the fid of that file. `dir' should be the fid of the directory.
+ * Return zero if succesful, and -1 otherwise.
+ */
+
+static int
+find_by_name (DirPage0 *page0,
+ const char *name,
+ VenusFid *fid,
+ const VenusFid *dir)
+{
+ const DirEntry *entry = find_entry (page0, name);
+
+ if (entry == NULL)
+ return -1;
+ fid->Cell = dir->Cell;
+ fid->fid.Volume = dir->fid.Volume;
+ fid->fid.Vnode = ntohl (entry->fid.Vnode);
+ fid->fid.Unique = ntohl (entry->fid.Unique);
+ return 0;
+}
+
+/*
+ * Change the fid for `name' to `fid'. Return 0 or -1.
+ */
+
+static int
+update_fid_by_name (DirPage0 *page0,
+ const char *name,
+ const VenusFid *fid)
+{
+ DirEntry *entry = find_entry (page0, name);
+
+ if (entry == NULL)
+ return -1;
+
+ entry->fid.Vnode = htonl (fid->fid.Vnode);
+ entry->fid.Unique = htonl (fid->fid.Unique);
+ return 0;
+}
+
+/*
+ * Return true if slot `off' on `page' is being used.
+ */
+
+static int
+used_slot (DirPage1 *page, int off)
+{
+ return page->header.pg_bitmap[off / 8] & (1 << (off % 8));
+}
+
+/*
+ * Mark slot `off' on `page' as being used.
+ */
+
+static void
+set_used (DirPage1 *page, int off)
+{
+ page->header.pg_bitmap[off / 8] |= 1 << (off % 8);
+}
+
+/*
+ * Mark slot `off' on `page' as not being used.
+ */
+
+static void
+set_unused (DirPage1 *page, int off)
+{
+ page->header.pg_bitmap[off / 8] &= ~(1 << (off % 8));
+}
+
+/*
+ * Is this page `pageno' empty?
+ */
+
+static int
+is_page_empty (DirPage0 *page0, unsigned pageno)
+{
+ DirPage1 *page;
+ int i;
+
+ if (pageno < MAXPAGES)
+ return page0->dheader.map[pageno] == ENTRIESPERPAGE - 1;
+ page = getpage (page0, pageno);
+ if (page->header.pg_bitmap[0] != 1)
+ return 0;
+ for (i = 1; i < sizeof(page->header.pg_bitmap); ++i)
+ if (page->header.pg_bitmap[i] != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Add a new page to the directory in `the_fbuf', returning a pointer
+ * to the new page in `ret_page'.
+ * Return 0 iff succesful.
+ */
+
+static int
+create_new_page (DirPage1 **ret_page,
+ fbuf *the_fbuf)
+{
+ int ret;
+ DirPage1 *page1;
+ size_t len = fbuf_len(the_fbuf);
+
+ ret = fbuf_truncate (the_fbuf, len + AFSDIR_PAGESIZE);
+ if (ret)
+ return ret;
+
+ page1 = (DirPage1 *)((char *)fbuf_buf(the_fbuf) + len);
+ page1->header.pg_pgcount = htons(0);
+ page1->header.pg_tag = htons(AFSDIRMAGIC);
+ page1->header.pg_freecount = ENTRIESPERPAGE - 1;
+ memset (page1->header.pg_bitmap, 0, sizeof(page1->header.pg_bitmap));
+ set_used (page1, 0);
+ *ret_page = page1;
+
+ return 0;
+}
+
+/*
+ * Create a new entry with name `filename', fid `fid', and next
+ * pointer `next' in the page `page' with page number `pageno'.
+ * Return the index in the page or -1 if unsuccesful.
+ */
+
+static int
+add_to_page (DirPage0 *page0,
+ DirPage1 *page,
+ unsigned pageno,
+ const char *filename,
+ AFSFid fid,
+ unsigned next)
+{
+ int i, j;
+ unsigned n;
+
+ n = 1 + additional_entries (filename);
+
+ if (pageno < MAXPAGES && page0->dheader.map[pageno] < n)
+ return -1;
+
+ for (i = 0; i < ENTRIESPERPAGE - n;) {
+ for (j = 0; j < n && !used_slot (page, i + j + 1); ++j)
+ ;
+ if (j == n) {
+ int k;
+
+ for (k = i + 1; k < i + j + 1; ++k)
+ page->header.pg_bitmap[k / 8] |= (1 << (k % 8));
+
+ page->entry[i].flag = 1;
+ page->entry[i].length = 0;
+ page->entry[i].next = next;
+ page->entry[i].fid.Vnode = htonl(fid.Vnode);
+ page->entry[i].fid.Unique = htonl(fid.Unique);
+ strcpy (page->entry[i].name, filename);
+ memset(page->entry[i + j - 1].fill, 0, 4);
+ if (pageno < MAXPAGES)
+ page0->dheader.map[pageno] -= n;
+ return i;
+ }
+ i += j + 1;
+ }
+ return -1;
+}
+
+/*
+ * Remove the entry `off' from the page `page' (page number `pageno').
+ */
+
+static int
+remove_from_page (DirPage0 *page0,
+ DirPage1 *page,
+ unsigned pageno,
+ unsigned off)
+{
+ DirEntry *entry = &page->entry[off];
+ unsigned n, i;
+
+ n = 1 + additional_entries (entry->name);
+
+ if (pageno < MAXPAGES)
+ page0->dheader.map[pageno] += n;
+
+ entry->next = 0;
+ entry->fid.Vnode = 0;
+ entry->fid.Unique = 0;
+
+ for (i = off + 1; i < off + n + 1; ++i)
+ set_unused (page, i);
+ return 0;
+}
+
+/*
+ * Lookup `name' in the AFS directory identified by `dir' and return
+ * the Fid in `file'. Return value is 0 or error code.
+ */
+
+int
+fdir_lookup (fbuf *the_fbuf, const VenusFid *dir,
+ const char *name, VenusFid *file)
+{
+ DirPage0 *page0;
+ unsigned ind;
+
+ page0 = (DirPage0 *)fbuf_buf(the_fbuf);
+ assert (page0);
+ ind = find_by_name (page0, name, file, dir);
+
+ if (ind == 0)
+ return 0;
+ else
+ return ENOENT;
+}
+
+/*
+ * Lookup `name' in the AFS directory identified by `dir' and change the
+ * fid to `fid'.
+ */
+
+int
+fdir_changefid (fbuf *the_fbuf,
+ const char *name,
+ const VenusFid *file)
+{
+ DirPage0 *page0;
+ int ret;
+
+ page0 = (DirPage0 *)fbuf_buf(the_fbuf);
+ assert (page0);
+ ret = update_fid_by_name (page0, name, file);
+
+ if (ret == 0)
+ return 0;
+ else
+ return ENOENT;
+}
+
+/*
+ * Return TRUE if dir is empty.
+ */
+
+int
+fdir_emptyp (fbuf *dir)
+{
+ DirPage0 *page0;
+ unsigned npages;
+
+ page0 = (DirPage0 *)fbuf_buf(dir);
+ assert (page0);
+
+ npages = ntohs(page0->header.pg_pgcount);
+
+ return (npages == 1) && (page0->dheader.map[0] == 49);
+}
+
+/*
+ * Read all entries in the AFS directory identified by `dir' and call
+ * `func' on each entry with the fid, the name, and `arg'.
+ */
+
+int
+fdir_readdir (fbuf *the_fbuf,
+ fdir_readdir_func func,
+ void *arg,
+ const VenusFid *dir)
+{
+ DirPage0 *page0;
+ unsigned i, j;
+ VenusFid fid;
+ unsigned len = fbuf_len(the_fbuf);
+ unsigned npages;
+
+ page0 = (DirPage0 *)fbuf_buf(the_fbuf);
+
+ assert (page0);
+
+ npages = ntohs(page0->header.pg_pgcount);
+
+ if (npages < len / AFSDIR_PAGESIZE)
+ npages = len / AFSDIR_PAGESIZE;
+
+ for (i = 0; i < npages; ++i) {
+ DirPage1 *page = getpage (page0, i);
+ unsigned first_slot;
+
+ if (i == 0)
+ first_slot = 12;
+ else
+ first_slot = 0;
+
+ for (j = first_slot; j < ENTRIESPERPAGE - 1; ++j) {
+ if (used_slot (page, j + 1)) {
+ DirEntry *entry = &page->entry[j];
+
+ assert (entry->flag);
+
+ fid.Cell = dir->Cell;
+ fid.fid.Volume = dir->fid.Volume;
+ fid.fid.Vnode = ntohl (entry->fid.Vnode);
+ fid.fid.Unique = ntohl (entry->fid.Unique);
+
+ (*func)(&fid, entry->name, arg);
+
+ j += additional_entries (entry->name);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Create a new directory with only . and ..
+ */
+
+int
+fdir_mkdir (fbuf *the_fbuf,
+ AFSFid dot,
+ AFSFid dot_dot)
+{
+ DirPage0 *page0;
+ DirPage1 *page;
+ int ind;
+ int i;
+ int tmp;
+ int ret;
+
+ ret = create_new_page (&page, the_fbuf);
+ if (ret)
+ return ret;
+
+ page0 = (DirPage0 *)fbuf_buf(the_fbuf);
+ memset (&page0->dheader, 0, sizeof(page0->dheader));
+ tmp = ENTRIESPERPAGE
+ - (sizeof(PageHeader) + sizeof(DirHeader)) / sizeof(DirEntry);
+ page0->header.pg_freecount = tmp;
+ page0->dheader.map[0] = tmp;
+ page0->header.pg_pgcount = htons(1);
+
+ for (i = 0; i < 13; ++i)
+ set_used (page, i);
+
+ assert (page0->dheader.hash[hashentry(".")] == 0);
+
+ ind = add_to_page (page0, page, 0, ".", dot, 0);
+
+ assert (ind >= 0);
+
+ page0->dheader.hash[hashentry(".")] = htons(ind + 1);
+
+ assert (page0->dheader.hash[hashentry("..")] == 0);
+
+ ind = add_to_page (page0, page, 0, "..", dot_dot, 0);
+
+ assert (ind >= 0);
+
+ page0->dheader.hash[hashentry("..")] = htons(ind + 1);
+
+ return 0;
+}
+
+/*
+ * Create a new entry with name `filename' and contents `fid' in `dir'.
+ */
+
+int
+fdir_creat (fbuf *dir,
+ const char *name,
+ AFSFid fid)
+{
+ int ret;
+ int i;
+ unsigned npages;
+ DirPage0 *page0;
+ DirPage1 *page;
+ int ind = 0;
+ unsigned hash_value, next;
+
+ assert (dir->len != 0);
+
+ page0 = (DirPage0 *)fbuf_buf(dir);
+ assert (page0);
+ npages = ntohs(page0->header.pg_pgcount);
+
+ assert (npages == dir->len / AFSDIR_PAGESIZE);
+
+ if (find_entry (page0, name))
+ return EEXIST;
+
+ hash_value = hashentry (name);
+ next = page0->dheader.hash[hash_value];
+
+ for (i = 0; i < npages; ++i) {
+ page = getpage (page0, i);
+ ind = add_to_page (page0, page, i, name, fid, next);
+ if (ind >= 0)
+ break;
+ }
+ if (i == npages) {
+ ret = create_new_page (&page, dir);
+ if (ret)
+ return ret;
+ page0 = (DirPage0 *)fbuf_buf(dir);
+ page0->header.pg_pgcount = htons(npages + 1);
+ if (i < MAXPAGES)
+ page0->dheader.map[i] = ENTRIESPERPAGE - 1;
+ ind = add_to_page (page0, page, i, name, fid, next);
+ assert (ind >= 0);
+ }
+ ind += i * ENTRIESPERPAGE;
+
+ page0->dheader.hash[hash_value] = htons(ind + 1);
+
+ return 0;
+}
+
+/*
+ * Remove the entry named `name' in dir.
+ */
+
+int
+fdir_remove (fbuf *dir,
+ const char *name,
+ AFSFid *fid)
+{
+ int i;
+ unsigned len = dir->len;
+ DirPage0 *page0;
+ DirPage1 *page;
+ unsigned hash_value;
+ DirEntry *entry = NULL;
+ DirEntry *prev_entry;
+ unsigned pageno;
+ int found;
+ unsigned npages;
+
+
+ page0 = (DirPage0 *)fbuf_buf(dir);
+ npages = ntohs(page0->header.pg_pgcount);
+ hash_value = hashentry (name);
+ i = ntohs(page0->dheader.hash[hash_value]);
+ found = i == 0;
+ prev_entry = NULL;
+ while (!found) {
+ entry = getentry (page0, i - 1);
+
+ if (strcmp (entry->name, name) == 0) {
+ found = TRUE;
+ } else {
+ i = ntohs(entry->next);
+ if (i == 0)
+ found = TRUE;
+ prev_entry = entry;
+ }
+ }
+ if (i == 0)
+ return ENOENT;
+ else {
+ if (fid) {
+ fid->Vnode = ntohl(entry->fid.Vnode);
+ fid->Unique = ntohl(entry->fid.Unique);
+ }
+
+ if (prev_entry == NULL)
+ page0->dheader.hash[hash_value] = entry->next;
+ else
+ prev_entry->next = entry->next;
+
+ pageno = (i - 1) / ENTRIESPERPAGE;
+ page = getpage (page0, pageno);
+ remove_from_page (page0, page, pageno, (i - 1) % ENTRIESPERPAGE);
+ if (pageno == npages - 1
+ && is_page_empty (page0, pageno)) {
+ do {
+ len -= AFSDIR_PAGESIZE;
+ --pageno;
+ --npages;
+ } while(is_page_empty(page0, pageno));
+ page0->header.pg_pgcount = htons(npages);
+ fbuf_truncate (dir, len);
+ }
+ return 0;
+ }
+}
diff --git a/usr.sbin/afs/src/lib/bufdir/fdir.h b/usr.sbin/afs/src/lib/bufdir/fdir.h
new file mode 100644
index 00000000000..697c156dba1
--- /dev/null
+++ b/usr.sbin/afs/src/lib/bufdir/fdir.h
@@ -0,0 +1,89 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * Interface to directory handling routines
+ */
+
+/* $Id: fdir.h,v 1.1 2000/09/11 14:40:55 art Exp $ */
+
+#ifndef _FDIR_H_
+#define _FDIR_H_
+
+#include <fs.h>
+#include <fbuf.h>
+
+int
+fdir_lookup (fbuf *the_fbuf,
+ const VenusFid *dir,
+ const char *name,
+ VenusFid *file);
+
+
+int
+fdir_changefid (fbuf *the_fbuf,
+ const char *name,
+ const VenusFid *file);
+
+int
+fdir_emptyp (fbuf *dir);
+
+typedef void (*fdir_readdir_func)(VenusFid *, const char *, void *);
+
+int
+fdir_readdir (fbuf *the_fbuf,
+ fdir_readdir_func func,
+ void *arg,
+ const VenusFid *dir);
+
+int
+fdir_creat (fbuf *dir,
+ const char *filename,
+ AFSFid fid);
+
+int
+fdir_remove (fbuf *dir,
+ const char *name,
+ AFSFid *fid);
+
+int
+fdir_mkdir (fbuf *dir,
+ AFSFid dot,
+ AFSFid dot_dot);
+
+#endif /* _FDIR_H_ */
diff --git a/usr.sbin/afs/src/lib/cmd/Makefile.in b/usr.sbin/afs/src/lib/cmd/Makefile.in
new file mode 100644
index 00000000000..0ba79f812b8
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/Makefile.in
@@ -0,0 +1,122 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:55 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+YACC = @YACC@
+LEX = @LEX@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+bindir = @bindir@
+mandir = @mandir@
+includedir = @includedir@
+
+LIBPREFIX = lib
+LIBEXT = a
+LIBNAME = $(LIBPREFIX)cmd
+cmd_LIB = $(LIBNAME).$(LIBEXT)
+
+testc_BIN = testc
+testc_1_MAN = testc.1
+
+PROGS = $(testc_BIN)
+install_MANS = cmd.3
+MANS = $(testc_1_MAN) $(install_MANS)
+
+LIB_SOURCES = cmd.c
+testc_SOURCES = testc.c
+
+SOURCES = $(LIB_SOURCES) $(BIN_SOURCES)
+
+LIB_OBJECTS = cmd.o
+testc_OBJECTS = testc.o
+
+OBJECTS = $(LIB_OBJECTS) $(testc_OBJECTS)
+
+all: $(cmd_LIB) $(PROGS) $(MANS)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(DEFS) -I../../include -I. -I$(srcdir) $(KRB4_INC_FLAGS) $(CFLAGS) $(CPPFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(includedir)/afs
+ $(INSTALL_DATA) $(srcdir)/cmd.h $(DESTDIR)$(includedir)/afs/cmd.h
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL) -m 555 $(cmd_LIB) $(DESTDIR)$(libdir)/$(cmd_LIB)
+ for man in $(install_MANS) ; do \
+ for a in 1 2 3 4 5 6 7 8 9 0 ; do \
+ if test `basename $$man .$$a`.$$a = $$man; then \
+ if test -f $$man ; then \
+ man_inst=$$man ; \
+ else \
+ man_inst=$(srcdir)/$$man; \
+ fi ;\
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$a; \
+ $(INSTALL_DATA) $$man_inst $(mandir)/man$$a/$$man; \
+ fi ; \
+ done ; \
+ done
+
+uninstall:
+ rm -f $(DESTDIR)$(includedir)/afs/cmd.h
+ rm -f $(DESTDIR)$(libdir)/$(cmd_LIB)
+ for man in $(install_MANS) ; do \
+ for a in 1 2 3 4 5 6 7 8 9 0 ; do \
+ if test `basename $$man .$$a`.$$a = $$man; then \
+ rm -f $(DESTDIR)$(mandir)/man$$a/$$man ; \
+ fi ; \
+ done ; \
+ done
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(cmd_LIB) $(PROGS) $(testc_1_MAN) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+testc: $(testc_OBJECTS) $(cmd_LIB)
+ $(CC) $(CFLAGS) -o $@ $(testc_OBJECTS) -L. -lcmd -L../roken -lroken
+
+testc.1: testc
+ srcdir=$(srcdir) CMD_MANDOC=foo ./testc help > testc.1
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=lib/cmd/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+$(OBJECTS): ../../include/config.h
+
+.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/lib/cmd/cmd.3 b/usr.sbin/afs/src/lib/cmd/cmd.3
new file mode 100644
index 00000000000..5de3ba984ae
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/cmd.3
@@ -0,0 +1,271 @@
+.\" $Id: cmd.3,v 1.1 2000/09/11 14:40:55 art Exp $
+.\" Things to fix:
+.\" * use better macros for arguments (like .Pa for files)
+.\"
+.Dd June 1, 2000
+.Dt fs 3
+.Os "Arla, KTH"
+.Sh NAME
+.Nm cmd
+.Nd command line parser and mdoc manual page generator
+.Sh SYNOPSIS
+.Fo "struct cmd_syndesc * cmd_CreateSyntax"
+.Fa "const char *name"
+.Fa "cmd_proc main"
+.Fa "void *rock"
+.Fa "const char *help_str"
+.Fc
+.Fo "int cmd_setBeforeProc"
+.Fa "int (*proc) (void *rock)"
+.Fa "void *rock"
+.Fc
+.Fo "int cmd_setAfterProc"
+.Fa "int (*proc) (void *rock)"
+.Fa "void *rock"
+.Fc
+.Fo "void cmd_AddParm"
+.Fa "struct cmd_syndesc *ts"
+.Fa "const char *cmd"
+.Fa "cmd_parmdesc_type type"
+.Fa "cmd_parmdesc_flags flags"
+.Fa "const char *help_str"
+.Fc
+.Fo "int cmd_CreateAlias"
+.Fa "struct cmd_syndesc *ts"
+.Fa "const char *name"
+.Fc
+.Fo "int cmd_Seek"
+.Fa "struct cmd_syndesc *ts"
+.Fa "int pos"
+.Fc
+.Fo "int cmd_ParseLine"
+.Fa "const char *line"
+.Fa "char **argv"
+.Fa "int *n"
+.Fa "int maxn"
+.Fc
+.Fo "void cmd_FreeArgv"
+.Fa "char **argv"
+.Fc
+.Fo "int cmd_Dispatch"
+.Fa "int argc"
+.Fa "char **argv"
+.Fc
+.Sh DESCRIPTION
+.Nm
+is a suite of functions that parses file for the Arla programs in a
+AFS compatible way.
+.Pp
+There is some problems with the cmd interface,
+both that you have to do a lof of post-parsing yourself (like fetching
+converting to numbers) and the interface isn't reenterant.
+.Pp
+You create a new command by calling
+.Fn cmd_CreateSyntax .
+An alias to this command can be added with
+.Fn cmd_CreateAlias .
+Then parameters can be added to the command with
+.Fn cmd_AddParm .
+Finally
+.Fn cmd_Dispatch
+is called and the argument are parsed.
+.Pp
+The
+.Fn cmd_CreateSyntax
+function adds a new command
+.Fa name
+to the syntax. If the command is found when parsing, then function
+.Fa main
+is called with the argument
+.Fa rock.
+The helpstring
+.Fn help_str
+is shown whenever help is needed for this command.
+.Pp
+The function
+.Fn cmd_setBeforeProc
+sets a function to be called when parsing is complete and the
+.Fa main
+is about to be called for current command.
+.Fa Rock
+is passed as an argument to
+.Fa proc
+whenever called.
+.Pp
+The function
+.Fn cmd_setAfterProc
+sets a function to be called after
+the
+.Fa main
+for the current command has been called.
+.Fa Rock
+is passed as an argument to
+.Fa proc
+whenever called.
+.Pp
+The function
+.Fn cmd_AddParm
+adds a new parameter
+.Fa cmd
+to the command
+.Fa ts
+of
+.Fa type
+and with
+.Fa flags .
+If the user want help about the command,
+.Fa help_str
+is incorporated in the help output.
+.Pp
+The function
+.Fn cmd_CreateAlias
+creates a alias
+.Fa name
+for the command
+.Fa ts .
+.Pp
+The function
+.Fn cmd_Seek
+changes the argument currently being set by
+.Fn cmd_AddParm
+This makes it possible to limit a
+.Fa CMD_LIST|CMD_EXPANDS
+parmeter, with respect to how many argument that it will parse.
+.Pp
+The function
+.Fn cmd_ParseLine
+will split up the
+.Fa line
+into argument that is saved in
+.Fa argv
+maxium of
+.Fa maxn
+will be parsed.
+The number of argument will be stored in
+.Fa n.
+.Pp
+The function
+.fn cmd_FreeArgv
+will free the arguments
+.Fa argv
+that
+.Fn cmd_ParseLine
+allocated.
+.Pp
+The function
+.Fn cmd_Dispatch
+will take the current syntax and try to parse the arguments
+.Fa argc, argv.
+.Pp
+When a
+.Xr mdoc(7)
+file is generated. The .ctx file for the command is read to add extra
+content to the manual-page. The file is split up in sections separated by
+.Pp
+.Dl %section-name part-name
+.Pp
+Typical lines are
+.Li %command
+.Fa commandname,
+where commandname is the name that was added with
+.Fn cmd_CreateSyntax.
+.Pp
+Other sections are
+.Bl -tag -width "section"
+.It %name description
+Description of the program (\&.Nm in mdoc).
+.It %name os
+Os version (\&.Os in mdoc).
+.It %name section
+Section of the manualpage (\&.Dt in mdoc).
+.It %section description
+Text for the DESCRIPTION section.
+.It %section errors
+Text for the ERRORS section.
+.It %section see also
+Text for the SEE ALSO section.
+.It %section history
+Text for the HISTORY section.
+.It %section authors
+Text for the AUTHORS section.
+.It %section BUGS
+Text for the bugs section.
+.El
+.Pp
+Lines starting with # are comments.
+.Sh ENVIRONMENT
+When
+.Ev CMD_MANDOC
+set to something and the built-in command
+.Cm help
+is called, mdoc output is generated.
+.Ev srcdir
+is looked upon when opening the .ctx file to enable building out of tree.
+.Sh EXAMPLES
+.Bd -literal
+#include <stdio.h>
+#include <err.h>
+#include <cmd.h>
+
+static int
+setacl (struct cmd_syndesc *t, void *ptr)
+{
+ struct cmd_item *it;
+ int i;
+
+ printf ("setacl:");
+ printf (" dir: %s aces:", (char *)t->params[0].items->data);
+ for (it = t->params[1].items; it ; it = it->next) {
+ printf (" %s", (char *)it->data);
+ i++;
+ }
+ if (t->params[2].items)
+ printf (" flag: -clear");
+ printf ("\n");
+ if (i % 2 != 0)
+ errx (1, "ace pairs isn't pairs");
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ struct cmd_syndesc *ts;
+ int ret;
+
+ ts = cmd_CreateSyntax ("setacl", setacl, NULL, "set a acl on a directory");
+
+ cmd_CreateAlias (ts, "sa");
+ cmd_AddParm (ts, "-dir", CMD_SINGLE, CMD_REQUIRED, "dir");
+ cmd_AddParm (ts, "-ace", CMD_LIST, CMD_REQUIRED, "acl entry");
+ cmd_AddParm (ts, "-clear", CMD_FLAG, CMD_OPTIONAL, "");
+
+ ret = cmd_Dispatch (argc, argv);
+ if (ret)
+ errx (1, "dispatch failed");
+
+ return 0;
+}
+
+.Ed
+.Sh FILES
+A file named the same way as the command binary (really argv[0]) with
+the extention .ctx will be used to add extra help-text in the mdoc
+manpage when its generated.
+.Sh SEE ALSO
+.Xr getarg(3),
+.Xr mdoc(7)
+.Sh HISTORY
+First written on CMU. Taken up by Transarc/IBM in their AFS
+product. Reimplmented for Arla since a lot of people missed it. When
+it got added to arla it also got functionally like generating mdoc
+output.
+.Sh AUTHORS
+Love Hörnquist-Åstrand <lha@stacken.kth.se>
+.Sh BUGS
+Plenty of them.
+.Pp
+.Fn cmd_ParseLine
+and
+.Fn cmd_FreeArgv
+isn't implemeted. \ No newline at end of file
diff --git a/usr.sbin/afs/src/lib/cmd/cmd.c b/usr.sbin/afs/src/lib/cmd/cmd.c
new file mode 100644
index 00000000000..41da62309d9
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/cmd.c
@@ -0,0 +1,1016 @@
+/*
+ * 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 <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <strings.h>
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+
+#include <cmd.h>
+
+#ifdef RCSID
+RCSID("$Id: cmd.c,v 1.1 2000/09/11 14:40:55 art Exp $");
+#endif
+
+static struct cmd_syndesc *cmd_cmds = NULL;
+static struct cmd_syndesc **cmd_lastcmd = &cmd_cmds;
+static int _cmd_init = 0;
+
+static int (*before_proc) (void *rock) = NULL;
+static void *before_rock = NULL;
+static int (*after_proc) (void *rock) = NULL;
+static void *after_rock = NULL;
+
+static void
+cmd_PrintSyntaxManDoc (const char *commandname);
+
+
+static struct cmd_syndesc *
+new_cmd (const char *name, const char *help_str, struct cmd_syndesc *alias)
+{
+ struct cmd_syndesc *ts;
+
+ ts = malloc (sizeof(*ts));
+ if (ts == NULL)
+ return NULL;
+ memset (ts, 0, sizeof (*ts));
+
+ if (name) {
+ ts->name = strdup (name);
+ if (ts->name == NULL) {
+ free (ts);
+ return NULL;
+ }
+ }
+ if (help_str) {
+ ts->help = strdup (help_str);
+ if (ts->help == NULL) {
+ free (ts->name);
+ free (ts);
+ return NULL;
+ }
+ }
+ if (alias) {
+ ts->aliasOf = alias;
+ ts->nextAlias = alias->nextAlias;
+ alias->nextAlias = ts;
+ ts->flags |= CMD_ALIAS;
+ }
+ if (ts->name == NULL) {
+ assert (cmd_cmds == NULL || cmd_cmds->name != NULL);
+ ts->next = cmd_cmds;
+ if (&cmd_cmds == cmd_lastcmd)
+ cmd_lastcmd = &ts->next;
+ cmd_cmds = ts;
+ } else {
+ *cmd_lastcmd = ts;
+ cmd_lastcmd = &ts->next;
+ }
+ return ts;
+}
+
+/*
+ *
+ */
+
+static int
+find_command (struct cmd_syndesc *cmd_cmds, const char *func,
+ struct cmd_syndesc **ret)
+{
+ struct cmd_syndesc *partial_match = NULL;
+ struct cmd_syndesc *ts;
+ int partial_len = strlen (func);
+
+ for (ts = cmd_cmds; ts; ts = ts->next) {
+ if (ts->name == NULL)
+ continue;
+ if (strcasecmp (ts->name, func) == 0) {
+ if (ts->aliasOf)
+ ts = ts->aliasOf;
+ *ret = ts;
+ return 0;
+ }
+ if (strncasecmp (ts->name, func, partial_len) == 0) {
+ if (partial_match)
+ return CMD_AMBIG;
+ partial_match = ts;
+ }
+ }
+ if (partial_match) {
+ if (partial_match->aliasOf)
+ partial_match = partial_match->aliasOf;
+ *ret = partial_match;
+ return 0;
+ }
+ return CMD_UNKNOWNCMD;
+}
+
+/*
+ *
+ */
+
+static void
+print_usage (const char *name, struct cmd_syndesc *ts)
+{
+ int i;
+
+ if (getenv ("CMD_MANDOC") != NULL) {
+ cmd_PrintSyntaxManDoc(__progname); /* XXX */
+ return;
+ }
+
+ printf ("%s", name);
+ if (ts->name)
+ printf (" %s", ts->name);
+
+ for (i = 0; i < CMD_MAXPARMS ; i++) {
+ char *help = ts->parms[i].help;
+ char *name = ts->parms[i].name;
+ if (help == NULL)
+ help = "arg";
+ if ((ts->parms[i].flags & CMD_HIDE) == CMD_HIDE || name == NULL)
+ continue;
+ printf (" ");
+ if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL)
+ printf ("[");
+ switch (ts->parms[i].type) {
+ case CMD_FLAG:
+ printf ("%s", name);
+ break;
+ case CMD_SINGLE:
+ printf ("%s <%s>", name, help);
+ break;
+ case CMD_LIST:
+ printf ("%s <%s>+", name, help);
+ break;
+ default:
+ abort();
+ }
+ if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL)
+ printf ("]");
+ }
+ if (ts->name == NULL)
+ printf (" command");
+ printf ("\n");
+}
+
+/*
+ *
+ */
+
+static int
+cmd_internal_help (struct cmd_syndesc *t, void *ptr)
+{
+ struct cmd_syndesc *ts;
+ char *help;
+
+ if (getenv ("CMD_MANDOC") != NULL) {
+ cmd_PrintSyntaxManDoc(__progname); /* XXX */
+ return 0;
+ }
+
+ if (t->parms[0].items == NULL) {
+
+ for (ts = cmd_cmds; ts; ts = ts->next) {
+ if (ts->name == NULL && cmd_cmds == ts)
+ continue;
+ if ((ts->flags & CMD_HIDDEN) == CMD_HIDDEN)
+ continue;
+ if (ts->aliasOf)
+ continue;
+ if (ts->help)
+ help = ts->help;
+ else
+ help = "";
+
+ printf ("%-10s %s\n", ts->name, help);
+ }
+ } else {
+ char *cmd = t->parms[0].items->data;
+ struct cmd_syndesc *ts;
+ int ret;
+
+ ret = find_command (cmd_cmds, cmd, &ts);
+ if (ret)
+ return ret;
+ print_usage (__progname, ts); /* XXX */
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+cmd_internal_apropos (struct cmd_syndesc *t, void *ptr)
+{
+ struct cmd_syndesc *ts;
+ char *cmd, *help;
+
+ cmd = t->parms[0].items->data;
+
+ for (ts = cmd_cmds; ts; ts = ts->next) {
+ if (ts->name == NULL && cmd_cmds == ts)
+ continue;
+ if (ts->help)
+ help = ts->help;
+ else
+ help = "";
+ if (strstr(ts->name, cmd))
+ printf ("%-10s %s\n", ts->name, help);
+ }
+ return 0;
+}
+
+/*
+ * Create a new command with `name' that will run the function `main'
+ * with the `rock'. When help is choose `help_str' will be displayed.
+ */
+
+struct cmd_syndesc *
+cmd_CreateSyntax (const char *name, cmd_proc main, void *rock,
+ const char *help_str)
+{
+ struct cmd_syndesc *ts;
+
+ ts = new_cmd (name, help_str, NULL);
+
+ ts->proc = main;
+ ts->rock = rock;
+
+ cmd_Seek (ts, CMD_HELPPARM);
+ cmd_AddParm (ts, "-help", CMD_FLAG, CMD_OPTIONAL, "get detailed help");
+ cmd_Seek (ts, 0);
+
+ return ts;
+}
+
+/*
+ *
+ */
+
+int
+cmd_SetBeforeProc (int (*proc) (void *), void *rock)
+{
+ before_proc = proc;
+ before_rock = rock;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+cmd_SetAfterProc (int (*proc) (void *rock), void *rock)
+{
+ after_proc = proc;
+ after_rock = rock;
+ return 0;
+}
+
+/*
+ * Allocate a new parameter to `ts' with name `cmd' of `type' and with
+ * `flags'. When help is needed show `help_str'.
+ */
+
+void
+cmd_AddParm (struct cmd_syndesc *ts, const char *name,
+ cmd_parmdesc_type type, cmd_parmdesc_flags flags,
+ const char *help_str)
+{
+ struct cmd_parmdesc *p = &ts->parms[ts->nParams];;
+
+ memset (p, 0, sizeof(*p));
+
+ if (ts->nParams > CMD_HELPPARM)
+ abort();
+
+ p->name = strdup (name);
+ if (p->name == NULL)
+ return;
+ p->help = strdup(help_str);
+ if (p->help == NULL) {
+ free (p->name);
+ return;
+ }
+ ts->nParams++;
+
+ p->type = type;
+ p->flags = flags;
+}
+
+/*
+ *
+ */
+
+int
+cmd_CreateAlias (struct cmd_syndesc *orignal, const char *name)
+{
+ struct cmd_syndesc *ts;
+ ts = new_cmd (name, NULL, orignal);
+ if (ts == NULL)
+ return CMD_INTERALERROR;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+cmd_Seek (struct cmd_syndesc *ts, int pos)
+{
+ if (pos > CMD_HELPPARM || pos < 0)
+ return CMD_EXCESSPARMS;
+ ts->nParams = pos;
+ return 0;
+}
+
+/*
+ *
+ */
+
+void
+cmd_FreeArgv (char **argv)
+{
+ return;
+}
+
+/*
+ *
+ */
+
+#define CMD_IS_CMD(str) (str[0] == '-' && !isdigit(str[1]))
+
+/*
+ *
+ */
+
+static struct cmd_parmdesc *
+find_next_param (struct cmd_syndesc *ts, int *curval)
+{
+ int i;
+ for (i = *curval; i < CMD_MAXPARMS ; i++) {
+ if ((ts->parms[i].flags & CMD_EXPANDS) == CMD_EXPANDS)
+ break;
+ if (ts->parms[i].name == NULL)
+ continue;
+ if (ts->parms[i].items != NULL)
+ continue;
+ break;
+ }
+ if (i >= CMD_MAXPARMS)
+ return NULL;
+ *curval = i;
+ return &ts->parms[i];
+}
+
+/*
+ *
+ */
+
+static int
+find_next_name (struct cmd_syndesc *ts, const char *name,
+ struct cmd_parmdesc **ret)
+{
+ struct cmd_parmdesc *partial_match = NULL;
+ int i, partial_len = strlen(name);
+
+ for (i = 0; i < CMD_MAXPARMS; i++) {
+ if (ts->parms[i].name == NULL)
+ continue;
+ if (strcasecmp (name, ts->parms[i].name) == 0) {
+ *ret = &ts->parms[i];
+ return 0;
+ }
+ if (strncasecmp (name, ts->parms[i].name, partial_len) == 0) {
+ if (partial_match)
+ return CMD_AMBIG;
+ partial_match = &ts->parms[i];
+ }
+ }
+ if (partial_match) {
+ *ret = partial_match;
+ return 0;
+ }
+ return CMD_UNKNOWNSWITCH;
+}
+
+/*
+ *
+ */
+
+static struct cmd_item *
+new_items (struct cmd_parmdesc *p)
+{
+ struct cmd_item *i;
+ i = malloc (sizeof (*i));
+ if (i == NULL)
+ err (1, "new_items");
+ i->next = p->items;
+ p->items = i;
+ return i;
+}
+
+/*
+ *
+ */
+
+static int
+parse_options (int argc, char **argv, int *optind, struct cmd_syndesc *ts,
+ int failp)
+{
+ struct cmd_parmdesc *p;
+ int i, ret;
+
+ for (i = 0; i < CMD_MAXPARMS; i++) {
+ if (ts->parms[i].name)
+ break;
+ }
+ if (i == CMD_MAXPARMS)
+ return 0;
+
+
+ for (i = 0; i < argc; i++) {
+ ret = find_next_name (ts, argv[i], &p);
+ if (ret) {
+ if (failp)
+ return ret;
+ break;
+ }
+ switch (p->type) {
+ case CMD_FLAG:
+ assert (p->items == NULL);
+ p->items = new_items (p);
+ p->items->data = p;
+ break;
+ case CMD_SINGLE:
+ assert (p->items == NULL);
+ if (i == argc - 1)
+ return CMD_TOOFEW;
+ i++;
+ p->items = new_items (p);
+ p->items->data = argv[i];
+ break;
+ case CMD_LIST:
+ if (i == argc - 1)
+ return CMD_TOOFEW;
+ i++;
+ while (i < argc) {
+ p->items = new_items (p);
+ p->items->data = argv[i];
+ if (i >= argc - 1 || CMD_IS_CMD(argv[i+1]))
+ break;
+ i++;
+ }
+ break;
+ default:
+ abort();
+ }
+ }
+ if (argc < i)
+ i = argc;
+ *optind = i;
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+parse_magic_options (int argc, char **argv, int *optind,
+ struct cmd_syndesc *ts)
+{
+ struct cmd_parmdesc *p;
+ int i, curval = 0;
+
+ for (i = 0; i < argc; i++) {
+ if (CMD_IS_CMD(argv[i]))
+ break;
+ p = find_next_param (ts, &curval);
+ if (p == NULL)
+ break;
+ if (p->type == CMD_FLAG) {
+#if 0
+ assert (p->items == NULL);
+ p->items = new_items (p);
+ p->items->data = p;
+#else
+ break;
+#endif
+ } else if (p->type == CMD_SINGLE) {
+ assert (p->items == NULL);
+ p->items = new_items (p);
+ p->items->data = argv[i];
+ } else if (p->type == CMD_LIST) {
+ while (i < argc) {
+ p->items = new_items (p);
+ p->items->data = argv[i];
+ if ((i >= argc - 1 || CMD_IS_CMD(argv[i+1]))
+ || (p->flags & CMD_EXPANDS) == 0)
+ break;
+ i++;
+ }
+ } else {
+#if 0
+ abort();
+#else
+ break;
+#endif
+ }
+ }
+ if (argc < i)
+ i = argc;
+ *optind = i;
+ return 0;
+}
+
+/*
+ *
+ */
+
+static struct cmd_parmdesc *
+req_argumentp (struct cmd_syndesc *ts)
+{
+ int i;
+
+ for (i = 0; i < CMD_MAXPARMS; i++) {
+ if (ts->parms[i].name == NULL)
+ continue;
+ if ((ts->parms[i].flags & CMD_OPTIONAL) == 0
+ && ts->parms[i].items == NULL)
+ return &ts->parms[i];
+ }
+ return NULL;
+}
+
+/*
+ *
+ */
+
+int
+cmd_ParseLine (const char *line, char **argv, int *n, int maxn)
+{
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+call_proc (const char *programname, struct cmd_syndesc *ts)
+{
+ struct cmd_parmdesc *p;
+ int ret;
+
+ if (ts->parms[CMD_HELPPARM].items) {
+ print_usage (programname, ts);
+ return 0;
+ }
+
+ p = req_argumentp (ts);
+ if (p) {
+ print_usage (programname, ts);
+ fprintf (stderr, "missing argument: %s\n", &p->name[1]);
+ return CMD_USAGE;
+ }
+
+ if (before_proc)
+ (*before_proc) (before_rock);
+
+ ret = (*ts->proc) (ts, ts->rock);
+
+ if (after_proc)
+ (*after_proc) (before_rock);
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+cmd_Dispatch (int argc, char **argv)
+{
+ struct cmd_syndesc *ts;
+ int optind = 0;
+ int ret;
+ char *programname = argv[0];
+
+ argc -= 1;
+ argv += 1;
+
+ if (!_cmd_init) {
+ if (cmd_cmds->next != NULL || cmd_cmds->proc == NULL) {
+ ts = cmd_CreateSyntax ("help", cmd_internal_help, NULL, "help");
+ cmd_AddParm (ts, "-cmd", CMD_SINGLE, CMD_OPTIONAL, "command");
+ ts = cmd_CreateSyntax ("apropos", cmd_internal_apropos,
+ NULL, "apropos");
+ cmd_AddParm (ts, "-cmd", CMD_SINGLE, CMD_REQUIRED, "command");
+ }
+ if (cmd_cmds->name)
+ ts = cmd_CreateSyntax ("main", NULL, NULL, NULL);
+ _cmd_init = 1;
+ }
+
+ if (cmd_cmds->next == NULL && cmd_cmds->proc) {
+ ret = parse_magic_options (argc, argv, &optind, ts);
+ if (ret)
+ return ret;
+
+ argv += optind;
+ argc -= optind;
+ optind = 0;
+ }
+ ret = parse_options (argc, argv, &optind, cmd_cmds, 0);
+ if (ret)
+ errx (1, "main parse failed");
+ if (cmd_cmds->next == NULL && cmd_cmds->proc) {
+ return call_proc (programname, cmd_cmds);
+ } else {
+ struct cmd_parmdesc *p;
+
+ if (cmd_cmds->parms[CMD_HELPPARM].items) {
+ print_usage (programname, cmd_cmds);
+ return 0;
+ }
+
+ p = req_argumentp (cmd_cmds);
+ if (p) {
+ fprintf (stderr, "missing argument: %s\n", &p->name[1]);
+ return CMD_USAGE;
+ }
+ }
+
+ argv += optind;
+ argc -= optind;
+
+ if (argc <= 0) {
+ print_usage (programname, ts);
+ return CMD_USAGE;
+ }
+
+ ret = find_command (cmd_cmds, argv[0], &ts);
+ if (ret)
+ return ret;
+
+ argv += 1;
+ argc -= 1;
+ optind = 0;
+
+ ret = parse_magic_options (argc, argv, &optind, ts);
+ if (ret)
+ return ret;
+
+ argv += optind;
+ argc -= optind;
+ optind = 0;
+
+ ret = parse_options (argc, argv, &optind, ts, 1);
+ if (ret)
+ return ret;
+
+ argv += optind;
+ argc -= optind;
+
+ if (argc != 0) {
+ print_usage (programname, ts);
+ return CMD_USAGE;
+ }
+
+ return call_proc (programname, ts);
+}
+
+
+static void
+cmd_PrintParams (struct cmd_syndesc *ts)
+{
+ int i;
+
+ for (i = 0; i < CMD_MAXPARMS ; i++) {
+ char *help = ts->parms[i].help;
+ if (ts->parms[i].name == NULL)
+ continue;
+ if (help == NULL)
+ help = "arg";
+ if ((ts->parms[i].flags & CMD_HIDE) == CMD_HIDE)
+ continue;
+ if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL)
+ printf (".Op ");
+ else
+ printf (".");
+ switch (ts->parms[i].type) {
+ case CMD_FLAG:
+ printf ("Cm %s\n", ts->parms[i].name);
+ break;
+ case CMD_SINGLE:
+ printf ("Cm %s Ar %s\n", ts->parms[i].name, help);
+ break;
+ case CMD_LIST:
+ printf ("Cm %s Ar %s ...\n", ts->parms[i].name, help);
+ break;
+ default: abort(); break;
+ }
+ }
+#if 0
+ for (i = 0; i < CMD_MAXPARMS ; i++) {
+ if (ts->parms[i].name == NULL)
+ continue;
+ printf ("\tflag: %s\n", ts->parms[i].name);
+ printf ("\t\thelp: %s\n", ts->parms[i].help);
+ printf ("\t\tflags: ");
+ if ((ts->parms[i].flags & CMD_REQUIRED) == CMD_REQUIRED)
+ printf ("required");
+ if ((ts->parms[i].flags & CMD_EXPANDS) == CMD_EXPANDS)
+ printf ("expands");
+ if ((ts->parms[i].flags & CMD_PROCESSED) == CMD_PROCESSED)
+ printf ("processed");
+ printf ("\n");
+ }
+#endif
+}
+
+/*
+ *
+ */
+
+static int
+cmd_ExtraText (const char *cmd, const char *sectionname,
+ const char *class, const char *name, int withcr)
+{
+ char *fn, *section;
+ char buf[1024];
+ FILE *f;
+ int len, searching = 1;
+
+ asprintf (&fn, "%s.ctx", cmd);
+ f = fopen (fn, "r");
+ if (f == NULL) {
+ free (fn);
+ if (getenv ("srcdir")) {
+ asprintf (&fn, "%s/%s.ctx", getenv("srcdir"), cmd);
+ f = fopen (fn, "r");
+ }
+ if (f == NULL)
+ return 0;
+ }
+ len = asprintf (&section, "%%%s %s", class, name);
+
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ buf[strlen(buf)-1] = '\0';
+
+ if (buf[0] == '#')
+ continue;
+
+ if (searching) {
+ if (strncasecmp (buf, section, len) == 0) {
+ searching = 0;
+ if (sectionname)
+ printf ("%s", sectionname);
+ }
+ } else {
+ char *p = buf;
+ if (buf[0] == '%') {
+ break;
+ }
+ while (isspace (*p)) p++;
+ if (*p == '\0')
+ continue;
+ printf ("%s%s", p, withcr ? "\n" : "");
+ }
+ }
+ fclose (f);
+ return searching;
+}
+
+static void
+cmd_PrintSyntaxManDoc (const char *commandname)
+{
+ char timestr[64], cmd[64];
+ time_t t;
+ struct cmd_syndesc *ts;
+
+ printf(".\\\" Things to fix:\n");
+ printf(".\\\" * use better macros for arguments (like .Pa for files)\n");
+ printf(".\\\"\n");
+
+ t = time(NULL);
+ strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t));
+ strlcpy(cmd, commandname, sizeof(cmd));
+ cmd[sizeof(cmd)-1] = '\0';
+/* XXX-libroken strupr(cmd);*/
+
+ printf(".Dd %s\n", timestr);
+ printf(".Dt %s ", cmd);
+ if (cmd_ExtraText (commandname, NULL, "name", "section", 0))
+ printf("SECTION");
+ printf ("\n");
+ if (cmd_ExtraText (commandname, ".Os ", "name", "OS", 0))
+ printf(".Os OPERATING_SYSTEM");
+ printf ("\n");
+ printf(".Sh NAME\n");
+ printf(".Nm %s\n", commandname);
+ if (cmd_ExtraText (commandname, ".Nd ", "name", "description", 1))
+ printf(".Nd in search of a description\n");
+ printf(".Sh SYNOPSIS\n");
+ printf(".Nm\n");
+ if (cmd_cmds->name == NULL)
+ cmd_PrintParams (cmd_cmds);
+ if (cmd_cmds->next)
+ printf (".Cm command\n.Op ...");
+ printf ("\n");
+ printf(".Sh DESCRIPTION\n");
+
+ cmd_ExtraText (commandname, NULL, "section", "description", 1);
+
+ if (cmd_cmds->name == NULL && cmd_cmds->next == NULL) {
+ printf (".Pp\n");
+ if (cmd_ExtraText (commandname, NULL, "command", "_main", 1))
+ printf ("Tell someone to add some helptext "
+ "here to the .ctx file\n");
+ } else {
+ printf (".Bl -tag -width Ds\n");
+
+ for (ts = cmd_cmds; ts; ts = ts->next) {
+ struct cmd_syndesc *t = ts->nextAlias;
+
+ if (ts->name == NULL && cmd_cmds == ts)
+ continue;
+ if ((ts->flags & CMD_HIDDEN) == CMD_HIDDEN)
+ continue;
+ if (ts->aliasOf)
+ continue;
+
+ printf (".It %s", ts->name);
+
+ if (t) {
+ while (t) {
+ printf (", %s", t->name);
+ t = t->nextAlias;
+ }
+ }
+ printf ("\n.Pp\n");
+ printf (".Nm \"%s %s\"\n", commandname, ts->name);
+ cmd_PrintParams (ts);
+ printf (".Pp\n");
+ if (strcmp (ts->name, "help") == 0) {
+ printf ("List all commands, or if\n"
+ ".Ar command\n"
+ "is given as an argument, help for that command.\n");
+ } else if (strcmp (ts->name, "apropos") == 0) {
+ printf ("List all command that have the argument\n.Ar command\n"
+ "as a subtring in themself.");
+ } else {
+ if (cmd_ExtraText (commandname, NULL, "command", ts->name, 1))
+ printf ("Tell someone to add some helptext "
+ "here to the .ctx file\n");
+ }
+ }
+ printf(".El\n");
+ }
+
+ cmd_ExtraText (commandname, ".Sh ERRORS\n", "section", "errors", 1);
+ cmd_ExtraText (commandname, ".Sh SEE ALSO\n", "section", "see also", 1);
+ cmd_ExtraText (commandname, ".Sh HISTORY\n", "section", "history", 1);
+ cmd_ExtraText (commandname, ".Sh AUTHORS\n", "section", "authors", 1);
+ cmd_ExtraText (commandname, ".Sh BUGS\n", "section", "bugs", 1);
+}
+
+/*
+ *
+ */
+
+void
+cmd_PrintSyntax (const char *commandname)
+{
+ const char *name;
+ struct cmd_syndesc *ts;
+ int i;
+
+ name = strrchr (commandname, '/');
+ if (name == NULL)
+ name = commandname;
+ else
+ name++;
+
+ if (getenv ("CMD_MANDOC") != NULL) {
+ cmd_PrintSyntaxManDoc(name);
+ return;
+ }
+
+ for (ts = cmd_cmds; ts; ts = ts->next) {
+ struct cmd_syndesc *t = ts->nextAlias;
+
+ if (ts->name == NULL && cmd_cmds == ts)
+ printf ("exec-file: %s\n", name);
+ else
+ printf ("command: %s - %s\n", ts->name, ts->help);
+ printf ("\tflags: ");
+ if ((ts->flags & CMD_ALIAS) == CMD_ALIAS)
+ printf (" alias");
+ if ((ts->flags & CMD_HIDDEN) == CMD_HIDDEN)
+ printf (" hidden");
+ printf ("\n");
+ if (ts->aliasOf)
+ continue;
+ if (t) {
+ printf ("\taliases:");
+ while (t) {
+ printf (" %s", t->name);
+ t = t->nextAlias;
+ }
+ printf ("\n");
+ }
+ for (i = 0; i < CMD_MAXPARMS ; i++) {
+ if (ts->parms[i].name == NULL)
+ continue;
+ printf ("\tflag: %s\n", ts->parms[i].name);
+ switch (ts->parms[i].type) {
+ case CMD_FLAG: printf ("\t\ttype: flag\n"); break;
+ case CMD_SINGLE: printf ("\t\ttype: single\n"); break;
+ case CMD_LIST: printf ("\t\ttype: list\n"); break;
+ default: abort(); break;
+ }
+ printf ("\t\thelp: %s\n", ts->parms[i].help);
+ printf ("\t\tflags: ");
+ if ((ts->parms[i].flags & CMD_REQUIRED) == CMD_REQUIRED)
+ printf ("required");
+ if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL)
+ printf ("optional");
+ if ((ts->parms[i].flags & CMD_EXPANDS) == CMD_EXPANDS)
+ printf ("expands");
+ if ((ts->parms[i].flags & CMD_HIDE) == CMD_HIDE)
+ printf ("hide");
+ if ((ts->parms[i].flags & CMD_PROCESSED) == CMD_PROCESSED)
+ printf ("processed");
+ printf ("\n");
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static const char *cmd_errors[] = {
+ "cmd - Excess parameters",
+ "cmd - Internal error",
+ "cmd - Notlist",
+ "cmd - Too many",
+ "cmd - Usage",
+ "cmd - Unknown command",
+ "cmd - Unknown switch",
+ "cmd - Ambigous",
+ "cmd - Too few arguments",
+ "cmd - Too many arguments"
+};
+
+const char *
+cmd_number2str(int error)
+{
+ if (error < CMD_EXCESSPARMS || error > CMD_TOOBIG)
+ return NULL;
+ return cmd_errors[error - CMD_EXCESSPARMS];
+}
diff --git a/usr.sbin/afs/src/lib/cmd/cmd.h b/usr.sbin/afs/src/lib/cmd/cmd.h
new file mode 100644
index 00000000000..32d8241104e
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/cmd.h
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/*
+ * $Id: cmd.h,v 1.1 2000/09/11 14:40:56 art Exp $
+ */
+
+#ifndef _ARLA_CMD_H
+#define _ARLA_CMD_H 1
+
+/* syncdesc */
+typedef enum { CMD_ALIAS = 1,
+ CMD_HIDDEN = 4 } cmd_syncdesc_flags;
+
+/* parmdesc */
+typedef enum { CMD_FLAG = 1,
+ CMD_SINGLE,
+ CMD_LIST } cmd_parmdesc_type;
+
+typedef enum { CMD_REQUIRED = 0x0,
+ CMD_OPTIONAL = 0x1,
+ CMD_EXPANDS = 0x2,
+ CMD_HIDE = 0x4,
+ CMD_PROCESSED = 0x8 } cmd_parmdesc_flags;
+
+enum { CMD_HELPPARM = 63, CMD_MAXPARMS = 64 } ;
+
+struct cmd_syndesc;
+
+typedef int (*cmd_proc) (struct cmd_syndesc *, void *);
+
+struct cmd_item {
+ struct cmd_item *next;
+ void *data;
+};
+
+struct cmd_parmdesc {
+ char *name;
+ cmd_parmdesc_type type;
+ struct cmd_item *items;
+ cmd_parmdesc_flags flags;
+ char *help;
+};
+
+struct cmd_syndesc {
+ struct cmd_syndesc *next;
+ struct cmd_syndesc *nextAlias;
+ struct cmd_syndesc *aliasOf;
+ char *name;
+ char *a0name;
+ char *help;
+ cmd_proc proc;
+ void *rock;
+ int nParams;
+ cmd_syncdesc_flags flags;
+ struct cmd_parmdesc parms[CMD_MAXPARMS];
+};
+
+struct cmd_syndesc *
+cmd_CreateSyntax (const char *name, cmd_proc main, void *rock,
+ const char *help_str);
+
+int
+cmd_SetBeforeProc (int (*proc) (void *rock), void *rock);
+
+int
+cmd_SetAfterProc (int (*proc) (void *rock), void *rock);
+
+void
+cmd_AddParm (struct cmd_syndesc *ts, const char *cmd,
+ cmd_parmdesc_type type, cmd_parmdesc_flags flags,
+ const char *help_str);
+
+int
+cmd_CreateAlias (struct cmd_syndesc *ts, const char *name);
+
+int
+cmd_Seek (struct cmd_syndesc *ts, int pos);
+
+void
+cmd_FreeArgv (char **argv);
+
+int
+cmd_ParseLine (const char *line, char **argv, int *n, int maxn);
+
+int
+cmd_Dispatch (int argc, char **argv);
+
+void
+cmd_PrintSyntax (const char *commandname);
+
+const char *
+cmd_number2str(int error);
+
+#define CMD_EXCESSPARMS 3359744
+#define CMD_INTERALERROR 3359745
+#define CMD_NOTLIST 3359746
+#define CMD_TOOMANY 3359747
+#define CMD_USAGE 3359748
+#define CMD_UNKNOWNCMD 3359749
+#define CMD_UNKNOWNSWITCH 3359750
+#define CMD_AMBIG 3359751
+#define CMD_TOOFEW 3359752
+#define CMD_TOOBIG 3359753
+
+#endif /* _ARLA_CMD_H */
diff --git a/usr.sbin/afs/src/lib/cmd/frame.ctx b/usr.sbin/afs/src/lib/cmd/frame.ctx
new file mode 100644
index 00000000000..0e83966123a
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/frame.ctx
@@ -0,0 +1,48 @@
+# $Id: frame.ctx,v 1.1 2000/09/11 14:40:56 art Exp $
+# This is a comment
+
+%name description
+
+ description here
+
+%name os
+
+ "Some enviroment"
+
+%name section
+
+ 1
+
+%command somecommand
+
+ Some help text that takes
+ .Ar argument
+
+%command someothercommand
+
+ Even more helptext
+
+%section bugs
+
+ Manual pages are boring to write
+
+%section history
+
+ This file is not that old.
+
+%section see also
+
+ .Xr ls(1),
+ .Xr some-other-command(7).
+
+%section authors
+
+ Mini-me <me@example.org>
+
+%section description
+
+ This is part of the DESCRIPTION section
+
+%section errors
+
+ This is part of the ERRORS section
diff --git a/usr.sbin/afs/src/lib/cmd/testc.c b/usr.sbin/afs/src/lib/cmd/testc.c
new file mode 100644
index 00000000000..bf33fbd51e4
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/testc.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+#include <cmd.h>
+
+static int
+MainProc (struct cmd_syndesc *t, void *ptr)
+{
+ printf ("main proc\n");
+ return 0;
+}
+
+static int
+setacl (struct cmd_syndesc *t, void *ptr)
+{
+ struct cmd_item *it;
+ int i;
+
+ printf ("setacl:");
+ printf (" dir:");
+ for (it = t->parms[0].items; it ; it = it->next) {
+ printf (" %s", (char *)it->data);
+ }
+ printf (" acls:");
+ for (i = 0, it = t->parms[1].items; it; it = it->next, i++)
+ printf (" %s", (char *)it->data);
+ printf (" flags:");
+ if (t->parms[2].items) printf (" -clear");
+ if (t->parms[3].items) printf (" -negative");
+ if (t->parms[4].items) printf (" -id");
+ if (t->parms[5].items) printf (" -if");
+ printf ("\n");
+ if (i % 2 != 0)
+ errx (1, "ace pairs isn't pairs");
+ return 0;
+}
+
+static int
+listacl (struct cmd_syndesc *t, void *ptr)
+{
+ struct cmd_item *it;
+
+ printf ("listacl: ");
+ for (it = t->parms[0].items; it ; it = it->next)
+ printf (" %s", (char *)it->data);
+ printf ("\n");
+ return 0;
+}
+
+static int
+listquota (struct cmd_syndesc *t, void *ptr)
+{
+ printf ("listquota\n");
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ struct cmd_syndesc *ts;
+ int ret;
+
+ set_progname (argv[0]);
+
+ ts = cmd_CreateSyntax (NULL, MainProc, NULL, "foo");
+
+ ts = cmd_CreateSyntax ("setacl", setacl, NULL, "set a acl on a directory");
+
+ cmd_CreateAlias (ts, "sa");
+ cmd_AddParm (ts, "-dir", CMD_LIST, CMD_REQUIRED, "dir");
+ cmd_AddParm (ts, "-acl", CMD_LIST, CMD_REQUIRED|CMD_EXPANDS, "acl entry");
+ cmd_AddParm (ts, "-clear", CMD_FLAG, CMD_OPTIONAL, "");
+ cmd_AddParm (ts, "-negative", CMD_FLAG, CMD_OPTIONAL, "");
+ cmd_AddParm (ts, "-id", CMD_FLAG, CMD_OPTIONAL, "");
+ cmd_AddParm (ts, "-if", CMD_FLAG, CMD_OPTIONAL, "");
+
+ ts = cmd_CreateSyntax ("listacl", listacl, NULL,
+ "list a acl on a directory");
+ cmd_CreateAlias (ts, "la");
+ cmd_AddParm (ts, "-dir", CMD_LIST, CMD_OPTIONAL|CMD_EXPANDS, "dir");
+
+ ts = cmd_CreateSyntax ("listquota", listquota,
+ NULL, "show quota in a volume");
+ cmd_CreateAlias (ts, "lq");
+
+#if 0
+ cmd_PrintSyntax("fs");
+#endif
+
+ ret = cmd_Dispatch (argc, argv);
+#if 0
+ if (ret) {
+ const char *error = cmd_number2str (ret);
+ if (error == NULL)
+ error = strerror (ret);
+ errx (1, "dispatch failed: %s (%d)", error, ret);
+ }
+#endif
+
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/lib/cmd/testc.ctx b/usr.sbin/afs/src/lib/cmd/testc.ctx
new file mode 100644
index 00000000000..4dd44f3501b
--- /dev/null
+++ b/usr.sbin/afs/src/lib/cmd/testc.ctx
@@ -0,0 +1,121 @@
+#
+# $Id: testc.ctx,v 1.1 2000/09/11 14:40:56 art Exp $
+#
+
+%name description
+
+ command to manipulate the filesystem
+
+%name os
+
+ "Arla, KTH"
+
+%name section
+
+ 1
+
+%command setacl
+
+ Set the ACL for the named directory
+ .Ar dir
+ to the list of
+ .Ar acl
+ entries. If the flag
+ .Fl clear
+ is specified all current ACL entries are removed before the
+ new one is added. You must have the A-ACL on the directory to
+ be able to change the ACL.
+
+ The ACL entry consist of two parts, a user/group and
+ rights. The rights are rwlidka.
+ .Bl -tag -width "Administer"
+ .It Em Read
+ the user/group can read files in this directory.
+ .It Em Write
+ the user/group can write files in this directory.
+ .It Em List
+ the user/group can list files in this directory, they
+ can also read symlinks.
+ .It Em Insert
+ the user/group can create new files in this directory.
+ .It Em Delete
+ the user/group can delete files from this directory.
+ .It Em locK
+ the user/group can do locking on files in this directory.
+ .It Em Administer
+ the user/group can change the acl and the modebits in this directory
+ .El
+ .Pp
+ There is also some named ACL that is easier to remember. Those are
+ .Ar all,
+ .Ar read,
+ .Ar write,
+ .Ar none,
+ .Ar mail.
+ All of these are quote obvoius what they do execpt the last
+ one, and you shouldn't use that one.
+ .Pp
+ There are three special groups that is good know know about:
+ .Bl -tag -width "Administer"
+ .It Em system:anyuser
+ any user of the AFS system
+ .It Em system:auth-user
+ any user the is authenticated to the cell that this directory exists.
+ Use
+ .Ic fs whatcell
+ to figure out what cell it is.
+ .It Em system:administrators
+ this is system-administrators of the cell. They can't read
+ files without with, but since the always can change the ACL
+ they can add them-self. You should trust them the are nice guys.
+ .El
+ .Pp
+ Groups and (remote)users can be created with
+ .Xr pts(1).
+
+ .Pp
+ Examples:
+ .Pp
+ .Nm fs setacl
+ \&. lha all
+ .Pp
+ .Nm fs setacl
+ \&. system:anyuser none
+
+%command listacl
+
+ List the ACL for the directory
+ .Ar dir
+ (or if its isn't specifed
+ .Pa .
+ will be used).
+
+%section bugs
+
+ Not really complete
+
+%section history
+
+ The fs command first appeared in Transarc AFS, it was
+ reimplemented and extended in arla project by a mixure of
+ people. In DCE/DFS the fs-commands name is
+ .Xr fts(1)
+ and in Coda the name is
+ .Xr cfs(1).
+
+%section see also
+
+ .Xr vos(1),
+ .Xr pts(1),
+ .Xr bos(1),
+ .Xr arlad(1)
+
+%section authors
+
+ Love Hörnquist-Åstrand <lha@stacken.kth.se>,
+ \&...
+# If you feel that you should be here, add yourself
+
+%section description
+
+ Some of the commands can only be run by root.
diff --git a/usr.sbin/afs/src/lib/editline/ChangeLog b/usr.sbin/afs/src/lib/editline/ChangeLog
new file mode 100644
index 00000000000..3226f28b630
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/ChangeLog
@@ -0,0 +1,93 @@
+2000-03-01 Assar Westerlund <assar@sics.se>
+
+ * edit_compat.c (readline): be more liberal in what we accept from
+ el_gets. if count == 0 -> interpret it as EOF. also copy the
+ string first and then cut of the newline, it's cleaner
+
+1999-12-23 Assar Westerlund <assar@sics.se>
+
+ * editline.c (TTYinfo): add fallback if we fail to find "le" in
+ termcap.
+
+1999-08-06 Assar Westerlund <assar@sics.se>
+
+ * editline.c (TTYinfo): copy backspace string to avoid referencing
+ into a local variable.
+
+1999-08-04 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: don't run testit in `make check'
+
+1999-04-11 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: don't run testit as a check
+
+Sat Apr 10 23:01:18 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * complete.c (rl_complete_filename): return if there were no
+ matches
+
+Thu Apr 8 15:08:25 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.in: snprintf
+
+ * roken_rename.h: add snprintf, asprintf
+
+ * Makefile.am: build testit
+
+ * complete.c: nuke NEW, DISPOSE, RENEW, and COPYFROMTO macros;
+ (rl_complete): call rl_list_possib instead of doing the same
+
+ * editline.h: nuke NEW, DISPOSE, RENEW, and COPYFROMTO macros
+
+ * editline.c: nuke NEW, DISPOSE, RENEW, and COPYFROMTO macros
+
+ * sysunix.c: add some whitespace
+
+Thu Mar 18 11:22:55 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: include Makefile.am.common
+
+Tue Mar 16 17:10:34 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * editline.c: remove protos for read/write
+
+Sat Mar 13 22:23:22 1999 Assar Westerlund <assar@sics.se>
+
+ * <roken.h>: add
+
+Sun Nov 22 10:40:28 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (WFLAGS): set
+
+Tue Sep 29 02:09:15 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (LIB_DEPS): add LIB_tgetent
+
+Thu Jul 2 15:10:08 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
+
+ * edit_compat.c: support for newer libedit
+
+Tue Jun 30 17:18:09 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (distclean): don't remove roken_rename.h
+
+Fri May 29 19:03:38 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (strdup.c): remove dependency
+
+Mon May 25 05:25:16 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): try to remove shared library debris
+
+Sun Apr 19 09:53:46 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add symlink magic for linux
+
+Sat Feb 7 07:24:30 1998 Assar Westerlund <assar@sics.se>
+
+ * editline.h: add prototypes
+
+Tue Feb 3 10:24:22 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * editline.c: If read returns EINTR, try again.
diff --git a/usr.sbin/afs/src/lib/editline/Makefile.in b/usr.sbin/afs/src/lib/editline/Makefile.in
new file mode 100644
index 00000000000..054469ff6d3
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/Makefile.in
@@ -0,0 +1,86 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:56 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)editline
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+SOURCES = edit_compat.c editline.c complete.c sysunix.c
+
+OBJECTS = @editline_OBJS@
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) -I$(srcdir)/../roken $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir); \
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB); \
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *.tab.c *~
+
+realclean: distclean
+ rm -f TAGS
+
+dist: $(DISTFILES)
+ for file in $(DISTFILES); do \
+ ln $$file ../`cat ../.fname`/lib \
+ || cp -p $$file ../`cat ../.fname`/lib; \
+ done
+
+$(LIBNAME).a: $(OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(OBJECTS)
+ -$(RANLIB) $@
+
+
+#$(LIBNAME).$(SHLIBEXT): $(OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(OBJECTS)
+
+$(OBJECTS): ../../include/config.h
diff --git a/usr.sbin/afs/src/lib/editline/README b/usr.sbin/afs/src/lib/editline/README
new file mode 100644
index 00000000000..829db995b8b
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/README
@@ -0,0 +1,45 @@
+$Revision: 1.1 $
+
+This is a line-editing library. It can be linked into almost any
+program to provide command-line editing and recall.
+
+It is call-compatible with the FSF readline library, but it is a
+fraction of the size (and offers fewer features). It does not use
+standard I/O. It is distributed under a "C News-like" copyright.
+
+Configuration is done in the Makefile. Type "make testit" to get
+a small slow shell for testing.
+
+An earlier version was distributed with Byron's rc. Principal
+changes over that version include:
+ Faster.
+ Is eight-bit clean (thanks to brendan@cs.widener.edu)
+ Written in K&R C, but ANSI compliant (gcc all warnings)
+ Propagates EOF properly; rc trip test now passes
+ Doesn't need or use or provide memmove.
+ More robust
+ Calling sequence changed to be compatible with readline.
+ Test program, new manpage, better configuration
+ More system-independant; includes Unix and OS-9 support.
+
+Enjoy,
+ Rich $alz
+ <rsalz@osf.org>
+
+ Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
+
+ This software is not subject to any license of the American Telephone
+ and Telegraph Company or of the Regents of the University of California.
+
+ Permission is granted to anyone to use this software for any purpose on
+ any computer system, and to alter it and redistribute it freely, subject
+ to the following restrictions:
+ 1. The authors are not responsible for the consequences of use of this
+ software, no matter how awful, even if they arise from flaws in it.
+ 2. The origin of this software must not be misrepresented, either by
+ explicit claim or by omission. Since few users ever read sources,
+ credits must appear in the documentation.
+ 3. Altered versions must be plainly marked as such, and must not be
+ misrepresented as being the original software. Since few users
+ ever read sources, credits must appear in the documentation.
+ 4. This notice may not be removed or altered.
diff --git a/usr.sbin/afs/src/lib/editline/complete.c b/usr.sbin/afs/src/lib/editline/complete.c
new file mode 100644
index 00000000000..90289198ecc
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/complete.c
@@ -0,0 +1,243 @@
+/* Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ * 1. The authors are not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ * 4. This notice may not be removed or altered.
+ */
+
+/*
+** History and file completion functions for editline library.
+*/
+#include <config.h>
+#include "editline.h"
+
+RCSID("$Id: complete.c,v 1.1 2000/09/11 14:40:56 art Exp $");
+
+/*
+** strcmp-like sorting predicate for qsort.
+*/
+static int
+compare(const void *p1, const void *p2)
+{
+ const char **v1;
+ const char **v2;
+
+ v1 = (const char **)p1;
+ v2 = (const char **)p2;
+ return strcmp(*v1, *v2);
+}
+
+/*
+** Fill in *avp with an array of names that match file, up to its length.
+** Ignore . and .. .
+*/
+static int
+FindMatches(char *dir, char *file, char ***avp)
+{
+ char **av;
+ char **new;
+ char *p;
+ DIR *dp;
+ DIRENTRY *ep;
+ size_t ac;
+ size_t len;
+
+ if ((dp = opendir(dir)) == NULL)
+ return 0;
+
+ av = NULL;
+ ac = 0;
+ len = strlen(file);
+ while ((ep = readdir(dp)) != NULL) {
+ p = ep->d_name;
+ if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
+ continue;
+ if (len && strncmp(p, file, len) != 0)
+ continue;
+
+ if ((ac % MEM_INC) == 0) {
+ if ((new = malloc(sizeof(char*) * (ac + MEM_INC))) == NULL)
+ break;
+ if (ac) {
+ memcpy(new, av, ac * sizeof (char **));
+ free(av);
+ }
+ *avp = av = new;
+ }
+
+ if ((av[ac] = strdup(p)) == NULL) {
+ if (ac == 0)
+ free(av);
+ break;
+ }
+ ac++;
+ }
+
+ /* Clean up and return. */
+ (void)closedir(dp);
+ if (ac)
+ qsort(av, ac, sizeof (char **), compare);
+ return ac;
+}
+
+/*
+** Split a pathname into allocated directory and trailing filename parts.
+*/
+static int SplitPath(char *path, char **dirpart, char **filepart)
+{
+ static char DOT[] = ".";
+ char *dpart;
+ char *fpart;
+
+ if ((fpart = strrchr(path, '/')) == NULL) {
+ if ((dpart = strdup(DOT)) == NULL)
+ return -1;
+ if ((fpart = strdup(path)) == NULL) {
+ free(dpart);
+ return -1;
+ }
+ }
+ else {
+ if ((dpart = strdup(path)) == NULL)
+ return -1;
+ dpart[fpart - path] = '\0';
+ if ((fpart = strdup(++fpart)) == NULL) {
+ free(dpart);
+ return -1;
+ }
+ }
+ *dirpart = dpart;
+ *filepart = fpart;
+ return 0;
+}
+
+/*
+** Attempt to complete the pathname, returning an allocated copy.
+** Fill in *unique if we completed it, or set it to 0 if ambiguous.
+*/
+
+static char *
+rl_complete_filename(char *pathname, int *unique)
+{
+ char **av;
+ char *new;
+ char *p;
+ size_t ac;
+ size_t end;
+ size_t i;
+ size_t j;
+ size_t len;
+ char *s;
+
+ ac = rl_list_possib(pathname, &av);
+ if(ac == 0)
+ return NULL;
+
+ s = strrchr(pathname, '/');
+ if(s == NULL)
+ len = strlen(pathname);
+ else
+ len = strlen(s + 1);
+
+ p = NULL;
+ if (ac == 1) {
+ /* Exactly one match -- finish it off. */
+ *unique = 1;
+ j = strlen(av[0]) - len + 2;
+ if ((p = malloc(j + 1)) != NULL) {
+ memcpy(p, av[0] + len, j);
+ asprintf(&new, "%s%s", pathname, p);
+ if(new != NULL) {
+ rl_add_slash(new, p);
+ free(new);
+ }
+ }
+ }
+ else {
+ *unique = 0;
+ if (len) {
+ /* Find largest matching substring. */
+ for (i = len, end = strlen(av[0]); i < end; i++)
+ for (j = 1; j < ac; j++)
+ if (av[0][i] != av[j][i])
+ goto breakout;
+ breakout:
+ if (i > len) {
+ j = i - len + 1;
+ if ((p = malloc(j)) != NULL) {
+ memcpy(p, av[0] + len, j);
+ p[j - 1] = '\0';
+ }
+ }
+ }
+ }
+
+ /* Clean up and return. */
+ for (i = 0; i < ac; i++)
+ free(av[i]);
+ free(av);
+ return p;
+}
+
+static rl_complete_func_t complete_func = rl_complete_filename;
+
+char *
+rl_complete(char *pathname, int *unique)
+{
+ return (*complete_func)(pathname, unique);
+}
+
+rl_complete_func_t
+rl_set_complete_func(rl_complete_func_t func)
+{
+ rl_complete_func_t old = complete_func;
+ complete_func = func;
+ return old;
+}
+
+
+/*
+** Return all possible completions.
+*/
+static int
+rl_list_possib_filename(char *pathname, char ***avp)
+{
+ char *dir;
+ char *file;
+ int ac;
+
+ if (SplitPath(pathname, &dir, &file) < 0)
+ return 0;
+ ac = FindMatches(dir, file, avp);
+ free(dir);
+ free(file);
+ return ac;
+}
+
+static rl_list_possib_func_t list_possib_func = rl_list_possib_filename;
+
+int
+rl_list_possib(char *pathname, char ***avp)
+{
+ return (*list_possib_func)(pathname, avp);
+}
+
+rl_list_possib_func_t
+rl_set_list_possib_func(rl_list_possib_func_t func)
+{
+ rl_list_possib_func_t old = list_possib_func;
+ list_possib_func = func;
+ return old;
+}
diff --git a/usr.sbin/afs/src/lib/editline/edit_compat.c b/usr.sbin/afs/src/lib/editline/edit_compat.c
new file mode 100644
index 00000000000..c80c169c15e
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/edit_compat.c
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <histedit.h>
+
+RCSID("$Id: edit_compat.c,v 1.1 2000/09/11 14:40:56 art Exp $");
+
+void
+rl_reset_terminal(char *p)
+{
+}
+
+void
+rl_initialize()
+{
+}
+
+static const char *pr;
+static const char* ret_prompt(EditLine *e)
+{
+ return pr;
+}
+
+static History *h;
+
+#ifdef H_SETSIZE
+#define EL_INIT_FOUR 1
+#else
+#ifdef H_SETMAXSIZE
+/* backwards compatibility */
+#define H_SETSIZE H_SETMAXSIZE
+#endif
+#endif
+
+char *
+readline(const char* prompt)
+{
+ static EditLine *e;
+#ifdef H_SETSIZE
+ HistEvent ev;
+#endif
+ int count;
+ const char *str;
+
+ if(e == NULL){
+#ifdef EL_INIT_FOUR
+ e = el_init("", stdin, stdout, stderr);
+#else
+ e = el_init("", stdin, stdout);
+#endif
+ el_set(e, EL_PROMPT, ret_prompt);
+ h = history_init();
+#ifdef H_SETSIZE
+ history(h, &ev, H_SETSIZE, 25);
+#else
+ history(h, H_EVENT, 25);
+#endif
+ el_set(e, EL_HIST, history, h);
+ el_set(e, EL_EDITOR, "emacs"); /* XXX? */
+ }
+ pr = prompt ? prompt : "";
+ str = el_gets(e, &count);
+ if (str && count > 0) {
+ char *ret = strdup (str);
+
+ if (ret == NULL)
+ return NULL;
+
+ if (ret[strlen(ret) - 1] == '\n')
+ ret[strlen(ret) - 1] = '\0';
+ return ret;
+ }
+ return NULL;
+}
+
+void
+add_history(char *p)
+{
+#ifdef H_SETSIZE
+ HistEvent ev;
+ history(h, &ev, H_ENTER, p);
+#else
+ history(h, H_ENTER, p);
+#endif
+}
diff --git a/usr.sbin/afs/src/lib/editline/editline.3 b/usr.sbin/afs/src/lib/editline/editline.3
new file mode 100644
index 00000000000..db0da38b933
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/editline.3
@@ -0,0 +1,175 @@
+.\" $Revision: 1.1 $
+.TH EDITLINE 3
+.SH NAME
+editline \- command-line editing library with history
+.SH SYNOPSIS
+.nf
+.B "char *"
+.B "readline(prompt)"
+.B " char *prompt;"
+
+.B "void"
+.B "add_history(line)"
+.B " char *line;"
+.fi
+.SH DESCRIPTION
+.I Editline
+is a library that provides an line-editing interface with text recall.
+It is intended to be compatible with the
+.I readline
+library provided by the Free Software Foundation, but much smaller.
+The bulk of this manual page describes the user interface.
+.PP
+The
+.I readline
+routine returns a line of text with the trailing newline removed.
+The data is returned in a buffer allocated with
+.IR malloc (3),
+so the space should be released with
+.IR free (3)
+when the calling program is done with it.
+Before accepting input from the user, the specified
+.I prompt
+is displayed on the terminal.
+.PP
+The
+.I add_history
+routine makes a copy of the specified
+.I line
+and adds it to the internal history list.
+.SS "User Interface"
+A program that uses this library provides a simple emacs-like editing
+interface to its users.
+A line may be edited before it is sent to the calling program by typing either
+control characters or escape sequences.
+A control character, shown as a caret followed by a letter, is typed by
+holding down the ``control'' key while the letter is typed.
+For example, ``^A'' is a control-A.
+An escape sequence is entered by typing the ``escape'' key followed by one or
+more characters.
+The escape key is abbreviated as ``ESC.''
+Note that unlike control keys, case matters in escape sequences; ``ESC\ F''
+is not the same as ``ESC\ f''.
+.PP
+An editing command may be typed anywhere on the line, not just at the
+beginning.
+In addition, a return may also be typed anywhere on the line, not just at
+the end.
+.PP
+Most editing commands may be given a repeat count,
+.IR n ,
+where
+.I n
+is a number.
+To enter a repeat count, type the escape key, the number, and then
+the command to execute.
+For example, ``ESC\ 4\ ^f'' moves forward four characters.
+If a command may be given a repeat count then the text ``[n]'' is given at the
+end of its description.
+.PP
+The following control characters are accepted:
+.RS
+.nf
+.ta \w'ESC DEL 'u
+^A Move to the beginning of the line
+^B Move left (backwards) [n]
+^D Delete character [n]
+^E Move to end of line
+^F Move right (forwards) [n]
+^G Ring the bell
+^H Delete character before cursor (backspace key) [n]
+^I Complete filename (tab key); see below
+^J Done with line (return key)
+^K Kill to end of line (or column [n])
+^L Redisplay line
+^M Done with line (alternate return key)
+^N Get next line from history [n]
+^P Get previous line from history [n]
+^R Search backward (forward if [n]) through history for text;
+\& must start line if text begins with an uparrow
+^T Transpose characters
+^V Insert next character, even if it is an edit command
+^W Wipe to the mark
+^X^X Exchange current location and mark
+^Y Yank back last killed text
+^[ Start an escape sequence (escape key)
+^]c Move forward to next character ``c''
+^? Delete character before cursor (delete key) [n]
+.fi
+.RE
+.PP
+The following escape sequences are provided.
+.RS
+.nf
+.ta \w'ESC DEL 'u
+ESC\ ^H Delete previous word (backspace key) [n]
+ESC\ DEL Delete previous word (delete key) [n]
+ESC\ SP Set the mark (space key); see ^X^X and ^Y above
+ESC\ \. Get the last (or [n]'th) word from previous line
+ESC\ ? Show possible completions; see below
+ESC\ < Move to start of history
+ESC\ > Move to end of history
+ESC\ b Move backward a word [n]
+ESC\ d Delete word under cursor [n]
+ESC\ f Move forward a word [n]
+ESC\ l Make word lowercase [n]
+ESC\ u Make word uppercase [n]
+ESC\ y Yank back last killed text
+ESC\ v Show library version
+ESC\ w Make area up to mark yankable
+ESC\ nn Set repeat count to the number nn
+ESC\ C Read from environment variable ``_C_'', where C is
+\& an uppercase letter
+.fi
+.RE
+.PP
+The
+.I editline
+library has a small macro facility.
+If you type the escape key followed by an uppercase letter,
+.IR C ,
+then the contents of the environment variable
+.I _C_
+are read in as if you had typed them at the keyboard.
+For example, if the variable
+.I _L_
+contains the following:
+.RS
+^A^Kecho '^V^[[H^V^[[2J'^M
+.RE
+Then typing ``ESC L'' will move to the beginning of the line, kill the
+entire line, enter the echo command needed to clear the terminal (if your
+terminal is like a VT-100), and send the line back to the shell.
+.PP
+The
+.I editline
+library also does filename completion.
+Suppose the root directory has the following files in it:
+.RS
+.nf
+.ta \w'core 'u
+bin vmunix
+core vmunix.old
+.fi
+.RE
+If you type ``rm\ /v'' and then the tab key.
+.I Editline
+will then finish off as much of the name as possible by adding ``munix''.
+Because the name is not unique, it will then beep.
+If you type the escape key and a question mark, it will display the
+two choices.
+If you then type a period and a tab, the library will finish off the filename
+for you:
+.RS
+.nf
+.RI "rm /v[TAB]" munix .TAB old
+.fi
+.RE
+The tab key is shown by ``[TAB]'' and the automatically-entered text
+is shown in italics.
+.SH "BUGS AND LIMITATIONS"
+Cannot handle lines more than 80 columns.
+.SH AUTHORS
+Simmule R. Turner <uunet.uu.net!capitol!sysgo!simmy>
+and Rich $alz <rsalz@osf.org>.
+Original manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>.
diff --git a/usr.sbin/afs/src/lib/editline/editline.c b/usr.sbin/afs/src/lib/editline/editline.c
new file mode 100644
index 00000000000..85d951ae3db
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/editline.c
@@ -0,0 +1,1376 @@
+/* Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ * 1. The authors are not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ * 4. This notice may not be removed or altered.
+ */
+
+/*
+** Main editing routines for editline library.
+*/
+#include <config.h>
+#include "editline.h"
+#include <ctype.h>
+#include <errno.h>
+
+RCSID("$Id: editline.c,v 1.1 2000/09/11 14:40:56 art Exp $");
+
+/*
+** Manifest constants.
+*/
+#define SCREEN_WIDTH 80
+#define SCREEN_ROWS 24
+#define NO_ARG (-1)
+#define DEL 127
+#define CTL(x) ((x) & 0x1F)
+#define ISCTL(x) ((x) && (x) < ' ')
+#define UNCTL(x) ((x) + 64)
+#define META(x) ((x) | 0x80)
+#define ISMETA(x) ((x) & 0x80)
+#define UNMETA(x) ((x) & 0x7F)
+#if !defined(HIST_SIZE)
+#define HIST_SIZE 20
+#endif /* !defined(HIST_SIZE) */
+
+/*
+** Command status codes.
+*/
+typedef enum _STATUS {
+ CSdone, CSeof, CSmove, CSdispatch, CSstay
+} STATUS;
+
+/*
+** The type of case-changing to perform.
+*/
+typedef enum _CASE {
+ TOupper, TOlower
+} CASE;
+
+/*
+** Key to command mapping.
+*/
+typedef struct _KEYMAP {
+ unsigned char Key;
+ STATUS (*Function)();
+} KEYMAP;
+
+/*
+** Command history structure.
+*/
+typedef struct _HISTORY {
+ int Size;
+ int Pos;
+ unsigned char *Lines[HIST_SIZE];
+} HISTORY;
+
+/*
+** Globals.
+*/
+int rl_eof;
+int rl_erase;
+int rl_intr;
+int rl_kill;
+
+static unsigned char NIL[] = "";
+static const unsigned char *Input = NIL;
+static unsigned char *Line;
+static const char *Prompt;
+static unsigned char *Yanked;
+static char *Screen;
+static char NEWLINE[]= CRLF;
+static HISTORY H;
+int rl_quit;
+static int Repeat;
+static int End;
+static int Mark;
+static int OldPoint;
+static int Point;
+static int PushBack;
+static int Pushed;
+static KEYMAP Map[33];
+static KEYMAP MetaMap[16];
+static size_t Length;
+static size_t ScreenCount;
+static size_t ScreenSize;
+static char *backspace;
+static int TTYwidth;
+static int TTYrows;
+
+/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */
+int rl_meta_chars = 1;
+
+/*
+** Declarations.
+*/
+static unsigned char *editinput(void);
+char *tgetstr(const char*, char**);
+int tgetent(char*, const char*);
+int tgetnum(const char*);
+
+/*
+** TTY input/output functions.
+*/
+
+static void
+TTYflush()
+{
+ if (ScreenCount) {
+ write(1, Screen, ScreenCount);
+ ScreenCount = 0;
+ }
+}
+
+static void
+TTYput(unsigned char c)
+{
+ Screen[ScreenCount] = c;
+ if (++ScreenCount >= ScreenSize - 1) {
+ ScreenSize += SCREEN_INC;
+ Screen = realloc(Screen, ScreenSize);
+ }
+}
+
+static void
+TTYputs(const char *p)
+{
+ while (*p)
+ TTYput(*p++);
+}
+
+static void
+TTYshow(unsigned char c)
+{
+ if (c == DEL) {
+ TTYput('^');
+ TTYput('?');
+ }
+ else if (ISCTL(c)) {
+ TTYput('^');
+ TTYput(UNCTL(c));
+ }
+ else if (rl_meta_chars && ISMETA(c)) {
+ TTYput('M');
+ TTYput('-');
+ TTYput(UNMETA(c));
+ }
+ else
+ TTYput(c);
+}
+
+static void
+TTYstring(unsigned char *p)
+{
+ while (*p)
+ TTYshow(*p++);
+}
+
+static int
+TTYget()
+{
+ char c;
+ int e;
+
+ TTYflush();
+ if (Pushed) {
+ Pushed = 0;
+ return PushBack;
+ }
+ if (*Input)
+ return *Input++;
+ do {
+ e = read(0, &c, 1);
+ } while(e < 0 && errno == EINTR);
+ if(e == 1)
+ return c;
+ return EOF;
+}
+
+static void
+TTYback(void)
+{
+ if (backspace)
+ TTYputs(backspace);
+ else
+ TTYput('\b');
+}
+
+static void
+TTYbackn(int n)
+{
+ while (--n >= 0)
+ TTYback();
+}
+
+static void
+TTYinfo()
+{
+ static int init;
+ char *term;
+ char buff[2048];
+ char *bp;
+ char *tmp;
+#if defined(TIOCGWINSZ)
+ struct winsize W;
+#endif /* defined(TIOCGWINSZ) */
+
+ if (init) {
+#if defined(TIOCGWINSZ)
+ /* Perhaps we got resized. */
+ if (ioctl(0, TIOCGWINSZ, &W) >= 0
+ && W.ws_col > 0 && W.ws_row > 0) {
+ TTYwidth = (int)W.ws_col;
+ TTYrows = (int)W.ws_row;
+ }
+#endif /* defined(TIOCGWINSZ) */
+ return;
+ }
+ init++;
+
+ TTYwidth = TTYrows = 0;
+ bp = &buff[0];
+ if ((term = getenv("TERM")) == NULL)
+ term = "dumb";
+ if (tgetent(buff, term) < 0) {
+ TTYwidth = SCREEN_WIDTH;
+ TTYrows = SCREEN_ROWS;
+ return;
+ }
+ tmp = tgetstr("le", &bp);
+ if (tmp != NULL)
+ backspace = strdup(tmp);
+ else
+ backspace = "\b";
+ TTYwidth = tgetnum("co");
+ TTYrows = tgetnum("li");
+
+#if defined(TIOCGWINSZ)
+ if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
+ TTYwidth = (int)W.ws_col;
+ TTYrows = (int)W.ws_row;
+ }
+#endif /* defined(TIOCGWINSZ) */
+
+ if (TTYwidth <= 0 || TTYrows <= 0) {
+ TTYwidth = SCREEN_WIDTH;
+ TTYrows = SCREEN_ROWS;
+ }
+}
+
+
+/*
+** Print an array of words in columns.
+*/
+static void
+columns(int ac, unsigned char **av)
+{
+ unsigned char *p;
+ int i;
+ int j;
+ int k;
+ int len;
+ int skip;
+ int longest;
+ int cols;
+
+ /* Find longest name, determine column count from that. */
+ for (longest = 0, i = 0; i < ac; i++)
+ if ((j = strlen((char *)av[i])) > longest)
+ longest = j;
+ cols = TTYwidth / (longest + 3);
+
+ TTYputs(NEWLINE);
+ for (skip = ac / cols + 1, i = 0; i < skip; i++) {
+ for (j = i; j < ac; j += skip) {
+ for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++)
+ TTYput(*p);
+ if (j + skip < ac)
+ while (++len < longest + 3)
+ TTYput(' ');
+ }
+ TTYputs(NEWLINE);
+ }
+}
+
+static void
+reposition()
+{
+ int i;
+ unsigned char *p;
+
+ TTYput('\r');
+ TTYputs(Prompt);
+ for (i = Point, p = Line; --i >= 0; p++)
+ TTYshow(*p);
+}
+
+static void
+left(STATUS Change)
+{
+ TTYback();
+ if (Point) {
+ if (ISCTL(Line[Point - 1]))
+ TTYback();
+ else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
+ TTYback();
+ TTYback();
+ }
+ }
+ if (Change == CSmove)
+ Point--;
+}
+
+static void
+right(STATUS Change)
+{
+ TTYshow(Line[Point]);
+ if (Change == CSmove)
+ Point++;
+}
+
+static STATUS
+ring_bell()
+{
+ TTYput('\07');
+ TTYflush();
+ return CSstay;
+}
+
+static STATUS
+do_macro(unsigned char c)
+{
+ unsigned char name[4];
+
+ name[0] = '_';
+ name[1] = c;
+ name[2] = '_';
+ name[3] = '\0';
+
+ if ((Input = (unsigned char *)getenv((char *)name)) == NULL) {
+ Input = NIL;
+ return ring_bell();
+ }
+ return CSstay;
+}
+
+static STATUS
+do_forward(STATUS move)
+{
+ int i;
+ unsigned char *p;
+
+ i = 0;
+ do {
+ p = &Line[Point];
+ for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++)
+ if (move == CSmove)
+ right(CSstay);
+
+ for (; Point < End && isalnum(*p); Point++, p++)
+ if (move == CSmove)
+ right(CSstay);
+
+ if (Point == End)
+ break;
+ } while (++i < Repeat);
+
+ return CSstay;
+}
+
+static STATUS
+do_case(CASE type)
+{
+ int i;
+ int end;
+ int count;
+ unsigned char *p;
+
+ do_forward(CSstay);
+ if (OldPoint != Point) {
+ if ((count = Point - OldPoint) < 0)
+ count = -count;
+ Point = OldPoint;
+ if ((end = Point + count) > End)
+ end = End;
+ for (i = Point, p = &Line[i]; i < end; i++, p++) {
+ if (type == TOupper) {
+ if (islower(*p))
+ *p = toupper(*p);
+ }
+ else if (isupper(*p))
+ *p = tolower(*p);
+ right(CSmove);
+ }
+ }
+ return CSstay;
+}
+
+static STATUS
+case_down_word()
+{
+ return do_case(TOlower);
+}
+
+static STATUS
+case_up_word()
+{
+ return do_case(TOupper);
+}
+
+static void
+ceol()
+{
+ int extras;
+ int i;
+ unsigned char *p;
+
+ for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {
+ TTYput(' ');
+ if (ISCTL(*p)) {
+ TTYput(' ');
+ extras++;
+ }
+ else if (rl_meta_chars && ISMETA(*p)) {
+ TTYput(' ');
+ TTYput(' ');
+ extras += 2;
+ }
+ }
+
+ for (i += extras; i > Point; i--)
+ TTYback();
+}
+
+static void
+clear_line()
+{
+ Point = -strlen(Prompt);
+ TTYput('\r');
+ ceol();
+ Point = 0;
+ End = 0;
+ Line[0] = '\0';
+}
+
+static STATUS
+insert_string(unsigned char *p)
+{
+ size_t len;
+ int i;
+ unsigned char *new;
+ unsigned char *q;
+
+ len = strlen((char *)p);
+ if (End + len >= Length) {
+ if ((new = malloc(sizeof(unsigned char) * (Length + len + MEM_INC))) == NULL)
+ return CSstay;
+ if (Length) {
+ memcpy(new, Line, Length);
+ free(Line);
+ }
+ Line = new;
+ Length += len + MEM_INC;
+ }
+
+ for (q = &Line[Point], i = End - Point; --i >= 0; )
+ q[len + i] = q[i];
+ memcpy(&Line[Point], p, len);
+ End += len;
+ Line[End] = '\0';
+ TTYstring(&Line[Point]);
+ Point += len;
+
+ return Point == End ? CSstay : CSmove;
+}
+
+
+static unsigned char *
+next_hist()
+{
+ return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
+}
+
+static unsigned char *
+prev_hist()
+{
+ return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
+}
+
+static STATUS
+do_insert_hist(unsigned char *p)
+{
+ if (p == NULL)
+ return ring_bell();
+ Point = 0;
+ reposition();
+ ceol();
+ End = 0;
+ return insert_string(p);
+}
+
+static STATUS
+do_hist(unsigned char *(*move)())
+{
+ unsigned char *p;
+ int i;
+
+ i = 0;
+ do {
+ if ((p = (*move)()) == NULL)
+ return ring_bell();
+ } while (++i < Repeat);
+ return do_insert_hist(p);
+}
+
+static STATUS
+h_next()
+{
+ return do_hist(next_hist);
+}
+
+static STATUS
+h_prev()
+{
+ return do_hist(prev_hist);
+}
+
+static STATUS
+h_first()
+{
+ return do_insert_hist(H.Lines[H.Pos = 0]);
+}
+
+static STATUS
+h_last()
+{
+ return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
+}
+
+/*
+** Return zero if pat appears as a substring in text.
+*/
+static int
+substrcmp(char *text, char *pat, int len)
+{
+ unsigned char c;
+
+ if ((c = *pat) == '\0')
+ return *text == '\0';
+ for ( ; *text; text++)
+ if (*text == c && strncmp(text, pat, len) == 0)
+ return 0;
+ return 1;
+}
+
+static unsigned char *
+search_hist(unsigned char *search, unsigned char *(*move)())
+{
+ static unsigned char *old_search;
+ int len;
+ int pos;
+ int (*match)();
+ char *pat;
+
+ /* Save or get remembered search pattern. */
+ if (search && *search) {
+ if (old_search)
+ free(old_search);
+ old_search = (unsigned char *)strdup((char *)search);
+ }
+ else {
+ if (old_search == NULL || *old_search == '\0')
+ return NULL;
+ search = old_search;
+ }
+
+ /* Set up pattern-finder. */
+ if (*search == '^') {
+ match = strncmp;
+ pat = (char *)(search + 1);
+ }
+ else {
+ match = substrcmp;
+ pat = (char *)search;
+ }
+ len = strlen(pat);
+
+ for (pos = H.Pos; (*move)() != NULL; )
+ if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0)
+ return H.Lines[H.Pos];
+ H.Pos = pos;
+ return NULL;
+}
+
+static STATUS
+h_search()
+{
+ static int Searching;
+ const char *old_prompt;
+ unsigned char *(*move)();
+ unsigned char *p;
+
+ if (Searching)
+ return ring_bell();
+ Searching = 1;
+
+ clear_line();
+ old_prompt = Prompt;
+ Prompt = "Search: ";
+ TTYputs(Prompt);
+ move = Repeat == NO_ARG ? prev_hist : next_hist;
+ p = search_hist(editinput(), move);
+ clear_line();
+ Prompt = old_prompt;
+ TTYputs(Prompt);
+
+ Searching = 0;
+ return do_insert_hist(p);
+}
+
+static STATUS
+fd_char()
+{
+ int i;
+
+ i = 0;
+ do {
+ if (Point >= End)
+ break;
+ right(CSmove);
+ } while (++i < Repeat);
+ return CSstay;
+}
+
+static void
+save_yank(int begin, int i)
+{
+ if (Yanked) {
+ free(Yanked);
+ Yanked = NULL;
+ }
+
+ if (i < 1)
+ return;
+
+ if ((Yanked = malloc(sizeof(unsigned char) * (i + 1))) != NULL) {
+ memcpy(Yanked, &Line[begin], i);
+ Yanked[i+1] = '\0';
+ }
+}
+
+static STATUS
+delete_string(int count)
+{
+ int i;
+ unsigned char *p;
+
+ if (count <= 0 || End == Point)
+ return ring_bell();
+
+ if (count == 1 && Point == End - 1) {
+ /* Optimize common case of delete at end of line. */
+ End--;
+ p = &Line[Point];
+ i = 1;
+ TTYput(' ');
+ if (ISCTL(*p)) {
+ i = 2;
+ TTYput(' ');
+ }
+ else if (rl_meta_chars && ISMETA(*p)) {
+ i = 3;
+ TTYput(' ');
+ TTYput(' ');
+ }
+ TTYbackn(i);
+ *p = '\0';
+ return CSmove;
+ }
+ if (Point + count > End && (count = End - Point) <= 0)
+ return CSstay;
+
+ if (count > 1)
+ save_yank(Point, count);
+
+ for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++)
+ p[0] = p[count];
+ ceol();
+ End -= count;
+ TTYstring(&Line[Point]);
+ return CSmove;
+}
+
+static STATUS
+bk_char()
+{
+ int i;
+
+ i = 0;
+ do {
+ if (Point == 0)
+ break;
+ left(CSmove);
+ } while (++i < Repeat);
+
+ return CSstay;
+}
+
+static STATUS
+bk_del_char()
+{
+ int i;
+
+ i = 0;
+ do {
+ if (Point == 0)
+ break;
+ left(CSmove);
+ } while (++i < Repeat);
+
+ return delete_string(i);
+}
+
+static STATUS
+redisplay()
+{
+ TTYputs(NEWLINE);
+ TTYputs(Prompt);
+ TTYstring(Line);
+ return CSmove;
+}
+
+static STATUS
+kill_line()
+{
+ int i;
+
+ if (Repeat != NO_ARG) {
+ if (Repeat < Point) {
+ i = Point;
+ Point = Repeat;
+ reposition();
+ delete_string(i - Point);
+ }
+ else if (Repeat > Point) {
+ right(CSmove);
+ delete_string(Repeat - Point - 1);
+ }
+ return CSmove;
+ }
+
+ save_yank(Point, End - Point);
+ Line[Point] = '\0';
+ ceol();
+ End = Point;
+ return CSstay;
+}
+
+static STATUS
+insert_char(int c)
+{
+ STATUS s;
+ unsigned char buff[2];
+ unsigned char *p;
+ unsigned char *q;
+ int i;
+
+ if (Repeat == NO_ARG || Repeat < 2) {
+ buff[0] = c;
+ buff[1] = '\0';
+ return insert_string(buff);
+ }
+
+ if ((p = malloc(Repeat + 1)) == NULL)
+ return CSstay;
+ for (i = Repeat, q = p; --i >= 0; )
+ *q++ = c;
+ *q = '\0';
+ Repeat = 0;
+ s = insert_string(p);
+ free(p);
+ return s;
+}
+
+static STATUS
+meta()
+{
+ unsigned int c;
+ KEYMAP *kp;
+
+ if ((c = TTYget()) == EOF)
+ return CSeof;
+ /* Also include VT-100 arrows. */
+ if (c == '[' || c == 'O')
+ switch (c = TTYget()) {
+ default: return ring_bell();
+ case EOF: return CSeof;
+ case 'A': return h_prev();
+ case 'B': return h_next();
+ case 'C': return fd_char();
+ case 'D': return bk_char();
+ }
+
+ if (isdigit(c)) {
+ for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); )
+ Repeat = Repeat * 10 + c - '0';
+ Pushed = 1;
+ PushBack = c;
+ return CSstay;
+ }
+
+ if (isupper(c))
+ return do_macro(c);
+ for (OldPoint = Point, kp = MetaMap; kp->Function; kp++)
+ if (kp->Key == c)
+ return (*kp->Function)();
+
+ return ring_bell();
+}
+
+static STATUS
+emacs(unsigned int c)
+{
+ STATUS s;
+ KEYMAP *kp;
+
+ if (ISMETA(c)) {
+ Pushed = 1;
+ PushBack = UNMETA(c);
+ return meta();
+ }
+ for (kp = Map; kp->Function; kp++)
+ if (kp->Key == c)
+ break;
+ s = kp->Function ? (*kp->Function)() : insert_char((int)c);
+ if (!Pushed)
+ /* No pushback means no repeat count; hacky, but true. */
+ Repeat = NO_ARG;
+ return s;
+}
+
+static STATUS
+TTYspecial(unsigned int c)
+{
+ if (ISMETA(c))
+ return CSdispatch;
+
+ if (c == rl_erase || c == DEL)
+ return bk_del_char();
+ if (c == rl_kill) {
+ if (Point != 0) {
+ Point = 0;
+ reposition();
+ }
+ Repeat = NO_ARG;
+ return kill_line();
+ }
+ if (c == rl_intr || c == rl_quit) {
+ Point = End = 0;
+ Line[0] = '\0';
+ return redisplay();
+ }
+ if (c == rl_eof && Point == 0 && End == 0)
+ return CSeof;
+
+ return CSdispatch;
+}
+
+static unsigned char *
+editinput()
+{
+ unsigned int c;
+
+ Repeat = NO_ARG;
+ OldPoint = Point = Mark = End = 0;
+ Line[0] = '\0';
+
+ while ((c = TTYget()) != EOF)
+ switch (TTYspecial(c)) {
+ case CSdone:
+ return Line;
+ case CSeof:
+ return NULL;
+ case CSmove:
+ reposition();
+ break;
+ case CSdispatch:
+ switch (emacs(c)) {
+ case CSdone:
+ return Line;
+ case CSeof:
+ return NULL;
+ case CSmove:
+ reposition();
+ break;
+ case CSdispatch:
+ case CSstay:
+ break;
+ }
+ break;
+ case CSstay:
+ break;
+ }
+ return NULL;
+}
+
+static void
+hist_add(unsigned char *p)
+{
+ int i;
+
+ if ((p = (unsigned char *)strdup((char *)p)) == NULL)
+ return;
+ if (H.Size < HIST_SIZE)
+ H.Lines[H.Size++] = p;
+ else {
+ free(H.Lines[0]);
+ for (i = 0; i < HIST_SIZE - 1; i++)
+ H.Lines[i] = H.Lines[i + 1];
+ H.Lines[i] = p;
+ }
+ H.Pos = H.Size - 1;
+}
+
+/*
+** For compatibility with FSF readline.
+*/
+/* ARGSUSED0 */
+void
+rl_reset_terminal(char *p)
+{
+}
+
+void
+rl_initialize(void)
+{
+}
+
+char *
+readline(const char* prompt)
+{
+ unsigned char *line;
+
+ if (Line == NULL) {
+ Length = MEM_INC;
+ if ((Line = malloc(Length)) == NULL)
+ return NULL;
+ }
+
+ TTYinfo();
+ rl_ttyset(0);
+ hist_add(NIL);
+ ScreenSize = SCREEN_INC;
+ Screen = malloc(ScreenSize);
+ Prompt = prompt ? prompt : (char *)NIL;
+ TTYputs(Prompt);
+ if ((line = editinput()) != NULL) {
+ line = (unsigned char *)strdup((char *)line);
+ TTYputs(NEWLINE);
+ TTYflush();
+ }
+ rl_ttyset(1);
+ free(Screen);
+ free(H.Lines[--H.Size]);
+ return (char *)line;
+}
+
+void
+add_history(char *p)
+{
+ if (p == NULL || *p == '\0')
+ return;
+
+#if defined(UNIQUE_HISTORY)
+ if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0)
+ return;
+#endif /* defined(UNIQUE_HISTORY) */
+ hist_add((unsigned char *)p);
+}
+
+
+static STATUS
+beg_line()
+{
+ if (Point) {
+ Point = 0;
+ return CSmove;
+ }
+ return CSstay;
+}
+
+static STATUS
+del_char()
+{
+ return delete_string(Repeat == NO_ARG ? 1 : Repeat);
+}
+
+static STATUS
+end_line()
+{
+ if (Point != End) {
+ Point = End;
+ return CSmove;
+ }
+ return CSstay;
+}
+
+/*
+** Move back to the beginning of the current word and return an
+** allocated copy of it.
+*/
+static unsigned char *
+find_word()
+{
+ static char SEPS[] = "#;&|^$=`'{}()<>\n\t ";
+ unsigned char *p;
+ unsigned char *new;
+ size_t len;
+
+ for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--)
+ continue;
+ len = Point - (p - Line) + 1;
+ if ((new = malloc(len)) == NULL)
+ return NULL;
+ memcpy(new, p, len);
+ new[len - 1] = '\0';
+ return new;
+}
+
+static STATUS
+c_complete()
+{
+ unsigned char *p;
+ unsigned char *word;
+ int unique;
+ STATUS s;
+
+ word = find_word();
+ p = (unsigned char *)rl_complete((char *)word, &unique);
+ if (word)
+ free(word);
+ if (p && *p) {
+ s = insert_string(p);
+ if (!unique)
+ ring_bell();
+ free(p);
+ return s;
+ }
+ return ring_bell();
+}
+
+static STATUS
+c_possible()
+{
+ unsigned char **av;
+ unsigned char *word;
+ int ac;
+
+ word = find_word();
+ ac = rl_list_possib((char *)word, (char ***)&av);
+ if (word)
+ free(word);
+ if (ac) {
+ columns(ac, av);
+ while (--ac >= 0)
+ free(av[ac]);
+ free(av);
+ return CSmove;
+ }
+ return ring_bell();
+}
+
+static STATUS
+accept_line()
+{
+ Line[End] = '\0';
+ return CSdone;
+}
+
+static STATUS
+transpose()
+{
+ unsigned char c;
+
+ if (Point) {
+ if (Point == End)
+ left(CSmove);
+ c = Line[Point - 1];
+ left(CSstay);
+ Line[Point - 1] = Line[Point];
+ TTYshow(Line[Point - 1]);
+ Line[Point++] = c;
+ TTYshow(c);
+ }
+ return CSstay;
+}
+
+static STATUS
+quote()
+{
+ unsigned int c;
+
+ return (c = TTYget()) == EOF ? CSeof : insert_char((int)c);
+}
+
+static STATUS
+wipe()
+{
+ int i;
+
+ if (Mark > End)
+ return ring_bell();
+
+ if (Point > Mark) {
+ i = Point;
+ Point = Mark;
+ Mark = i;
+ reposition();
+ }
+
+ return delete_string(Mark - Point);
+}
+
+static STATUS
+mk_set()
+{
+ Mark = Point;
+ return CSstay;
+}
+
+static STATUS
+exchange()
+{
+ unsigned int c;
+
+ if ((c = TTYget()) != CTL('X'))
+ return c == EOF ? CSeof : ring_bell();
+
+ if ((c = Mark) <= End) {
+ Mark = Point;
+ Point = c;
+ return CSmove;
+ }
+ return CSstay;
+}
+
+static STATUS
+yank()
+{
+ if (Yanked && *Yanked)
+ return insert_string(Yanked);
+ return CSstay;
+}
+
+static STATUS
+copy_region()
+{
+ if (Mark > End)
+ return ring_bell();
+
+ if (Point > Mark)
+ save_yank(Mark, Point - Mark);
+ else
+ save_yank(Point, Mark - Point);
+
+ return CSstay;
+}
+
+static STATUS
+move_to_char()
+{
+ unsigned int c;
+ int i;
+ unsigned char *p;
+
+ if ((c = TTYget()) == EOF)
+ return CSeof;
+ for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
+ if (*p == c) {
+ Point = i;
+ return CSmove;
+ }
+ return CSstay;
+}
+
+static STATUS
+fd_word()
+{
+ return do_forward(CSmove);
+}
+
+static STATUS
+fd_kill_word()
+{
+ int i;
+
+ do_forward(CSstay);
+ if (OldPoint != Point) {
+ i = Point - OldPoint;
+ Point = OldPoint;
+ return delete_string(i);
+ }
+ return CSstay;
+}
+
+static STATUS
+bk_word()
+{
+ int i;
+ unsigned char *p;
+
+ i = 0;
+ do {
+ for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
+ left(CSmove);
+
+ for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--)
+ left(CSmove);
+
+ if (Point == 0)
+ break;
+ } while (++i < Repeat);
+
+ return CSstay;
+}
+
+static STATUS
+bk_kill_word()
+{
+ bk_word();
+ if (OldPoint != Point)
+ return delete_string(OldPoint - Point);
+ return CSstay;
+}
+
+static int
+argify(unsigned char *line, unsigned char ***avp)
+{
+ unsigned char *c;
+ unsigned char **p;
+ unsigned char **new;
+ int ac;
+ int i;
+
+ i = MEM_INC;
+ if ((*avp = p = malloc(sizeof(unsigned char*) * i))== NULL)
+ return 0;
+
+ for (c = line; isspace(*c); c++)
+ continue;
+ if (*c == '\n' || *c == '\0')
+ return 0;
+
+ for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) {
+ if (isspace(*c)) {
+ *c++ = '\0';
+ if (*c && *c != '\n') {
+ if (ac + 1 == i) {
+ new = malloc(sizeof(unsigned char*) * (i + MEM_INC));
+ if (new == NULL) {
+ p[ac] = NULL;
+ return ac;
+ }
+ memcpy(new, p, i * sizeof (char **));
+ i += MEM_INC;
+ free(p);
+ *avp = p = new;
+ }
+ p[ac++] = c;
+ }
+ }
+ else
+ c++;
+ }
+ *c = '\0';
+ p[ac] = NULL;
+ return ac;
+}
+
+static STATUS
+last_argument()
+{
+ unsigned char **av;
+ unsigned char *p;
+ STATUS s;
+ int ac;
+
+ if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
+ return ring_bell();
+
+ if ((p = (unsigned char *)strdup((char *)p)) == NULL)
+ return CSstay;
+ ac = argify(p, &av);
+
+ if (Repeat != NO_ARG)
+ s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
+ else
+ s = ac ? insert_string(av[ac - 1]) : CSstay;
+
+ if (ac)
+ free(av);
+ free(p);
+ return s;
+}
+
+static KEYMAP Map[33] = {
+ { CTL('@'), ring_bell },
+ { CTL('A'), beg_line },
+ { CTL('B'), bk_char },
+ { CTL('D'), del_char },
+ { CTL('E'), end_line },
+ { CTL('F'), fd_char },
+ { CTL('G'), ring_bell },
+ { CTL('H'), bk_del_char },
+ { CTL('I'), c_complete },
+ { CTL('J'), accept_line },
+ { CTL('K'), kill_line },
+ { CTL('L'), redisplay },
+ { CTL('M'), accept_line },
+ { CTL('N'), h_next },
+ { CTL('O'), ring_bell },
+ { CTL('P'), h_prev },
+ { CTL('Q'), ring_bell },
+ { CTL('R'), h_search },
+ { CTL('S'), ring_bell },
+ { CTL('T'), transpose },
+ { CTL('U'), ring_bell },
+ { CTL('V'), quote },
+ { CTL('W'), wipe },
+ { CTL('X'), exchange },
+ { CTL('Y'), yank },
+ { CTL('Z'), ring_bell },
+ { CTL('['), meta },
+ { CTL(']'), move_to_char },
+ { CTL('^'), ring_bell },
+ { CTL('_'), ring_bell },
+ { 0, NULL }
+};
+
+static KEYMAP MetaMap[16]= {
+ { CTL('H'), bk_kill_word },
+ { DEL, bk_kill_word },
+ { ' ', mk_set },
+ { '.', last_argument },
+ { '<', h_first },
+ { '>', h_last },
+ { '?', c_possible },
+ { 'b', bk_word },
+ { 'd', fd_kill_word },
+ { 'f', fd_word },
+ { 'l', case_down_word },
+ { 'u', case_up_word },
+ { 'y', yank },
+ { 'w', copy_region },
+ { 0, NULL }
+};
diff --git a/usr.sbin/afs/src/lib/editline/editline.h b/usr.sbin/afs/src/lib/editline/editline.h
new file mode 100644
index 00000000000..942c91673c3
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/editline.h
@@ -0,0 +1,64 @@
+/* $Revision: 1.1 $
+**
+** Internal header file for editline library.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CRLF "\r\n"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+typedef struct dirent DIRENTRY;
+#else
+#include <sys/dir.h>
+typedef struct direct DIRENTRY;
+#endif
+
+#include <roken.h>
+
+#if !defined(S_ISDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif /* !defined(S_ISDIR) */
+
+typedef unsigned char CHAR;
+
+#define MEM_INC 64
+#define SCREEN_INC 256
+
+/*
+** Variables and routines internal to this package.
+*/
+extern int rl_eof;
+extern int rl_erase;
+extern int rl_intr;
+extern int rl_kill;
+extern int rl_quit;
+
+typedef char* (*rl_complete_func_t)(char*, int*);
+
+typedef int (*rl_list_possib_func_t)(char*, char***);
+
+void add_history (char*);
+char* readline (const char* prompt);
+void rl_add_slash (char*, char*);
+char* rl_complete (char*, int*);
+void rl_initialize (void);
+int rl_list_possib (char*, char***);
+void rl_reset_terminal (char*);
+void rl_ttyset (int);
+rl_complete_func_t rl_set_complete_func (rl_complete_func_t);
+rl_list_possib_func_t rl_set_list_possib_func (rl_list_possib_func_t);
+
diff --git a/usr.sbin/afs/src/lib/editline/sysunix.c b/usr.sbin/afs/src/lib/editline/sysunix.c
new file mode 100644
index 00000000000..c3d4481dc0f
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/sysunix.c
@@ -0,0 +1,92 @@
+/* Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ * 1. The authors are not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ * 4. This notice may not be removed or altered.
+ */
+
+/*
+** Unix system-dependant routines for editline library.
+*/
+#include <config.h>
+#include "editline.h"
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#else
+#include <sgtty.h>
+#endif
+
+RCSID("$Id: sysunix.c,v 1.1 2000/09/11 14:40:56 art Exp $");
+
+#ifdef HAVE_TERMIOS_H
+
+void
+rl_ttyset(int Reset)
+{
+ static struct termios old;
+ struct termios new;
+
+ if (Reset == 0) {
+ tcgetattr(0, &old);
+ rl_erase = old.c_cc[VERASE];
+ rl_kill = old.c_cc[VKILL];
+ rl_eof = old.c_cc[VEOF];
+ rl_intr = old.c_cc[VINTR];
+ rl_quit = old.c_cc[VQUIT];
+
+ new = old;
+ new.c_cc[VINTR] = -1;
+ new.c_cc[VQUIT] = -1;
+ new.c_lflag &= ~(ECHO | ICANON);
+ new.c_iflag &= ~(ISTRIP | INPCK);
+ new.c_cc[VMIN] = 1;
+ new.c_cc[VTIME] = 0;
+ tcsetattr(0, TCSANOW, &new);
+ }
+ else
+ tcsetattr(0, TCSANOW, &old);
+}
+
+#else /* !HAVE_TERMIOS_H */
+
+void
+rl_ttyset(int Reset)
+{
+ static struct sgttyb old;
+ struct sgttyb new;
+
+ if (Reset == 0) {
+ ioctl(0, TIOCGETP, &old);
+ rl_erase = old.sg_erase;
+ rl_kill = old.sg_kill;
+ new = old;
+ new.sg_flags &= ~(ECHO | ICANON);
+ new.sg_flags &= ~(ISTRIP | INPCK);
+ ioctl(0, TIOCSETP, &new);
+ } else {
+ ioctl(0, TIOCSETP, &old);
+ }
+}
+#endif /* HAVE_TERMIOS_H */
+
+void
+rl_add_slash(char *path, char *p)
+{
+ struct stat Sb;
+
+ if (stat(path, &Sb) >= 0)
+ strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ");
+}
diff --git a/usr.sbin/afs/src/lib/editline/testit.c b/usr.sbin/afs/src/lib/editline/testit.c
new file mode 100644
index 00000000000..02a93fcc724
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/testit.c
@@ -0,0 +1,38 @@
+/* $Revision: 1.1 $
+**
+** A "micro-shell" to test editline library.
+** If given any arguments, commands aren't executed.
+*/
+#if defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "editline.h"
+
+int
+main(int ac, char **av)
+{
+ char *p;
+ int doit;
+
+ doit = ac == 1;
+ while ((p = readline("testit> ")) != NULL) {
+ (void)printf("\t\t\t|%s|\n", p);
+ if (doit)
+ if (strncmp(p, "cd ", 3) == 0) {
+ if (chdir(&p[3]) < 0)
+ perror(&p[3]);
+ } else if (system(p) != 0) {
+ perror(p);
+ }
+ add_history(p);
+ free(p);
+ }
+ exit(0);
+ /* NOTREACHED */
+}
diff --git a/usr.sbin/afs/src/lib/editline/unix.h b/usr.sbin/afs/src/lib/editline/unix.h
new file mode 100644
index 00000000000..fe6beedcec2
--- /dev/null
+++ b/usr.sbin/afs/src/lib/editline/unix.h
@@ -0,0 +1,22 @@
+/* $Revision: 1.1 $
+**
+** Editline system header file for Unix.
+*/
+
+#define CRLF "\r\n"
+#define FORWARD STATIC
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(USE_DIRENT)
+#include <dirent.h>
+typedef struct dirent DIRENTRY;
+#else
+#include <sys/dir.h>
+typedef struct direct DIRENTRY;
+#endif /* defined(USE_DIRENT) */
+
+#if !defined(S_ISDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif /* !defined(S_ISDIR) */
diff --git a/usr.sbin/afs/src/lib/ko/Makefile.in b/usr.sbin/afs/src/lib/ko/Makefile.in
new file mode 100644
index 00000000000..bcfa00d4b2c
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/Makefile.in
@@ -0,0 +1,161 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:40:57 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I../../include \
+ -I$(srcdir)/../../include \
+ -I../.. -I$(srcdir)/../.. \
+ -I../../rxdef \
+ @KRB4_INC_FLAGS@
+
+CFLAGS = @CFLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+KRB4_LIB_FLAGS = @KRB4_LIB_FLAGS@
+
+LIBS = -L. -lko \
+ -L../../util -lutil \
+ -L../roken -lroken \
+ $(KRB4_LIB_FLAGS) \
+ @LIBS@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+target_os = @target_os@
+target_vendor = @target_vendor@
+target_cpu = @target_cpu@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)ko
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+PROGS = gensysname kotest
+
+DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DARLACACHEDIR=\"$(ARLACACHEDIR)\" \
+ -DARLACONFFILE=\"$(ARLACONFFILE)\" \
+ $(GENSYSNAMEDEFS)
+
+LIB_SOURCES = koerror.c \
+ kocell.c \
+ ports.c \
+ part.c \
+ sysname.c \
+ vlmisc.c \
+ afsconf.c \
+ auth.c
+
+SOURCES = $(LIB_SOURCES) $(gensysname_SRCS)
+
+LIB_OBJECTS = koerror.o \
+ kocell.o \
+ ports.o \
+ part.o \
+ sysname.o \
+ vlmisc.o \
+ afsconf.o \
+ auth.o
+
+HEADERS = cellconfig.h auth.h
+
+GENSYSNAMEDEFS= @DEFS@ -DARLAOS=\"$(target_os)\" \
+ -DARLAVENDOR=\"$(target_vendor)\" \
+ -DARLACPU=\"$(target_cpu)\"
+
+gensysname_SRCS = gensysname.c
+
+gensysname_OBJS = gensysname.o
+
+kotest_SRCS = kotest.c
+
+kotest_OBJS = kotest.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB) $(PROGS)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+sysname.c: gensysname
+ ./gensysname -c > $@
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+ for i in $(HEADERS); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir)/$$i; \
+ done
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+ for i in $(HEADERS); do \
+ rm -f $(DESTDIR)$(includedir)/$$i; \
+ done
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+
+gensysname: $(gensysname_OBJS)
+ $(CC) -o $@ $(gensysname_OBJS) -L../../util -lutil -L../roken -lroken
+
+kotest: $(kotest_OBJS) $(LIBNAME).a
+ $(CC) -o $@ $(kotest_OBJS) $(LIBS)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a sysname.c
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../include/config.h
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=lib/ko/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/lib/ko/afsconf.c b/usr.sbin/afs/src/lib/ko/afsconf.c
new file mode 100644
index 00000000000..779ee8e965e
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/afsconf.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "ko_locl.h"
+#include "cellconfig.h"
+#include "ports.h"
+
+RCSID("$Id: afsconf.c,v 1.1 2000/09/11 14:40:57 art Exp $");
+
+/*
+ * Currently only handles dir_path == NULL
+ */
+
+struct afsconf_dir *
+afsconf_Open(const char *dir_path)
+{
+ struct afsconf_dir *ret;
+
+ assert (dir_path == NULL);
+ ret = malloc (sizeof (*ret));
+ if (ret == NULL)
+ return NULL;
+ cell_init (0);
+ ports_init ();
+ return ret;
+}
+
+/*
+ * get the name of the local cell,
+ * return value == 0 -> success, otherwise -> failure
+ */
+
+int
+afsconf_GetLocalCell (struct afsconf_dir *ctx, char *cell, size_t len)
+{
+ strlcpy (cell, cell_getthiscell (), len);
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+afsconf_GetCellInfo (struct afsconf_dir *ctx,
+ const char *cellname,
+ char *unknown, /* XXX */
+ struct afsconf_cell *conf)
+{
+ cell_entry *entry = cell_get_by_name (cellname);
+ int i;
+
+ if (entry == NULL)
+ return -1;
+
+ strlcpy (conf->name, entry->name, sizeof(conf->name));
+ conf->numServers = entry->ndbservers;
+ conf->flags = 0;
+ for (i = 0; i < entry->ndbservers; ++i) {
+ memset (&conf->hostAddr[i], 0, sizeof(conf->hostAddr[i]));
+ conf->hostAddr[i].sin_family = AF_INET;
+ conf->hostAddr[i].sin_addr = entry->dbservers[i].addr;
+ conf->hostAddr[i].sin_port = afsvldbport;
+ strlcpy (conf->hostName[i], entry->dbservers[i].name,
+ sizeof(conf->hostName[i]));
+ }
+ conf->linkedCell = NULL;
+ return 0;
+}
+
+/*
+ * destroy ctx
+ */
+
+int
+afsconf_Close(struct afsconf_dir *ctx)
+{
+ free (ctx);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/lib/ko/auth.c b/usr.sbin/afs/src/lib/ko/auth.c
new file mode 100644
index 00000000000..6d1b9454e4a
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/auth.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "ko_locl.h"
+#include "auth.h"
+
+RCSID("$Id: auth.c,v 1.1 2000/09/11 14:40:57 art Exp $");
+
+#ifdef KERBEROS
+
+#define AFS_PRINCIPAL "afs"
+#define AFS_INSTANCE ""
+
+/*
+ * Try to fetch the token for `server' into `token'.
+ * We should also fill in `client', but we don't.
+ */
+
+int
+ktc_GetToken(const struct ktc_principal *server,
+ struct ktc_token *token,
+ int token_len,
+ struct ktc_principal *client)
+{
+ u_int32_t i;
+ unsigned char t[128];
+ struct ViceIoctl parms;
+
+ assert (sizeof(*token) == token_len);
+
+ parms.in = (void *)&i;
+ parms.in_size = sizeof(i);
+ parms.out = (void *)t;
+ parms.out_size = sizeof(t);
+
+ for (i = 0; k_pioctl(NULL, VIOCGETTOK, &parms, 0) == 0; i++) {
+ int32_t size_secret_tok, size_clear_tok;
+ const unsigned char *r = t;
+ const unsigned char *secret_token;
+ struct ClearToken ct;
+ const char *cell;
+
+ memcpy (&size_secret_tok, r, sizeof(size_secret_tok));
+ r += sizeof(size_secret_tok);
+ secret_token = r;
+ r += size_secret_tok;
+ memcpy (&size_clear_tok, r, sizeof(size_clear_tok));
+ r += sizeof(size_clear_tok);
+ memcpy (&ct, r, size_clear_tok);
+ r += size_clear_tok;
+ /* there is a int32_t with length of cellname, but we dont read it */
+ r += sizeof(int32_t);
+ cell = (const char *)r;
+
+ if (strcmp (cell, server->cell) == 0
+ && strcmp (server->name, AFS_PRINCIPAL) == 0
+ && strcmp (server->instance, AFS_INSTANCE) == 0) {
+ token->startTime = ct.BeginTimestamp;
+ token->endTime = ct.EndTimestamp;
+ memcpy (token->sessionKey.data, ct.HandShakeKey, 8);
+ token->kvno = ct.AuthHandle;
+ token->ticketLen = size_secret_tok;
+ memcpy (token->ticket, secret_token, size_secret_tok);
+ memset (&ct, 0, sizeof(ct));
+ return 0;
+ }
+ memset (&ct, 0, sizeof(ct));
+ }
+ return -1;
+}
+
+/*
+ * store the token in `token' for `server' into the kernel
+ */
+
+int
+ktc_SetToken(const struct ktc_principal *server,
+ const struct ktc_token *token,
+ const struct ktc_principal *client,
+ int unknown) /* XXX */
+{
+ const char *cell;
+ CREDENTIALS cred;
+ int ret;
+ char *p;
+ uid_t uid = 0;
+
+ if (strcmp(server->name, AFS_PRINCIPAL) != 0
+ || strcmp(server->instance, AFS_INSTANCE) != 0)
+ return -1;
+ cell = server->cell;
+ strlcpy(cred.service, server->name, sizeof(cred.service));
+ strlcpy(cred.instance, server->instance, sizeof(cred.instance));
+ strlcpy(cred.realm, server->cell, sizeof(cred.realm));
+ memcpy (cred.session, token->sessionKey.data, 8);
+ cred.lifetime = krb_time_to_life (token->startTime, token->endTime);
+ cred.kvno = token->kvno;
+ cred.ticket_st.length = token->ticketLen;
+ memcpy (cred.ticket_st.dat, token->ticket, token->ticketLen);
+ cred.issue_date = token->startTime;
+ strlcpy(cred.pname, client->name, sizeof(cred.pname));
+ strlcpy(cred.pinst, client->instance, sizeof(cred.pinst));
+ p = strstr (client->name, "0123456789");
+ if (p != NULL) {
+ char *end;
+
+ uid = strtol (p, &end, 0);
+ }
+ ret = kafs_settoken (cell, uid, &cred);
+ memset (&cred, 0, sizeof(cred));
+ return ret;
+}
+
+#endif /* KERBEROS */
diff --git a/usr.sbin/afs/src/lib/ko/auth.h b/usr.sbin/afs/src/lib/ko/auth.h
new file mode 100644
index 00000000000..2eeb79cf8c8
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/auth.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: auth.h,v 1.1 2000/09/11 14:40:57 art Exp $ */
+
+#ifndef __AUTH_H
+#define __AUTH_H 1
+
+#ifdef KERBEROS
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <atypes.h>
+#include <rx/rx.h>
+#include <krb.h>
+#include <kafs.h>
+#include <rxkad.h>
+
+struct ktc_token {
+ int32_t startTime;
+ int32_t endTime;
+ struct ktc_encryptionKey sessionKey;
+ short kvno;
+ int ticketLen;
+ char ticket[MAXKTCTICKETLEN];
+};
+
+int
+ktc_GetToken(const struct ktc_principal *server,
+ struct ktc_token *token,
+ int token_len,
+ struct ktc_principal *client);
+
+int
+ktc_SetToken(const struct ktc_principal *server,
+ const struct ktc_token *token,
+ const struct ktc_principal *client,
+ int unknown); /* XXX */
+
+#endif /* KERBEROS */
+
+#endif /* __AUTH_H */
diff --git a/usr.sbin/afs/src/lib/ko/cellconfig.h b/usr.sbin/afs/src/lib/ko/cellconfig.h
new file mode 100644
index 00000000000..52c5089c011
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/cellconfig.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: cellconfig.h,v 1.1 2000/09/11 14:40:57 art Exp $ */
+
+#ifndef __CELLCONFIG_H
+#define __CELLCONFIG_H 1
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <atypes.h>
+
+/* sizes */
+
+#define MAXCELLCHARS 64
+#define MAXHOSTSPERCELL 8
+#define MAXHOSTCHARS 64
+
+/* paths */
+
+#define AFSCONF_CLIENTNAME NULL
+
+struct afsconf_cell {
+ char name[MAXCELLCHARS];
+ short numServers;
+ short flags;
+ struct sockaddr_in hostAddr[MAXHOSTSPERCELL];
+ char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS];
+ char *linkedCell;
+};
+
+struct afsconf_dir {
+ int dummy;
+};
+
+struct afsconf_dir *afsconf_Open(const char *dir_path);
+int afsconf_GetLocalCell(struct afsconf_dir *ctx, char *cell, size_t len);
+int
+afsconf_GetCellInfo (struct afsconf_dir *ctx,
+ const char *cellname,
+ char *unknown, /* XXX */
+ struct afsconf_cell *conf);
+
+int
+afsconf_Close(struct afsconf_dir *ctx);
+
+#endif /* __CELLCONFIG_H */
diff --git a/usr.sbin/afs/src/lib/ko/kotest.c b/usr.sbin/afs/src/lib/ko/kotest.c
new file mode 100644
index 00000000000..db89bb1fec5
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/kotest.c
@@ -0,0 +1,79 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 libko works as expected
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <err.h>
+#include <roken.h>
+#include <ko.h>
+
+RCSID("$Id: kotest.c,v 1.1 2000/09/11 14:40:58 art Exp $");
+
+int
+main (int argc, char **argv)
+{
+ const char *name;
+ int ret = 0;
+
+ cell_init(0);
+
+ name = cell_expand_cell ("stacken");
+ if (strcmp (name, "stacken.kth.se") != 0) {
+ warnx ("stacken failed");
+ ret = 1;
+ }
+
+
+ name = cell_expand_cell ("gurkmacka");
+ if (strcmp (name, "gurkmacka") != 0) {
+ warnx ("gurkmacka failed");
+ ret = 1;
+ }
+
+ return ret;
+}
diff --git a/usr.sbin/afs/src/lib/ko/part.c b/usr.sbin/afs/src/lib/ko/part.c
new file mode 100644
index 00000000000..b09af1a16d1
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/part.c
@@ -0,0 +1,103 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "ko_locl.h"
+
+#include "part.h"
+
+RCSID("$Id: part.c,v 1.1 2000/09/11 14:40:58 art Exp $");
+
+/*
+ * partition_num2name
+ *
+ * write the string of the partition number `id' in `str' (which is of
+ * size `sz') and return the number of characters written.
+ */
+
+int
+partition_num2name (int id, char *str, size_t sz)
+{
+ if (id < 26)
+ return snprintf (str, sz, "/vicep%c", 'a' + id);
+ else
+ return snprintf (str, sz, "/vicep%c%c",
+ 'a' + id / 26 - 1, 'a' + id % 26);
+}
+
+/*
+ * partition_name2num
+ * convert a char string that might be a partition to a
+ * number.
+ *
+ * returns -1 is there is an error
+ *
+ */
+
+int
+partition_name2num(const char *name)
+{
+ int ret;
+
+ if (strncmp(name, "/vicep", 6) == 0)
+ name += 6;
+ else if (strncmp(name, "vicep", 5) == 0)
+ name += 5;
+
+ if (*name == '\0')
+ return -1;
+
+ if(*(name+1) == '\0') {
+ if(isalpha((unsigned char)*name)) {
+ ret = tolower((unsigned char)*name) - 'a';
+ } else
+ return -1;
+ } else if (name[2] == '\0') {
+ if (isalpha((unsigned char)name[0])
+ && isalpha((unsigned char)name[1])) {
+ ret = 26 * (tolower((unsigned char)*(name)) - 'a' + 1)
+ + tolower((unsigned char)*(name+1)) - 'a';
+ } else
+ return -1;
+ } else
+ return -1;
+
+ if(ret > 255)
+ return -1;
+
+ return ret;
+}
diff --git a/usr.sbin/afs/src/lib/ko/part.h b/usr.sbin/afs/src/lib/ko/part.h
new file mode 100644
index 00000000000..fdee064d939
--- /dev/null
+++ b/usr.sbin/afs/src/lib/ko/part.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: part.h,v 1.1 2000/09/11 14:40:58 art Exp $ */
+
+int partition_num2name(int id, char *str, size_t sz);
+int partition_name2num(const char *name);
diff --git a/usr.sbin/afs/src/lib/sl/Makefile.in b/usr.sbin/afs/src/lib/sl/Makefile.in
new file mode 100644
index 00000000000..1951d845547
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/Makefile.in
@@ -0,0 +1,117 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:06 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+YACC = @YACC@
+LEX = @LEX@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+bindir = @bindir@
+includedir = @includedir@
+
+KRB4_INC_FLAGS = @KRB4_INC_FLAGS@
+
+LIBPREFIX = lib
+LIBEXT = a
+LIBNAME = $(LIBPREFIX)sl
+sl_LIB = $(LIBNAME).$(LIBEXT)
+LIBNAME2 = $(LIBPREFIX)ss
+ss_LIB = $(LIBNAME2).$(LIBEXT)
+PROGS = mk_cmds
+
+LIB_SOURCES = sl.c ss.c
+EXTRA_SOURCES = strtok_r.c snprintf.c
+
+SOURCES = $(LIB_SOURCES) make_cmds.c $(EXTRA_SOURCES)
+
+LIBADD = strtok_r.o snprintf.o
+
+LIB_OBJECTS = sl.o ss.o $(LIBADD)
+
+mk_cmds_OBJECTS = make_cmds.o parse.o lex.o snprintf.o
+
+OBJECTS = $(LIB_OBJECTS) $(mk_cmds_OBJECTS)
+
+all: $(sl_LIB) $(PROGS)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(DEFS) -I../../include -I. -I$(srcdir) $(KRB4_INC_FLAGS) $(CFLAGS) $(CPPFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(includedir)/ss
+ $(INSTALL_DATA) $(srcdir)/ss.h $(DESTDIR)$(includedir)/ss/ss.h
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL) -m 555 $(sl_LIB) $(DESTDIR)$(libdir)/$(sl_LIB)
+ $(INSTALL) -m 555 $(sl_LIB) $(DESTDIR)$(libdir)/$(ss_LIB)
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ $(INSTALL) -m 0555 $(PROGS) $(DESTDIR)$(bindir)/$(PROGS)
+
+uninstall:
+ rm -f $(DESTDIR)$(includedir)/ss/ss.h
+ rm -f $(DESTDIR)$(libdir)/$(sl_LIB) $(DESTDIR)$(libdir)/$(ss_LIB)
+ rm -f $(DESTDIR)$(bindir)/$(PROGS)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(sl_LIB) $(PROGS) lex.c parse.c parse.h *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+$(OBJECTS): ../../include/config.h
+
+$(mk_cmds_OBJECTS): parse.h
+
+mk_cmds: $(mk_cmds_OBJECTS)
+ $(CC) $(CFLAGS) -o $@ $(mk_cmds_OBJECTS) -L../roken -lroken
+
+parse.c: parse.h
+parse.h: $(srcdir)/parse.y
+ $(YACC) -d $(srcdir)/parse.y
+ mv -f y.tab.h parse.h
+ mv -f y.tab.c parse.c
+
+lex.c: $(srcdir)/lex.l
+ $(LEX) $(srcdir)/lex.l
+ mv -f lex.yy.c lex.c
+
+strtok_r.c:
+ test -f strtok_r.c || $(LN_S) $(srcdir)/../roken/strtok_r.c .
+snprintf.c:
+ test -f snprintf.c || $(LN_S) $(srcdir)/../roken/snprintf.c .
+
+.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/lib/sl/lex.l b/usr.sbin/afs/src/lib/sl/lex.l
new file mode 100644
index 00000000000..8163d9d718d
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/lex.l
@@ -0,0 +1,117 @@
+%{
+/*
+ * Copyright (c) 1998 - 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.
+ */
+
+#include "make_cmds.h"
+#include "parse.h"
+
+RCSID("$Id: lex.l,v 1.1 2000/09/11 14:41:07 art Exp $");
+
+static unsigned lineno = 1;
+static int getstring(void);
+
+#define YY_NO_UNPUT
+
+#undef ECHO
+
+%}
+
+
+%%
+command_table { return TABLE; }
+request { return REQUEST; }
+unknown { return UNKNOWN; }
+unimplemented { return UNIMPLEMENTED; }
+end { return END; }
+#[^\n]* ;
+[ \t] ;
+\n { lineno++; }
+\" { return getstring(); }
+[a-zA-Z0-9_]+ { yylval.string = strdup(yytext); return STRING; }
+. { return *yytext; }
+%%
+
+#ifndef yywrap /* XXX */
+int
+yywrap ()
+{
+ return 1;
+}
+#endif
+
+static int
+getstring(void)
+{
+ char x[128];
+ int i = 0;
+ int c;
+ int backslash = 0;
+ while((c = input()) != EOF){
+ if(backslash) {
+ if(c == 'n')
+ c = '\n';
+ else if(c == 't')
+ c = '\t';
+ x[i++] = c;
+ backslash = 0;
+ continue;
+ }
+ if(c == '\n'){
+ error_message("unterminated string");
+ lineno++;
+ break;
+ }
+ if(c == '\\'){
+ backslash++;
+ continue;
+ }
+ if(c == '\"')
+ break;
+ x[i++] = c;
+ }
+ x[i] = '\0';
+ yylval.string = strdup(x);
+ return STRING;
+}
+
+void
+error_message (const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ fprintf (stderr, "%s:%d: ", filename, lineno);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ numerror++;
+}
diff --git a/usr.sbin/afs/src/lib/sl/make_cmds.c b/usr.sbin/afs/src/lib/sl/make_cmds.c
new file mode 100644
index 00000000000..3d126ab4df9
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/make_cmds.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include "make_cmds.h"
+#include <getarg.h>
+
+RCSID("$Id: make_cmds.c,v 1.1 2000/09/11 14:41:07 art Exp $");
+
+#include <roken.h>
+#include <err.h>
+#include "parse.h"
+
+int numerror;
+extern FILE *yyin;
+FILE *c_file;
+
+extern void yyparse(void);
+
+#ifdef YYDEBUG
+extern int yydebug = 1;
+#endif
+
+char *filename;
+char *table_name;
+
+static struct command_list *commands;
+
+void
+add_command(char *function,
+ char *help,
+ struct string_list *aliases,
+ unsigned flags)
+{
+ struct command_list *cl = malloc(sizeof(*cl));
+
+ if (cl == NULL)
+ err (1, "malloc");
+ cl->function = function;
+ cl->help = help;
+ cl->aliases = aliases;
+ cl->flags = flags;
+ cl->next = NULL;
+ if(commands) {
+ *commands->tail = cl;
+ commands->tail = &cl->next;
+ return;
+ }
+ cl->tail = &cl->next;
+ commands = cl;
+}
+
+static char *
+quote(const char *str)
+{
+ char buf[1024]; /* XXX */
+ const char *p;
+ char *q;
+ q = buf;
+
+ *q++ = '\"';
+ for(p = str; *p != '\0'; p++) {
+ if(*p == '\n') {
+ *q++ = '\\';
+ *q++ = 'n';
+ continue;
+ }
+ if(*p == '\t') {
+ *q++ = '\\';
+ *q++ = 't';
+ continue;
+ }
+ if(*p == '\"' || *p == '\\')
+ *q++ = '\\';
+ *q++ = *p;
+ }
+ *q++ = '\"';
+ *q++ = '\0';
+ return strdup(buf);
+}
+
+static void
+generate_commands(void)
+{
+ char *base;
+ char *cfn;
+ char *p;
+
+ p = strrchr(table_name, '/');
+ if(p == NULL)
+ p = table_name;
+ else
+ p++;
+
+ base = strdup (p);
+ if (base == NULL)
+ err (1, "strdup");
+
+ p = strrchr(base, '.');
+ if(p)
+ *p = '\0';
+
+ asprintf(&cfn, "%s.c", base);
+ if (cfn == NULL)
+ err (1, "asprintf");
+
+ c_file = fopen(cfn, "w");
+ if (c_file == NULL)
+ err (1, "cannot fopen %s", cfn);
+
+ fprintf(c_file, "/* Generated from %s */\n", filename);
+ fprintf(c_file, "\n");
+ fprintf(c_file, "#include <stddef.h>\n");
+ fprintf(c_file, "#include <sl.h>\n");
+ fprintf(c_file, "\n");
+
+ {
+ struct command_list *cl, *xl;
+ char *p, *q;
+
+ for(cl = commands; cl; cl = cl->next) {
+ for(xl = commands; xl != cl; xl = xl->next)
+ if(strcmp(cl->function, xl->function) == 0)
+ break;
+ if(xl != cl)
+ continue;
+ /* XXX hack for ss_quit */
+ if(strcmp(cl->function, "ss_quit") == 0) {
+ fprintf(c_file, "int %s (int, char**);\n", cl->function);
+ fprintf(c_file, "#define _ss_quit_wrap ss_quit\n\n");
+ continue;
+ }
+ fprintf(c_file, "void %s (int, char**);\n", cl->function);
+ fprintf(c_file, "static int _%s_wrap (int argc, char **argv)\n",
+ cl->function);
+ fprintf(c_file, "{\n");
+ fprintf(c_file, " %s (argc, argv);\n", cl->function);
+ fprintf(c_file, " return 0;\n");
+ fprintf(c_file, "}\n\n");
+ }
+
+ fprintf(c_file, "SL_cmd %s[] = {\n", table_name);
+ for(cl = commands; cl; cl = cl->next) {
+ struct string_list *sl;
+ sl = cl->aliases;
+ p = quote(sl->string);
+ q = quote(cl->help);
+ fprintf(c_file, " { %s, _%s_wrap, %s },\n", p, cl->function, q);
+ free(p);
+ free(q);
+
+ for(sl = sl->next; sl; sl = sl->next) {
+ p = quote(sl->string);
+ fprintf(c_file, " { %s },\n", p);
+ free(p);
+ }
+ }
+ fprintf(c_file, " { NULL },\n");
+ fprintf(c_file, "};\n");
+ fprintf(c_file, "\n");
+ }
+ fclose(c_file);
+ free(base);
+ free(cfn);
+}
+
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag },
+ { NULL },
+};
+
+static void
+usage(int code)
+{
+ arg_printusage(args, NULL, "command-table", ARG_DEFAULT);
+ exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optind = 0;
+
+ set_progname(argv[0]);
+ if(getarg(args, argc, argv, &optind, ARG_DEFAULT))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ printf ("$Id: make_cmds.c,v 1.1 2000/09/11 14:41:07 art Exp $\n");
+ exit(0);
+ }
+
+ if(argc == optind)
+ usage(1);
+ filename = argv[optind];
+ yyin = fopen(filename, "r");
+ if(yyin == NULL)
+ err(1, "%s", filename);
+
+ yyparse();
+
+ generate_commands();
+
+ if(numerror)
+ return 1;
+ return 0;
+}
diff --git a/usr.sbin/afs/src/lib/sl/make_cmds.h b/usr.sbin/afs/src/lib/sl/make_cmds.h
new file mode 100644
index 00000000000..6b66ddc1370
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/make_cmds.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1998 - 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.
+ */
+
+/* $Id: make_cmds.h,v 1.1 2000/09/11 14:41:07 art Exp $ */
+
+#ifndef __MAKE_CMDS_H__
+#define __MAKE_CMDS_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <roken.h>
+
+extern char *filename;
+extern char *table_name;
+extern int numerror;
+
+struct command_list {
+ char *function;
+ char *help;
+ struct string_list *aliases;
+ unsigned flags;
+ struct command_list *next;
+ struct command_list **tail;
+};
+
+struct string_list {
+ char *string;
+ struct string_list *next;
+ struct string_list **tail;
+};
+
+void add_command(char*, char*, struct string_list*, unsigned);
+
+void error_message(const char *, ...)
+ __attribute__ ((format (printf, 1,2)));
+
+int yylex (void);
+
+#endif /* __MAKE_CMDS_H__ */
diff --git a/usr.sbin/afs/src/lib/sl/parse.y b/usr.sbin/afs/src/lib/sl/parse.y
new file mode 100644
index 00000000000..e41e1a72c37
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/parse.y
@@ -0,0 +1,167 @@
+%{
+/*
+ * Copyright (c) 1998 - 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.
+ */
+
+#include "make_cmds.h"
+RCSID("$Id: parse.y,v 1.1 2000/09/11 14:41:07 art Exp $");
+
+static void yyerror (char *s);
+
+struct string_list* append_string(struct string_list*, char*);
+void free_string_list(struct string_list *list);
+unsigned string_to_flag(const char *);
+
+/* This is for bison */
+
+#if !defined(alloca) && !defined(HAVE_ALLOCA)
+#define alloca(x) malloc(x)
+#endif
+
+%}
+
+%union {
+ char *string;
+ unsigned number;
+ struct string_list *list;
+}
+
+%token TABLE REQUEST UNKNOWN UNIMPLEMENTED END
+%token <string> STRING
+%type <number> flag flags
+%type <list> aliases
+
+%%
+
+file : /* */
+ | statements
+ ;
+
+statements : statement
+ | statements statement
+ ;
+
+statement : TABLE STRING ';'
+ {
+ table_name = $2;
+ }
+ | REQUEST STRING ',' STRING ',' aliases ',' '(' flags ')' ';'
+ {
+ add_command($2, $4, $6, $9);
+ }
+ | REQUEST STRING ',' STRING ',' aliases ';'
+ {
+ add_command($2, $4, $6, 0);
+ }
+ | UNIMPLEMENTED STRING ',' STRING ',' aliases ';'
+ {
+ free($2);
+ free($4);
+ free_string_list($6);
+ }
+ | UNKNOWN aliases ';'
+ {
+ free_string_list($2);
+ }
+ | END ';'
+ {
+ YYACCEPT;
+ }
+ ;
+
+aliases : STRING
+ {
+ $$ = append_string(NULL, $1);
+ }
+ | aliases ',' STRING
+ {
+ $$ = append_string($1, $3);
+ }
+ ;
+
+flags : flag
+ {
+ $$ = $1;
+ }
+ | flags ',' flag
+ {
+ $$ = $1 | $3;
+ }
+ ;
+flag : STRING
+ {
+ $$ = string_to_flag($1);
+ free($1);
+ }
+ ;
+
+
+
+%%
+
+static void
+yyerror (char *s)
+{
+ error_message ("%s\n", s);
+}
+
+struct string_list*
+append_string(struct string_list *list, char *str)
+{
+ struct string_list *sl = malloc(sizeof(*sl));
+ sl->string = str;
+ sl->next = NULL;
+ if(list) {
+ *list->tail = sl;
+ list->tail = &sl->next;
+ return list;
+ }
+ sl->tail = &sl->next;
+ return sl;
+}
+
+void
+free_string_list(struct string_list *list)
+{
+ while(list) {
+ struct string_list *sl = list->next;
+ free(list->string);
+ free(list);
+ list = sl;
+ }
+}
+
+unsigned
+string_to_flag(const char *string)
+{
+ return 0;
+}
diff --git a/usr.sbin/afs/src/lib/sl/ss.c b/usr.sbin/afs/src/lib/sl/ss.c
new file mode 100644
index 00000000000..44765c340b5
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/ss.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1998 - 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.
+ */
+
+#include "sl_locl.h"
+#if defined(HAVE_COM_ERR_H)
+#include <com_err.h>
+#elif defined(HAVE_ET_COM_ERR_H)
+#include <et/com_err.h>
+#endif
+#include "ss.h"
+
+RCSID("$Id: ss.c,v 1.1 2000/09/11 14:41:07 art Exp $");
+
+struct ss_subst {
+ char *name;
+ char *version;
+ char *info;
+ ss_request_table *table;
+};
+
+static struct ss_subst subsystems[2];
+static int num_subsystems;
+
+int
+ss_create_invocation(const char *subsystem,
+ const char *version,
+ const char *info,
+ ss_request_table *table,
+ int *code)
+{
+ struct ss_subst *ss;
+ if(num_subsystems >= sizeof(subsystems) / sizeof(subsystems[0])) {
+ *code = 17;
+ return 0;
+ }
+ ss = &subsystems[num_subsystems];
+ ss->name = subsystem ? strdup(subsystem) : NULL;
+ ss->version = version ? strdup(version) : NULL;
+ ss->info = info ? strdup(info) : NULL;
+ ss->table = table;
+ *code = 0;
+ return num_subsystems++;
+}
+
+void
+ss_error (int index, long code, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ com_err_va (subsystems[index].name, code, fmt, ap);
+ va_end(ap);
+}
+
+void
+ss_perror (int index, long code, const char *msg)
+{
+ ss_error(index, code, "%s", msg);
+}
+
+int
+ss_execute_command(int index, char **argv)
+{
+ int argc = 0;
+ while(argv[argc++]);
+ sl_command(subsystems[index].table, argc, argv);
+ return 0;
+}
+
+int
+ss_execute_line (int index, const char *line)
+{
+ char *buf = strdup(line);
+ int argc;
+ char **argv;
+
+ sl_make_argv(buf, &argc, &argv);
+ sl_command(subsystems[index].table, argc, argv);
+ free(buf);
+ return 0;
+}
+
+int
+ss_listen (int index)
+{
+ char *prompt = malloc(strlen(subsystems[index].name) + 3);
+ if(prompt == NULL) {
+ abort();
+ }
+ strcpy(prompt, subsystems[index].name);
+ strcat(prompt, ": ");
+ sl_loop(subsystems[index].table, prompt);
+ free(prompt);
+ return 0;
+}
+
+int
+ss_list_requests(int argc, char **argv /* , int index, void *info */)
+{
+ sl_help(subsystems[0 /* index */].table, argc, argv);
+ return 0;
+}
+
+int
+ss_quit(int argc, char **argv)
+{
+ return 1;
+}
diff --git a/usr.sbin/afs/src/lib/sl/ss.h b/usr.sbin/afs/src/lib/sl/ss.h
new file mode 100644
index 00000000000..fad7317b4e7
--- /dev/null
+++ b/usr.sbin/afs/src/lib/sl/ss.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1998 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: ss.h,v 1.1 2000/09/11 14:41:07 art Exp $ */
+
+/* SS compatibility for SL */
+
+#ifndef __ss_h__
+#define __ss_h__
+
+#include <sl.h>
+
+typedef SL_cmd ss_request_table;
+
+int ss_create_invocation (const char *, const char *, const char*,
+ ss_request_table*, int*);
+
+void ss_error (int, long, const char*, ...);
+int ss_execute_command (int, char**);
+int ss_execute_line (int, const char*);
+int ss_list_requests (int argc, char**);
+int ss_listen (int);
+void ss_perror (int, long, const char*);
+int ss_quit (int argc, char**);
+
+#endif /* __ss_h__ */
diff --git a/usr.sbin/afs/src/lwp/Makefile.in b/usr.sbin/afs/src/lwp/Makefile.in
new file mode 100644
index 00000000000..e19bb3279e4
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/Makefile.in
@@ -0,0 +1,119 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:07 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+GCC = @GCC@
+CPP = @CPP@
+AS = as
+AR = ar
+RM = rm
+RANLIB = @RANLIB@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+SHELL = /bin/sh
+LN_S = @LN_S@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+HOST_CPU = @host_cpu@
+HOST_OS = @host_os@
+
+INCLUDES = -I../include
+
+PROCESS_S = process.aix22.S \
+ process.alpha.S \
+ process.hpux.S \
+ process.i386.S \
+ process.ibm032.S \
+ process.m68k.S \
+ process.mips.S \
+ process.ppc.S \
+ process.rios.S \
+ process.sparc.S \
+ process.vax.S
+
+
+REALCFLAGS = $(INCLUDES) @DEFS@ @CFLAGS@ -DFD_SPEED_HACK -DDEBUG \
+ $(CFLAGS) @PLWP_INC_FLAGS@
+
+LIB = liblwp.a
+
+include_HEADERS = lock.h preempt.h timer.h
+
+liblwp_OBJECTS = @LWP_O@ @LWP_PROCESS@ lock.o iomgr.o timer.o fasttime.o q.o \
+ preempt.o
+
+TEST_PROGRAMS = testlwp rw
+
+all: $(LIB) $(TEST_PROGRAMS)
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+ for x in $(include_HEADERS); do \
+ b=`basename $$x`; \
+ $(INSTALL_DATA) $(srcdir)/$$b $(DESTDIR)$(includedir)/$$b; \
+ done
+ $(INSTALL_DATA) $(srcdir)/@LWP_H@ $(DESTDIR)$(includedir)/lwp.h
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+ for x in $(include_HEADERS); do \
+ rm -f $(DESTDIR)$(includedir)/$$x; \
+ done
+ rm -f $(DESTDIR)$(includedir)/lwp.h
+
+liblwp.a: $(liblwp_OBJECTS)
+ $(RM) -f $@
+ $(AR) rc $@ $(liblwp_OBJECTS)
+ $(RANLIB) $@
+
+make-process.o.sh: make-process.o.sh.in ../config.status
+ cd ..; CONFIG_FILES=lwp/make-process.o.sh CONFIG_HEADERS= $(SHELL) config.status
+
+# More magic, close your eyes.
+process.o: $(PROCESS_S) make-process.o.sh testprocess.o preempt.o @LWP_O@
+ $(SHELL) make-process.o.sh
+
+testlwp: testlwp.o liblwp.a
+ $(CC) -o testlwp testlwp.o -L. -llwp -L../lib/roken \
+ -lroken @PLWP_LIB_FLAGS@
+rw: rw.o liblwp.a
+ $(CC) -o rw rw.o -L. -llwp -L../lib/roken \
+ -lroken @PLWP_LIB_FLAGS@
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(REALCFLAGS) -I$(srcdir) -I. $<
+
+# dependencies
+
+iomgr.o: iomgr.c @LWP_H@ timer.h
+preempt.o: preempt.c @LWP_H@ preempt.h
+@LWP_O@: @LWP_C@ @LWP_H@
+lock.o: lock.c lock.h @LWP_H@
+timer.o: timer.c
+fasttime.o: fasttime.c
+q.o: q.c
+rw.o: rw.c
+testprocess.o: testprocess.c
+testlwp.o: testlwp.c
+
+clean:
+ rm -f *.o *.a core process.ss process.i $(LIB) make-process.o.sh testprocess $(TEST_PROGRAMS)
+
+distclean: clean
+ rm -f Makefile
+
+realclean: clean
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=lwp/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all install uninstall clean distclean realclean
diff --git a/usr.sbin/afs/src/lwp/lwp_asm.c b/usr.sbin/afs/src/lwp/lwp_asm.c
new file mode 100644
index 00000000000..b3c27cb6682
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/lwp_asm.c
@@ -0,0 +1,1054 @@
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+/*******************************************************************\
+* *
+* Information Technology Center *
+* Carnegie-Mellon University *
+* *
+* *
+\*******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* allocate externs here */
+#define LWP_KERNEL
+
+#include "lwp.h"
+
+RCSID("$Id: lwp_asm.c,v 1.1 2000/09/11 14:41:08 art Exp $");
+
+#ifdef AFS_AIX32_ENV
+#include <ulimit.h>
+#include <sys/errno.h>
+#include <sys/user.h>
+#include <sys/pseg.h>
+#include <sys/core.h>
+#pragma alloca
+#endif
+
+extern char PRE_Block; /* from preempt.c */
+
+#define ON 1
+#define OFF 0
+#define TRUE 1
+#define FALSE 0
+#define READY 2
+#define WAITING 3
+#define DESTROYED 4
+#define QWAITING 5
+#define MAXINT (~(1<<((sizeof(int)*8)-1)))
+#define MINSTACK 44
+
+
+/*
+ * I don't really know if this is the right thing to do, but
+ * now I don't get any unalinged memory access on my alpha /lha
+ */
+
+#if defined(__alpha) || defined(__uxpv__) || defined(__sparcv9)
+#define REGSIZE 8
+#else
+#define REGSIZE 4
+#endif
+
+
+#ifdef __hp9000s800
+#define MINFRAME 64
+#endif
+
+/* Debugging macro */
+#ifdef DEBUG
+#define Debug(level, msg)\
+ if (lwp_debug && lwp_debug >= level) {\
+ printf("***LWP (%p): ", lwp_cpptr);\
+ printf msg;\
+ putchar('\n');\
+ }
+
+#else
+#define Debug(level, msg)
+
+#endif
+
+/* Prototypes */
+static void Abort_LWP(char *msg) ;
+static void Dispatcher(void);
+static void Create_Process_Part2(void);
+static void purge_dead_pcbs(void) ;
+static void Overflow_Complain (void) ;
+static void Dispose_of_Dead_PCB (PROCESS cur) ;
+static void Free_PCB(PROCESS pid) ;
+static void Exit_LWP(void);
+static void Initialize_PCB(PROCESS temp, int priority, char *stack,
+ int stacksize, void (*ep)() , char *parm,
+ char *name) ;
+static long Initialize_Stack(char *stackptr,int stacksize) ;
+static int Stack_Used(char *stackptr, int stacksize) ;
+static int Internal_Signal(register char *event) ;
+char (*RC_to_ASCII());
+
+#define MAX_PRIORITIES (LWP_MAX_PRIORITY+1)
+
+struct QUEUE {
+ PROCESS head;
+ int count;
+} runnable[MAX_PRIORITIES], blocked;
+/*
+ * Invariant for runnable queues: The head of each queue points to the
+ * currently running process if it is in that queue, or it points to the
+ * next process in that queue that should run.
+ */
+
+/* Offset of stack field within pcb -- used by stack checking stuff */
+int stack_offset;
+
+/* special user-tweakable option for AIX */
+int lwp_MaxStackSize = 32768;
+
+/* biggest LWP stack created so far */
+int lwp_MaxStackSeen = 0;
+
+/* Stack checking action */
+int lwp_overflowAction = LWP_SOABORT;
+
+/* Controls stack size counting. */
+int lwp_stackUseEnabled = TRUE; /* pay the price */
+
+int lwp_nextindex;
+
+static void
+lwp_remove(register PROCESS p, register struct QUEUE *q)
+{
+ /* Special test for only element on queue */
+ if (q->count == 1)
+ q -> head = NULL;
+ else {
+ /* Not only element, do normal remove */
+ p -> next -> prev = p -> prev;
+ p -> prev -> next = p -> next;
+ }
+ /* See if head pointing to this element */
+ if (q->head == p) q -> head = p -> next;
+ q->count--;
+ p -> next = p -> prev = NULL;
+}
+
+static void
+insert(register PROCESS p, register struct QUEUE *q)
+{
+ if (q->head == NULL) { /* Queue is empty */
+ q -> head = p;
+ p -> next = p -> prev = p;
+ } else { /* Regular insert */
+ p -> prev = q -> head -> prev;
+ q -> head -> prev -> next = p;
+ q -> head -> prev = p;
+ p -> next = q -> head;
+ }
+ q->count++;
+}
+
+static void
+move(PROCESS p, struct QUEUE *from, struct QUEUE *to)
+{
+ lwp_remove(p, from);
+
+ insert(p, to);
+}
+
+/* Iterator macro */
+#define for_all_elts(var, q, body)\
+ {\
+ register PROCESS var, _NEXT_;\
+ register int _I_;\
+ for (_I_=q.count, var = q.head; _I_>0; _I_--, var=_NEXT_) {\
+ _NEXT_ = var -> next;\
+ body\
+ }\
+ }
+
+/* */
+/*****************************************************************************\
+* *
+* Following section documents the Assembler interfaces used by LWP code *
+* *
+\*****************************************************************************/
+
+/*
+ * savecontext(int (*ep)(), struct lwp_context *savearea, char *sp);
+ * XXX - the above prototype is a lie.
+ * Stub for Assembler routine that will
+ * save the current SP value in the passed
+ * context savearea and call the function
+ * whose entry point is in ep. If the sp
+ * parameter is NULL, the current stack is
+ * used, otherwise sp becomes the new stack
+ * pointer.
+ *
+ * returnto(struct lwp_context *savearea);
+ *
+ * Stub for Assembler routine that will
+ * restore context from a passed savearea
+ * and return to the restored C frame.
+ *
+ */
+
+void savecontext(void (*)(), struct lwp_context *, char *);
+void returnto(struct lwp_context *);
+
+/* Macro to force a re-schedule. Strange name is historical */
+#define Set_LWP_RC() savecontext(Dispatcher, &lwp_cpptr->context, NULL)
+
+static struct lwp_ctl *lwp_init = 0;
+
+int
+LWP_QWait(void)
+{
+ register PROCESS tp;
+ (tp=lwp_cpptr) -> status = QWAITING;
+ lwp_remove(tp, &runnable[tp->priority]);
+ Set_LWP_RC();
+ return LWP_SUCCESS;
+}
+
+int
+LWP_QSignal(register PROCESS pid)
+{
+ if (pid->status == QWAITING) {
+ pid->status = READY;
+ insert(pid, &runnable[pid->priority]);
+ return LWP_SUCCESS;
+ }
+ else return LWP_ENOWAIT;
+}
+
+#ifdef AFS_AIX32_ENV
+char *
+reserveFromStack(size)
+ register long size;
+{
+ char *x;
+ x = alloca(size);
+ return x;
+}
+#endif
+
+int
+LWP_CreateProcess(void (*ep)(), int stacksize, int priority,
+ char *parm, char *name, PROCESS *pid)
+{
+ PROCESS temp, temp2;
+#ifdef AFS_AIX32_ENV
+ static char *stackptr = 0;
+#else
+ char *stackptr;
+#endif
+
+#if defined(AFS_LWP_MINSTACKSIZE)
+ /*
+ * on some systems (e.g. hpux), a minimum usable stack size has
+ * been discovered
+ */
+ if (stacksize < AFS_LWP_MINSTACKSIZE) {
+ stacksize = AFS_LWP_MINSTACKSIZE;
+ }
+#endif /* defined(AFS_LWP_MINSTACKSIZE) */
+ /* more stack size computations; keep track of for IOMGR */
+ if (lwp_MaxStackSeen < stacksize)
+ lwp_MaxStackSeen = stacksize;
+
+ Debug(0, ("Entered LWP_CreateProcess"))
+ /* Throw away all dead process control blocks */
+ purge_dead_pcbs();
+ if (lwp_init) {
+ temp = (PROCESS) malloc (sizeof (struct lwp_pcb));
+ if (temp == NULL) {
+ Set_LWP_RC();
+ return LWP_ENOMEM;
+ }
+ if (stacksize < MINSTACK)
+ stacksize = 1000;
+ else
+#ifdef __hp9000s800
+ stacksize = 8 * ((stacksize+7) / 8);
+#else
+ stacksize = REGSIZE * ((stacksize+REGSIZE-1) / REGSIZE);
+#endif
+#ifdef AFS_AIX32_ENV
+ if (!stackptr) {
+ /*
+ * The following signal action for AIX is necessary so that in case of a
+ * crash (i.e. core is generated) we can include the user's data section
+ * in the core dump. Unfortunately, by default, only a partial core is
+ * generated which, in many cases, isn't too useful.
+ *
+ * We also do it here in case the main program forgets to do it.
+ */
+ struct sigaction nsa;
+ extern int geteuid();
+
+ sigemptyset(&nsa.sa_mask);
+ nsa.sa_handler = SIG_DFL;
+ nsa.sa_flags = SA_FULLDUMP;
+ sigaction(SIGSEGV, &nsa, NULL);
+
+ /*
+ * First we need to increase the default resource limits,
+ * if necessary, so that we can guarantee that we have the
+ * resources to create the core file, but we can't always
+ * do it as an ordinary user.
+ */
+ if (!geteuid()) {
+ setlim(RLIMIT_FSIZE, 0, 1048575); /* 1 Gig */
+ setlim(RLIMIT_STACK, 0, 65536); /* 65 Meg */
+ setlim(RLIMIT_CORE, 0, 131072); /* 131 Meg */
+ }
+ /*
+ * Now reserve in one scoop all the stack space that will be used
+ * by the particular application's main (i.e. non-lwp) body. This
+ * is plenty space for any of our applications.
+ */
+ stackptr = reserveFromStack(lwp_MaxStackSize);
+ }
+ stackptr -= stacksize;
+#else
+ if ((stackptr = (char *) malloc(stacksize)) == NULL) {
+ Set_LWP_RC();
+ return LWP_ENOMEM;
+ }
+#endif
+ if (priority < 0 || priority >= MAX_PRIORITIES) {
+ Set_LWP_RC();
+ return LWP_EBADPRI;
+ }
+ Initialize_Stack(stackptr, stacksize);
+ Initialize_PCB(temp, priority, stackptr, stacksize, ep, parm, name);
+ insert(temp, &runnable[priority]);
+ temp2 = lwp_cpptr;
+ if (PRE_Block != 0) Abort_LWP("PRE_Block not 0");
+
+ /* Gross hack: beware! */
+ PRE_Block = 1;
+ lwp_cpptr = temp;
+#ifdef __hp9000s800
+ savecontext(Create_Process_Part2, &temp2->context, stackptr+MINFRAME);
+#else
+ savecontext(Create_Process_Part2, &temp2->context,
+ stackptr+stacksize-REGSIZE);
+#endif
+ /* End of gross hack */
+
+ Set_LWP_RC();
+ *pid = temp;
+ return 0;
+ } else
+ return LWP_EINIT;
+}
+
+/* returns pid of current process */
+int
+LWP_CurrentProcess(PROCESS *pid)
+{
+ Debug(0, ("Entered Current_Process"))
+ if (lwp_init) {
+ *pid = lwp_cpptr;
+ return LWP_SUCCESS;
+ } else
+ return LWP_EINIT;
+}
+
+#define LWPANCHOR (*lwp_init)
+
+/* destroy a lightweight process */
+int
+LWP_DestroyProcess(PROCESS pid)
+{
+ PROCESS temp;
+
+ Debug(0, ("Entered Destroy_Process"))
+ if (lwp_init) {
+ if (lwp_cpptr != pid) {
+ Dispose_of_Dead_PCB(pid);
+ Set_LWP_RC();
+ } else {
+ pid -> status = DESTROYED;
+ move(pid, &runnable[pid->priority], &blocked);
+ temp = lwp_cpptr;
+#ifdef __hp9000s800
+ savecontext(Dispatcher, &(temp -> context),
+ &(LWPANCHOR.dsptchstack[MINFRAME]));
+#else
+ savecontext(Dispatcher, &(temp -> context),
+ &(LWPANCHOR.dsptchstack[(sizeof LWPANCHOR.dsptchstack)-REGSIZE]));
+#endif
+ }
+ return LWP_SUCCESS;
+ } else
+ return LWP_EINIT;
+}
+
+/* explicit voluntary preemption */
+int
+LWP_DispatchProcess(void)
+{
+ Debug(2, ("Entered Dispatch_Process"))
+ if (lwp_init) {
+ Set_LWP_RC();
+ return LWP_SUCCESS;
+ } else
+ return LWP_EINIT;
+}
+
+#ifdef DEBUG
+static void Dump_One_Process(PROCESS pid);
+
+static void
+Dump_Processes(void)
+{
+ if (lwp_init) {
+ register int i;
+ for (i=0; i<MAX_PRIORITIES; i++)
+ for_all_elts(x, runnable[i], {
+ printf("[Priority %d]\n", i);
+ Dump_One_Process(x);
+ })
+ for_all_elts(x, blocked, { Dump_One_Process(x); })
+ } else
+ printf("***LWP: LWP support not initialized\n");
+}
+#endif
+
+/* returns process priority */
+int
+LWP_GetProcessPriority(PROCESS pid, int *priority)
+{
+ Debug(0, ("Entered Get_Process_Priority"))
+ if (lwp_init) {
+ *priority = pid -> priority;
+ return 0;
+ } else
+ return LWP_EINIT;
+}
+
+int
+LWP_InitializeProcessSupport(int priority, PROCESS *pid)
+{
+ PROCESS temp;
+ struct lwp_pcb dummy;
+ register int i;
+
+ Debug(0, ("Entered LWP_InitializeProcessSupport"))
+ if (lwp_init != NULL) return LWP_SUCCESS;
+
+ /* Set up offset for stack checking -- do this as soon as possible */
+ stack_offset = (char *) &dummy.stack - (char *) &dummy;
+
+ if (priority >= MAX_PRIORITIES) return LWP_EBADPRI;
+ for (i=0; i<MAX_PRIORITIES; i++) {
+ runnable[i].head = NULL;
+ runnable[i].count = 0;
+ }
+ blocked.head = NULL;
+ blocked.count = 0;
+ lwp_init = (struct lwp_ctl *) malloc(sizeof(struct lwp_ctl));
+ temp = (PROCESS) malloc(sizeof(struct lwp_pcb));
+ if (lwp_init == NULL || temp == NULL)
+ Abort_LWP("Insufficient Storage to Initialize LWP Support");
+ LWPANCHOR.processcnt = 1;
+ LWPANCHOR.outerpid = temp;
+ LWPANCHOR.outersp = NULL;
+ Initialize_PCB(temp, priority, NULL, 0, NULL, NULL,
+ "Main Process [created by LWP]");
+ insert(temp, &runnable[priority]);
+ savecontext(Dispatcher, &temp->context, NULL);
+ LWPANCHOR.outersp = temp -> context.topstack;
+ Set_LWP_RC();
+ *pid = temp;
+ return LWP_SUCCESS;
+}
+
+/* signal the occurence of an event */
+int
+LWP_INTERNALSIGNAL(void *event, int yield)
+{
+ Debug(2, ("Entered LWP_SignalProcess"))
+ if (lwp_init) {
+ int rc;
+ rc = Internal_Signal(event);
+ if (yield) Set_LWP_RC();
+ return rc;
+ } else
+ return LWP_EINIT;
+}
+
+/* terminate all LWP support */
+int
+LWP_TerminateProcessSupport(void)
+{
+ register int i;
+
+ Debug(0, ("Entered Terminate_Process_Support"))
+ if (lwp_init == NULL) return LWP_EINIT;
+ if (lwp_cpptr != LWPANCHOR.outerpid)
+ Abort_LWP("Terminate_Process_Support invoked from wrong process!");
+ for (i=0; i<MAX_PRIORITIES; i++)
+ for_all_elts(cur, runnable[i], { Free_PCB(cur); })
+ for_all_elts(cur, blocked, { Free_PCB(cur); })
+ free(lwp_init);
+ lwp_init = NULL;
+ return LWP_SUCCESS;
+}
+
+/* wait on m of n events */
+int
+LWP_MwaitProcess(int wcount, char *evlist[])
+{
+ register int ecount, i;
+
+
+ Debug(0, ("Entered Mwait_Process [waitcnt = %d]", wcount))
+
+ if (evlist == NULL) {
+ Set_LWP_RC();
+ return LWP_EBADCOUNT;
+ }
+
+ for (ecount = 0; evlist[ecount] != NULL; ecount++) ;
+
+ if (ecount == 0) {
+ Set_LWP_RC();
+ return LWP_EBADCOUNT;
+ }
+
+ if (lwp_init) {
+
+ if (wcount>ecount || wcount<0) {
+ Set_LWP_RC();
+ return LWP_EBADCOUNT;
+ }
+ if (ecount > lwp_cpptr->eventlistsize) {
+
+ lwp_cpptr->eventlist = (char **)realloc(lwp_cpptr->eventlist,
+ ecount*sizeof(char *));
+ lwp_cpptr->eventlistsize = ecount;
+ }
+ for (i=0; i<ecount; i++) lwp_cpptr -> eventlist[i] = evlist[i];
+ if (wcount > 0) {
+ lwp_cpptr -> status = WAITING;
+
+ move(lwp_cpptr, &runnable[lwp_cpptr->priority], &blocked);
+ }
+ lwp_cpptr -> wakevent = 0;
+ lwp_cpptr -> waitcnt = wcount;
+ lwp_cpptr -> eventcnt = ecount;
+
+ Set_LWP_RC();
+
+ return LWP_SUCCESS;
+ }
+
+ return LWP_EINIT;
+}
+
+/* wait on a single event */
+int
+LWP_WaitProcess(void *event)
+{
+ char *tempev[2];
+
+ Debug(2, ("Entered Wait_Process"))
+ if (event == NULL) return LWP_EBADEVENT;
+ tempev[0] = event;
+ tempev[1] = NULL;
+ return LWP_MwaitProcess(1, tempev);
+}
+
+int
+LWP_StackUsed(PROCESS pid, int *max, int *used)
+{
+ *max = pid -> stacksize;
+ *used = Stack_Used(pid->stack, *max);
+ if (*used == 0)
+ return LWP_NO_STACK;
+ return LWP_SUCCESS;
+}
+
+/*
+ * The following functions are strictly
+ * INTERNAL to the LWP support package.
+ */
+
+static void
+Abort_LWP(char *msg)
+{
+ struct lwp_context tempcontext;
+
+ Debug(0, ("Entered Abort_LWP"))
+ printf("***LWP: %s\n",msg);
+ printf("***LWP: Abort --- dumping PCBs ...\n");
+#ifdef DEBUG
+ Dump_Processes();
+#endif
+ if (LWPANCHOR.outersp == NULL)
+ Exit_LWP();
+ else
+ savecontext(Exit_LWP, &tempcontext, LWPANCHOR.outersp);
+}
+
+/* creates a context for the new process */
+static void
+Create_Process_Part2(void)
+{
+ PROCESS temp;
+
+ Debug(2, ("Entered Create_Process_Part2"))
+ temp = lwp_cpptr; /* Get current process id */
+ savecontext(Dispatcher, &temp->context, NULL);
+ (*temp->ep)(temp->parm);
+ LWP_DestroyProcess(temp);
+}
+
+/* remove a PCB from the process list */
+static void
+Delete_PCB(register PROCESS pid)
+{
+ Debug(4, ("Entered Delete_PCB"))
+ lwp_remove(pid, (pid->blockflag ||
+ pid->status==WAITING ||
+ pid->status==DESTROYED
+ ? &blocked
+ : &runnable[pid->priority]));
+ LWPANCHOR.processcnt--;
+}
+
+#ifdef DEBUG
+static void
+Dump_One_Process(PROCESS pid)
+{
+ int i;
+
+ printf("***LWP: Process Control Block at %p\n", pid);
+ printf("***LWP: Name: %s\n", pid->name);
+ if (pid->ep != NULL)
+ printf("***LWP: Initial entry point: %p\n", pid->ep);
+ if (pid->blockflag) printf("BLOCKED and ");
+ switch (pid->status) {
+ case READY: printf("READY"); break;
+ case WAITING: printf("WAITING"); break;
+ case DESTROYED: printf("DESTROYED"); break;
+ default: printf("unknown");
+ }
+ putchar('\n');
+ printf("***LWP: Priority: %d \tInitial parameter: %p\n",
+ pid->priority, pid->parm);
+ if (pid->stacksize != 0) {
+ printf("***LWP: Stacksize: %d \tStack base address: %p\n",
+ pid->stacksize, pid->stack);
+ printf("***LWP: HWM stack usage: ");
+ printf("%d\n", Stack_Used(pid->stack,pid->stacksize));
+ free (pid->stack);
+ }
+ printf("***LWP: Current Stack Pointer: %p\n", pid->context.topstack);
+ if (pid->eventcnt > 0) {
+ printf("***LWP: Number of events outstanding: %d\n", pid->waitcnt);
+ printf("***LWP: Event id list:");
+ for (i=0;i<pid->eventcnt;i++)
+ printf(" %p", pid->eventlist[i]);
+ putchar('\n');
+ }
+ if (pid->wakevent>0)
+ printf("***LWP: Number of last wakeup event: %d\n", pid->wakevent);
+}
+#endif
+
+static void
+purge_dead_pcbs(void)
+{
+ for_all_elts(cur, blocked, {
+ if (cur->status == DESTROYED) Dispose_of_Dead_PCB(cur);
+ })
+}
+
+int LWP_TraceProcesses = 0;
+
+/* Lightweight process dispatcher */
+static void
+Dispatcher(void)
+{
+ register int i;
+#ifdef DEBUG
+ static int dispatch_count = 0;
+
+ if (LWP_TraceProcesses > 0) {
+ for (i=0; i<MAX_PRIORITIES; i++) {
+ printf("[Priority %d, runnable (%d):", i, runnable[i].count);
+ for_all_elts(p, runnable[i], {
+ printf(" \"%s\"", p->name);
+ })
+ puts("]");
+ }
+ printf("[Blocked (%d):", blocked.count);
+ for_all_elts(p, blocked, {
+ printf(" \"%s\"", p->name);
+ })
+ puts("]");
+ }
+#endif
+
+ /*
+ * Check for stack overflow if this lwp has a stack. Check for
+ * the guard word at the front of the stack being damaged and
+ * for the stack pointer being below the front of the stack.
+ * WARNING! This code assumes that stacks grow downward.
+ */
+#ifdef __hp9000s800
+ /* Fix this (stackcheck at other end of stack???) */
+ if (lwp_cpptr != NULL && lwp_cpptr->stack != NULL
+ && (lwp_cpptr->stackcheck !=
+ *(long *)((lwp_cpptr->stack) + lwp_cpptr->stacksize - 4)
+ || lwp_cpptr->context.topstack >
+ lwp_cpptr->stack + lwp_cpptr->stacksize - 4)) {
+#else
+ if (lwp_cpptr != NULL && lwp_cpptr->stack != NULL
+ && (lwp_cpptr->stackcheck != *(long *)(lwp_cpptr->stack)
+ || lwp_cpptr->context.topstack < lwp_cpptr->stack)) {
+#endif
+
+ printf("stackcheck = %lul: stack = %lul\n",
+ lwp_cpptr->stackcheck,
+ *(long *)lwp_cpptr->stack);
+ printf("topstack = %lul\n", *(long *)lwp_cpptr->context.topstack);
+
+ switch (lwp_overflowAction) {
+ case LWP_SOQUIET:
+ break;
+ case LWP_SOABORT:
+ Overflow_Complain();
+ abort ();
+ case LWP_SOMESSAGE:
+ default:
+ Overflow_Complain();
+ lwp_overflowAction = LWP_SOQUIET;
+ break;
+ }
+ }
+
+
+ /*
+ * Move head of current runnable queue forward if current LWP
+ * is still in it.
+ */
+ if (lwp_cpptr != NULL && lwp_cpptr == runnable[lwp_cpptr->priority].head)
+ runnable[lwp_cpptr->priority].head = runnable[lwp_cpptr->priority].head->next;
+ /* Find highest priority with runnable processes. */
+ for (i=MAX_PRIORITIES-1; i>=0; i--)
+ if (runnable[i].head != NULL) break;
+
+ if (i < 0) Abort_LWP("No READY processes");
+
+#ifdef DEBUG
+ if (LWP_TraceProcesses > 0)
+ printf("Dispatch %d [PCB at %p] \"%s\"\n",
+ ++dispatch_count,
+ runnable[i].head,
+ runnable[i].head->name);
+#endif
+ if (PRE_Block != 1) Abort_LWP("PRE_Block not 1");
+ lwp_cpptr = runnable[i].head;
+
+ returnto(&lwp_cpptr->context);
+}
+
+/* Complain of a stack overflow to stderr without using stdio. */
+static void
+Overflow_Complain (void)
+{
+ static char msg1[] = "LWP: stack overflow in process ";
+ static char msg2[] = "!\n";
+
+ write (2, msg1, sizeof(msg1) - 1);
+ write (2, lwp_cpptr->name, strlen(lwp_cpptr->name));
+ write (2, msg2, sizeof(msg2) - 1);
+}
+
+static void
+Dispose_of_Dead_PCB (PROCESS cur)
+{
+ Debug(4, ("Entered Dispose_of_Dead_PCB"))
+ Delete_PCB(cur);
+ Free_PCB(cur);
+/*
+ Internal_Signal(cur);
+*/
+}
+
+static void
+Exit_LWP(void)
+{
+ abort();
+}
+
+static void
+Free_PCB(PROCESS pid)
+{
+ Debug(4, ("Entered Free_PCB"))
+ if (pid -> stack != NULL) {
+ Debug(0, ("HWM stack usage: %d, [PCB at %p]",
+ Stack_Used(pid->stack,pid->stacksize), pid))
+ free(pid -> stack);
+ }
+ if (pid->eventlist != NULL) free(pid->eventlist);
+ free(pid);
+}
+
+static void
+Initialize_PCB(PROCESS temp, int priority, char *stack, int stacksize,
+ void (*ep)(), char *parm, char *name)
+{
+ register int i = 0;
+
+ Debug(4, ("Entered Initialize_PCB"))
+ if (name != NULL)
+ while (((temp -> name[i] = name[i]) != '\0') && (i < 31)) i++;
+ temp -> name[31] = '\0';
+ temp -> status = READY;
+ temp -> eventlist = (char **)malloc(EVINITSIZE*sizeof(char *));
+ temp -> eventlistsize = EVINITSIZE;
+ temp -> eventcnt = 0;
+ temp -> wakevent = 0;
+ temp -> waitcnt = 0;
+ temp -> blockflag = 0;
+ temp -> iomgrRequest = 0;
+ temp -> priority = priority;
+ temp -> index = lwp_nextindex++;
+ temp -> stack = stack;
+ temp -> stacksize = stacksize;
+#ifdef __hp9000s800
+ if (temp -> stack != NULL)
+ temp -> stackcheck = *(long *) ((temp -> stack) + stacksize - 4);
+#else
+ if (temp -> stack != NULL)
+ temp -> stackcheck = *(long *) (temp -> stack);
+#endif
+ temp -> ep = ep;
+ temp -> parm = parm;
+ temp -> misc = NULL; /* currently unused */
+ temp -> next = NULL;
+ temp -> prev = NULL;
+ temp -> rused = 0;
+ temp -> level = 1; /* non-preemptable */
+}
+
+static int
+Internal_Signal(register char *event)
+{
+ int rc = LWP_ENOWAIT;
+ register int i;
+
+ Debug(0, ("Entered Internal_Signal [event id %p]", event))
+ if (!lwp_init) return LWP_EINIT;
+ if (event == NULL) return LWP_EBADEVENT;
+ for_all_elts(temp, blocked, {
+ if (temp->status == WAITING)
+ for (i=0; i < temp->eventcnt; i++) {
+ if (temp -> eventlist[i] == event) {
+ temp -> eventlist[i] = NULL;
+ rc = LWP_SUCCESS;
+ Debug(0, ("Signal satisfied for PCB %p", temp))
+ if (--temp->waitcnt == 0) {
+ temp -> status = READY;
+ temp -> wakevent = i+1;
+ move(temp, &blocked, &runnable[temp->priority]);
+ break;
+ }
+ }
+ }
+ })
+ return rc;
+}
+
+/* This can be any unlikely pattern except 0x00010203 or the reverse. */
+#define STACKMAGIC 0xBADBADBA
+static long
+Initialize_Stack(char *stackptr, int stacksize)
+{
+ register int i;
+
+ Debug(4, ("Entered Initialize_Stack"))
+ if (lwp_stackUseEnabled)
+ for (i=0; i<stacksize; i++)
+ stackptr[i] = i &0xff;
+ else
+#ifdef __hp9000s800
+ *(long *)(stackptr + stacksize - 4) = STACKMAGIC;
+#else
+ *(long *)stackptr = STACKMAGIC;
+#endif
+ return 0; /* XXX - added. No clue what it should be */
+}
+
+static int
+Stack_Used(register char *stackptr, int stacksize)
+{
+ register int i;
+
+#ifdef __hp9000s800
+ if (*(long *) (stackptr + stacksize - 4) == STACKMAGIC)
+ return 0;
+ else {
+ for (i = stacksize - 1; i >= 0 ; i--)
+ if ((unsigned char) stackptr[i] != (i & 0xff))
+ return (i);
+ return 0;
+ }
+#else
+ if (*(long *) stackptr == STACKMAGIC)
+ return 0;
+ else {
+ for (i = 0; i < stacksize; i++)
+ if ((unsigned char) stackptr[i] != (i & 0xff))
+ return (stacksize - i);
+ return 0;
+ }
+#endif
+}
+
+
+/*
+ * Finds a free rock and sets its value to Value.
+ * Return codes:
+ * LWP_SUCCESS Rock did not exist and a new one was used
+ * LWP_EBADROCK Rock already exists.
+ * LWP_ENOROCKS All rocks are in use.
+
+ * From the above semantics, you can only set a rock value once.
+ * This is specificallY to prevent multiple users of the LWP package from
+ * accidentally using the same Tag value and clobbering others. You can always
+ * use one level of indirection to obtain a rock whose contents can change.
+ */
+
+int
+LWP_NewRock(int Tag, char *Value)
+{
+ register int i;
+ register struct rock *ra; /* rock array */
+
+ ra = lwp_cpptr->rlist;
+
+ for (i = 0; i < lwp_cpptr->rused; i++)
+ if (ra[i].tag == Tag) return(LWP_EBADROCK);
+
+ if (lwp_cpptr->rused < MAXROCKS)
+ {
+ ra[lwp_cpptr->rused].tag = Tag;
+ ra[lwp_cpptr->rused].value = Value;
+ lwp_cpptr->rused++;
+ return(LWP_SUCCESS);
+ }
+ else return(LWP_ENOROCKS);
+}
+
+/*
+ * Obtains the pointer Value associated with the rock Tag of this LWP.
+ * Returns:
+ * LWP_SUCCESS if specified rock exists and Value has been filled
+ * LWP_EBADROCK rock specified does not exist
+ */
+int
+LWP_GetRock(int Tag, char **Value)
+{
+ register int i;
+ register struct rock *ra;
+
+ ra = lwp_cpptr->rlist;
+
+ for (i = 0; i < lwp_cpptr->rused; i++)
+ if (ra[i].tag == Tag)
+ {
+ *Value = ra[i].value;
+ return(LWP_SUCCESS);
+ }
+ return(LWP_EBADROCK);
+}
+
+
+#ifdef AFS_AIX32_ENV
+setlim(limcon, hard, limit)
+ int limcon;
+ uchar_t hard;
+{
+ struct rlimit rlim;
+
+ (void) getrlimit(limcon, &rlim);
+
+ limit = limit * 1024;
+ if (hard)
+ rlim.rlim_max = limit;
+ else if (limit == RLIM_INFINITY && geteuid() != 0)
+ rlim.rlim_cur = rlim.rlim_max;
+ else
+ rlim.rlim_cur = limit;
+
+ /* Must use ulimit() due to Posix constraints */
+ if (limcon == RLIMIT_FSIZE) {
+ if (ulimit(UL_SETFSIZE, ((hard ? rlim.rlim_max : rlim.rlim_cur) / 512)) < 0) {
+ printf("Can't %s%s limit\n",
+ limit == RLIM_INFINITY ? "remove" : "set", hard ? " hard" : "");
+ return (-1);
+ }
+ } else {
+ if (setrlimit(limcon, &rlim) < 0) {
+ perror("");
+ printf("Can't %s%s limit\n",
+ limit == RLIM_INFINITY ? "remove" : "set", hard ? " hard" : "");
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+
+#ifdef notdef
+/*
+ * Print the specific limit out
+ */
+plim(name, lc, hard)
+ char *name;
+ long lc;
+ uchar_t hard;
+{
+ struct rlimit rlim;
+ int lim;
+
+ printf("%s \t", name);
+ (void) getrlimit(lc, &rlim);
+ lim = hard ? rlim.rlim_max : rlim.rlim_cur;
+ if (lim == RLIM_INFINITY)
+ printf("unlimited");
+ printf("%d %s", lim / 1024, "kbytes");
+ printf("\n");
+}
+#endif
+#endif
diff --git a/usr.sbin/afs/src/lwp/lwp_asm.h b/usr.sbin/afs/src/lwp/lwp_asm.h
new file mode 100644
index 00000000000..650505de541
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/lwp_asm.h
@@ -0,0 +1,229 @@
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+/*******************************************************************\
+* *
+* Information Technology Center *
+* Carnegie-Mellon University *
+* *
+* *
+\*******************************************************************/
+
+/* $Id: lwp_asm.h,v 1.1 2000/09/11 14:41:08 art Exp $ */
+
+#ifndef __LWP_INCLUDE_
+#define __LWP_INCLUDE_ 1
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifdef HAVE_POSIX_SIGNALS
+#define AFS_POSIX_SIGNALS 1
+#endif
+
+#define LWP_SUCCESS 0
+#define LWP_EBADPID -1
+#define LWP_EBLOCKED -2
+#define LWP_EINIT -3
+#define LWP_EMAXPROC -4
+#define LWP_ENOBLOCK -5
+#define LWP_ENOMEM -6
+#define LWP_ENOPROCESS -7
+#define LWP_ENOWAIT -8
+#define LWP_EBADCOUNT -9
+#define LWP_EBADEVENT -10
+#define LWP_EBADPRI -11
+#define LWP_NO_STACK -12
+/* These two are for the signal mechanism. */
+#define LWP_EBADSIG -13 /* bad signal number */
+#define LWP_ESYSTEM -14 /* system call failed */
+/* These are for the rock mechanism */
+#define LWP_ENOROCKS -15 /* all rocks are in use */
+#define LWP_EBADROCK -16 /* the specified rock does not exist */
+
+
+/* Maximum priority permissible (minimum is always 0) */
+#define LWP_MAX_PRIORITY 4 /* changed from 1 by Satya, 22 Nov. 85 */
+
+/* Usual priority used by user LWPs */
+#define LWP_NORMAL_PRIORITY (LWP_MAX_PRIORITY-2)
+
+/* Initial size of eventlist in a PCB; grows dynamically */
+#define EVINITSIZE 5
+
+typedef struct lwp_pcb *PROCESS;
+
+struct lwp_context { /* saved context for dispatcher */
+ char *topstack; /* ptr to top of process stack */
+#ifdef sparc
+#ifdef save_allregs
+#ifdef __sparcv9
+#define nregs (7+1+62+2)
+#else
+#define nregs (7+1+32+2+32+2) /* g1-g7, y reg, f0-f31, fsr, fq, c0-c31, csr, cq. */
+#endif
+ long globals[nregs];
+#undef nregs
+#else
+ long globals[8]; /* g1-g7 and y registers. */
+#endif
+#endif
+#if defined(powerpc) || defined(ppc) || defined(powerc)
+ char *linkRegister; /* the contents of the link register */
+ long conditionRegister; /* the contents of the condition register */
+#endif /* defined(powerpc) || defined(ppc) || defined(powerc) */
+};
+
+struct rock
+ {/* to hide things associated with this LWP under */
+ int tag; /* unique identifier for this rock */
+ char *value; /* pointer to some arbitrary data structure */
+ };
+
+#define MAXROCKS 4 /* max no. of rocks per LWP */
+
+struct lwp_pcb { /* process control block */
+ char name[32]; /* ASCII name */
+ int rc; /* most recent return code */
+ char status; /* status flags */
+ char blockflag; /* if (blockflag), process blocked */
+ char eventlistsize; /* size of eventlist array */
+ char padding; /* force 32-bit alignment */
+ char **eventlist; /* ptr to array of eventids */
+ int eventcnt; /* no. of events currently in eventlist array*/
+ int wakevent; /* index of eventid causing wakeup */
+ int waitcnt; /* min number of events awaited */
+ int priority; /* dispatching priority */
+ struct lwp_pcb *misc; /* for LWP internal use only */
+ char *stack; /* ptr to process stack */
+ int stacksize; /* size of stack */
+ long stackcheck; /* first word of stack for overflow checking */
+ void (*ep)(); /* initial entry point */
+ char *parm; /* initial parm for process */
+ struct lwp_context
+ context; /* saved context for next dispatch */
+ int rused; /* no of rocks presently in use */
+ struct rock rlist[MAXROCKS]; /* set of rocks to hide things under */
+ struct lwp_pcb *next, *prev; /* ptrs to next and previous pcb */
+ int level; /* nesting level of critical sections */
+ struct IoRequest *iomgrRequest; /* request we're waiting for */
+ int index; /* LWP index: should be small index; actually is
+ incremented on each lwp_create_process */
+ };
+
+extern int lwp_nextindex; /* Next lwp index to assign */
+
+
+#ifndef LWP_KERNEL
+#define LWP_ActiveProcess (lwp_cpptr+0)
+#define LWP_Index() (LWP_ActiveProcess->index)
+#define LWP_HighestIndex() (lwp_nextindex - 1)
+#define LWP_SignalProcess(event) LWP_INTERNALSIGNAL(event, 1)
+#define LWP_NoYieldSignal(event) LWP_INTERNALSIGNAL(event, 0)
+
+extern
+#endif
+ PROCESS lwp_cpptr; /* pointer to current process pcb */
+
+struct lwp_ctl { /* LWP control structure */
+ int processcnt; /* number of lightweight processes */
+ char *outersp; /* outermost stack pointer */
+ struct lwp_pcb *outerpid; /* process carved by Initialize */
+ struct lwp_pcb *first, last; /* ptrs to first and last pcbs */
+#ifdef __hp9000s800
+ double dsptchstack[100]; /* stack for dispatcher use only */
+ /* force 8 byte alignment */
+#else
+ char dsptchstack[800]; /* stack for dispatcher use only */
+#endif
+};
+
+#ifndef LWP_KERNEL
+extern
+#endif
+ char lwp_debug; /* ON = show LWP debugging trace */
+
+#if defined(AFS_SUN5_ENV) || defined(AFS_LINUX_ENV)
+#define AFS_POSIX_SIGNALS
+#endif
+
+/*
+ * Under hpux, any stack size smaller than 16K seems prone to
+ * overflow problems.
+ */
+#if defined(AFS_HPUX_ENV) || defined(AFS_NEXT_ENV) /*|| defined(AFS_SUN5_ENV)*/
+#define AFS_LWP_MINSTACKSIZE (100 * 1024)
+#else
+#define AFS_LWP_MINSTACKSIZE (100 * 1024)
+#endif /* defined(AFS_HPUX_ENV) */
+
+/* Action to take on stack overflow. */
+#define LWP_SOQUIET 1 /* do nothing */
+#define LWP_SOABORT 2 /* abort the program */
+#define LWP_SOMESSAGE 3 /* print a message and be quiet */
+extern int lwp_overflowAction;
+
+/* Tells if stack size counting is enabled. */
+extern int lwp_stackUseEnabled;
+extern int lwp_MaxStackSeen;
+
+struct timeval;
+
+int LWP_QSignal(PROCESS);
+int LWP_DispatchProcess(void);
+int LWP_InitializeProcessSupport(int, PROCESS *);
+int LWP_DestroyProcess(PROCESS);
+int LWP_QWait(void);
+
+/* exported interface */
+int LWP_CreateProcess(void (*)(), int, int, char *, char *, PROCESS *);
+int LWP_CurrentProcess(PROCESS *);
+int LWP_WaitProcess(void *);
+int LWP_INTERNALSIGNAL(void *, int);
+int LWP_DispatchProcess(void);
+int LWP_GetProcessPriority(PROCESS pid, int *priority);
+int LWP_TerminateProcessSupport(void);
+int LWP_MwaitProcess(int wcount, char *evlist[]);
+int LWP_StackUsed(PROCESS pid, int *max, int *used);
+
+void IOMGR_Sleep(unsigned int);
+int IOMGR_Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+long IOMGR_Poll(void);
+int IOMGR_Cancel(register PROCESS);
+int IOMGR_Initialize(void);
+int IOMGR_SoftSig(void (*aproc)(), char *arock);
+int IOMGR_Finalize(void);
+int IOMGR_Signal (int signo, char *event);
+int IOMGR_CancelSignal (int signo);
+
+int LWP_NewRock(int Tag, char *Value);
+int LWP_GetRock(int Tag, char **Value);
+
+
+#endif /* __LWP_INCLUDE_ */
diff --git a/usr.sbin/afs/src/lwp/lwp_elf.h b/usr.sbin/afs/src/lwp/lwp_elf.h
new file mode 100644
index 00000000000..e17f7ddaeb2
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/lwp_elf.h
@@ -0,0 +1,29 @@
+/*
+ * For common usage of elf platforms
+ *
+ * $Id: lwp_elf.h,v 1.1 2000/09/11 14:41:08 art Exp $
+ */
+
+#ifndef _C_LABEL
+#if !defined(SYSV) && !defined(__ELF__) && !defined(AFS_SUN5_ENV)
+#ifdef __STDC__
+#define _C_LABEL(name) _##name
+#else
+#define _C_LABEL(name) _/**/name
+#endif
+#else /* SYSV || __ELF__ || AFS_SUN5_ENV */
+#define _C_LABEL(name) name
+#endif
+#endif /* _C_LABEL */
+
+#ifndef ENTRY
+#if !defined(SYSV) && !defined(__ELF__) && !defined(AFS_SUN5_ENV)
+#ifdef __STDC__
+#define ENTRY(name) _##name##:
+#else
+#define ENTRY(name) _/**/name/**/:
+#endif
+#else /* SYSV || __ELF__ || AFS_SUN5_ENV */
+#define ENTRY(name) name:
+#endif
+#endif /* _C_LABEL */
diff --git a/usr.sbin/afs/src/lwp/process.aix22.S b/usr.sbin/afs/src/lwp/process.aix22.S
new file mode 100644
index 00000000000..86923c6c124
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.aix22.S
@@ -0,0 +1,120 @@
+/* $Id: process.aix22.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+/*
+#
+# Information Technology Center
+# Carnegie-Mellon University
+#
+*/
+/*
+#
+# Process assembly language assist for Sailboats.
+#
+*/
+
+ .text
+ .globl .savecontext
+ .align 1
+
+/*
+#
+# struct savearea {
+# char *topstack;
+# }
+#
+*/
+
+
+/*# Offsets of fields*/
+.set topstack,0
+
+/*# Stuff to allow saving/restoring registers*/
+.set regspace,64
+.set freg,0
+
+/*
+#
+# savecontext(f, area1, newsp)
+# int (*f)(); struct savearea *area1; char *newsp;
+#
+*/
+
+.savecontext:
+ ai 1,1,-regspace # Save frame pointer & ...
+
+/*# Save registers*/
+ stm 0,0(1) # Change this if save fewer regs.
+ lr 14,0
+/*# Set preemption semaphore*/
+ lis 6,1
+ l 7,4(14)
+ stc 6,0(7)
+/*# r3 = base of savearea*/
+ st 1,topstack(3) # area1->topstack = sp
+/*# New sp is in r4.*/
+ ci 4,0
+ beq L1 # If newsp == 0, no stack switch
+ cas 1,4,0 # Switch to new stack
+L1:
+ l 6,0(2) # r2 = _f
+ balrx 15,6 # f()
+ cas 0,2,0
+ .data 3
+ .globl _savecontext
+_savecontext:
+ .long .savecontext
+ .long _PRE_Block
+/*
+#
+# returnto(area2)
+# struct savearea *area2;
+#
+*/
+
+ .text
+ .globl .returnto
+ .align 1
+.returnto:
+ l 1,topstack(2)
+/*
+# Now in the context of the savecontext stack to be restored.
+# Start with the registers...
+# Clear preemption semaphore
+*/
+ lr 14,0
+ lis 6,0
+ l 7,4(14)
+ stc 6,0(7)
+ lm 0,0(1) # Change if saving fewer regs.
+ brx 15 # Return to previous process
+ ai 1,1,regspace
+ .data 3
+ .globl _returnto
+_returnto:
+ .long .returnto
+ .long _PRE_Block
diff --git a/usr.sbin/afs/src/lwp/process.alpha.S b/usr.sbin/afs/src/lwp/process.alpha.S
new file mode 100644
index 00000000000..0712a9e30db
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.alpha.S
@@ -0,0 +1,205 @@
+/* $Id: process.alpha.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+/* Code for DEC Alpha architecture */
+#ifdef AFS_OSF_ENV
+#include <machine/asm.h>
+#include <machine/regdef.h>
+#define fs0 $f2
+#define fs1 $f3
+#define fs2 $f4
+#define fs3 $f5
+#define fs4 $f6
+#define fs5 $f7
+#define fs6 $f8
+#define fs7 $f9
+#elif AFS_LINUX_ENV
+#define v0 $0
+#define t0 $1
+#define t1 $2
+#define t2 $3
+#define t3 $4
+#define t4 $5
+#define t5 $6
+#define t6 $7
+#define t7 $8
+
+#define s0 $9
+#define s1 $10
+#define s2 $11
+#define s3 $12
+#define s4 $13
+#define s5 $14
+#define s6 $15
+
+#define fp $15
+#define a0 $16
+#define a1 $17
+#define a2 $18
+#define a3 $19
+#define a4 $20
+#define a5 $21
+#define t8 $22
+#define t9 $23
+#define t10 $24
+#define t11 $25
+#define ra $26
+#define pv $27
+#define t12 $27
+#define at $28
+#define gp $29
+#define sp $30
+#define zero $31
+
+#define fs0 $f2
+#define fs1 $f3
+#define fs2 $f4
+#define fs3 $f5
+#define fs4 $f6
+#define fs5 $f7
+#define fs6 $f8
+#define fs7 $f9
+
+#define M_S0 0x00000200
+#define M_S1 0x00000400
+#define M_S2 0x00000800
+#define M_S3 0x00001000
+#define M_S4 0x00002000
+#define M_S5 0x00004000
+#define M_S6 0x00008000
+
+#define M_RA 0x04000000
+
+#define END(proc) \
+ .end proc
+
+#define NESTED(x, fsize, rpc) \
+ .globl x ; \
+ .ent x,0 ; \
+x: ; \
+ .frame sp,fsize, rpc
+
+
+#define LEAF(x) \
+ .globl x ; \
+ .ent x,0 ; \
+x: ; \
+ .frame sp,0,ra
+
+#define IMPORT(sym, size) \
+ .extern sym,size
+#elif defined(HAVE_MACHINE_ASM_H) /* BSD */
+#include <machine/asm.h>
+#elif defined(HAVE_MACH_ALPHA_ASM_H) /* OSF */
+#include <mach/alpha/asm.h>
+#endif
+
+#define FRAMESIZE ((8*8)+8+(7*8))
+#define floats 0
+#define registers (floats+(8*8))
+#define returnaddr (FRAMESIZE-8)
+#define topstack 0
+
+#if defined(AFS_OSF_ENV) || defined(AFS_LINUX_ENV)
+ IMPORT(PRE_Block,4)
+#endif
+.align 4
+#if defined(AFS_OSF_ENV) || defined(AFS_LINUX_ENV)
+NESTED(savecontext,FRAMESIZE,ra)
+#else /* OSF || LINUX */
+NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc)
+#endif /* OSF */
+ ldgp gp,0(pv)
+ lda t0, 1(zero)
+ stl t0, PRE_Block
+ lda sp,-FRAMESIZE(sp)
+/* Save callee-saved registers. */
+ stq s0, (registers+0) (sp)
+ stq s1, (registers+8) (sp)
+ stq s2, (registers+16) (sp)
+ stq s3, (registers+24) (sp)
+ stq s4, (registers+32) (sp)
+ stq s5, (registers+40) (sp)
+ stq s6, (registers+48) (sp)
+/* Save return address */
+ stq ra, returnaddr(sp)
+
+#if !defined(AFS_BSD_ENV)
+ .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE
+#endif
+
+/* Save floating point registers */
+ stt fs0, (floats+0) (sp)
+ stt fs1, (floats+8) (sp)
+ stt fs2, (floats+16) (sp)
+ stt fs3, (floats+24) (sp)
+ stt fs4, (floats+32) (sp)
+ stt fs5, (floats+40) (sp)
+ stt fs6, (floats+48) (sp)
+ stt fs7, (floats+56) (sp)
+
+ .prologue 1
+ stq sp, topstack(a1)
+ or a0,zero,pv /* call point in pv */
+ beq a2, samestack
+ or a2,zero,sp /* switch stack */
+samestack:
+ jsr ra,(pv),0 /* off we go */
+ END(savecontext)
+
+#if defined(AFS_OSF_ENV) || defined(AFS_LINUX_ENV)
+LEAF(returnto)
+#else
+LEAF(returnto,1)
+#endif
+ ldgp gp,0(pv)
+
+ .prologue 1
+ ldq sp, topstack(a0)
+/* Restore callee-saved regs */
+ ldq s0, (registers+0) (sp)
+ ldq s1, (registers+8) (sp)
+ ldq s2, (registers+16) (sp)
+ ldq s3, (registers+24) (sp)
+ ldq s4, (registers+32) (sp)
+ ldq s5, (registers+40) (sp)
+ ldq s6, (registers+48) (sp)
+/* Return address */
+ ldq ra, returnaddr(sp)
+/* Floating point registers */
+ ldt fs0, (floats+0) (sp)
+ ldt fs1, (floats+8) (sp)
+ ldt fs2, (floats+16) (sp)
+ ldt fs3, (floats+24) (sp)
+ ldt fs4, (floats+32) (sp)
+ ldt fs5, (floats+40) (sp)
+ ldt fs6, (floats+48) (sp)
+ ldt fs7, (floats+56) (sp)
+ lda sp, FRAMESIZE(sp)
+ stl zero, PRE_Block
+ RET
+ END(returnto)
diff --git a/usr.sbin/afs/src/lwp/process.hpux.S b/usr.sbin/afs/src/lwp/process.hpux.S
new file mode 100644
index 00000000000..873f9c45c44
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.hpux.S
@@ -0,0 +1,219 @@
+#ifdef AFS_HPUX_ENV
+#ifdef hp9000s300
+/*
+#
+# Process assembly language assist for HP 9000 series 300s.
+#
+*/
+
+ text
+
+/*
+#
+# struct savearea {
+# char *topstack;
+# }
+#
+*/
+
+ global _PRE_Block
+
+ set topstack,0
+
+/* Stuff to allow saving/restoring registers */
+ set NREGS,13
+ set REGS,0x3ffe # d1-d7 & a0-a5
+
+/*
+# savecontext(f, area1, newsp)
+# int (*f)(); struct savearea *area1; char *newsp;
+*/
+
+/* Stack offsets of arguments */
+ set f,8
+ set area1,12
+ set newsp,16
+
+ global _savecontext
+_savecontext:
+ mov.b &1,_PRE_Block # Dont allow any interrupt finagling
+ link %a6,&-(NREGS*4) # Save frame pointer & ...
+ # ... allocate space for nregs registers
+/* Save registers */
+ movem.l &REGS,(%sp)
+
+ mov.l area1(%a6),%a0 # a0 = base of savearea
+ mov.l %sp,topstack(%a0) # area->topstack = sp
+ mov.l newsp(%a6),%d0 # Get new sp
+ beq.b l1 # If newsp == 0, no stack switch
+ mov.l %d0,%sp # Switch to new stack
+l1:
+ mov.l f(%a6),%a0 # a0 = f
+ jsr (%a0) # f()
+
+/* It is impossible to be here, so abort() */
+
+ jsr _abort
+
+/*
+# returnto(area2)
+# struct savearea *area2;
+*/
+
+/* Stack offset of argument */
+set area2,8
+
+ global _returnto
+_returnto:
+ link %a6,&0
+ mov.l area2(%a6),%a0 # Base of savearea
+ mov.l topstack(%a0),%sp # Restore sp
+/* Restore registers */
+ movem.l (%sp),&REGS
+
+ add.l &(NREGS*4),%sp
+ mov.l %sp,%a6 # Argghh...be careful here
+ unlk %a6
+ clr.b _PRE_Block
+ rts # Return to previous process
+#else
+
+/* start of S700 code */
+#ifdef AFS_HPUX_PIC_ENV
+/* this code is PIC */
+ .CODE
+
+ ;
+ ; savecontext(f, area1, newsp)
+ ; int (*f)();
+ ; struct savearea *area1;
+ ; char *newsp;
+ ;
+savecontext
+ .PROC
+ ;
+ ; Callinfo sets up register saves using the ENTRY_GR
+ ; and ENTRY_FR parameters. ENTRY_FR=21 is only valid
+ ; for PA 1.1. (How to deal with this for 800?)
+ ;
+ .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21
+ ; The ENTER statement generates register saves and
+ ; procedure setup.
+ .ENTER
+
+ LDI 1,%r1 ; Store a (char) 1 in
+ LDW T'PRE_Block(0,%r19),%r31 ; global variable
+ STB %r1,0(0,%r31) ; PRE_Block.
+
+
+ COPY %arg0,%r22 ; Copy arg0 (f) to dyncall's input register.
+
+ COMIB,= 0,%arg2,L$0001 ; Compare arg2 (newsp) to 0. Execute the
+ ; next instruction regardless of value.
+ STW %r30,0(0,%arg1) ; Store the stack pointer in the first
+ ; element (0th offset) of arg1 (area1).
+ COPY %arg2,%r30 ; Move arg2 (newsp) into the stack ptr.
+
+L$0001
+ .CALL
+ BL $$dyncall,%r31 ; Dynamic call using pointer in r22.
+ COPY %r31,%r2
+ COPY %r20, %r19 ; restore link table.
+
+ .CALL
+ BL exit,%r2 ; Can't get here, so abort.
+ NOP
+ .LEAVE
+ .PROCEND
+
+ ; returnto(area2)
+ ; struct savearea *area2;
+ ;
+returnto
+ .PROC
+ .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21
+ ; No ENTRY is used since this is a magic routine.
+ LDWS 0(0,%arg0),%r30 ; Load the stack pointer from area2
+
+ LDW T'PRE_Block(0,%r19),%r31 ; set PRE_Block = 0;
+ STB %r0,0(0,%r31)
+ .LEAVE
+ .PROCEND
+
+ .EXPORT savecontext,ENTRY
+ .EXPORT returnto,ENTRY
+ .IMPORT PRE_Block,DATA
+ .IMPORT $$dyncall,MILLICODE
+ .IMPORT exit,CODE
+
+ .END
+#else /* AFS_HPUX_PIC_ENV */
+/* non-pic'ified code */
+ .CODE
+
+ ;
+ ; savecontext(f, area1, newsp)
+ ; int (*f)();
+ ; struct savearea *area1;
+ ; char *newsp;
+ ;
+savecontext
+ .PROC
+ ;
+ ; Callinfo sets up register saves using the ENTRY_GR
+ ; and ENTRY_FR parameters. ENTRY_FR=21 is only valid
+ ; for PA 1.1. (How to deal with this for 800?)
+ ;
+ .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21
+ ; The ENTER statement generates register saves and
+ ; procedure setup.
+ .ENTER
+
+ LDI 1,%r31 ; Store a (char) 1 in
+ ADDIL LR'PRE_Block-$global$,%r27 ; global variable
+ STB %r31,RR'PRE_Block-$global$(0,%r1) ; PRE_Block.
+
+ COPY %r26,%r22 ; Copy arg0 (f) to dyncall's input register.
+
+ COMIB,= 0,%r24,L$0001 ; Compare arg2 (newsp) to 0. Execute the
+ ; next instruction regardless of value.
+ STWS %r30,0(0,%r25) ; Store the stack pointer in the first
+ ; element (0th offset) of arg1 (area1).
+ COPY %r24,%r30 ; Move arg2 (newsp) into the stack ptr.
+
+L$0001
+ .CALL
+ BL $$dyncall,%r31 ; Dynamic call using pointer in r22.
+ COPY %r31,%r2
+
+ .CALL
+ BL abort,%r2 ; Can't get here, so abort.
+ NOP
+ .LEAVE
+ .PROCEND
+
+ ; returnto(area2)
+ ; struct savearea *area2;
+ ;
+returnto
+ .PROC
+ .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21
+ ; No ENTRY is used since this is a magic routine.
+ ADDIL LR'PRE_Block-$global$,%r27 ; PRE_Block = 0
+ STB %r0,RR'PRE_Block-$global$(0,%r1)
+
+ LDWS 0(0,%r26),%r30 ; Load the stack pointer from area2
+ .LEAVE
+ .PROCEND
+
+ .EXPORT savecontext,ENTRY
+ .EXPORT returnto,ENTRY
+ .IMPORT $global$,DATA
+ .IMPORT PRE_Block,DATA
+ .IMPORT $$dyncall,MILLICODE
+ .IMPORT abort,CODE
+
+ .END
+#endif /* AFS_HPUX_PIC_ENV */
+#endif /* hp9000s300 */
+#endif /* AFS_HPUX_ENV */
diff --git a/usr.sbin/afs/src/lwp/process.i386.S b/usr.sbin/afs/src/lwp/process.i386.S
new file mode 100644
index 00000000000..15697b7f0a3
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.i386.S
@@ -0,0 +1,111 @@
+/* $Id: process.i386.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+/* i386 Assembly
+ *
+ * Written by Derek Atkins <warlord@MIT.EDU>
+ * (debugging help by Chris Provenzano <proven@mit.edu>)
+ * 11/1991
+ * + * "ojala que sea correcto!"
+ */
+
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#endif
+
+#include <lwp_elf.h>
+
+
+ .file "process.s"
+
+ .data
+
+ .text
+
+/*
+ * struct savearea {
+ * char *topstack;
+ * }
+ */
+
+ .set topstack,0
+
+/*
+ * savecontext(f, area1, newsp)
+ * int (*f)(); struct savearea *area1; char *newsp;
+ */
+
+/* offsets, to make my life easier! */
+ .set f,8
+ .set area1,12
+ .set newsp,16
+
+.globl _C_LABEL(PRE_Block)
+.globl _C_LABEL(savecontext)
+
+ENTRY(savecontext)
+ pushl %ebp /* New Frame! */
+ movl %esp,%ebp
+ pushal /* Push all registers */
+ movl $1,_C_LABEL(PRE_Block) /* Do not allow any interrupt finagling */
+ movl area1(%ebp),%eax /* eax = base of savearea */
+ movl %esp,topstack(%eax) /* area->topstack = esp */
+ movl newsp(%ebp),%eax /* get new sp into eax */
+ cmpl $0,%eax
+ je L1 /* if new sp is 0 then dont change esp */
+ movl %eax,%esp /* go ahead. make my day! */
+L1:
+ jmp *f(%ebp) /* ebx = &f */
+
+/* Shouldnt be here....*/
+
+ call _C_LABEL(abort)
+
+/*
+ * returnto(area2)
+ * struct savearea *area2;
+ */
+
+/* stack offset */
+ .set area2,8
+
+.globl _C_LABEL(returnto)
+
+ENTRY(returnto)
+ pushl %ebp
+ movl %esp, %ebp /* New frame, to get correct pointer */
+ movl area2(%ebp),%eax /* eax = area2 */
+ movl topstack(%eax),%esp /* restore esp */
+ popal
+ movl $0,_C_LABEL(PRE_Block) /* clear it up... */
+ popl %ebp
+ ret
+
+/* I see, said the blind man, as he picked up his hammer and saw! */
+ pushl $1234
+ call _C_LABEL(abort)
+
diff --git a/usr.sbin/afs/src/lwp/process.ibm032.S b/usr.sbin/afs/src/lwp/process.ibm032.S
new file mode 100644
index 00000000000..858bdba0566
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.ibm032.S
@@ -0,0 +1,109 @@
+/* $Id: process.ibm032.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+|
+| Information Technology Center
+| Carnegie-Mellon University
+|
+|
+ .data
+ .globl .oVncs
+ .set .oVncs,0
+
+ .globl _savecontext
+_savecontext:
+ .long _.savecontext
+
+ .globl _returnto
+_returnto:
+ .long _.returnto
+
+|
+| Process assembly language assist for Sailboats.
+|
+
+ .text
+ .align 2
+
+|
+| struct savearea {
+| char *topstack;
+| }
+|
+
+| Offsets of fields
+.set topstack,0
+
+| Stuff to allow saving/restoring registers
+.set regspace,64
+.set freg,0
+
+|
+| savecontext(f, area1, newsp)
+| int (*f)(); struct savearea *area1; char *newsp;
+|
+
+ .globl _.savecontext
+_.savecontext:
+ ai sp,sp,-regspace | Save frame pointer & ...
+ | ... allocate space for 16 registers
+| Save registers
+ stm r0,0(sp) | Change this if save fewer regs.
+| Set preemption semaphore
+ get r6,$1
+ get r7,$_PRE_Block
+ putc r6,0(r7) | PRE_Block = 1
+| r3 = base of savearea
+ put sp,topstack(r3) | area1->topstack = sp
+| New sp is in r4.
+ cis r4,0
+ be L1 | If newsp == 0, no stack switch
+ cas sp,r4,r0 | Switch to new stack
+L1:
+ get r6,0(r2) | r2 = _f
+ balrx r15,r6 | f()
+ cas r0,r2,r0
+
+|
+| returnto(area2)
+| struct savearea *area2;
+|
+
+ .globl _.returnto
+_.returnto:
+ get sp,topstack(r2)
+| Now in the context of the savecontext stack to be restored.
+| Start with the registers...
+| Clear preemption semaphore
+ get r6,$0
+ get r7,$_PRE_Block
+ putc r6,0(r7) | PRE_Block = 0
+ lm r0,0(sp) | Change if saving fewer regs.
+ brx r15 | Return to previous process
+ ai sp,sp,regspace
+ .data
+ .ltorg
diff --git a/usr.sbin/afs/src/lwp/process.m68k.S b/usr.sbin/afs/src/lwp/process.m68k.S
new file mode 100644
index 00000000000..96b3489d953
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.m68k.S
@@ -0,0 +1,125 @@
+/* $Id: process.m68k.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+#include <lwp_elf.h>
+
+#if !defined(__ELF__) && !defined(sun3)
+#define reg(x) x
+#else /* __ELF__ || sun3 */
+#ifdef __STDC__
+#define reg(x) %##x
+#else
+#define reg(x) %/**/x
+#endif /* __STDC__ */
+#endif /* __ELF__ || sun3 */
+
+/*
+#
+# Information Technology Center
+# Carnegie-Mellon University
+#
+#
+*/
+ .data
+
+/*
+#
+# Process assembly language assist for Suns.
+#
+*/
+
+ .text
+ .even
+
+/*
+#
+# struct savearea {
+# char *topstack;
+# }
+#
+*/
+
+ .globl _C_LABEL(PRE_Block)
+ .globl _C_LABEL(savecontext)
+ .globl _C_LABEL(returnto)
+
+topstack = 0
+
+/* Stuff to allow saving/restoring registers */
+nregs = 13
+regs = 0x3ffe | d1-d7 & a0-a5
+
+/*
+# savecontext(f, area1, newsp)
+# int (*f)(); struct savearea *area1; char *newsp;
+*/
+
+/* Stack offsets of arguments */
+f = 8
+area1 = 12
+newsp = 16
+
+ENTRY(savecontext)
+ movb #1,_C_LABEL(PRE_Block) | Dont allow any interrupt finagling
+ link reg(a6),#-(nregs*4) | Save frame pointer & ...
+ | ... allocate space for nregs registers
+/* Save registers */
+ moveml #regs,reg(sp)@
+
+ movl reg(a6)@(area1),reg(a0) | a0 = base of savearea
+ movl reg(sp),reg(a0)@(topstack) | area->topstack = sp
+ movl reg(a6)@(newsp),reg(d0) | Get new sp
+ jeq forw1 | If newsp == 0, no stack switch
+ movl reg(d0),reg(sp) | Switch to new stack
+forw1:
+ movl reg(a6)@(f),reg(a0) | a0 = f
+ jbsr reg(a0)@ | f()
+
+/* It is impossible to be here, so abort() */
+
+ jbsr _C_LABEL(abort)
+
+/*
+# returnto(area2)
+# struct savearea *area2;
+*/
+
+/* Stack offset of argument */
+area2 = 8
+
+ENTRY(returnto)
+ link reg(a6),#0
+ movl reg(a6)@(area2),reg(a0) | Base of savearea
+ movl reg(a0)@(topstack),reg(sp) | Restore sp
+/* Restore registers */
+ moveml reg(sp)@,#regs
+
+ addl #(nregs*4),reg(sp)
+ movl reg(sp),reg(a6) | Argghh...be careful here
+ unlk reg(a6)
+ clrb _C_LABEL(PRE_Block)
+ rts | Return to previous process
diff --git a/usr.sbin/afs/src/lwp/process.mips.S b/usr.sbin/afs/src/lwp/process.mips.S
new file mode 100644
index 00000000000..bb8dd989899
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.mips.S
@@ -0,0 +1,213 @@
+/* $Id: process.mips.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+#ifdef HAVE_PIC
+ .option pic2
+
+#if defined(HAVE_MACHINE_REGDEF_H)
+#include <machine/regdef.h>
+#elif defined(HAVE_REGDEF_H)
+#include <regdef.h>
+#endif
+
+/* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */
+#define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4
+#define floats 0
+#define registers floats + 6 * 8
+#define returnaddr regspace - 4
+#define topstack 0
+#define GPOFF regspace - 8
+ .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
+ .ent savecontext /* Insert debugger information. */
+savecontext:
+ .set noreorder
+ .cpload t9 # set up gp for KPIC
+ .set reorder
+ subu sp, regspace
+ .cprestore GPOFF # trigger t9/jalr
+ .set noreorder
+ li t0, 1
+ .extern PRE_Block
+ sb t0, PRE_Block
+ .set reorder
+ .frame sp, regspace, ra
+/* Save registers. */
+ sw s0, registers + 0(sp)
+ sw s1, registers + 4(sp)
+ sw s2, registers + 8(sp)
+ sw s3, registers + 12(sp)
+ sw s4, registers + 16(sp)
+ sw s5, registers + 20(sp)
+ sw s6, registers + 24(sp)
+ sw s7, registers + 28(sp)
+ sw s8, registers + 32(sp)
+/* Save return address */
+ sw ra, returnaddr(sp)
+ .mask 0xc0ff0000, -4
+/* Need to save floating point registers? */
+ s.d $f20, floats + 0(sp)
+ s.d $f22, floats + 8(sp)
+ s.d $f24, floats + 16(sp)
+ s.d $f26, floats + 24(sp)
+ s.d $f28, floats + 32(sp)
+ s.d $f30, floats + 40(sp)
+ .fmask 0x55400000, regspace
+ sw sp, topstack(a1)
+ beq a2, $0, samestack
+ move sp, a2
+samestack:
+ move t9, a0
+ j t9
+ .end savecontext
+
+ .globl returnto
+ .ent returnto
+returnto:
+ .set noreorder
+ .cpload t9 # set up gp for KPIC
+ .set reorder
+
+ lw sp, topstack(a0)
+ lw s0, registers + 0(sp)
+ lw s1, registers + 4(sp)
+ lw s2, registers + 8(sp)
+ lw s3, registers + 12(sp)
+ lw s4, registers + 16(sp)
+ lw s5, registers + 20(sp)
+ lw s6, registers + 24(sp)
+ lw s7, registers + 28(sp)
+ lw s8, registers + 32(sp)
+/* Save return address */
+ lw ra, returnaddr(sp)
+/* Need to save floating point registers? */
+ l.d $f20, floats + 0(sp)
+ l.d $f22, floats + 8(sp)
+ l.d $f24, floats + 16(sp)
+ l.d $f26, floats + 24(sp)
+ l.d $f28, floats + 32(sp)
+ l.d $f30, floats + 40(sp)
+ .set noreorder
+ addu sp, regspace
+ la t0, PRE_Block
+ j ra
+ sb zero, 0(t0)
+ .set reorder
+ .end returnto
+
+#else
+/* Code for MIPS R2000/R3000 architecture
+ * Written by Zalman Stern April 30th, 1989.
+ */
+
+#if defined(HAVE_REGDEF_H)
+#include <regdef.h> /* Allow use of symbolic names for registers. */
+#else
+#define sp $29
+#define ra $31
+#define t0 $8
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define s0 $16
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define s8 $30
+#endif
+
+#define regspace 9 * 4 + 4 + 6 * 8
+#define floats 0
+#define registers floats + 6 * 8
+#define returnaddr regspace - 4
+#define topstack 0
+ .globl savecontext /* MIPS' C compiler doesnt prepend underscores. */
+ .ent savecontext /* Insert debugger information. */
+savecontext:
+ li t0, 1
+ .extern PRE_Block
+ sb t0, PRE_Block
+ subu sp, regspace
+ .frame sp, regspace, ra
+/* Save registers. */
+ sw s0, registers + 0(sp)
+ sw s1, registers + 4(sp)
+ sw s2, registers + 8(sp)
+ sw s3, registers + 12(sp)
+ sw s4, registers + 16(sp)
+ sw s5, registers + 20(sp)
+ sw s6, registers + 24(sp)
+ sw s7, registers + 28(sp)
+ sw s8, registers + 32(sp)
+/* Save return address */
+ sw ra, returnaddr(sp)
+ .mask 0xc0ff0000, -4
+/* Need to save floating point registers? */
+ s.d $f20, floats + 0(sp)
+ s.d $f22, floats + 8(sp)
+ s.d $f24, floats + 16(sp)
+ s.d $f26, floats + 24(sp)
+ s.d $f28, floats + 32(sp)
+ s.d $f30, floats + 40(sp)
+ .fmask 0x55400000, regspace
+ sw sp, topstack(a1)
+ beq a2, $0, samestack
+ addu sp, $0, a2
+samestack:
+ jal a0
+ .end savecontext
+
+ .globl returnto
+ .ent returnto
+returnto:
+ lw sp, topstack(a0)
+ lw s0, registers + 0(sp)
+ lw s1, registers + 4(sp)
+ lw s2, registers + 8(sp)
+ lw s3, registers + 12(sp)
+ lw s4, registers + 16(sp)
+ lw s5, registers + 20(sp)
+ lw s6, registers + 24(sp)
+ lw s7, registers + 28(sp)
+ lw s8, registers + 32(sp)
+/* Save return address */
+ lw ra, returnaddr(sp)
+/* Need to save floating point registers? */
+ l.d $f20, floats + 0(sp)
+ l.d $f22, floats + 8(sp)
+ l.d $f24, floats + 16(sp)
+ l.d $f26, floats + 24(sp)
+ l.d $f28, floats + 32(sp)
+ l.d $f30, floats + 40(sp)
+ addu sp, regspace
+ sb $0, PRE_Block
+ j ra
+ .end returnto
+#endif /* HAVE_PIC */
diff --git a/usr.sbin/afs/src/lwp/process.patch.S b/usr.sbin/afs/src/lwp/process.patch.S
new file mode 100644
index 00000000000..e1db4307bc3
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.patch.S
@@ -0,0 +1,80 @@
+--- arla-0.23/lwp/process.S~ Sun Mar 28 16:13:33 1999
++++ arla-0.23/lwp/process.S Fri Aug 13 09:35:56 1999
+@@ -207,7 +207,7 @@
+ #
+ */
+
+- .globl _PRE_Block
++ .globl PRE_Block
+
+ topstack = 0
+
+@@ -225,26 +225,26 @@
+ area1 = 12
+ newsp = 16
+
+- .globl _savecontext
+-_savecontext:
+- movb #1,_PRE_Block | Dont allow any interrupt finagling
+- link a6,#-(nregs*4) | Save frame pointer & ...
++ .globl savecontext
++savecontext:
++ movb #1,PRE_Block | Dont allow any interrupt finagling
++ link %a6,#-(nregs*4) | Save frame pointer & ...
+ | ... allocate space for nregs registers
+ /* Save registers */
+- moveml #regs,sp@
++ moveml #regs,%sp@
+
+- movl a6@(area1),a0 | a0 = base of savearea
+- movl sp,a0@(topstack) | area->topstack = sp
+- movl a6@(newsp),d0 | Get new sp
++ movl %a6@(area1),%a0 | a0 = base of savearea
++ movl %sp,%a0@(topstack) | area->topstack = sp
++ movl %a6@(newsp),%d0 | Get new sp
+ jeq forw1 | If newsp == 0, no stack switch
+- movl d0,sp | Switch to new stack
++ movl %d0,%sp | Switch to new stack
+ forw1:
+- movl a6@(f),a0 | a0 = f
+- jbsr a0@ | f()
++ movl %a6@(f),%a0 | a0 = f
++ jbsr %a0@ | f()
+
+ /* It is impossible to be here, so abort() */
+
+- jbsr _abort
++ jbsr abort
+
+ /*
+ # returnto(area2)
+@@ -254,18 +254,18 @@
+ /* Stack offset of argument */
+ area2 = 8
+
+- .globl _returnto
+-_returnto:
+- link a6,#0
+- movl a6@(area2),a0 | Base of savearea
+- movl a0@(topstack),sp | Restore sp
++ .globl returnto
++returnto:
++ link %a6,#0
++ movl %a6@(area2),%a0 | Base of savearea
++ movl %a0@(topstack),%sp | Restore sp
+ /* Restore registers */
+- moveml sp@,#regs
++ moveml %sp@,#regs
+
+- addl #(nregs*4),sp
+- movl sp,a6 | Argghh...be careful here
+- unlk a6
+- clrb _PRE_Block
++ addl #(nregs*4),%sp
++ movl %sp,%a6 | Argghh...be careful here
++ unlk %a6
++ clrb PRE_Block
+ rts | Return to previous process
+ #endif /* mc68000 */
+
+
diff --git a/usr.sbin/afs/src/lwp/process.ppc.S b/usr.sbin/afs/src/lwp/process.ppc.S
new file mode 100644
index 00000000000..20be513e86b
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.ppc.S
@@ -0,0 +1,182 @@
+/* $Id: process.ppc.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+
+/* Comments:
+ * 1. Registers R10..R31 and CR0..CR7 are saved
+ * 2. "struct savearea" must hold at least 3 pointers (long)
+ * 3. This code will only work on 32 bit machines (601..604), not 620
+ * 4. No floating point registers are saved
+ * 5. The save stack "frame" is bigger than absolutely necessary. The
+ * PowerPC [AIX] ABI needs this extra space.
+ */
+
+
+/* Mach-O assemblers */
+#if !defined(NeXT) && !defined(__APPLE__)
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+#define r13 13
+#define r14 14
+#define r15 15
+#define r16 16
+#define r17 17
+#define r18 18
+#define r19 19
+#define r20 20
+#define r21 21
+#define r22 22
+#define r23 23
+#define r24 24
+#define r25 25
+#define r26 26
+#define r27 27
+#define r28 28
+#define r29 29
+#define r30 30
+#define r31 31
+#endif /* !NeXT && !__APPLE__ */
+
+
+/*
+ * savecontext(int (*f)(), struct savearea *save, char *newsp)
+ */
+
+#define FRAME_SIZE (32*4)+(8*4)
+#define FRAME_OFFSET (8*4)
+
+#define TOP_OF_STACK (0*4)
+#define RETURN (1*4)
+#define CCR (2*4)
+
+#if defined(NeXT) || defined(__APPLE__)
+ .globl _savecontext
+_savecontext:
+ lis r9,ha16(_PRE_Block) /* Disable interrupt fiddling */
+ li r8,1
+ stb r8,lo16(_PRE_Block)(r9)
+#else
+ .globl savecontext
+savecontext:
+ lis r9,PRE_Block@ha /* Disable interrupt fiddling */
+ li r8,1
+ stb r8,PRE_Block@l(r9)
+#endif /* NeXT || __APPLE__ */
+ subi r1,r1,FRAME_SIZE
+ mfcr r9
+ stw r9,CCR(r4)
+ stw r10,10*4+FRAME_OFFSET(r1) /* Save registers */
+ stw r11,11*4+FRAME_OFFSET(r1)
+ stw r12,12*4+FRAME_OFFSET(r1)
+ stw r13,13*4+FRAME_OFFSET(r1)
+ stw r14,14*4+FRAME_OFFSET(r1)
+ stw r15,15*4+FRAME_OFFSET(r1)
+ stw r16,16*4+FRAME_OFFSET(r1)
+ stw r17,17*4+FRAME_OFFSET(r1)
+ stw r18,18*4+FRAME_OFFSET(r1)
+ stw r19,19*4+FRAME_OFFSET(r1)
+ stw r20,20*4+FRAME_OFFSET(r1)
+ stw r21,21*4+FRAME_OFFSET(r1)
+ stw r22,22*4+FRAME_OFFSET(r1)
+ stw r23,23*4+FRAME_OFFSET(r1)
+ stw r24,24*4+FRAME_OFFSET(r1)
+ stw r25,25*4+FRAME_OFFSET(r1)
+ stw r26,26*4+FRAME_OFFSET(r1)
+ stw r27,27*4+FRAME_OFFSET(r1)
+ stw r28,28*4+FRAME_OFFSET(r1)
+ stw r29,29*4+FRAME_OFFSET(r1)
+ stw r30,30*4+FRAME_OFFSET(r1)
+ stw r31,31*4+FRAME_OFFSET(r1)
+ stw r1,TOP_OF_STACK(r4)
+ cmpi 0,r5,0 /* New stack specified? */
+ mflr r0
+ stw r0,RETURN(r4)
+ mtlr r3
+ beq L1 /* No - don't muck with pointer */
+
+ mr r1,r5
+L1: blr /* Return */
+
+/*
+ * returnto(struct savearea *area)
+ */
+#if defined(NeXT) || defined(__APPLE__)
+ .globl _returnto
+_returnto:
+#else
+ .globl returnto
+returnto:
+#endif /* NeXT || __APPLE__ */
+ lwz r1,TOP_OF_STACK(r3) /* Update stack pointer */
+ lwz r0,RETURN(r3) /* Get return address */
+ mtlr r0
+ lwz r4,CCR(r3)
+ mtcrf 0xFF,r4
+ lwz r10,10*4+FRAME_OFFSET(r1) /* Restore registers */
+ lwz r11,11*4+FRAME_OFFSET(r1)
+ lwz r12,12*4+FRAME_OFFSET(r1)
+ lwz r13,13*4+FRAME_OFFSET(r1)
+ lwz r14,14*4+FRAME_OFFSET(r1)
+ lwz r15,15*4+FRAME_OFFSET(r1)
+ lwz r16,16*4+FRAME_OFFSET(r1)
+ lwz r17,17*4+FRAME_OFFSET(r1)
+ lwz r18,18*4+FRAME_OFFSET(r1)
+ lwz r19,19*4+FRAME_OFFSET(r1)
+ lwz r20,20*4+FRAME_OFFSET(r1)
+ lwz r21,21*4+FRAME_OFFSET(r1)
+ lwz r22,22*4+FRAME_OFFSET(r1)
+ lwz r23,23*4+FRAME_OFFSET(r1)
+ lwz r24,24*4+FRAME_OFFSET(r1)
+ lwz r25,25*4+FRAME_OFFSET(r1)
+ lwz r26,26*4+FRAME_OFFSET(r1)
+ lwz r27,27*4+FRAME_OFFSET(r1)
+ lwz r28,28*4+FRAME_OFFSET(r1)
+ lwz r29,29*4+FRAME_OFFSET(r1)
+ lwz r30,30*4+FRAME_OFFSET(r1)
+ lwz r31,31*4+FRAME_OFFSET(r1)
+#if defined(NeXT) || defined(__APPLE__)
+ lis r9,ha16(_PRE_Block) /* Re-enable interrupt fiddling */
+ li r8,0
+ stb r8,lo16(_PRE_Block)(r9)
+#else
+ lis r9,PRE_Block@ha /* Re-enable interrupt fiddling */
+ li r8,0
+ stb r8,PRE_Block@l(r9)
+#endif /* NeXT || __APPLE__ */
+ addi r1,r1,FRAME_SIZE
+ blr
diff --git a/usr.sbin/afs/src/lwp/process.rios.S b/usr.sbin/afs/src/lwp/process.rios.S
new file mode 100644
index 00000000000..b676f16cd6d
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.rios.S
@@ -0,0 +1,179 @@
+/* $Id: process.rios.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+/* lws 92.11.18 I don't know if we have to save the TOC (R2) or not...
+ * Note that stack-frame is supposed to be aligned on
+ * a double-word boundary.
+ * For details about RIOS calling conventions
+ * see the Assembler manual and /usr/include/sys/asdef.s
+ */
+
+
+/*
+ * savecontext(f, area1, newsp)
+ * int (*f)(); struct savearea *area1; char *newsp;
+ */
+ .set topstack, 0
+ .set cr0, 0
+ .set toc, 2
+ .set r0, 0
+ .set r1, 1
+ .set r2, 2
+ .set r3, 3
+ .set r4, 4
+ .set r5, 5
+ .set r6, 6
+ .set r7, 7
+ .set r12, 12
+ .set a_f, r3
+ .set a_area1, r4
+ .set a_newsp, r5
+
+ .set argarea, 32
+ .set linkarea, 24
+ .set nfprs, 18
+ .set ngprs, 20
+ .set szdsa, 8*nfprs+4*ngprs+linkarea+argarea
+
+ .csect .savecontext[PR]
+ .globl .savecontext[PR]
+
+ mflr r0 # save link register
+
+/*
+ * save floating point registers. Interleave some other stuff for
+ * timing reasons. Set up conditions and registers for branches
+ * early, so that processor can prefetch instructions.
+ */
+ stfd 14, -144(1)
+ stfd 15, -136(1)
+
+ mfcr r12 # save CR
+
+ stfd 16, -128(1)
+ stfd 17, -120(1)
+
+ l 11, 0(a_f) # r11 <- *(a_f)
+
+ stfd 18, -112(1)
+ stfd 19, -104(1)
+
+ cmpi cr0, a_newsp, 0 # cr0 <- (a_newsp :: 0)
+
+ stfd 20, -96(1)
+ stfd 21, -88(1)
+ stfd 22, -80(1)
+
+ mtlr 11 # set up lr early so prefetch works
+
+ stfd 23, -72(1)
+ stfd 24, -64(1)
+ stfd 25, -56(1)
+
+ st r0, 8(r1) # save return addr
+
+ stfd 26, -48(1)
+ stfd 27, -40(1)
+ stfd 28, -32(1)
+
+ st 12, 4(r1) # save CR
+
+ stfd 29, -24(1)
+ stfd 30, -16(1)
+ stfd 31, -8(1)
+
+/*
+ * save general-purpose registers
+ */
+ stm 12, -8*nfprs-4*ngprs(r1)# save the general-purpose regs
+ stu r1, -szdsa(r1) # dec SP and save back chain
+
+ l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
+ cal r6, 1(r0) # r6 <- #1
+ stb r6, 0(r7) # r6 -> PRE_Block
+
+ st r1, topstack(a_area1) # save old SP
+
+ beq L1 # if (a_newsp == 0) goto L1
+
+ mr r1, r5 # r1 <- a_newsp -- load new SP
+
+L1: brl # pc <- lr -- (*a_f)()
+
+/*
+ * returnto(area2) This is a little jumbled, I tried to interleave
+ * memory accesses with simple instructions for speed, and I tried to
+ * set up the link register and condition register reasonably early
+ * so that processor instruction prefetching might help us out a little.
+ */
+ .set a_area2, r3
+
+ .csect .returnto[PR]
+ .globl .returnto[PR]
+
+ l r1, topstack(a_area2) # r1 <- a_area2->topstack
+ cal r1, szdsa(r1) # pop off frame
+ l r7, PRE_Block.S(toc) # r7 <- &PRE_Block
+
+ l 8, 8(1) # restore lr
+ mtlr 8 # do it early so prefetch works
+
+ lm 12, -8*nfprs-4*ngprs(r1)
+ cal r6, 0(r0) # r6 <- #0
+ mtcrf 0x38, 12 # put back cr
+ stb r6, 0(r7) # r6 -> PRE_Block
+
+/*
+ * restore FPRs here!
+ */
+ lfd 14, -144(1)
+ lfd 15, -136(1)
+ lfd 16, -128(1)
+ lfd 17, -120(1)
+ lfd 18, -112(1)
+ lfd 19, -104(1)
+ lfd 20, -96(1)
+ lfd 21, -88(1)
+ lfd 22, -80(1)
+ lfd 23, -72(1)
+ lfd 24, -64(1)
+ lfd 25, -56(1)
+ lfd 26, -48(1)
+ lfd 27, -40(1)
+ lfd 28, -32(1)
+ lfd 29, -24(1)
+ lfd 30, -16(1)
+ lfd 31, -8(1)
+
+ brl # pc <- lr -- return
+
+ .toc
+
+PRE_Block.S:
+ .tc PRE_Block[tc], PRE_Block[ua]
+ .extern PRE_Block[ua]
+
diff --git a/usr.sbin/afs/src/lwp/process.sparc.S b/usr.sbin/afs/src/lwp/process.sparc.S
new file mode 100644
index 00000000000..b67744f11ea
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.sparc.S
@@ -0,0 +1,534 @@
+/* $Id: process.sparc.S,v 1.1 2000/09/11 14:41:09 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+#if defined(AFS_SUN5_ENV)
+#include <sys/asm_linkage.h>
+#include <sys/trap.h>
+#ifndef STACK_BIAS
+#define STACK_BIAS 0
+#endif
+#elif defined(AFS_BSD_ENV)
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#endif
+#include <machine/trap.h>
+#define ST_FLUSH_WINDOWS ST_FLUSHWIN
+#define MINFRAME 92
+#define SA(x) (((x)+7)&~7)
+#define STACK_ALIGN 8
+#define STACK_BIAS 0
+#elif defined(AFS_LINUX_ENV)
+#define AFS_SUN5_ENV 1 /* Make believe this is Solaris */
+#define ST_FLUSH_WINDOWS 0x03 /* XXX: from asm/traps.h */
+#define MINFRAME 92
+#define SA(x) (((x)+7)&~7)
+#define STACK_ALIGN 8
+#define STACK_BIAS 0
+#else /* SunOS4 */
+#include <sun4/asm_linkage.h>
+#include <sun4/trap.h>
+#define STACK_BIAS 0
+#endif
+
+#include <lwp_elf.h>
+
+ .data
+ .globl _C_LABEL(PRE_Block)
+/*
+# savecontext(f, area1, newsp)
+# int (*f)(); struct savearea *area1; char *newsp;
+*/
+
+ .text
+ .globl _C_LABEL(savecontext)
+ENTRY(savecontext)
+ save %sp, -SA(MINFRAME), %sp ! Get new window
+ ta ST_FLUSH_WINDOWS ! FLush all other active windows
+
+ /* The following 3 lines do the equivalent of: _PRE_Block = 1 */
+#ifdef AFS_SUN5_ENV
+
+#ifdef __sparcv9
+ sethi %hh(PRE_Block),%l0
+ or %l0,%hm(PRE_Block),%l0
+ sethi %lm(PRE_Block),%g1
+ or %g1,%lo(PRE_Block),%g1
+ sllx %l0,32,%l0
+ or %l0,%g1,%l0
+#else
+ sethi %hi(PRE_Block),%l0
+ or %l0,%lo(_C_LABEL(PRE_Block)),%l0
+#endif
+#else /* AFS_SUN5_ENV */
+ set _C_LABEL(PRE_Block), %l0
+#endif
+ mov 1,%l1
+ stb %l1, [%l0]
+
+#ifdef __sparcv9
+
+topstack = 0
+globals = 8
+
+ /* These declarations are needed if you're running Solaris 7,
+ * and are compiling with -xarch=v9 and have an as from WorkShop
+ * Compilers 5.0 98/12/21 (or more recent). Hopefully,
+ * AS_UNDERSTANDS_REGISTER will be set correctly by configure, if
+ * that's not the case, edit here and send a bug report.
+ */
+
+#if AS_UNDERSTANDS_REGISTER
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .register %g6, #scratch
+ .register %g7, #scratch
+#endif
+
+ stx %fp,[%i1+topstack] ! area1->topstack = sp
+
+ stx %g1, [%i1 + globals + 0] /* Save all globals just in case */
+ stx %g2, [%i1 + globals + 8]
+ stx %g3, [%i1 + globals + 16]
+ stx %g4, [%i1 + globals + 24]
+ stx %g5, [%i1 + globals + 32]
+ stx %g6, [%i1 + globals + 40]
+ stx %g7, [%i1 + globals + 48]
+ mov %y, %g1
+ stx %g1, [%i1 + globals + 56]
+
+#ifdef save_allregs
+ stx %f0, [%i1 + globals + 64 + 0]
+ stx %f1, [%i1 + globals + 64 + 8]
+ stx %f2, [%i1 + globals + 64 + 16]
+ stx %f3, [%i1 + globals + 64 + 24]
+ stx %f4, [%i1 + globals + 64 + 32]
+ stx %f5, [%i1 + globals + 64 + 40]
+ stx %f6, [%i1 + globals + 64 + 48]
+ stx %f7, [%i1 + globals + 64 + 56]
+ stx %f8, [%i1 + globals + 64 + 64]
+ stx %f9, [%i1 + globals + 64 + 72]
+ stx %f10, [%i1 + globals + 64 + 80]
+ stx %f11, [%i1 + globals + 64 + 88]
+ stx %f12, [%i1 + globals + 64 + 96]
+ stx %f13, [%i1 + globals + 64 + 104]
+ stx %f14, [%i1 + globals + 64 + 112]
+ stx %f15, [%i1 + globals + 64 + 120]
+ stx %f16, [%i1 + globals + 64 + 128]
+ stx %f17, [%i1 + globals + 64 + 136]
+ stx %f18, [%i1 + globals + 64 + 144]
+ stx %f19, [%i1 + globals + 64 + 152]
+ stx %f20, [%i1 + globals + 64 + 160]
+ stx %f21, [%i1 + globals + 64 + 168]
+ stx %f22, [%i1 + globals + 64 + 176]
+ stx %f23, [%i1 + globals + 64 + 184]
+ stx %f24, [%i1 + globals + 64 + 192]
+ stx %f25, [%i1 + globals + 64 + 200]
+ stx %f26, [%i1 + globals + 64 + 208]
+ stx %f27, [%i1 + globals + 64 + 216]
+ stx %f28, [%i1 + globals + 64 + 224]
+ stx %f29, [%i1 + globals + 64 + 232]
+ stx %f30, [%i1 + globals + 64 + 240]
+ stx %f31, [%i1 + globals + 64 + 248]
+ stx %f32, [%i1 + globals + 64 + 256]
+ stx %f33, [%i1 + globals + 64 + 264]
+ stx %f34, [%i1 + globals + 64 + 272]
+ stx %f35, [%i1 + globals + 64 + 280]
+ stx %f36, [%i1 + globals + 64 + 288]
+ stx %f37, [%i1 + globals + 64 + 296]
+ stx %f38, [%i1 + globals + 64 + 304]
+ stx %f39, [%i1 + globals + 64 + 312]
+ stx %f40, [%i1 + globals + 64 + 320]
+ stx %f41, [%i1 + globals + 64 + 328]
+ stx %f42, [%i1 + globals + 64 + 336]
+ stx %f43, [%i1 + globals + 64 + 344]
+ stx %f44, [%i1 + globals + 64 + 352]
+ stx %f45, [%i1 + globals + 64 + 360]
+ stx %f46, [%i1 + globals + 64 + 368]
+ stx %f47, [%i1 + globals + 64 + 376]
+ stx %f48, [%i1 + globals + 64 + 384]
+ stx %f49, [%i1 + globals + 64 + 392]
+ stx %f50, [%i1 + globals + 64 + 400]
+ stx %f51, [%i1 + globals + 64 + 408]
+ stx %f52, [%i1 + globals + 64 + 416]
+ stx %f53, [%i1 + globals + 64 + 424]
+ stx %f54, [%i1 + globals + 64 + 432]
+ stx %f55, [%i1 + globals + 64 + 440]
+ stx %f56, [%i1 + globals + 64 + 448]
+ stx %f57, [%i1 + globals + 64 + 456]
+ stx %f59, [%i1 + globals + 64 + 464]
+ stx %f60, [%i1 + globals + 64 + 472]
+ stx %f61, [%i1 + globals + 64 + 480]
+#ifdef notdef
+ mov %fsr,%g1
+ stx %g1, [%i1 + globals + 64 + 488]
+ mov %fq,%g1
+ stx %g1, [%i1 + globals + 64 + 496]
+#endif
+
+#endif
+
+#else /* !__sparcv9 */
+
+topstack = 0
+globals = 4
+
+ st %fp,[%i1+topstack] ! area1->topstack = sp
+
+ st %g1, [%i1 + globals + 0] /* Save all globals just in case */
+ st %g2, [%i1 + globals + 4]
+ st %g3, [%i1 + globals + 8]
+ st %g4, [%i1 + globals + 12]
+ st %g5, [%i1 + globals + 16]
+ st %g6, [%i1 + globals + 20]
+ st %g7, [%i1 + globals + 24]
+ mov %y, %g1
+ st %g1, [%i1 + globals + 28]
+
+#ifdef save_allregs
+ st %f0, [%i1 + globals + 32 + 0] ! Save all floating point registers
+ st %f1, [%i1 + globals + 32 + 4]
+ st %f2, [%i1 + globals + 32 + 8]
+ st %f3, [%i1 + globals + 32 + 12]
+ st %f4, [%i1 + globals + 32 + 16]
+ st %f5, [%i1 + globals + 32 + 20]
+ st %f6, [%i1 + globals + 32 + 24]
+ st %f7, [%i1 + globals + 32 + 28]
+ st %f8, [%i1 + globals + 64 + 0]
+ st %f9, [%i1 + globals + 64 + 4]
+ st %f10, [%i1 + globals + 64 + 8]
+ st %f11, [%i1 + globals + 64 + 12]
+ st %f12, [%i1 + globals + 64 + 16]
+ st %f13, [%i1 + globals + 64 + 20]
+ st %f14, [%i1 + globals + 64 + 24]
+ st %f15, [%i1 + globals + 64 + 28]
+ st %f16, [%i1 + globals + 64 + 32]
+ st %f17, [%i1 + globals + 64 + 36]
+ st %f18, [%i1 + globals + 64 + 40]
+ st %f19, [%i1 + globals + 64 + 44]
+ st %f20, [%i1 + globals + 64 + 48]
+ st %f21, [%i1 + globals + 64 + 52]
+ st %f22, [%i1 + globals + 64 + 56]
+ st %f23, [%i1 + globals + 64 + 60]
+ st %f24, [%i1 + globals + 64 + 64]
+ st %f25, [%i1 + globals + 64 + 68]
+ st %f26, [%i1 + globals + 64 + 72]
+ st %f27, [%i1 + globals + 64 + 76]
+ st %f28, [%i1 + globals + 64 + 80]
+ st %f29, [%i1 + globals + 64 + 84]
+ st %f30, [%i1 + globals + 64 + 88]
+ st %f31, [%i1 + globals + 64 + 92]
+#ifdef notdef
+ mov %fsr,%g1
+ st %g1, [%i1 + globals + 64 + 96]
+ mov %fq,%g1
+ st %g1, [%i1 + globals + 64 + 100]
+#endif
+
+ st %c0, [%i1 + globals + 168 + 0] ! Save all coprocessor registers
+ st %c1, [%i1 + globals + 168 + 4]
+ st %c2, [%i1 + globals + 168 + 8]
+ st %c3, [%i1 + globals + 168 + 12]
+ st %c4, [%i1 + globals + 168 + 16]
+ st %c5, [%i1 + globals + 168 + 20]
+ st %c6, [%i1 + globals + 168 + 24]
+ st %c7, [%i1 + globals + 168 + 28]
+ st %c8, [%i1 + globals + 200 + 0]
+ st %c9, [%i1 + globals + 200 + 4]
+ st %c10, [%i1 + globals + 200 + 8]
+ st %c11, [%i1 + globals + 200 + 12]
+ st %c12, [%i1 + globals + 200 + 16]
+ st %c13, [%i1 + globals + 200 + 20]
+ st %c14, [%i1 + globals + 200 + 24]
+ st %c15, [%i1 + globals + 200 + 28]
+ st %c16, [%i1 + globals + 200 + 32]
+ st %c17, [%i1 + globals + 200 + 36]
+ st %c18, [%i1 + globals + 200 + 40]
+ st %c19, [%i1 + globals + 200 + 44]
+ st %c20, [%i1 + globals + 200 + 48]
+ st %c21, [%i1 + globals + 200 + 52]
+ st %c22, [%i1 + globals + 200 + 56]
+ st %c23, [%i1 + globals + 200 + 60]
+ st %c24, [%i1 + globals + 200 + 64]
+ st %c25, [%i1 + globals + 200 + 68]
+ st %c26, [%i1 + globals + 200 + 72]
+ st %c27, [%i1 + globals + 200 + 76]
+ st %c28, [%i1 + globals + 200 + 80]
+ st %c29, [%i1 + globals + 200 + 84]
+ st %c30, [%i1 + globals + 200 + 88]
+ st %c31, [%i1 + globals + 200 + 92]
+#ifdef notdef
+ mov %csr,%g1
+ st %g1, [%i1 + globals + 200 + 96]
+ mov %cq,%g1
+ st %g1, [%i1 + globals + 200 + 100]
+#endif
+#endif
+
+#endif /* __sparcv9 */
+
+ cmp %i2, 0
+ be,a L1 ! if (newsp == 0) no stack switch
+ nop
+#ifdef notdef
+ add %i2, STACK_ALIGN - 1, %i2
+ and %i2, ~(STACK_ALIGN - 1), %i2
+ sub %i2, SA(MINFRAME), %fp
+ call %i0
+ restore
+#else
+ ! This used to compute a new stack frame base, write it into
+ ! FP, and restore to enter the new frame. But that left a window
+ ! in which FP could be written into the backing store for this
+ ! frame, to be tripped over later by returnto. So instead we do
+ ! the restore first, then modify SP to enter the new frame. We
+ ! can still refer to our argument as %02.
+ restore
+ add %o2, STACK_ALIGN - 1, %o2
+ and %o2, ~(STACK_ALIGN - 1), %o2
+ call %o0
+ sub %o2, SA(MINFRAME) + STACK_BIAS, %sp
+#endif
+
+L1: call %i0 ! call f()
+ nop
+
+
+! returnto(area1)
+! struct savearea *area1;
+ .globl _C_LABEL(returnto)
+ENTRY(returnto)
+ ta ST_FLUSH_WINDOWS ! FLush all other active windows
+
+#ifdef __sparcv9
+
+#ifdef save_allregs
+ ldx [%i1 + globals + 64 + 0], %f0
+ ldx [%i1 + globals + 64 + 8], %f1
+ ldx [%i1 + globals + 64 + 16], %f2
+ ldx [%i1 + globals + 64 + 24], %f3
+ ldx [%i1 + globals + 64 + 32], %f4
+ ldx [%i1 + globals + 64 + 40], %f5
+ ldx [%i1 + globals + 64 + 48], %f6
+ ldx [%i1 + globals + 64 + 56], %f7
+ ldx [%i1 + globals + 64 + 64], %f8
+ ldx [%i1 + globals + 64 + 72], %f9
+ ldx [%i1 + globals + 64 + 80], %f10
+ ldx [%i1 + globals + 64 + 88], %f11
+ ldx [%i1 + globals + 64 + 96], %f12
+ ldx [%i1 + globals + 64 + 104], %f13
+ ldx [%i1 + globals + 64 + 112], %f14
+ ldx [%i1 + globals + 64 + 120], %f15
+ ldx [%i1 + globals + 64 + 128], %f16
+ ldx [%i1 + globals + 64 + 136], %f17
+ ldx [%i1 + globals + 64 + 144], %f18
+ ldx [%i1 + globals + 64 + 152], %f19
+ ldx [%i1 + globals + 64 + 160], %f20
+ ldx [%i1 + globals + 64 + 168], %f21
+ ldx [%i1 + globals + 64 + 176], %f22
+ ldx [%i1 + globals + 64 + 184], %f23
+ ldx [%i1 + globals + 64 + 192], %f24
+ ldx [%i1 + globals + 64 + 200], %f25
+ ldx [%i1 + globals + 64 + 208], %f26
+ ldx [%i1 + globals + 64 + 216], %f27
+ ldx [%i1 + globals + 64 + 224], %f28
+ ldx [%i1 + globals + 64 + 232], %f29
+ ldx [%i1 + globals + 64 + 240], %f30
+ ldx [%i1 + globals + 64 + 248], %f31
+ ldx [%i1 + globals + 64 + 256], %f32
+ ldx [%i1 + globals + 64 + 264], %f33
+ ldx [%i1 + globals + 64 + 272], %f34
+ ldx [%i1 + globals + 64 + 280], %f35
+ ldx [%i1 + globals + 64 + 288], %f36
+ ldx [%i1 + globals + 64 + 296], %f37
+ ldx [%i1 + globals + 64 + 304], %f38
+ ldx [%i1 + globals + 64 + 312], %f39
+ ldx [%i1 + globals + 64 + 320], %f40
+ ldx [%i1 + globals + 64 + 328], %f41
+ ldx [%i1 + globals + 64 + 336], %f42
+ ldx [%i1 + globals + 64 + 344], %f43
+ ldx [%i1 + globals + 64 + 352], %f44
+ ldx [%i1 + globals + 64 + 360], %f45
+ ldx [%i1 + globals + 64 + 368], %f46
+ ldx [%i1 + globals + 64 + 376], %f47
+ ldx [%i1 + globals + 64 + 384], %f48
+ ldx [%i1 + globals + 64 + 392], %f49
+ ldx [%i1 + globals + 64 + 400], %f50
+ ldx [%i1 + globals + 64 + 408], %f51
+ ldx [%i1 + globals + 64 + 416], %f52
+ ldx [%i1 + globals + 64 + 424], %f53
+ ldx [%i1 + globals + 64 + 432], %f54
+ ldx [%i1 + globals + 64 + 440], %f55
+ ldx [%i1 + globals + 64 + 448], %f56
+ ldx [%i1 + globals + 64 + 456], %f57
+ ldx [%i1 + globals + 64 + 464], %f59
+ ldx [%i1 + globals + 64 + 472], %f60
+ ldx [%i1 + globals + 64 + 480], %f61
+#ifdef notdef
+ mov %fsr,%g1
+ ldx [%i1 + globals + 64 + 488], %g1
+ mov %fq,%g1
+ ldx [%i1 + globals + 64 + 496], %g1
+#endif
+
+#endif
+
+ ldx [%o0+topstack],%g1 ! sp = area1->topstack
+ sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
+ sub %fp, SA(MINFRAME), %sp
+
+ ldx [%o0 + globals + 56], %g1 ! Restore global regs back
+ mov %g1, %y
+ ldx [%o0 + globals + 0], %g1
+ ldx [%o0 + globals + 8], %g2
+ ldx [%o0 + globals + 16], %g3
+ ldx [%o0 + globals + 24],%g4
+ ldx [%o0 + globals + 32],%g5
+ ldx [%o0 + globals + 40],%g6
+ ldx [%o0 + globals + 48],%g7
+
+#else /* !__sparcv9 */
+
+ ld [%o0+topstack],%g1 ! sp = area1->topstack
+ sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place
+ sub %fp, SA(MINFRAME), %sp
+
+#ifdef save_allregs
+ ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers
+ ld [%o0 + globals + 32 + 4],%f1
+ ld [%o0 + globals + 32 + 8],%f2
+ ld [%o0 + globals + 32 + 12],%f3
+ ld [%o0 + globals + 32 + 16],%f4
+ ld [%o0 + globals + 32 + 20],%f5
+ ld [%o0 + globals + 32 + 24],%f6
+ ld [%o0 + globals + 32 + 28],%f7
+ ld [%o0 + globals + 64 + 0],%f8
+ ld [%o0 + globals + 64 + 4],%f9
+ ld [%o0 + globals + 64 + 8],%f10
+ ld [%o0 + globals + 64 + 12],%f11
+ ld [%o0 + globals + 64 + 16],%f12
+ ld [%o0 + globals + 64 + 20],%f13
+ ld [%o0 + globals + 64 + 24],%f14
+ ld [%o0 + globals + 64 + 28],%f15
+ ld [%o0 + globals + 64 + 32],%f16
+ ld [%o0 + globals + 64 + 36],%f17
+ ld [%o0 + globals + 64 + 40],%f18
+ ld [%o0 + globals + 64 + 44],%f19
+ ld [%o0 + globals + 64 + 48],%f20
+ ld [%o0 + globals + 64 + 52],%f21
+ ld [%o0 + globals + 64 + 56],%f22
+ ld [%o0 + globals + 64 + 60],%f23
+ ld [%o0 + globals + 64 + 64],%f24
+ ld [%o0 + globals + 64 + 68],%f25
+ ld [%o0 + globals + 64 + 72],%f26
+ ld [%o0 + globals + 64 + 76],%f27
+ ld [%o0 + globals + 64 + 80],%f28
+ ld [%o0 + globals + 64 + 84],%f29
+ ld [%o0 + globals + 64 + 88],%f30
+ ld [%o0 + globals + 64 + 92],%f31
+#ifdef notdef
+ ld [%o0 + globals + 64 + 96],%g1
+ mov %g1, %fsr
+ ld [%o0 + globals + 64 + 100],%g1
+ mov %g1, %fq
+#endif
+
+ ld [%o0 + globals + 168 + 0],%c0 ! Restore floating-point registers
+ ld [%o0 + globals + 168 + 4],%c1
+ ld [%o0 + globals + 168 + 8],%c2
+ ld [%o0 + globals + 168 + 12],%c3
+ ld [%o0 + globals + 168 + 16],%c4
+ ld [%o0 + globals + 168 + 20],%c5
+ ld [%o0 + globals + 168 + 24],%c6
+ ld [%o0 + globals + 168 + 28],%c7
+ ld [%o0 + globals + 200 + 0],%c8
+ ld [%o0 + globals + 200 + 4],%c9
+ ld [%o0 + globals + 200 + 8],%c10
+ ld [%o0 + globals + 200 + 12],%c11
+ ld [%o0 + globals + 200 + 16],%c12
+ ld [%o0 + globals + 200 + 20],%c13
+ ld [%o0 + globals + 200 + 24],%c14
+ ld [%o0 + globals + 200 + 28],%c15
+ ld [%o0 + globals + 200 + 32],%c16
+ ld [%o0 + globals + 200 + 36],%c17
+ ld [%o0 + globals + 200 + 40],%c18
+ ld [%o0 + globals + 200 + 44],%c19
+ ld [%o0 + globals + 200 + 48],%c20
+ ld [%o0 + globals + 200 + 52],%c21
+ ld [%o0 + globals + 200 + 56],%c22
+ ld [%o0 + globals + 200 + 60],%c23
+ ld [%o0 + globals + 200 + 64],%c24
+ ld [%o0 + globals + 200 + 68],%c25
+ ld [%o0 + globals + 200 + 72],%c26
+ ld [%o0 + globals + 200 + 76],%c27
+ ld [%o0 + globals + 200 + 80],%c28
+ ld [%o0 + globals + 200 + 84],%c29
+ ld [%o0 + globals + 200 + 88],%c30
+ ld [%o0 + globals + 200 + 92],%c31
+#ifdef notdef
+ ld [%o0 + globals + 200 + 96],%g1
+ mov %g1, %csr
+ ld [%o0 + globals + 200 + 100],%g1
+ mov %g1, %cq
+#endif
+#endif
+ ld [%o0 + globals + 28], %g1 ! Restore global regs back
+ mov %g1, %y
+ ld [%o0 + globals + 0], %g1
+ ld [%o0 + globals + 4], %g2
+ ld [%o0 + globals + 8], %g3
+ ld [%o0 + globals + 12],%g4
+ ld [%o0 + globals + 16],%g5
+ ld [%o0 + globals + 20],%g6
+ ld [%o0 + globals + 24],%g7
+
+#endif /* __sparcv9 */
+
+ /* The following 3 lines are equivalent to: _PRE_Block = 0 */
+#ifdef AFS_SUN5_ENV
+#ifdef __sparcv9
+ sethi %hh(_C_LABEL(PRE_Block)),%l0
+ or %l0,%hm(_C_LABEL(PRE_Block)),%l0
+ sethi %lm(_C_LABEL(PRE_Block)),%g1
+ or %g1,%lo(_C_LABEL(PRE_Block)),%g1
+ sllx %l0,32,%l0
+ or %l0,%g1,%l0
+#else
+ sethi %hi(_C_LABEL(PRE_Block)),%l0
+ or %l0,%lo(_C_LABEL(PRE_Block)),%l0
+#endif
+#else /* AFS_SUN5_ENV */
+ set _C_LABEL(PRE_Block), %l0
+#endif
+ mov 0,%l1
+ stb %l1, [%l0]
+
+ restore
+ restore
+
+ retl
+ nop
+
diff --git a/usr.sbin/afs/src/lwp/process.vax.S b/usr.sbin/afs/src/lwp/process.vax.S
new file mode 100644
index 00000000000..00fd59d2d16
--- /dev/null
+++ b/usr.sbin/afs/src/lwp/process.vax.S
@@ -0,0 +1,108 @@
+/* $Id: process.vax.S,v 1.1 2000/09/11 14:41:10 art Exp $ */
+
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+
+#include <config.h>
+
+#undef RCSID
+
+/*
+#
+# Information Technology Center
+# Carnegie-Mellon University
+#
+#
+*/
+ .data
+
+/*
+#
+# Transcribed for Vaxen by M. Satyanarayanan, September 1985
+# Algorithm: "Monkey see, monkey do"
+#
+*/
+
+ .text
+
+/*
+#
+# struct savearea {
+# char *topstack;
+# }
+#
+*/
+
+ .set topstack,0
+
+/* Stuff to allow saving/restoring registers */
+
+/*
+# savecontext(f, area1, newsp)
+# int (*f)(); struct savearea *area1; char *newsp;
+*/
+
+/* Stack offsets of arguments */
+ .set f,4
+ .set area1,8
+ .set newsp,12
+
+.globl _PRE_Block
+.globl _savecontext
+
+_savecontext:
+ .word 0x0ffc # Save regs R2-R11
+ movb $1,_PRE_Block # Critical section for preemption code
+ pushl ap # save old ap
+ pushl fp # save old fp
+ movl area1(ap),r0 # r0 = base of savearea
+ movl sp,topstack(r0) # area->topstack = sp
+ movl newsp(ap),r0 # Get new sp
+ beql L1 # if new sp is 0, dont change stacks
+ movl r0,sp # else switch to new stack
+L1:
+ movl f(ap),r1 # r1 = f
+ calls $0,0(r1) # f()
+
+/* It is impossible to be here, so abort() */
+
+ calls $0,_abort
+
+/*
+# returnto(area2)
+# struct savearea *area2;
+*/
+
+/* Stack offset of argument */
+ .set area2,4
+
+ .globl _returnto
+_returnto:
+ .word 0x0 # Who cares about these regs?
+ movl area2(ap),r0 # r0 = address of area2
+ movl topstack(r0),sp # Restore sp
+ movl (sp)+,fp # Restore fp
+ movl (sp)+,ap # ,,,,
+ clrb _PRE_Block # End of preemption critical section
+ ret
+
+ pushl $1234 # I will gloat, Kazar
+ calls $0,_abort
diff --git a/usr.sbin/afs/src/make-release b/usr.sbin/afs/src/make-release
new file mode 100644
index 00000000000..b3fa9e3657b
--- /dev/null
+++ b/usr.sbin/afs/src/make-release
@@ -0,0 +1,26 @@
+#!/bin/sh
+# $Id: make-release,v 1.1 2000/09/11 14:40:29 art Exp $
+
+if [ ! -f configure.in ]; then
+ echo "Must be in top directory"
+ exit 1
+fi
+
+if [ $# -ne 1 -a $# -ne 2 ]; then
+ echo "make-release version [branch]"
+ exit 1
+fi
+
+if [ "$2" != "" ]; then
+ rev="-r $2"
+fi
+
+HV="$1" emacs -batch -q -no-site-file -l ./make-release.el || exit
+
+files="configure.in ChangeLog README LIESMICH doc/arla.texi"
+
+echo cvs ci -m \"Release $1\" $files
+cvs ci -m "Release $1" $files || exit 1
+v=`echo $1 | sed 's/\./-/g'`
+echo cvs rtag $rev arla-$v arla
+cvs rtag $rev arla-$v arla || exit 1
diff --git a/usr.sbin/afs/src/make-release.el b/usr.sbin/afs/src/make-release.el
new file mode 100644
index 00000000000..59d3b9a69d9
--- /dev/null
+++ b/usr.sbin/afs/src/make-release.el
@@ -0,0 +1,25 @@
+; $Id: make-release.el,v 1.1 2000/09/11 14:40:30 art Exp $
+
+(defun bump-version (filename prefix v-string)
+ (save-excursion
+ (find-file filename)
+ (while (re-search-forward (concat prefix "[0-9\\.]*[0-9]") nil t)
+ (replace-match v-string nil nil))
+ (save-buffer)))
+
+(let* ((version (getenv "HV"))
+ (arla-version (concat "arla-" version))
+ (version-string (concat "Release " version)))
+ (find-file "configure.in")
+ (re-search-forward "VERSION=\\(.*\\)$")
+ (replace-match version nil nil nil 1)
+ (save-buffer)
+ (find-file "ChangeLog")
+ (add-change-log-entry nil nil nil nil)
+ (insert version-string)
+ (save-buffer)
+ (mapcar (function (lambda (v) (bump-version v "arla-" arla-version)))
+ '("README" "LIESMICH"))
+ (mapcar (function (lambda (v) (bump-version v "version " version-string)))
+ '("doc/arla.texi"))
+ (kill-emacs))
diff --git a/usr.sbin/afs/src/milko/ChangeLog b/usr.sbin/afs/src/milko/ChangeLog
new file mode 100644
index 00000000000..2966ce549db
--- /dev/null
+++ b/usr.sbin/afs/src/milko/ChangeLog
@@ -0,0 +1,1227 @@
+2000-08-24 Love <lha@stacken.kth.se>
+
+ * fs/fileserver.c: update code to new mlog_log_set_level
+ * lib/mlog/mlog.c: new log_log
+
+2000-08-21 Tomas Olsson <tol@stacken.kth.se>
+
+ * pts/ptserver.c (localize_name): use strlcpy
+ * fs/connsec.c (fs_connsec_anonymous): added - set up anonymous CPS
+ (fs_connsec_createconn): use fs_connsec_anonymous() when auth fails
+ * lib/vld/vld.c (super_user): check if member of
+ system:administrators
+ * lib/ropa/ropa.c (client_update_interfaces): ntohl() is no longer
+ needed
+
+2000-08-17 Tomas Olsson <tol@stacken.kth.se>
+
+ * vldb/vldbserver.c (VL_GetEntryByIDN): local variable to save
+ const arg voltype
+ * pts/pr.c (PR_{NameToID,NewEntry,INewEntry}): use localize_name()
+ to get well formatted name
+ (PR_IDToName): check args
+ (PR_{ListElements,GetCPS}): use new listelements()
+ * pts/ptserver.h: new proto for listelements() added
+ localize_name()
+ * pts/ptserver.c: add & use debug functions
+ (localize_name): added
+ (addtogroup,removefromgroup): use prentry.count, make sure no
+ holes in entrylists
+ (listelements): new bool arg, use prentry.count, add own & if arg
+ set default ids
+ * lib/vld/vld.c (vld_create_volume): less wild default privileges
+ (super_user): always return 0
+ (vld_check_rights): check rights, don't make everything up
+ * lib/vld/salvage.c: more unsigned
+ * lib/vld/vld.h: more unsigned
+ * lib/vld/mnode.h: use unsigned instead of long for flags
+ * lib/ropa/ropa.c (find_client): fix typo
+ (client_update_interfaces): use htohl() on hidden elements in
+ struct from peer
+ (ropa_init): get & save debuglevel for later use
+ (debug_print_callbacks): don't iterate if MDEBROPA not set i debuglevel
+ * fs/fsprocs.c (check_ss_bits): set mask appropriately when
+ creating
+ * fs/connsec.c (get_conn): use netinit_client_getcred()
+ (fs_connsec_nametoid): better handling of connection to ptserver, retry
+ (fs_connsec_createconn): send full principal to PR_NameToID
+ * lib/msecurity/netinit.c (server_get_cred): rename to
+ netinit_client_getcred(), try harder to get ticket
+ (network_init): get our own ticket file
+ (netinit_getrealm): added
+ * lib/msecurity/netinit.h: rename server_get_cred() to
+ netinit_client_getcred() add netinit_getrealm()
+ * appl/perf/perf.c (do_bulkstat): fix typo
+ * README: myhost instead of localhost
+
+2000-08-12 Mattias Amnefelt <mattiasa@e.kth.se>
+
+ * pts/pr.c: added body for PR_ListElements, PR_AddToGroup and
+ PR_RemoveFromGroup
+ * pts/ptserver.c: added update_entry, listelements, addtogroup and
+ removefromgroup
+ * pts/ptserver.h: added listselements, addtogroup and
+ removefromgroup
+
+2000-08-11 Mattias Amnefelt <mattiasa@e.kth.se>
+
+ * lib/msecurity/msecurity/msecurity.c: use $prefixed configdir for
+ superuserlist
+
+2000-08-10 Love <lha@stacken.kth.se>
+
+ * lib/vld/vld.c (vld_storestatus_to_dent): permit s[gu]id binaries
+ (vld_modify_vnode): dont assert admin
+
+ * fs/fsprocs.c (RXAFS_{MakeDir,CreateFile}): check storestatus
+ (RXAFS_Symlink): pass on storestatus from caller after checking it
+ (check_ss_bits): check storestatus bit from user.
+ (StoreData,StoreStatus): call check_ss_bits
+
+2000-08-10 Tomas Olsson <tol@stacken.kth.se>
+
+ * lib/vld/vld.c (vld_modify_vnode): get fetchstatus after
+ modifying
+
+ * lib/vld/mnode.c (mnode_find): save node in lru
+ (mnode_free): better handling of bad nodes, save node in lru
+ (mnode_remove): remove node from lru before adding it again
+
+ * lib/ropa/ropa.c: more logging, use debug_print_callbacks() and
+ print_callback_sub()
+ (break_ccpair): check cc->li for NULL before listdel
+ (ropa_drop_callback): no error if arg-lists have different lengths
+ (heapcleaner): cowardly avoid error, leave list handling to break_ccpair()
+
+ * fs/fsprocs.c (RXAFS_FetchData): more logging, return nothing on
+ weird offset
+ (RXAFS_StoreData): handle strange strange filelength arg more nicely, more logging
+ (RXAFS_{CreateFile,GiveUpCallbacks,GetRootVolume,GetTime}): more logging
+
+2000-07-24 Tomas Olsson <tol@stacken.kth.se>
+
+ * lib/ropa/ropa.c: improve debug formatting
+
+ * fs/fsprocs.c (StoreData): log offset and length
+ (removenode): use new vld_adjust_linkcount(), vld_modify_vnode()
+ (RXAFS_{CreateFile,Rename,Symlink}): use vld_modify_vnode() to update size
+ (RXAFS_MakeDir): use new vld_adjust_linkcount(), vld_modify_vnode()
+
+ * lib/vld/mdir.c (mdir_{creat,remove,mkdir}): use mnode_update_size()
+
+ * lib/vld/mnode.h: added mnode_update_size(),
+ mnode_update_size_cached()
+
+ * lib/vld/mnode.c: added mnode_update_size(),
+ mnode_update_size_cached() (moved from vld.c)
+
+ * lib/vld/vld.h: remove vld_update_size(),
+ vld_update_size_cached() vld_adjust_linkcount() now takes an mnode
+
+ * lib/vld/vld.c (vld_create_entry): set DataVersion to current
+ time
+ (vld_adjust_linkcount): take the mnode as arg, update it properly too
+ (vld_update_size, vld_update_size_cached): renamed and moved to mnode.c
+ (vld_{fent,dent}_to_fetchstatus): use mnode_update_size_cached()
+ (vld_modify_vnode): use only non-null arguments, update DataVersion & Length
+
+ * lib/msecurity/netinit.c (network_init): don't overwrite cached
+ realm
+
+2000-07-24 Love <lha@stacken.kth.se>
+
+ * fs/fsprocs.c (RXAFS_StoreACL): break callback
+ (RXAFS_Rename): break new parent is needed, don't break child
+
+2000-07-22 Love <lha@stacken.kth.se>
+
+ * appl/sked/sked.c: more userfriendly, prime for hash, debug
+ example.
+
+ * lib/voldb/voldb.c (voldb_del_entry): remove bogus assert
+ * lib/voldb/vol.c (vol_create): gc unused variable, don't remove
+ the file when failing to store data.
+ * lib/voldb/vdb_flat.c (vdbflat_del_entry):L remove bugus assert,
+ reset even more values.
+
+ * lib/vld/vld.c: use already defined macros, fix some bugs.
+ * lib/vld/salvage.c: use already defined macros, fix some bugs.
+
+2000-07-21 Love <lha@stacken.kth.se>
+
+ * bos/*: move out bosserver proc
+
+ * appl/sked/Makefile.in: include debugging
+ * appl/sked/sked.c: Added salvage command, fixed debugging
+
+ * include/mdebug.h: more debug stuff
+
+ * lib/voldb/voldb.c:(voldb_get_volume): remove bogus assert
+
+ * lib/dpart/dpart.[ch]: (dp_parse): new function
+ (dp_getpart): new function
+ (dp_create): make work for large partitions
+
+ * fs/fsrv_locl.h: include <salvage.h>
+ * fs/fileserver.c:move logging stuff, salvage rename, unsigned printing
+ * fs/Makefile.in: remove salvage.c
+ * fs/salvage.c: move to lib/vld
+
+ * lib/vld/debug.c: moved mdebug stuff here.
+ * lib/vld/salvage.[ch]: move here from fs/, made it work
+ * lib/vld/Makefile.in: move salvage.c here from fs/salvage.c
+ make it work even more
+ * lib/vld/Makefile.in: Added salvage.c
+
+2000-07-16 Love <lha@stacken.kth.se>
+
+ * pts/ptserver.c: removed unused stuff, added more static's, redid
+ opening of db.
+ * lib/voldb/voldb.c (voldb_get_entry): make it work for TYPE_LINK
+ (voldb_get_volume): new function to fetch volume-number
+ * lib/voldb/voldb.h (voldb_get_volume): new function to fetch
+ volume-number
+
+2000-07-15 Tomas Olsson <tol@stacken.kth.se>
+
+ * lib/ropa/ropa.h: add ropa_drop_callbacks() new interface for
+ ropa_break_callback()
+ * lib/ropa/ropa.c: logging stuff
+ (break_ccpair): delete from callback´s ccpairs
+ (break_callback): new argument break_own, break own callback only if set
+ (ropa_break_callback): new arg break_own, don´t return if unknown client
+ (ropa_drop_callbacks): added.
+ * fs/fsprocs.c (RXAFS_StoreData): don´t check offset/len, more
+ logging, break callback
+ (RXAFS_StoreStatus): break callback
+ (removenode, RXAFS_CreateFile): break callback for directory as well
+ (RXAFS_Rename): use afs_dir_p(), break callbacks
+ (RXAFS_Symlink): more logging, break callback for directory, set mode bits correctly
+ (RXAFS_Makedir): callbacks handling
+ (RXAFS_GiveUpCallBacks): use ropa_drop_callbacks()
+ * lib/ropa/Makefile.in: -I for mlog, mdebug
+ * include/mdebug.h: add MDEBROPA
+ * fs/fileserver.c: add --debug=ropa, MDEBROPA
+ * appl/sked/sked.c (volls_cmd): make it almost work
+
+2000-07-02 Tomas Olsson <tol@stacken.kth.se>
+
+ * README: add some info about -cell
+ * lib/dpart/dvol.c: unused, removed
+ * lib/ropa/ropa.h: new ropa_break_callback() prototype
+ * lib/ropa/ropa.c (*): define & use ROPA_MTU
+ (callbacks_cmp): return 0 only when equal
+ (client_update_interfaces): also consider host-IP from call
+ (client_init): call client_update_interfaces() new way
+ (ropa_getcallback): call client_update_interfaces() new way,
+ fix callback-list handling
+ (ropa_break_callback): reorder arguments
+
+2000-06-24 Love <lha@stacken.kth.se>
+
+ * lib/ropa/ropa.c (clear_addr): clear a address
+ (client_deref): don't memset client.addr[]
+ (client_update_interfaces): use clear_addr
+
+2000-06-24 Harald Barth <haba@pdc.kth.se>
+
+ * README: spell
+ * lib/ropa/ropa.c: port in ropa_client structure is in network
+ byte order and therefore no conversion when calling
+ rx_NewConnection.
+ * fs/fileserver.c: Added flag for forced salvage
+ * README: more info about starting servers
+
+Fri Jun 23 21:06:29 2000 Tomas Olsson <tol@pizza.stacken.kth.se>
+
+ * lib/ropa/ropa.c, lib/vld/vld.c: NULL test
+ * lib/voldb/voldb.c, lib/voldb/voldb.h: make afs_dir_p work
+
+Thu Jun 22 17:21:06 2000 Tomas Olsson <tol@pizza.stacken.kth.se>
+
+ * lib/vld/vld.c (vld_create_entry): clean up on error
+ (vld_set_onode, vld_adjust_linkcount, vld_open_vnode,
+ vld_modify_vnode, vld_put_acl, vld_remove_node): use afs_dir_p()
+ (vld_create_volume): don't close fd again
+ (vld_register_vol_type): fix check
+
+ * lib/voldb/voldb.c: rewrite conversion routines
+ (voldb_init): fix typo
+ (voldb_close): don't close fd again
+
+ * lib/voldb/voldb.h: added afs_dir_p()
+
+ * lib/voldb/vdb_flat.c (vdbflat_init): more sane checks & cleanup
+ on error
+ (vdbflat_close): close fd.
+ (vdbflat_extend_db): fix sanity checks
+ (vdbflat_del_entry): fix checks
+
+ * vldb/vled.c: include limits.h
+
+ * bos/bosserver.c: added BOZO_SetStatus()
+
+2000-06-05 Love <lha@s3.kth.se>
+
+ * lib/ropa/ropa.c (client_update_interfaces): don't memset that
+ wildly
+ (clients_hash_ip): remove somewhat bogus assert
+ (client_query): move assert here
+ * bos/bosserver.c: update to new ydr code
+ * appl/perf/perf.c: update to new cb code
+
+2000-06-04 Magnus Ahltorp <ahltorp@nada.kth.se>
+
+ * fs/connsec.c: (fs_connsec_idtoname): handle null error strings
+
+2000-06-02 Magnus Ahltorp <ahltorp@nada.kth.se>
+
+ * fs/salvage.c: volume numbers are unsigned
+
+ * lib/voldb/vol.c (vol_create): set inUse and destroyMe
+
+ * lib/vld/vld.h: transactions
+
+ * lib/vld/vld.c: transactions
+
+ * fs/volprocs.c: added transactions
+
+ * fs/fsprocs.c (fs_init_req): Check busy
+
+ * fs/fileserver.c (main): set progname
+
+2000-05-27 Love <lha@s3.kth.se>
+
+ * lib/ropa/ropa.c (heapcleaner): remove the ccpair from the
+ callback's list of callbacks
+ (struct ropa_ccpair): cb_li, pointer to li on callback
+ (add_client): store where the cc is stored in the callbacks list
+ of cc's
+ (break_ccpairs): remove the ccpair from the callback's list of
+ callbacks
+
+ * bos/kconf.[ch]: files stolen and changed from ej (that stole
+ them from heimdal)
+
+ * lib/ropa/ropa.c: removed borken paranoia, new paranoia, extended
+ paranoia, fixed bugs, made it almost work.
+
+ * include/mdebug.h (MDEBFS): added
+
+ * lib/vld/mnode.c (mnode_cmp): made it work
+ (mnode_remove): new function, remove a node from the cache
+
+ * fs/salvage.c: fix logging, fix multiple parents, fix logging to
+ wrong level
+
+ * fs/fsprocs.c (*): added some simple debugging, make directory
+ operations more paranoid of the input vnode, make removal
+ operations clean mnode cache
+ (rm,rmdir,mv)
+
+ * fs/fileserver.c (milko_deb_units): added fs debuglevel
+
+ * appl/perf/perf.c (cmcb_init): made static
+
+2000-05-25 Love <lha@s3.kth.se>
+
+ * vldb/vled.c (*): update to new vldb_print_entry
+ * vldb/vldb_locl.h (vldb_print_entry): update prototype
+ * vldb/vl_db.c (vldb_print_entry): long version with
+ server-addresses
+
+ * lib/vld/common.c: local_opaque2ino: don't export
+
+ * lib/msecurity/netinit.c (server_get_cred): more type
+
+ * README: expand even more
+
+2000-05-24 Harald Barth <haba@puffin.pdc.kth.se>
+
+ * README: Explain afs@REALM principal better
+
+2000-05-02 Tomas Olsson <tol@fredrika-bremer.stacken.kth.se>
+
+ * appl/perf/perf.c (do_createfilecontent): update to new StoreData
+
+2000-05-01 Tomas Olsson <tol@stacken.kth.se>
+
+ * arla/milko/fs/fsprocs.c: (RXAFS_FetchACL): return negative ACL:s
+ as well
+ (RXAFS_BulkStatus): immediate return if vld_check_rights() fails
+
+2000-05-01 Magnus Ahltorp <ahltorp@nada.kth.se>
+
+ * vldb/vldbserver.c: Spellfix, (main): call set_progname
+
+2000-04-30 Assar Westerlund <assar@sics.se>
+
+ * fs/fsprocs.c (RXAFS_StoreData): update to new StoreData
+ * fs/fsprocs.c: update fdir_changefid. adapt.
+
+2000-04-28 Love <lha@s3.kth.se>
+
+ * lib/vstatus/vstatus.c (vstatus_print_onode): unconfuse printing
+ of o->data
+
+2000-03-20 Love <lha@s3.kth.se>
+
+ * lib/ropa/ropa.c (callback_ref): use the right list
+
+2000-03-19 Love <lha@s3.kth.se>
+
+ * fs/fileserver.c(usage): print usage in gnu-style too
+
+2000-03-09 Love <lha@s3.kth.se>
+
+ * lib/vld/vld.c: (vld_open_vnode): get cached test right.
+ (iter_vol): typecast to right struct
+
+ * fs/salvage.c: more paranoia
+
+2000-03-06 Love <lha@s3.kth.se>
+
+ * lib/vld/vld.c (iter_vol): ref volumes during call to `func'
+
+ * fs/salvage.c (tree_connectvity): make volume-db's uptodate,
+ don't free volume, since it isn't ref:ed
+
+ * lib/vld/vld.c (vld_iter_vol): pass the right argument
+
+2000-03-05 Love <lha@s3.kth.se>
+
+ * */*: mlogging and some basic salvager
+
+ * include/mdebug.h: debug constants for milko
+
+ * lib/mlog/mlog.[ch]: logging subsystem
+
+2000-03-04 Love <lha@s3.kth.se>
+
+ * lib/voldb/{voldb.c,vdb_flat.c}: use only mmap, change who is
+ resonsible for writing down header to disk.
+
+ * lib/vld/vld.c(vld_create_volume): close is done in VOLOP(close)
+ (vld_check_right): stop permitting the client to do anything when
+ ptserver is down.
+
+ * appl/sked/sked.c: restructure due to changes in voldb/vldb
+
+2000-02-27 Love <lha@s3.kth.se>
+
+ * vldb/vled.c: some more edlike functionallity, added print,
+ backup and search
+
+ * vldb/vldbserver.c (*): some cleaning
+
+2000-02-22 Love <lha@s3.kth.se>
+
+ * lib/voldb/vdb_flat.c: added prototypes
+
+ * lib/vld/vld.h: added prototypes
+
+ * lib/vld/vld.c: added prototypes
+
+ * lib/vld/glue.c (add_entry): added special handling for files
+
+ * lib/vld/fvol.h: added fvol_offset2opaque
+
+ * lib/vld/fvol.c: clear out the most obvious bugs
+
+ * lib/ropa/ropa.h: update ropa_getcallback added some missing
+ prototypes
+
+ * lib/ropa/ropa.c: clear out the most obvious bugs
+
+ * fs/fsprocs.c (*): fix arguments for ropa_getcallback
+
+2000-02-19 Love <lha@s3.kth.se>
+
+ * fs/fileserver.c: init LWP since ropa needs it
+
+ * fs/fsprocs.c: remove old traces of ropa, and small bug fixes
+
+ * lib/msecurity/netinit.c: Try also afs.realm@REALM
+
+ * lib/vld: Moved the [sf]vol stuff here
+
+ * lib/vld/vld.[ch]: add vld_set_onode
+
+ * dumbclient/*: replaced by perf
+
+1999-11-03 Love <lha@s3.kth.se>
+
+ * vldb/vldbserver.c (main): move port initlization later.
+ (open_db): added what filed we failed to open.
+ (vldbserver_create): add what database we are creating.
+
+ * appl/bootstrap/boot-strap.sh.in: Add support for the
+ pts, vldb and srvtab creation.
+
+ * vldb/vldbserver.c (*): break out the creating of the database
+ and opening of it, add a flag to make that you tell the server to
+ explicit only create the database.
+
+ * pts/ptserver.c (*): break out the creating of the database and
+ opening of it, add a flag to make that you tell the server to
+ explicit only create the database.
+
+ * appl/sked/sked.c (*): create a global varibale interactivep and
+ a macro INTER_RETURN() and start to use it. This enables us to
+ give a sane exit-code when running in command-line-mode.
+
+ * appl/bootstrap: Added shellscript to bootstrap
+
+ * fs/fsprocs.c (RXAFS_BulkStatus): first implemtation using mnode
+ interface XXX
+
+ * lib/vld/vld.c (vld_create_entry): if directory, set acl
+ (vld_create_entry): memset acl, add dummy entry for anonymous
+
+ * lib/voldb/voldb.c (voldb_pretty_print_dir): more pretty
+ printing.
+
+ * pts/pr.c (PR_IDToName): when failed to find name in database
+ print number instead of the empty string.
+
+ * lib/voldb/Makefile.in: added vstatus
+
+ * fs/fsprocs.c (RXAFS_{Symlink,MakeDir,CreateFile}): use new
+ vld_create_entry()
+ * fs/Makefile.in: added vstatus
+
+ * lib/vstatus/vstatus.h: Added wrapper #ifdef/#endif
+ (vstatus_print_onode): new function.
+
+ * lib/vstatus/vstatus.c (vstatus_print_onode): new function.
+
+ * lib/voldb/voldb.h: Added <vstatus.h> Removed <vstat.h>
+
+ * lib/voldb/voldb.c (voldb_flush): let the lower layer do the
+ flush
+ (*print_print*): again print the onode_opaque
+
+ * lib/voldb/vdb_flat.c (*): changed how we find where to write the
+ bits
+ (*): removed #if 0 code, and finally fixed some bugs.
+
+ * lib/svol/Makefile.in (INCLUDES): add
+ -I$(srcdir)/../../lib/vstatus
+
+ * appl/sked/sked.c (show_volume): print vnode
+
+ * appl/sked/Makefile.in (INCLUDES): add
+ -I$(srcdir)/../../lib/vstatus
+
+ * lib/vld/vld.h (vld_create_entry): changed signature.
+
+ * lib/vld/vld.c (vld_create_entry): changed parent fid to a mnode
+ to be able to copy the acl when its a dir.
+
+1999-11-02 Love <lha@s3.kth.se>
+
+ * fs/Makefile.in(INCLUDES): Add ../lib/vstatus
+
+ * appl/sked/sked.c: don't print inode numbers.
+
+ * lib/vld/vld.c(*): converted fully to opaque
+
+ * lib/svol/svol.c: random fixes to make it build
+
+ * lib/voldb/voldb.h: Add <vstat.h>
+
+ * lib/voldb/vdb_flat.c (*): Added length pointers.
+
+ * lib/voldb/Makefile.in (INCLUDES): add ../vstatus
+
+ * lib/voldb/voldb_internal.h (voldb_type): make del_entry right
+ type.
+
+ * lib/svol/svol.c: use opaque
+
+ * lib/voldb/voldb.c (voldb_get_size): new function. don't print
+ the opaque structure.
+
+ * lib/voldb/voldb.h: use opaque structure.
+
+ * lib/vstatus/vstatus.c: remove comment.
+
+1999-11-02 Magnus Ahltorp <map@stacken.kth.se>
+
+ * fs/fsprocs.c (RXAFS_FetchACL): Implement
+ (RXAFS_StoreACL): Implement
+ (RXAFS_MakeDir): Inherit ACL from parent
+
+ * fs/connsec.[ch] (fs_connsec_nametoid): Added
+ (fs_connsec_idtoname): Added
+
+ * pts/pr.c (PR_GetCPS): Authenticated user is always member of
+ system:anyuser and system:authuser
+
+ * pts/ptserver.c (prserver_init): Add system:anyuser and
+ system:authuser when creating the database
+
+ * lib/voldb/voldb.h: Move struct acl_entry out of the
+ voldb_dir_entry struct
+
+ * lib/vld/vld.[ch] (vld_create_volume): put "system:authuser rl"
+ acl entry into root node
+ (vld_check_rights): use msec, check negacl, check rights more
+ correctly
+ (vld_put_acl): Added
+
+1999-10-24 Love <lha@s3.kth.se>
+
+ * lib/vld/vld.c (vld_db_uptodate): dont close fd's, any add
+ comment why
+
+ * lib/vld/vld.c (vld_db_uptodate): close fd's when needed, set
+ pointer to NULL when failing, add comment about bringing volume
+ offline
+
+1999-10-23 Magnus Ahltorp <map@stacken.kth.se>
+
+ * lib/voldb/vdb_flat.c (vdbflat_put_acl): put acl at correct
+ position
+
+1999-10-22 Magnus Ahltorp <map@stacken.kth.se>
+
+ * fs/connsec.h: Remove fs_connsec_newconn
+
+ * fs/connsec.c: Get CPS
+
+ * lib/msecurity/msecurity.[ch] (sec_getname): Call with
+ rx_connection instead of rx_call
+
+ * pts/ptserver.c: Bring ptserver init up-to-date
+
+ * pts/Makefile.in: Added MILKO_SYSCONFDIR
+
+ * fs/Makefile.in: Added libacl and libptclient
+
+ * fs/fsrv_locl.h: Include getarg.h
+
+ * fs/fileserver.c (main): Added getarg support, removed connection
+ creation routine
+
+ * fs/fsprocs.c (RXAFS_Symlink): fd is not closed by fbuf_end
+
+ * lib/msecurity/netinit.[ch] (server_get_cred): Added
+
+1999-10-19 Magnus Ahltorp <map@stacken.kth.se>
+
+ * fs/fsprocs.c (*): pass around msec instead of prlist
+ (fs_init_msec): get security context
+ (RXAFS_FetchACL): return bogus acl
+ (removenode): adjust correct link count, clear ep
+ (RXAFS_*): return correct FetchStatus
+ (RXAFS_Rename): handle move to existing files
+
+ * fs/fsrv_locl.h: Added connsec.h
+
+ * fs/fileserver.c (main): register connection {new, destroy}
+ functions
+
+ * fs/Makefile.in: Added connsec.o
+
+ * lib/vld/mnode.h: Added struct fs_security_context
+
+ * lib/vld/mdir.c (mdir_mkdir): update length
+
+ * lib/vld/vld.h (vld_create_entry): pass around msec instead of prlist
+ (vld_create_directory): remove prototype
+
+ * lib/vld/vld.c (*): pass around msec instead of prlist
+ (vld_set_author): add function
+ (vld_create_entry): optionally return child mnode, set
+ various status fields
+ (vld_storestatus_to_?ent): don't update ServerModTime
+ (vld_check_rights): change from bogus unix bits to correct
+ afs access bits
+ (vld_modify_vnode): don't assert on admin bits when only
+ changing size, force setting of fs
+
+ * fs/connsec.h: Added.
+ * fs/connsec.c: Added.
+
+1999-10-18 Magnus Ahltorp <map@stacken.kth.se>
+
+ * milko/lib/voldb/voldb.c: Updated comments.
+
+1999-10-16 Magnus Ahltorp <map@stacken.kth.se>
+
+ * milko/lib/voldb/voldb.[ch]: Added voldb_update_time.
+
+1999-10-15 Love <lha@s3.kth.se>
+
+ * lib/vld/vld.c (vld_check_rights): remove over paranoid assert()
+
+ * lib/voldb/voldb_internal.h (voldb_put_file): put file and not
+ get.
+
+ * lib/vld/vld.c (vld_create_entry): set type of e.
+
+ * lib/vld/vld.[ch] (vld_check_accces): return errno instead of Bool
+
+ * lib/vld/vld.c (vld_open_vnode): get getting data, remember to
+ set flag.
+
+ * lib/vld/vld.c (vld_update_size_cached,
+ vld_{d,f,}ent_to_fetchstatus): assert on right things
+
+ * lib/vld/vld.c (vld_open_vnode): use the voldb entry in n.
+
+ * lib/vld/mnode.c (mnode_init): fixed common if (foo) bug
+
+ * appl/sked/sked.c (main): init mnode support.
+
+ * pts/pr.c: move <assert.h> to avoid collision with <rxkad.h>
+
+ * lib/voldb/voldb_locl.h: added <fs.h>
+
+ * lib/voldb/voldb_internal.h: inline some functions.
+
+ * lib/voldb/voldb.h (*): merge voldb_get_{dir,file} to
+ voldb_get_entry, added negative acl's
+
+ * lib/voldb/voldb.c (*): merge voldb_get_{dir,file} to
+ voldb_get_entry
+
+ * lib/voldb/vdb_flat.c (*acl*): add negative acl
+
+ * lib/vld/vld.c (*): new style mnode
+
+ * lib/vld/Makefile.in: no more separate mdir, moved here instead
+
+ * lib/svol/svol.c: printf mangleing and newstyle mnode
+
+ * lib/msecurity/netinit.[ch] (network_init): request should return a
+ int32_t
+
+ * lib/msecurity/msecurity.c: move <assert.h> to avoid collition in
+ <rxkad.h>
+
+ * lib/Makefile.in (SUBDIRS): no more mdir
+
+ * fs/fsrv_locl.h: Added <mdir.h>
+
+ * fs/fsprocs.c (*): new style mnode
+
+ * fs/Makefile.in: mdir have moved
+
+ * appl/sked/sked.c: new mdir style, new mnode, disable ls command
+ for now.
+
+ * README: Random advice
+
+1999-09-26 Love <lha@s3.kth.se>
+
+ * lib/vld/vld.h: clearified comment of backstores
+
+ * README: we dont know anything about non-kth-krb telnet
+
+ * lib/voldb/vdb_flat.c (vdbflat_del_entry): put data on freelist.
+
+1999-09-25 Love <lha@s3.kth.se>
+
+ * README: Added comments about vld and voldb
+
+ * fs/fsprocs.c (*): fbuf related bugs fixed.
+
+ * fs/fileserver.c (sigusr1): exit with 2
+
+ * lib/mdir/mdir.c: fix fbuf related bugs
+
+ * lib/vstatus/vstat.xg (vstatus): add voldbtype
+
+ * **.[ch]: adapt to new voldb structure
+
+ * lib/voldb/*.[ch]: break out voldb flat to make possible to
+ use diffrent types of voldb:s
+
+1999-09-13 Love <lha@s3.kth.se>
+
+ * bos/boserver.c: 'add some more functionality (like (stupid)
+ configfile and mailing when things die.
+
+1999-09-10 Assar Westerlund <assar@sics.se>
+
+ * vldb/vldbserver.c: add --noauth
+
+ * pts/ptserver.c: add --noauth
+
+ * bos/bosserver.c: add --noauth
+
+ * lib/msecurity/msecurity.h (sec_disable_superuser_check): add
+ prototype
+
+ * lib/msecurity/msecurity.c (sec_disable_superuser_check): add
+ (sec_superuser): check for disabled check
+ (sec_add_superuser, sec_del_superuser): ifdef KERBEROS
+
+ * lib/msecurity/netinit.c: handle !KERBEROS
+
+ * vldb/ubikprocs.c: handle !KERBEROS
+
+ * pts/pr.c: handle !KERBEROS
+
+1999-08-08 Assar Westerlund <assar@sics.se>
+
+ * fs/fsprocs.c (RXAFS_BulkStatus): allocate StatArray and CBArray
+
+1999-07-15 Assar Westerlund <assar@sics.se>
+
+ * pts/Makefile.in (LIBS): add kafs, to get krb_life_to_time :-(
+
+ * fs/Makefile.in (LIBS): add kafs, to get krb_life_to_time :-(
+
+ * bos/Makefile.in (LIBS): add kafs, to get krb_life_to_time :-(
+
+ * dumbclient/Makefile.in (LIBS): add kafs, to get krb_life_to_time
+ :-(
+
+1999-07-12 Magnus Ahltorp <map@stacken.kth.se>
+
+ * fs/volprocs.c: Added
+
+1999-07-09 Marcus Sundberg <mackan@stacken.kth.se>
+
+ * appl/sked/Makefile.in, bos/Makefile.in, fs/Makefile.in,
+ pts/Makefile.in, vldb/Makefile.in: Add @PLWP_LIB_FLAGS@ when
+ linking with -llwp.
+
+1999-07-04 Love <lha@s3.kth.se>
+
+ * lib/voldb/voldb.c (voldb_pretty_print_{dir,file}): print unique
+
+ * appl/sked/sked.c (volls_cmd): implement
+ (volvnode_cmd): fix off-by-1 error re to voldb
+
+ * appl/sked/Makefile.in (INCLUDE): Add mdir
+
+1999-07-04 Magnus Ahltorp <map@it.kth.se>
+
+ * fs/fsprocs.c: Update the size of the symlink file
+
+1999-06-23 Love <lha@s3.kth.se>
+
+ * fs/fsprocs.c: use new vld_create_*
+
+ * lib/voldb/voldb.h(voldb_{file,dir}_entry: reclain spare1
+
+ * lib/voldb/voldb.c(voldb_new_entry): Add unique
+ (voldb_{put,get}_{dir,file}): use unique
+
+ * lib/vld/vld.c:(vld_create_{file,dirctory}: Add unique.
+
+ * lib/svol/svol.c: Added <rx/rx.h>
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * fs/fsprocs.c (RXAFS_StoreData): call copyrx2fd correctly
+
+1999-06-20 Assar Westerlund <assar@sics.se>
+
+ * fs/fsprocs.c (RXAFS_StoreData): return EINVAL instead of
+ asserting if given bad arguments
+
+ * fs/fsprocs.c: de-mulify
+ (RXAFS_FetchData): handle a_offset correctly
+
+1999-06-10 Love <lha@s3.kth.se>
+
+ * appl/sked/sked.c: add <rx/rx.h> and <fbuf.h>, reset some vars
+
+ * lib/vld/vld.c: (vld_create_directory): change place of . and
+ .. to make it work
+
+1999-06-09 Love <lha@s3.kth.se>
+
+ * lib/voldb/voldb.c: (voldb_del_entry): reset ino num,
+ (voldb_pretty_print*): print ino in hex
+
+ * README: Talk about CellServDB/ThisCell and run-tests
+
+ * fs/fsprocs.c: use new vld_update_size_fbuf
+
+ * lib/vld/vld.[ch]: vld_update_size -> \1_{fd,fbuf}
+
+1999-06-07 Love <lha@s3.kth.se>
+
+ * bos/bosserver.c(main): use new network_kerberos_init.
+
+ * vldb/vldbserver.c(main): use new network_kerberos_init.
+
+ * lib/msecurity/Makefile.ini(DEFS): Add MILKO_SYSCONFDIR
+
+ * lib/msecurity/netinit.c: (network_kerberos_init): use default if
+ given a NULL
+
+1999-05-30 Love <lha@s3.kth.se>
+
+ * fs/fsprocs.c (RXAFS_BulkStatus): the turn the < the right way,
+ and reverse the previos patch
+
+ * fs/fsprocs.c (RXAFS_BulkStat): only free volh if set
+
+ * appl/sked/sked.c (*): Added new function volvnode that gives
+ info about a volume (and the vnodes)
+
+ * bos/bosserver.c: Added some comments
+
+ * lib/vld/vld.c (*): start to use vol->flags.voldbp
+
+ * lib/voldb/voldb.c (voldb_pretty_print_{file,dir}): new function
+ (voldb_header_info): new function
+
+ * fs/fsprocs.c (RXAFS_StoreData): return sane size
+ (RXAFS_BulkStat) : XXX remove paranoid
+
+ * bos/Makefile.in (DEFS) += MILKO_LIBEXECDIR
+
+ * vldb/Makefile.in (DEFS) += MILKO_SYSCONFDIR
+
+ * bos/bosserver.c (args) += added prefix
+ (start_server) use prefix
+
+ * vldb/vldbserver.c (vldbserver_init): Added arguemnt that tells
+ where the vl_database is stored.
+ (getargs) += prefix
+
+ * Makefile.in(SUBDIRS): Added bos
+
+ * bos/*: Added partial nonworking bosserver.
+
+1999-05-29 Love <lha@s3.kth.se>
+
+ * fs/fsprocs.c (RXAFSStoreData,RXAFSFetchData): close fd after
+ use.
+
+1999-05-28 Love <lha@s3.kth.se>
+
+ * vldb/vldbserver.c: add option cell
+
+ * fs/fsprocs.c(RXAFS_SymLink): Make it work (check if fil exist etc)
+
+ * fs/fsprocs.c (RXAFS_SymLink): First version of symlink
+ (RXAFS_CreateFile): Get right size of dir-node, remove child-node
+ when failed to add direntry.
+ (RXAFS_MakeDir): Get right size of parent-dir-node
+
+ * lib/vld/vld.h(vld_create_file): add the type of entry
+ (vld_[fd]ent_to_fetchstatus): use vld_update_size
+ (vld_update_size): new function
+
+ * lib/vld/vld.h (vld_create_file): add the type of entry
+ (vld_update_size): new function
+
+1999-05-25 Love <lha@s3.kth.se>
+
+ * lib/vld/vld.c (vld_storestatus_to_[fd]ent): use current time if
+ SS_MODTIME isn't set
+
+ * fs/fsrv_locl.h: <netinit.h> <msecurity.h> <ko.h>
+
+ * pts/ptserver.c: remove common code and use network_init instead
+
+ * vldb/vldbserver.c: remove common code and use network_init instead
+
+ * fs/fileserver.c: remove common code and use network_init instead
+
+ * fs/Makefile.in: msecurity
+
+ * README: Kerberos comments
+
+ * lib/msecurity/Makefile.in: Added netinit.[ch]
+
+ * lib/msecurity/netinit.[ch]: Added, to start up a rxserver in a
+ simple way.
+
+1999-05-19 Love <lha@s3.kth.se>
+
+ * vldb/Makefile.in: gc, add msecurity,acl
+
+ * vldb/vldbserver.c: Debugging, add sec_is_superuser()
+
+ * lib/vld/vld.c (vld_create_directory,vld_create_file): use ino_t
+ instead of int32_t
+
+1999-05-18 Love <lha@s3.kth.se>
+
+ * vldb/vldbserver.c: break out of milko, start to use
+ lib/ko/ports
+
+ * lib/Makefile.in(SUBDIRS): add msecurity
+
+ * pts/{pts.c,pr.c}: move to pts/, break out of milko.
+
+ * lib/msecurity/msecurity.[ch]:move to milko/lib/msecurity, do
+ kerberos patches, break out of milko
+
+1999-05-17 Love <lha@s3.kth.se>
+
+ * Milko is dead, long live Milko
+
+ * */*: Added filbunke - nnp-server-class fileserver
+
+ * */*: FS releated things removed. vldb and pts things moved to
+ separate directories.
+
+1998-11-08 Love <lha@s3.kth.se>
+
+ * ontop_ff.xg: numacl.
+
+ * ontop_subr.c: Dont loop twice in ontop_alloc_vnode if sucessful.
+
+ * ontopfs.c: ontop_{fetch,store}acl
+
+ * Makefile.in: added afsacl.
+
+1998-11-05 Love <lha@s3.kth.se>
+
+ * ontopfs.c(ontop_init): run ontop_initworker().
+
+ * ontop_subr.c: Added a thread that precreate vnodes when
+ num(vnodes) of a volume gets low.
+
+ * ontop_ff.xg(ontop_vnode): split free to oddfree and evenfree,
+ add used
+
+ * milko.c(main): Move init network to top.
+
+1998-11-04 Love <lha@s3.kth.se>
+
+ * mbuf.c (malloc_create): do paranoid things about creation of a
+ malloc_create.
+
+ * ontop_subr.c: Breakout the creation of a vnode.
+
+ * ontopfs.c (createentry): Update right vnode.
+ (update_vnode): UnixModeBits & 0666
+ (ontop_vnode2AFSStoreStatus): Add filetypebits by hand.
+
+1998-10-22 Love <lha@s3.kth.se>
+
+ * fs.c (RXAFS_Link): Implement.
+
+ * ontopfs.c: Use flags for createentry()/delete_entry().
+ (ot_lookup): New function.
+ (ontop_rename): Implement.
+ (ontop_link): Implement.
+
+ * ontop_subr.c: Use LinkCount when allocing and freeing vnodes.
+
+ * README: Tell what filesystem might work.
+
+1998-10-21 Love <lha@s3.kth.se>
+
+ * fileserver.h: Fixed prottypes for *link.
+
+ * README: Fixed sentence about romedia.
+
+ * ontopfs.c: (delete_entry): New common function for RemoveDir and
+ RemoveFile.
+ (ontop_removedir): Made use os delete_entry.
+ (ontop_removefile): Implemeted using delete_entry().
+ (create_entry): Fixed indenting bug.
+ (ontop_symlink): Implemented.
+
+ * fs.c: (RXAFS_RemoveFile): Implemented.
+ (RXAFS_Rename): Implemented.
+ (RXAFS_SymLink): Implemented.
+
+1998-10-15 Love <lha@s3.kth.se>
+
+ * ontopfs.c: (ontop_putdate): Store file.
+ (ontop_createfile): Implemented.
+ (update_vnode): New function.
+ (createentry): New function.
+ (ontop_makedir): use createentry
+
+ * ufsmedia.[ch]: Begining of code for FH support.
+
+ * mbuf.h: Prototype for mbuf_resize().
+
+ * mbuf.c: Implement reallen for malloced mbuf.
+
+ * fs.c: Return more sane values for not implemented functions (EPERM).
+ (RXAFS_CreateFile): Write downcall to fs-module.
+
+ * filesystem.h: link and symlink.
+
+ * fhget.[ch]: (fhtonum) and (numtofh): New functions
+
+ * README: Added COMMENTS section.
+
+ * Makefile.in: Clean out the autogenerated files.
+
+1998-10-12 Love <lha@s3.kth.se>
+
+ * ontopfs.c: (ontop2afsrights) more bogus rights.
+ (ontop_makedir): Free the right vnode.
+ (ontop_removedir): new function (should use mdir_emptyp().
+
+ * ontop_subr.c: Added function ontop_free_vnode() to free vnode.
+
+ * mdir.[ch]: New function mdir_emptyp() that might work.
+
+ * fs.c: Added code for ontop_removedir.
+
+ * fileserver.h: Added prototypes/entries in struct filesystem for:
+ storeacl, createfile, removefile, and fsrename.
+
+ * README: Added note about filesystem.
+
+1998-10-09 Love <lha@s3.kth.se>
+
+ * README: Added some text about the thingy.
+
+ * ontop_subr.c: (ontop_store_types): add gotfh type.
+ (openvnode): Open with fhget() if it exists.
+ (ontop_create_vnode): If we have fhget() store the FH too.
+
+ * ontop_ff.xg: changed ontop_vnode.storage to OPAQUE from VARRAY.
+
+ * milko_locl.h: Add includefiles for fhget(), remove dbi.h forever.
+
+ * milko.c: (main) Test if use have fh* with fhprobe().
+
+ * fhget.[ch]: Stolen from arlad/fcache.c, and changed to fit milko
+
+1998-10-07 Love <lha@s3.kth.se>
+
+ * ontopfs.c: Added support for mkdir.
+
+1998-10-06 Love <lha@s3.kth.se>
+
+ * Got ontopfs to list . and .. for the first time.
+
+ * Lost a bunch of entries in a disk-crash, maybe I should
+ checkin the code a little bit more often.
+
+1998-09-06 Love <lha@s3.kth.se>
+
+ * ufsmedia.c(ufs_putdata): - Added filelen and truncated file,
+ - added check if fd is a directory.
+
+ * fs.c: - Fixed prototype for RXAFS_Symlink.
+
+ * fileserver.h: Added filelen to putdata.
+
+1998-09-04 Love <lha@s3.kth.se>
+
+ * ontofs.c: Started to write the filesystem that will live
+ on top of another.
+
+1998-09-03 Love <lha@s3.kth.se>
+
+ * First time RDWR support, but stil lacking all dir-ops.
+
+ * libmsys/t.c: Test program for milkosys.
+
+ * db/t.c: Testprogram for dbi interface.
+
+ * db/dbi.c: a generic db interface.
+
+ * db/db.c: db interface to dbi.
+
+ * vldbserver.c: New file, broke out of fs.
+
+ * volcommon.c: New file, functions common from volser and fs.
+
+ * volser.c: New server (to be able to fool vos).
+
+ * service.h: Added more services.
+
+ * ufsmedia.c: Added writesupport, still no auth.
+
+ * fs.c: Added code for StoreStatus, StoreData and GetTime.
+
+ * Makefile.in: Added some new files and targets.
+
+ * libmsys/msys.c: Added findmilkosyscall() and istatpath().
+
+1998-09-01 Love <lha@s3.kth.se>
+
+ * ufsmedia.c: Reworked bake_afsdir.
+
+ * sys/modsys.c: Added a new subcall, istatpath.
+
+1998-08-27 Love <lha@s3.kth.se>
+
+ * s/vldb.c/vldbserver.c/: Broke out of the generic server.
+ Added dbi support.
+
+ * db/db.h: A interface for the db interface.
+
+ * db/dbi.[ch]: Added, a generic interface to databases.
+
+1998-08-10 Love <lha@s3.kth.se>
+
+ * sys/msc.h: Added.
+
+ * sys/modsys.c: Added, the FreeBSD milko-syscall.
+
+ * libmsys/msys.h: Added, prototype.
+
+ * libmsys/msys.c: Added, lib for the milkosyscall.
+
+ * libmsys/t.c: Added, testprogram for the lib.
+
+ * ufsmedia.c: Added, export your ufs filesystem. ro, no security.
+
+ * volser.c: Added ufs_filesystemtest. (really need config-file)
+
+ * vldb.c: Moved ipaddress (really need vldb &| config-file)
+
+ * romedia.c: Const'ize.
+
+ * milko_locl.h: Added a bunch of new headfiles.
+
+ * mdir.c(mdir_mkdir): Made sure ret has a sane value.
+
+ * mbuf.c(mcopybuf2rx): Fixed bugs.
+
+ * fs.c: Cleaned up and fixed warnings.
+
+ * fileserver.h: Added some more vop's and const'ized.
+
+ * fileserver.c: Added FILESYSTEM_UFS
+
+ * Makefile.in: cleaned up and and added FILESYSTEM_UFS
+
+Mon Jul 13 21:37:28 1998 Assar Westerlund <assar@sics.se>
+
+ * dumbclient/Makefile.in: compat with stupid makes
+
+ * Makefile.in: compat with stupid makes
+
+1998-06-26 Love Hornquist-Astrand <lha@junkyard.stacken.kth.se>
+
+ * fs.c(RXAFS_FetchData): Fix NULL check.
+
+ * romedia.c(rom_init): Don't open the database rw.
+ (romi_getstatus): Parse input w/o sscanf()
+
+ * volser.c(volser_init): Added static configation (need conffile soon)
+ (volser_addVolume): Fix init
+
+ * romedia.c,roindex.c: Added support for dates,
+ no more 201450000 dates :(
+
+ * mbuf.c: Added support for malloc mbufs.
+
+ * Makefile.in: Fixed building and installing.
+
+1998-06-20 Love <lha@s3.kth.se>
+
+ * disklayer.h: Dont know if this is enough.
+
+1998-06-08 Love <lha@s3.kth.se>
+
+ * Added filserver.c
+
+ * *.c: Started to use define FILESYSTEM_READONLY
+
+ * volser.c (*): Fixes and bring uptodate.
+
diff --git a/usr.sbin/afs/src/milko/Makefile.in b/usr.sbin/afs/src/milko/Makefile.in
new file mode 100644
index 00000000000..8cea6db9543
--- /dev/null
+++ b/usr.sbin/afs/src/milko/Makefile.in
@@ -0,0 +1,48 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:11 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+SUBDIRS = lib appl fs vldb pts bos
+
+all:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+clean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+realclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+distclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+mostlyclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+install:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+uninstall:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+Makefile: Makefile.in ../config.status
+ cd .. ; CONFIG_FILES=milko/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all clean realclean distclean mostlyclean install uninstall
diff --git a/usr.sbin/afs/src/milko/README b/usr.sbin/afs/src/milko/README
new file mode 100644
index 00000000000..3c74d35634a
--- /dev/null
+++ b/usr.sbin/afs/src/milko/README
@@ -0,0 +1,196 @@
+ Milko ($Id: README,v 1.1 2000/09/11 14:41:11 art Exp $)
+=====
+
+Note:
+ milko is still highly experimental, and is neither stable nor
+ full-featured.
+
+* Parts
+
+ fs - FileServer
+ vldb - Volume Location DataBase-server
+ pts - ProTection-Server
+ appl/sked - maintaining volumes the hard way
+
+ lib/dpart - partition parsing and handling
+ lib/mdir - directory handling (unused ?)
+ lib/svol -
+ lib/vld - volume,voldb<->afs interfrace.
+ This would also be the place where to
+ add caching of ``vnodes'', manybe fbuf's too.
+ contains the simple (stupid) volume
+ and ro-volume.
+ lib/voldb - file and directory vnode db.
+ There is today one backend of voldb: vdb_flat
+ vdb_flat is a flat-db to store inodes. Not very
+ smart, but should be efficent enough.
+ lib/vstatus - the volume-node
+
+* Installation
+
+ 1. Create a /vicepa in whatever way
+
+ 2. CellServDB and ThisCell
+
+ Add your cell to $PREFIX/etc/CellServDB and make it the default
+ cell by adding to to $PREFIX/etc/ThisCell.
+
+ 3. If you have Kerberos (you really should have, because it is not
+ tested without).
+
+ This text assumes kth-krb.
+ [If you want support for another kerberos, modify/add apropriate text]
+
+ Get a srvtab for afs@YOUR.REALM, or if you want to use a "subcell"
+ use afs.your.subcell@YOUR.REALM, where your.subcell is the instance.
+ I you don't already have one, ksrvutil will create a principal
+ afs@YOUR.REALM for you. Put the srvtab i $PREFIX/etc/srvtab
+ (really $sysconfdir). Note the empty string '' when you input the
+ Kerberos instance below.
+
+ datan:~$ /usr/athena/sbin/ksrvutil -p lha.admin -f /usr/arla/etc/srvtab get
+ Name [rcmd]: afs
+ Instance [datan]: ''
+ Realm [MY.REALM]:
+ Is this correct? (y,n) [y]:
+ Add more keys (y,n) [n]:
+ Password for lha.admin@MY.REALM:
+ Added afs@MY.REALM
+ Old keyfile in /usr/arla/etc/srvtab.old.
+
+ Verify that you got you principal right
+
+ datan:~$ ksrvutil -f /usr/arla/etc/srvtab list
+ Version Principal
+ 2 afs@MY.REALM
+
+ Add your "afs admin instance" to the $PREFIX/etc/superuserlist
+ file. This can be whatever you like, but has been in most cases
+ .admin (or .root depending on local religion).
+
+ Get your "afs admin instance".
+
+ datan:~$ kauth lha.root
+ lha.root@MY.REALM's Password:
+
+ Verify that you get an afs token
+
+ datan:~$ afslog -c my.cell
+ datan:~$ klist -v
+ Ticket file: /tmp/tkt0
+ Principal: lha@MY.REALM
+
+ Issued Expires Principal (kvno)
+ May 25 03:07:02 May 25 13:07:02 krbtgt.MY.REALM@MY.REALM (1)
+ May 25 03:06:49 May 25 13:06:49 afs@MY.REALM (2)
+
+ Note that the ``afs'' key also can be named ``afs.my.cell''.
+ Its imperative that the key versions (kvno) match up.
+
+ 4. Start vldb-server.
+
+ It will NOT create a databasefile (vl_database) if missing.
+ The first time you have to run the vldbserver with -create
+ as an argument.
+
+ datan:~/obj/arla/milko/vldb# gdb -q vldbserver
+ (gdb) r
+ Starting program: /home/lha/obj/milko/vldb/vldbserver
+ Milko vldbserver 0.26 started
+
+ The vldbserver can be used with -noauth for testing purposes.
+
+ 5. Add root.afs to vldb
+
+ You have to use arla's vos.
+
+ datan:~$ vos createentry -id root.afs -host myhost \
+ -fsserver myhost -part /vicepa -rw 3
+
+ If you use afs.my.cell@MY.REALM (not afs@MY.REALM), you
+ have to add ``-cell my.cell'' to the above command line.
+
+ 6. Create volume root.afs on disk
+
+ datan:~obj/milko/appl/sked# ./sked volcreate /vicepa 3 root.afs
+ volume 3 created successfully
+
+ 7. Start ptserver
+
+ datan:~obj/milko/fs# gdb -q ptserver
+ (gdb) r
+ Starting program: /home/lha/obj/milko/pts/ptserver
+
+ If you need to initialize the pts database, use ptserver -create.
+
+ 8. Start fileserver
+
+ datan:~obj/milko/fs# gdb -q fileserver
+ (gdb) r
+ Starting program: /home/lha/obj/milko/fs/fileserver
+ fileserver booting
+ fileserver started, serving data
+
+ Handy args which can be given to fileserver (check with
+ fileserver --help):
+ --noauth (for testing)
+ --log=file (instead of logging to syslog)
+ --debug=all|errors|warnings|voldb|vld|salvage|fs
+ --cell=cellname
+
+ 9. bosserver
+
+ After running make install you can use $PREFIX/libexec/bosserver
+ to start both the vlserver, ptserver and fileserver.
+
+ 10. run-tests
+
+ Run run-tests in tests/, WORKDIR=/afs ./run-tests -milko -all
+
+ 11. Now what ?
+
+ Find bugs, and report them to <arla-drinkers@stacken.kth.se>.
+
+* Profiling
+
+ If you want profiling information, add -pg (gcc) to CFLAGS, LDFLAGS and
+ recompile.
+
+ When you feel you're done, send the fileserver a USR1 and look for the
+ gprof.out in /vicepa.
+
+* Advice
+
+ Documentation how things works is included in the sourcecode.
+
+ There should be a notice in the top (after the copyright blub)
+ that will give you a general idea what the module (should) do.
+
+ Each function should documented in the comment above the function.
+ Where each argument is described. Any simple/complex/no-trivial
+ locking event should be documented.
+
+ If you see any assert()s in the top of the function (just after
+ the local variables) they are PART OF the documentation. See
+ example [1] below. This makes it easier to find interface
+ changes and other brainlossage.
+
+ If you find something that is undocumented, write documentation!
+ If you find documentation that is invalid, rewrite!
+
+ I'm told the documentation in c-code isn't enough. Guess there
+ should be a greater plan.
+
+[1]
+ Here is an example that the function foo() requires that bar
+ is set. It isn't written in the comment field, instead
+ its checked runtime.
+
+ int
+ foo (int *bar)
+ {
+ int baz;
+
+ assert (bar);
+ return 0;
+ }
diff --git a/usr.sbin/afs/src/milko/appl/Makefile.in b/usr.sbin/afs/src/milko/appl/Makefile.in
new file mode 100644
index 00000000000..c979d008b34
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/Makefile.in
@@ -0,0 +1,48 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:11 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+SUBDIRS = sked perf
+
+all:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+clean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+realclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+distclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+mostlyclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+install:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+uninstall:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+Makefile: Makefile.in ../../config.status
+ cd ../.. ; CONFIG_FILES=milko/appl/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all clean realclean distclean mostlyclean install uninstall
diff --git a/usr.sbin/afs/src/milko/appl/bootstrap/Makefile.in b/usr.sbin/afs/src/milko/appl/bootstrap/Makefile.in
new file mode 100644
index 00000000000..7ffff3bf53d
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/bootstrap/Makefile.in
@@ -0,0 +1,58 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:11 art Exp $
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+RM = rm
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sbindir = @sbindir@
+transform = @program_transform_name@
+
+PROGS = boot-strap.sh anti-boot-strap.sh
+
+all: $(PROGS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -I../../../include -I$(srcdir)/../../../include $<
+
+clean:
+ $(RM) -f $(PROGS) startarla *.o *~
+
+boot-strap.sh: boot-strap.sh.in
+ cd ../../.. ; CONFIG_FILES=milko/appl/bootstrap/boot-strap.sh CONFIG_HEADERS= $(SHELL) config.status
+ chmod +x $@
+anti-boot-strap.sh: anti-boot-strap.sh.in
+ cd ../../.. ; CONFIG_FILES=milko/appl/bootstrap/anti-boot-strap.sh CONFIG_HEADERS= $(SHELL) config.status
+ chmod +x $@
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../.. ; CONFIG_FILES=milko/appl/bootstrap/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(sbindir)
+ PROG_SBIN='$(PROGS)'; for x in $$PROG_SBIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(sbindir)/$$f; \
+ done
+
+uninstall:
+ PROG_SBIN='$(PROGS)'; for x in $$PROG_SBIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(sbindir)/$$f; \
+ done
+
+.PHONY: all install uninstall clean
diff --git a/usr.sbin/afs/src/milko/appl/bootstrap/anti-boot-strap.sh.in b/usr.sbin/afs/src/milko/appl/bootstrap/anti-boot-strap.sh.in
new file mode 100644
index 00000000000..6428987dc7c
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/bootstrap/anti-boot-strap.sh.in
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Shell-script to ANTI bootstrap a cell
+#
+
+# shell stuff
+
+version="$Id: anti-boot-strap.sh.in,v 1.1 2000/09/11 14:41:11 art Exp $"
+usage="NOT USE IF YOU DONT KNOW _=*KNOW*=_ WHAT YOU ARE DOING"
+
+PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH
+
+real_useage="$0 magic4711 /partN sysconfdir"
+
+
+if test $# -ne 3; then
+ echo $usage ; exit 1;
+fi
+
+if test $1 != "magic4711"; then
+ echo $usage ; exit 1;
+fi
+
+
+if [ ! -d $2 ] ; then
+ echo $usage ; exit 1;
+fi
+
+if [ ! -d $3 ] ; then
+ echo $usage ; exit 1;
+fi
+
+###
+
+echo -n "Trying to cleanup..."
+
+for a in $2/*; do
+ rm -rf $a
+done
+
+rm -f $3/pr_database
+rm -f $3/vl_database
+rm -f $3/srvtab
+rm -f $3/srvtab.old
+
+echo "done."
+
+exit 0; \ No newline at end of file
diff --git a/usr.sbin/afs/src/milko/appl/bootstrap/boot-strap.sh.in b/usr.sbin/afs/src/milko/appl/bootstrap/boot-strap.sh.in
new file mode 100644
index 00000000000..6a878ea7cc7
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/bootstrap/boot-strap.sh.in
@@ -0,0 +1,149 @@
+#!/bin/sh
+#
+# Shell-script to bootstrap cell
+#
+
+# shell stuff
+
+version="$Id: boot-strap.sh.in,v 1.1 2000/09/11 14:41:11 art Exp $"
+usage="Usage: $0 [-v] [-p /viceN ]"
+
+#
+# Milko Boot variables
+#
+
+#all zeros are needed on ROOTVOLNUM
+
+ROOTVOL=root.cell
+ROOTVOLNUM=00000003
+ROOTPART=/vicepa
+
+#
+# Autoconf stuff
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libexecdir=@libexecdir@
+sysconfdir=@sysconfdir@
+
+ksrvutil=/usr/athena/sbin/ksrvutil
+
+while test $# -gt 0
+do
+ case $1 in
+ -v) echo $version ; shift ; exit 1 ;;
+ -p) ROOTPART=$2 ;
+ shift 2 2>/dev/null || { echo $usage ; exit 1 }
+ ;;
+ *) echo $usage ; exit 1; break;;
+ esac
+done
+
+#
+# What we do if we fail
+#
+
+antibootstrapbin="${sbindir}/anti-boot-strap.sh"
+antibootstrap="${antibootstrapbin} magic4711 $ROOTPART ${sysconfdir}"
+
+
+PROGRAMS="$sbindir/sked \
+ $libexecdir/fileserver \
+ $libexecdir/ptserver \
+ $libexecdir/bosserver \
+ $libexecdir/vldbserver \
+ $antibootstrapbin "
+
+for a in $PROGRAMS; do
+ if [ ! -x $a ] ; then
+ echo "ERROR: missing $a, did you do a make install ?";
+ exit 1;
+ fi
+done
+
+if [ ! -d $ROOTPART ]; then
+ echo "ERROR: You don't have a $ROOTPART katalog/mountpoint."
+ echo "Please create.";
+ exit 1
+fi
+
+# XXX figure out hostname
+
+if [ -f $ROOTPART/vol$ROOTVOLNUM ] ; then
+ echo "WARNING: are you sure you want to overwrite a existing installation"
+ echo "There seams to be traces of a installation $ROOTPART"
+ echo "Please remove it before retrying if you don't want it"
+ exit 1
+fi
+
+if [ -f $sysconfdir/pr_database ] ; then
+ echo "WARNING: there is already a pr database"
+ echo "Remove it ($sysconfdir/pr_database) it you want to proceed"
+ exit 1
+fi
+
+if [ -f $sysconfdir/vl_database ] ; then
+ echo "WARNING: there is already a vl database"
+ echo "Remove it ($sysconfdir/vl_database) it you want to proceed"
+ exit 1
+fi
+
+
+if $sbindir/sked volcreate ${ROOTPART} ${ROOTVOLNUM} ${ROOTVOL}; then
+ : ;
+else
+ echo "ERROR: failed to created ${ROOTVOL} with sked";
+ exec ${antibootstrap}
+fi
+
+# XXX create root srvtab
+
+if $libexecdir/vldbserver -create ; then
+ : ;
+else
+ echo "ERROR: failed to vl database";
+ exec ${antibootstrap}
+fi
+
+# XXX add rootvol
+
+if $libexecdir/ptserver -create ; then
+ : ;
+else
+ echo "ERROR: failed to pts database";
+ exec ${antibootstrap}
+fi
+
+# XXX create a bosserver.conf
+
+# XXX tell how to add users to system:administators (pts cu foo -local)
+
+# XXX tell how to start bosserver
+
+if test -x $ksrvutil ; then
+ echo "Now its time to create kerberos tickets for you cell"
+ echo " For Name[rcmd]: write: afs"
+ echo " For Instance[hostname]: write: you.cell.here"
+ echo " For Realm [YOUR.REALM]: write YOUR.REALM.HERE"
+ echo ""
+ echo " the rest is obvious"
+
+ command="$ksrvutil -f $sysconfdir/srvtab -p $USER.admin get"
+
+ echo "The command I'm try is \"$command\""
+
+ eval $command
+
+else
+
+ echo "No kth-krb ksrvutil, create a srvtab with afs.you\.cell\.@YOUR.REALM"
+ echo "token in $sysconfdir"
+
+fi
+
+echo "Congratulations, done"
+
+exit 0; \ No newline at end of file
diff --git a/usr.sbin/afs/src/milko/appl/perf/Makefile.in b/usr.sbin/afs/src/milko/appl/perf/Makefile.in
new file mode 100644
index 00000000000..38fe26eae41
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/perf/Makefile.in
@@ -0,0 +1,112 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:11 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sbindir = @sbindir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = perf
+PROGS = $(APPL_BIN)
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+
+ETAGS = etags
+INCLUDES = -I$(srcdir)/../../fs \
+ -I$(srcdir)/../../../include \
+ -I$(srcdir)/../../../appl/lib \
+ -I$(srcdir) \
+ -I$(srcdir)/../../.. \
+ -I../../../include \
+ -I../../../rxdef \
+ @KRB4_INC_FLAGS@ \
+ -I.
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) $(X_CFLAGS)
+RXKAD_LIBS = @RXKAD_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../../../lib/sl -lsl \
+ @LIB_readline@ \
+ -L../../../util -lutil \
+ -L../../../rx -lrx \
+ -L../../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../../appl/lib -larlalib \
+ -L../../../lib/ko -lko \
+ -L../../../rxdef -lrxdefclient \
+ -L../../../lib/roken \
+ @MILKO_RXKAD_LIBS2@ \
+ @KRB4_LIB_FLAGS@ \
+ -L../../../util -lutil \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../../util/libutil.a ../../../lib/sl/libsl.a \
+ ../../../lib/roken/libroken.a
+
+PERF_SRCS = perf.c
+SRCS = $(PERF_SRCS)
+PERF_OBJS = perf.o
+HDRS = perf.h
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(sbindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(sbindir)/$$f; \
+ done
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(sbindir)/$$f; \
+ done
+
+perf: $(PERF_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(PERF_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/appl/perf/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/milko/appl/perf/perf.c b/usr.sbin/afs/src/milko/appl/perf/perf.c
new file mode 100644
index 00000000000..8a59cc376ce
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/perf/perf.c
@@ -0,0 +1,680 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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
+
+RCSID("$Id: perf.c,v 1.1 2000/09/11 14:41:12 art Exp $");
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <assert.h>
+#include <err.h>
+
+#include <service.h>
+
+#include <cb.ss.h>
+#include <fs.cs.h>
+
+#include <des.h>
+#include <krb.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+#include <rxkad/rxkad.h>
+
+#include <atypes.h>
+
+#include <arlalib.h>
+#include <ports.h>
+#include <service.h>
+
+#include <getarg.h>
+
+static char *arg_cell = NULL;
+
+/*
+ * Each client need a callbackserver, here we go...
+ */
+
+int
+RXAFSCB_Probe (struct rx_call *a_rxCallP)
+{
+ return 0;
+}
+
+int
+RXAFSCB_InitCallBackState (struct rx_call *a_rxCallP)
+{
+ return 0;
+}
+
+int
+RXAFSCB_CallBack (struct rx_call *a_rxCallP,
+ const AFSCBFids *a_fidArrayP,
+ const AFSCBs *a_callBackArrayP)
+{
+ return 0;
+}
+
+
+int
+RXAFSCB_GetLock(struct rx_call *a_rxCallP,
+ int32_t index,
+ AFSDBLock *lock)
+{
+ return 1;
+}
+
+int
+RXAFSCB_GetCE(struct rx_call *a_rxCallP,
+ int32_t index,
+ AFSDBCacheEntry *dbentry)
+{
+ return 1;
+}
+
+int
+RXAFSCB_XStatsVersion(struct rx_call *a_rxCallP,
+ int32_t *version)
+{
+ return EOPNOTSUPP;
+}
+
+int
+RXAFSCB_GetXStats(struct rx_call *a_rxCallP,
+ int32_t client_version_num,
+ int32_t collection_number,
+ int32_t *server_version_number,
+ int32_t *time,
+ AFSCB_CollData *stats)
+{
+ return EOPNOTSUPP;
+}
+
+int
+RXAFSCB_InitCallBackState2(struct rx_call *a_rxCallP,
+ interfaceAddr *addr)
+{
+ return EOPNOTSUPP;
+}
+
+int
+RXAFSCB_WhoAreYou(struct rx_call *a_rxCallP,
+ interfaceAddr *addr)
+{
+ return EOPNOTSUPP;
+}
+
+int
+RXAFSCB_InitCallBackState3(struct rx_call *a_rxCallP,
+ const afsUUID *server_uuid)
+{
+ return EOPNOTSUPP;
+}
+
+int
+RXAFSCB_ProbeUUID(struct rx_call *a_rxCallP,
+ const afsUUID *uuid)
+{
+ return EOPNOTSUPP;
+}
+
+static void
+cmcb_init (void)
+{
+ static struct rx_securityClass *nullSecObjP;
+ static struct rx_securityClass *(securityObjects[1]);
+
+ nullSecObjP = rxnull_NewClientSecurityObject ();
+ if (nullSecObjP == NULL) {
+ printf("Cannot create null security object.\n");
+ return;
+ }
+
+ securityObjects[0] = nullSecObjP;
+
+ if (rx_NewService (0, CM_SERVICE_ID, "cm", securityObjects,
+ sizeof(securityObjects) / sizeof(*securityObjects),
+ RXAFSCB_ExecuteRequest) == NULL ) {
+ printf("Cannot install service.\n");
+ return;
+ }
+ rx_StartServer (0);
+}
+
+/*
+ *
+ */
+
+static struct timeval timer_start;
+static struct timeval timer_stop;
+static int timer_check = 0;
+
+static void
+start_timer (void)
+{
+ timer_check++;
+ gettimeofday (&timer_start, NULL);
+}
+
+/*
+ *
+ */
+
+static void
+end_and_print_timer (char *str)
+{
+ long long start_l, stop_l;
+
+ timer_check--;
+ assert (timer_check == 0);
+ gettimeofday(&timer_stop, NULL);
+ start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
+ stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
+ printf("%s:\t%8llu msec\n", str, (stop_l-start_l)/1000);
+}
+
+
+static void
+do_createfile (struct rx_connection *conn, const AFSFid *parent,
+ const char *name, AFSFid *child)
+{
+ static AFSStoreStatus InStatus = { 0,0,0,0,0 };
+ AFSFetchStatus OutFidStatus, OutDirStatus;
+ AFSCallBack CallBack;
+ AFSVolSync a_volSyncP;
+ int ret;
+
+ ret = RXAFS_CreateFile (conn, parent, name, &InStatus,
+ child, &OutFidStatus, &OutDirStatus,
+ &CallBack, &a_volSyncP);
+ if (ret)
+ errx (1, "RXAFS_CreateFile returned %d", ret);
+}
+
+static void
+do_createfilecontent (struct rx_connection *conn, const AFSFid *parent,
+ const char *name, AFSFid *child, int size,
+ int times, char *buffer)
+{
+ static AFSStoreStatus InStatus = { 0,0,0,0,0 };
+ AFSFetchStatus OutFidStatus, OutDirStatus;
+ AFSCallBack CallBack;
+ AFSVolSync a_volSyncP;
+ int ret;
+ struct rx_call *call;
+ int i;
+
+ ret = RXAFS_CreateFile (conn, parent, name, &InStatus,
+ child, &OutFidStatus, &OutDirStatus,
+ &CallBack, &a_volSyncP);
+ if (ret)
+ errx (1, "RXAFS_CreateFile returned %d", ret);
+
+ call = rx_NewCall (conn);
+
+ if (call == NULL)
+ errx (1, "rx_NewCall returned NULL");
+
+ ret = StartRXAFS_StoreData (call, child, &InStatus,
+ 0, size*times, size*times);
+
+ if (ret)
+ errx (1, "StartRXAFS_StoreData returned %d", ret);
+
+ for (i = 0; i < times; i++) {
+ ret = rx_Write(call, buffer, size);
+ if (ret != size)
+ errx (1, "rx_Write returned %d", ret);
+ }
+
+ ret = EndRXAFS_StoreData (call, &OutFidStatus, &a_volSyncP);
+
+ if (ret)
+ errx (1, "StartRXAFS_StoreData returned %d", ret);
+
+ ret = rx_EndCall(call, ret);
+ if (ret)
+ errx (1, "rx_EndCall returned %d", ret);
+}
+
+static void
+do_readfilecontent (struct rx_connection *conn, const AFSFid *fid,
+ int size,
+ int times, char *buffer)
+{
+ AFSFetchStatus OutFidStatus;
+ AFSCallBack CallBack;
+ AFSVolSync a_volSyncP;
+ int ret;
+ struct rx_call *call;
+ int i;
+
+ call = rx_NewCall (conn);
+
+ if (call == NULL)
+ errx (1, "rx_NewCall returned NULL");
+
+ ret = StartRXAFS_FetchData (call, fid, 0, size*times);
+
+ if (ret)
+ errx (1, "StartRXAFS_FetchData returned %d", ret);
+
+ for (i = 0; i < times; i++) {
+ ret = rx_Read(call, buffer, size);
+ if (ret != size)
+ errx (1, "rx_Read returned %d", ret);
+ }
+
+ ret = EndRXAFS_FetchData (call, &OutFidStatus, &CallBack,
+ &a_volSyncP);
+ if (ret)
+ errx (1, "StartRXAFS_FetchData returned %d", ret);
+
+ ret = rx_EndCall(call, ret);
+ if (ret)
+ errx (1, "rx_EndCall returned %d", ret);
+}
+
+static void
+do_gtod (struct rx_connection *conn)
+{
+ int ret;
+ int32_t sec, usec;
+
+ ret = RXAFS_GetTime (conn, &sec, &usec);
+ if (ret)
+ errx (1, "RXAFS_GetTime returned %d", ret);
+}
+
+static void
+do_mkdir (struct rx_connection *conn, const AFSFid *parent,
+ const char *name, AFSFid *child)
+{
+ static AFSStoreStatus InStatus = { 0,0,0,0,0 };
+ AFSFetchStatus OutFidStatus, OutDirStatus;
+ AFSCallBack CallBack;
+ AFSVolSync a_volSyncP;
+ int ret;
+
+ ret = RXAFS_MakeDir (conn, parent, name, &InStatus,
+ child, &OutFidStatus, &OutDirStatus,
+ &CallBack, &a_volSyncP);
+ if (ret)
+ errx (1, "RXAFS_MakeDir returned %d", ret);
+}
+
+
+static void
+do_rmdir (struct rx_connection *conn, const AFSFid *parent,
+ const char *name)
+{
+ AFSFetchStatus a_newParentDirStatP;
+ AFSVolSync a_volSyncP;
+ int ret;
+
+ ret = RXAFS_RemoveDir (conn, parent, name, &a_newParentDirStatP,
+ &a_volSyncP);
+ if (ret)
+ errx (1, "RXAFS_RemoveDir returned %d", ret);
+}
+
+static void
+do_removefile (struct rx_connection *conn, const AFSFid *parent,
+ const char *name)
+{
+ AFSFetchStatus a_newParentDirStatP;
+ AFSVolSync a_volSyncP;
+ int ret;
+
+ ret = RXAFS_RemoveFile (conn, parent, name, &a_newParentDirStatP,
+ &a_volSyncP);
+ if (ret)
+ errx (1, "RXAFS_RemoveDir returned %d", ret);
+}
+
+static void __attribute__((__unused__))
+do_bulkstat (struct rx_connection *conn, AFSFid *fids,
+ int num)
+{
+ AFSCBFids FidsArray;
+ AFSBulkStats StatArray;
+ AFSCBs CBArray;
+ AFSVolSync Sync;
+ int ret;
+
+ FidsArray.val = fids;
+ FidsArray.len = num;
+
+ ret = RXAFS_BulkStatus (conn, &FidsArray, &StatArray, &CBArray, &Sync);
+ if (ret)
+ errx (1, "RXAFS_BulkStatus faile with %d", ret);
+
+ free (StatArray.val);
+ free (CBArray.val);
+}
+
+/*
+ *
+ */
+
+typedef void (*create_many_create)(struct rx_connection *conn,
+ const AFSFid *parent,
+ const char *name,
+ AFSFid *child);
+typedef void (*create_many_remove)(struct rx_connection *conn,
+ const AFSFid *parent,
+ const char *name);
+
+static void
+create_many_entry (struct rx_connection *conn, AFSFid *parentfid, int num,
+ create_many_create create,
+ create_many_remove remove,
+ const char *entry_name)
+{
+ char *dir, *stamp;
+ AFSFid fid;
+ AFSFid *files;
+ int i;
+ char filename[MAXPATHLEN];
+
+ assert (num >= 0);
+
+ files = emalloc (num * sizeof (fid));
+
+ asprintf (&stamp, "creating %d %ss", num, entry_name);
+
+ asprintf (&dir, "create_many_files-%d-time-%d", num, (int)time(NULL));
+ do_mkdir (conn, parentfid, dir, &fid);
+
+ start_timer();
+ for (i = 0; i < num; i++) {
+ snprintf (filename, sizeof(filename), "%d", i);
+ (create) (conn, &fid, filename, &files[i]);
+ }
+ end_and_print_timer (stamp);
+
+ free (stamp);
+ asprintf (&stamp, "removing %d %ss", num, entry_name);
+
+ start_timer();
+ for (i = 0; i < num; i++) {
+ snprintf (filename, sizeof(filename), "%d", i);
+ (remove) (conn, &fid, filename);
+ }
+ end_and_print_timer (stamp);
+
+ do_rmdir (conn, parentfid, dir);
+
+ free (stamp);
+ free (dir);
+}
+
+static void
+create_and_read_content (struct rx_connection *conn, AFSFid *parentfid, int size)
+{
+ char *dir, *stamp;
+ AFSFid fid;
+ AFSFid file;
+ char *buffer;
+
+ asprintf (&stamp, "writing %dM data", size);
+
+ asprintf (&dir, "write_big_files-%d-time-%d", size, (int)time(NULL));
+ do_mkdir (conn, parentfid, dir, &fid);
+
+ buffer = malloc(1024*1024);
+ memset(buffer, 'X', 1024*1024);
+
+ start_timer();
+ do_createfilecontent (conn, &fid, "foo", &file, 1024*1024,
+ size, buffer);
+ end_and_print_timer (stamp);
+
+ free (stamp);
+
+ asprintf (&stamp, "reading %dM data", size);
+ start_timer();
+ do_readfilecontent (conn, &file, 1024*1024, size, buffer);
+ end_and_print_timer (stamp);
+
+ free(stamp);
+
+ free(buffer);
+
+ asprintf (&stamp, "removing %dM data", size);
+
+ start_timer();
+ do_removefile (conn, &fid, "foo");
+ end_and_print_timer (stamp);
+
+ do_rmdir (conn, parentfid, dir);
+
+ free (stamp);
+ free (dir);
+}
+
+static void
+bench_gettime(struct rx_connection *conn, int times)
+{
+ char *stamp;
+ int i;
+
+ asprintf (&stamp, "gettime %d times", times);
+
+ start_timer();
+ for (i = 0; i < times; i++)
+ do_gtod (conn);
+ end_and_print_timer (stamp);
+
+ free (stamp);
+}
+
+/*
+ *
+ */
+
+static int
+do_bench (char *host, int volume, arlalib_authflags_t auth)
+{
+ struct rx_connection *conn;
+ AFSFid root;
+
+ conn = arlalib_getconnbyname (arg_cell, host, afsport,
+ FS_SERVICE_ID, auth);
+ if (conn == NULL)
+ errx (1, "arlalib_getconnbyname failed");
+
+
+ root.Volume = volume;
+ root.Vnode = 1;
+ root.Unique = 1;
+
+ bench_gettime(conn, 1);
+ bench_gettime(conn, 100);
+ bench_gettime(conn, 1000);
+ bench_gettime(conn, 2000);
+ create_and_read_content (conn, &root, 1);
+ create_and_read_content (conn, &root, 2);
+ create_and_read_content (conn, &root, 10);
+ create_and_read_content (conn, &root, 20);
+ create_and_read_content (conn, &root, 30);
+ create_and_read_content (conn, &root, 40);
+ create_and_read_content (conn, &root, 50);
+
+ create_many_entry (conn, &root, 1000,do_createfile,do_removefile, "file");
+ create_many_entry (conn, &root, 2000,do_createfile,do_removefile, "file");
+ create_many_entry (conn, &root, 4000,do_createfile,do_removefile, "file");
+ create_many_entry (conn, &root, 8000,do_createfile,do_removefile, "file");
+
+ create_many_entry (conn, &root, 1000, do_mkdir, do_rmdir, "dir");
+ create_many_entry (conn, &root, 2000, do_mkdir, do_rmdir, "dir");
+ create_many_entry (conn, &root, 4000, do_mkdir, do_rmdir, "dir");
+ create_many_entry (conn, &root, 8000, do_mkdir, do_rmdir, "dir");
+
+ rx_DestroyConnection(conn);
+
+ return 0;
+}
+
+static int
+do_readbench(char *host, int volume, int vnode, int uniq, arlalib_authflags_t auth)
+{
+ char *stamp;
+ char *buffer;
+ AFSFid file;
+ struct rx_connection *conn;
+
+ conn = arlalib_getconnbyname (arg_cell, host, afsport,
+ FS_SERVICE_ID, auth);
+
+ buffer = malloc(1024*1024);
+ asprintf (&stamp, "reading %dM data", 10);
+ file.Vnode = vnode;
+ file.Volume = volume;
+ file.Unique = uniq;
+ start_timer();
+ do_readfilecontent (conn, &file, 1024*1024, 10, buffer);
+ end_and_print_timer (stamp);
+
+ free(stamp);
+ free(buffer);
+ rx_DestroyConnection(conn);
+ return 0;
+}
+
+/*
+ *
+ */
+
+static char *arg_host = NULL;
+static int arg_volume = 0;
+static int arg_authlevel = 2;
+static int arg_help = 0;
+static int arg_vnode = 0;
+static int arg_uniq = 0;
+
+struct getargs args[] = {
+ {"host", 0, arg_string, &arg_host,
+ "what host to use", "host", arg_mandatory},
+ {"volume", 0, arg_integer, &arg_volume,
+ "what volume to use", NULL, arg_mandatory},
+ {"authlevel",0, arg_integer, &arg_authlevel,
+ "authlevel", NULL, arg_mandatory},
+ {"help", 0, arg_flag, &arg_help,
+ "authlevel", NULL, arg_mandatory},
+ {"vnode", 0, arg_integer, &arg_vnode,
+ "what vnode to read from", NULL, arg_optional},
+ {"uniq", 0, arg_integer, &arg_uniq,
+ "what uniq to read from", NULL, arg_optional},
+ {"cell", 0, arg_string, &arg_cell,
+ "cell", NULL, arg_optional},
+ { NULL, 0}
+};
+
+static void
+usage (int eval)
+{
+ arg_printusage(args, "perf", NULL, ARG_AFSSTYLE);
+
+ printf ("\nTips:\n"
+ " on errors use `fs strerror <errno>' to figure"
+ " out what was wrong\n");
+
+ exit (eval);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int ret, optind = 0;
+ arlalib_authflags_t auth;
+ char *auth_string;
+
+ printf ("afs low-level performance tester\n");
+
+ ret = rx_Init (htons(4712));
+ if (ret)
+ errx (1, "rx_Init returnd %d", ret);
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage (args, "", NULL, ARG_AFSSTYLE);
+ return 0;
+ }
+
+ if (arg_help)
+ usage (0);
+
+ ports_init ();
+ cmcb_init();
+
+ switch (arg_authlevel) {
+ case 1:
+ auth = AUTHFLAGS_NOAUTH;
+ auth_string = "clear";
+ break;
+ case 2:
+ auth = AUTHFLAGS_TICKET;
+ auth_string = "auth";
+ rxkad_min_level = rxkad_auth;
+ break;
+ case 3:
+ auth = AUTHFLAGS_TICKET;
+ auth_string = "crypt";
+ rxkad_min_level = rxkad_crypt;
+ break;
+ default:
+ errx (1, "authlevel: only 1, 2 or 3 is valid (clear, auth, crypt)");
+ }
+
+ printf ("Perf\n");
+ printf ("host: %s, volume: %d, auth: %s\n",
+ arg_host, arg_volume, auth_string);
+
+ if (arg_vnode && arg_uniq)
+ do_readbench(arg_host, arg_volume, arg_vnode, arg_uniq, auth);
+ else
+ do_bench (arg_host, arg_volume, auth);
+
+ return 0;
+}
+
+
diff --git a/usr.sbin/afs/src/milko/appl/sked/Makefile.in b/usr.sbin/afs/src/milko/appl/sked/Makefile.in
new file mode 100644
index 00000000000..0e2267fbe9c
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/sked/Makefile.in
@@ -0,0 +1,124 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:12 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+LN_S = @LN_S@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sbindir = @sbindir@
+transform = @program_transform_name@
+EXECSUFFIX = @EXECSUFFIX@
+
+APPL_BIN = sked
+PROGS = $(APPL_BIN)
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+
+ETAGS = etags
+INCLUDES = -I$(srcdir)/../../fs \
+ -I$(srcdir)/../../../include \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../../lib/mlog \
+ -I$(srcdir)/../../lib/voldb \
+ -I$(srcdir)/../../lib/dpart \
+ -I$(srcdir)/../../lib/vld \
+ -I$(srcdir)/../../lib/vstatus \
+ -I$(srcdir)/../../../lib/bufdir \
+ -I$(srcdir)/../../lib/mdir \
+ -I$(srcdir)/../../lib/vstatus \
+ -I../../lib/vstatus \
+ -I../../../include \
+ -I../../../rxdef \
+ -I$(srcdir) \
+ -I$(srcdir)/../../.. \
+ -I.
+
+DEFINES =
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) $(X_CFLAGS)
+RXKAD_LIBS = @RXKAD_LIBS@
+LIB_tgetent = @LIB_tgetent@
+LIBS = -L../../../lib/sl -lsl \
+ @LIB_readline@ \
+ -L../../lib/dpart -ldpart \
+ -L../../lib/vld -lvld \
+ -L../../lib/voldb -lvoldb \
+ -L../../lib/vstatus -lvstatus \
+ -L../../lib/mlog -lmlog \
+ -L../../../lib/bufdir -lbufdir \
+ -L../../../rx -lrx \
+ -L../../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../../rxdef -lrxvolserver \
+ -L../../../util -lutil \
+ -L../../../lib/ko -lko \
+ -L../../../lib/roken \
+ -lroken @LIBS@
+
+LIBDEPENDS = ../../../util/libutil.a ../../../lib/sl/libsl.a \
+ ../../../lib/roken/libroken.a ../../lib/voldb/libvoldb.a \
+ ../../lib/dpart/libdpart.a ../../lib/vld/libvld.a \
+ ../../lib/mlog/libmlog.a
+
+SKED_SRCS = sked.c
+SRCS = $(SKED_SRCS)
+SKED_OBJS = sked.o
+HDRS = sked.h
+
+all: $(PROGS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(sbindir)
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(sbindir)/$$f; \
+ done
+
+uninstall:
+ PROG_BIN='$(APPL_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(sbindir)/$$f; \
+ done
+
+sked: $(SKED_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(SKED_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/appl/sked/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/milko/appl/sked/sked.c b/usr.sbin/afs/src/milko/appl/sked/sked.c
new file mode 100644
index 00000000000..df4a10aa90c
--- /dev/null
+++ b/usr.sbin/afs/src/milko/appl/sked/sked.c
@@ -0,0 +1,793 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+#include "roken.h"
+
+RCSID("$Id: sked.c,v 1.1 2000/09/11 14:41:12 art Exp $");
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <err.h>
+#include <assert.h>
+
+#include <sl.h>
+#include <getarg.h>
+
+#include <atypes.h>
+#include <rx/rx.h>
+#include <fbuf.h>
+#include <fs_def.h>
+#include <pts.h>
+#include <dpart.h>
+#include <vstatus.h>
+#include <voldb.h>
+#include <vld.h>
+#include <mnode.h>
+#include <vldb.h>
+#include <mdir.h>
+#include <salvage.h>
+#include <mlog.h>
+#include <mdebug.h>
+
+static int interactivep = 0;
+
+#define INTER_RETURN(ret) if (interactivep) return 0; else exit (ret);
+
+static int
+create_volume (u_int32_t part, u_int32_t num, char *name)
+{
+ int ret;
+ int32_t backstoretype = VLD_SVOL;
+ struct dp_part *dp;
+
+
+ ret = dp_create (part, &dp);
+ if (ret)
+ return ret;
+
+ ret = vld_create_volume (dp, num, name, backstoretype, RWVOL, 0);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+show_volume (u_int32_t part, u_int32_t num)
+{
+ volume_handle *vh = NULL;
+ int ret;
+ struct dp_part *dp = NULL;
+
+ ret = dp_create (part, &dp);
+ if (ret) {
+ printf ("show_volume: dp_create: %d\n", ret);
+ goto out;
+ }
+
+ ret = vld_open_volume_by_num (dp, num, &vh);
+ if (ret) {
+ printf ("show_volume: vld_open_volume_ny_num: %d\n", ret);
+ goto out;
+ }
+
+ ret = vld_info_uptodatep (vh);
+ if (ret) {
+ printf ("show_volume: vld_info_uptodatep: %d\n", ret);
+ goto out;
+ }
+
+ printf ("volume-type:\t%s\n", vld_backstoretype_name(vh->type));
+ printf ("------------------------\n");
+ vol_pretty_print_info (stdout, &vh->info);
+
+ ret = vld_db_uptodate (vh);
+ if (ret) {
+ printf ("show_volume: vld_db_uptodate: %d\n", ret);
+ goto out;
+ }
+
+ printf ("voldb header:\n dir:\n");
+ voldb_pretty_print_header(vh->db[0]);
+ printf ("file:\n");
+ voldb_pretty_print_header(vh->db[1]);
+
+ printf ("info: ");
+ vstatus_print_onode (stdout, &vh->sino);
+ printf ("dir: ");
+ vstatus_print_onode (stdout, &vh->dino);
+ printf ("file: ");
+ vstatus_print_onode (stdout, &vh->fino);
+
+ out:
+ if (vh)
+ vld_free (vh);
+ if (dp)
+ dp_free (dp);
+
+ INTER_RETURN(ret ? 1 : 0);
+}
+
+/*
+ *
+ */
+
+static void
+showvols_cb (void *data, int fd)
+{
+ struct dp_part *dp = data;
+ volume_handle *vh;
+ int ret;
+
+ assert (dp);
+
+ ret = vld_open_volume_by_fd (dp, fd, &vh);
+ if (ret) {
+ printf ("showvols_cb: vld_open_volume_by_fd: %d\n", ret);
+ }
+
+ ret = vld_info_uptodatep (vh);
+ if (ret) {
+ printf ("showvols_cb: vld_info_uptodatep: %d\n", ret);
+ vld_free (vh);
+ }
+
+ if (vh->vol != vh->info.volid)
+ printf ("PANIC: vh->vol != vh->info.volid\n");
+
+ printf ("%-32s %-4s %-4s %-8u %-8u %-8u %-8u\n",
+ vh->info.name, vld_backstoretype_name(vh->type),
+ vol_voltype2name(vh->info.type), vh->vol,
+ vh->info.backupID, vh->info.parentID,
+ vh->info.cloneID);
+
+ vld_free (vh);
+}
+
+/*
+ * List volumes on partition `part'.
+ */
+
+static int
+show_vols (u_int32_t part)
+{
+ struct dp_part *p;
+ int ret;
+
+ ret = dp_create (part, &p);
+ if (ret)
+ errx (1, "dp_create returned %d", ret);
+
+ printf ("%-32s %-4s %-4s %-8s %-8s %-8s %-8s\n",
+ "Name", "Type", "Type",
+ "VolID", "BackupID", "ParentID", "cloneID");
+ ret = dp_findvol (p, showvols_cb, p);
+ if (ret)
+ errx (1, "dp_findvol returned %d", ret);
+
+ dp_free (p);
+
+ return 0;
+}
+
+/*
+ * sl commands
+ */
+
+static int
+volcreate_cmd (int argc, char **argv)
+{
+ u_int32_t num, part;
+ int ret;
+
+ if (argc != 4) {
+ printf ("usage: volcreate part num name\n");
+ INTER_RETURN(1);
+ }
+
+ part = atoi (argv[1]);
+
+ num = atoi (argv[2]);
+ if (num == 0) {
+ printf ("volcreate: `%s' is a invalid argument for volnum\n", argv[2]);
+ INTER_RETURN(1);
+ }
+
+ ret = create_volume (part, num, argv[3]);
+ if (ret) {
+ printf ("volcreate: create_volume returned: %d\n", ret);
+ INTER_RETURN(ret);
+ }
+
+ printf ("volume %u created successfully\n", num);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+volshow_cmd (int argc, char **argv)
+{
+ u_int32_t num, part;
+ int ret;
+
+ if (argc != 3) {
+ printf ("usage: volshow part num\n");
+ INTER_RETURN(1);
+ }
+
+ part = atoi (argv[1]);
+
+ num = atoi (argv[2]);
+ if (num == 0) {
+ printf ("volcreate: `%s' is a invalid argument for volnum\n", argv[2]);
+ INTER_RETURN(1);
+ }
+
+ ret = show_volume (part, num);
+ if (ret) {
+ printf ("volshow: show_volume returned: %d\n", ret);
+ INTER_RETURN(ret);
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+vollist_cmd (int argc, char **argv)
+{
+ u_int32_t part;
+ int ret;
+
+ if (argc != 2) {
+ printf ("usage: vollist part\n");
+ INTER_RETURN(1);
+ }
+
+ part = atoi (argv[1]);
+
+ ret = show_vols (part);
+ if (ret) {
+ printf ("vollist: show_vols returned: %d\n", ret);
+ INTER_RETURN(ret);
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static void
+volls_dir_cb (VenusFid *fid, const char *name, void *arg)
+{
+ printf ("%-60s %d.%d.%d\n",
+ name,
+ fid->fid.Volume,
+ fid->fid.Vnode,
+ fid->fid.Unique);
+}
+
+static int
+volls_cmd (int argc, char **argv)
+{
+ u_int32_t part;
+ u_int32_t vol;
+ u_int32_t vnode;
+ struct dp_part *dp;
+ int ret;
+
+ if (argc != 4) {
+ printf ("volls part volume# vnode#\n");
+ INTER_RETURN(1);
+ }
+
+ part = atoi(argv[1]);
+ vol = atoi(argv[2]);
+ if (vol == 0) {
+ printf ("erronous volume number\n");
+ INTER_RETURN(1);
+ }
+
+ vnode = atoi(argv[3]);
+ if (vnode == 0) {
+ printf ("erronous vnode number\n");
+ INTER_RETURN(1);
+ }
+
+ ret = dp_create (part, &dp);
+ if (ret) {
+ printf ("volls: dp_create: %d\n", ret);
+ INTER_RETURN(1);
+ }
+
+ {
+ struct volume_handle *volh;
+ struct mnode n;
+ struct msec m;
+
+ memset (&n, 0, sizeof(n));
+
+ ret = vld_open_volume_by_num (dp, vol, &volh);
+ if (ret)
+ errx (1, "volls: vld_open_volume_by_num: %d", ret);
+
+ ret = vld_db_uptodate (volh);
+ if (ret)
+ errx (1, "volls: vld_db_uptodate: %d", ret);
+
+#if 1
+ n.fid.Vnode = vnode;
+ m.flags = VOLOP_GETSTATUS;
+
+ ret = vld_open_vnode (volh, &n, &m);
+ if (ret)
+ errx (1, "volls: vld_open_vnode failed with %d\n", ret);
+#else
+ abort();
+#endif
+
+ printf ("mode=%o ino=%x dev=%x rdev=%x\n",
+ n.sb.st_mode, n.sb.st_ino, n.sb.st_dev, n.sb.st_rdev);
+
+ printf ("size: %d\nparent fid: %d.%d\n",
+ n.fs.Length, n.fs.ParentVnode, n.fs.ParentUnique);
+
+ if (afs_dir_p (vnode)) {
+ VenusFid fid;
+ fid.Cell = 0;
+ fid.fid.Volume = volh->vol;
+ fid.fid.Vnode = vnode;
+ fid.fid.Unique = 0;
+
+ ret = mdir_readdir (&n, volls_dir_cb, NULL, &fid);
+ if (ret)
+ errx (1, "volls: mdir_readdir failed with %d", ret);
+
+ } else {
+ printf ("this is a file.... XXX\n");
+ }
+
+ close (n.fd);
+
+ vld_free(volh);
+
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+volvnode_cmd (int argc, char **argv)
+{
+ u_int32_t part;
+ char *part_str = NULL;
+ u_int32_t vol;
+ char *vol_str = NULL;
+ struct dp_part *dp;
+ int do_list = 0;
+ int ret, optind = 0;
+
+ struct getargs args[] = {
+ {"part", 0, arg_string, NULL,
+ "what part to use", NULL, arg_mandatory},
+ {"vol", 0, arg_string, NULL,
+ "what vol to use", NULL, arg_mandatory},
+ {"list", 'l', arg_flag, NULL,
+ "list vnodes" },
+ { NULL, 0, arg_end, NULL }
+ }, *arg;
+
+ arg = args;
+ arg->value = &part_str; arg++;
+ arg->value = &vol_str; arg++;
+ arg->value = &do_list; arg++;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(args, "volvnode", NULL, ARG_AFSSTYLE);
+ INTER_RETURN(1);
+ }
+ part = atoi(part_str);
+ vol = atoi(vol_str);
+ if (vol == 0) {
+ printf ("erronous volume number\n");
+ INTER_RETURN(1);
+ }
+
+ ret = dp_create (part, &dp);
+ if (ret) {
+ printf ("volls: dp_create: %d\n", ret);
+ INTER_RETURN(1);
+ }
+
+ {
+ struct volume_handle *volh;
+ int i;
+ u_int32_t num, flags;
+
+
+ ret = vld_open_volume_by_num (dp, vol, &volh);
+ if (ret)
+ errx (1, "volvnode: vld_open_volume_by_num: %d", ret);
+
+ /*
+ * print volume header
+ */
+
+ ret = vld_info_uptodatep (volh);
+ if (ret)
+ errx (1, "vld_info_uptodatep: %d", ret);
+
+ vol_pretty_print_info (stdout, &volh->info);
+
+ /*
+ * Print nodes
+ */
+
+ ret = vld_db_uptodate (volh);
+ if (ret)
+ errx (1, "vld_db_uptodate: %d", ret);
+
+ /*
+ * Print dir nodes
+ */
+
+ ret = voldb_header_info (volh->db[0], &num, &flags);
+ if (ret)
+ errx (1, "voldb_header_info: %d", ret);
+
+ printf ("---------------------------------\n");
+ printf ("dir nodes contain:\n");
+ printf (" num: %d\tflags 0x%x\n", num, flags);
+ printf ("---------------------------------\n");
+
+ if (do_list) {
+ for (i = 0; i < num; i++) {
+ struct voldb_entry e;
+
+ printf ("dnode #%d\n", i);
+
+ ret = voldb_get_entry (volh->db[0], i, &e);
+ if (ret)
+ errx (1, "voldb_get_dir (%d) returned: %d", i, ret);
+ voldb_pretty_print_dir (&e.u.dir);
+ }
+ }
+
+ /*
+ * Print file nodes
+ */
+
+ ret = voldb_header_info (volh->db[1], &num, &flags);
+ if (ret)
+ errx (1, "voldb_header_info: %d", ret);
+
+ printf ("---------------------------------\n");
+ printf ("file nodes contain:\n");
+ printf (" num: %d\tflags 0x%x\n", num, flags);
+ printf ("---------------------------------\n");
+
+ if (do_list) {
+ for (i = 0; i < num; i++) {
+ struct voldb_entry e;
+
+ printf ("fnode #%d\n", i);
+
+ ret = voldb_get_entry (volh->db[1], i, &e);
+ if (ret)
+ errx (1, "voldb_get_dir (%d) returned: %d", i, ret);
+ voldb_pretty_print_file (&e.u.file);
+ }
+ }
+
+ vld_free(volh);
+
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+fvolcreate_cmd (int argc, char **argv)
+{
+ u_int32_t part;
+ char *part_str = NULL;
+ char *path_str = NULL;
+ int vol_int = 0;
+ struct dp_part *dp;
+ int ret, optind = 0;
+
+ struct getargs args[] = {
+ {"part", 0, arg_string, NULL,
+ "what part to use", NULL, arg_mandatory},
+ {"vol", 0, arg_integer, NULL,
+ "what vol-number to use", NULL, arg_mandatory},
+ {"path", 0, arg_string, NULL,
+ "what path to volume-ify", NULL, arg_mandatory},
+ { NULL, 0, arg_end, NULL }
+ }, *arg;
+
+ arg = args;
+ arg->value = &part_str; arg++;
+ arg->value = &vol_int; arg++;
+ arg->value = &path_str; arg++;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(args, "volvnode", NULL, ARG_AFSSTYLE);
+ INTER_RETURN(1);
+ }
+
+ part = atoi(part_str);
+ if (vol_int == 0) {
+ printf ("erronous volume number\n");
+ INTER_RETURN(1);
+ }
+
+ ret = dp_create (part, &dp);
+ if (ret) {
+ printf ("volls: dp_create: %d\n", ret);
+ INTER_RETURN(1);
+ }
+
+ ret = vld_fvol_create_volume_ondisk (dp, vol_int, path_str);
+ if (ret) {
+ printf ("volls: fvol_create_volume_ondisk: %d\n", ret);
+ INTER_RETURN(1);
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+showvolname_cmd (int argc, char **argv)
+{
+ int ret;
+ u_int32_t num;
+ u_int32_t part;
+ char name[MAXPATHLEN];
+
+ if (argc != 2 && argc != 3)
+ errx (1, "usage: showvolname [part] volnum");
+
+ if (argc == 2) {
+ num = atoi (argv[1]);
+ if (num == 0)
+ errx (1, "showvolname: `%s' is a invalid argument", argv[1]);
+
+ ret = vol_getname (num, name, sizeof (name));
+ if (ret) {
+ printf ("vol_getname returned %d", ret);
+ INTER_RETURN(ret);
+ }
+ printf ("volume name is: %s\n", name);
+ } else {
+ part = atoi (argv[1]); /* XXX 0 is valid volume */
+
+ num = atoi (argv[2]);
+ if (num == 0)
+ errx (1, "showvolname: `%s' is a invalid argument", argv[2]);
+
+ ret = vol_getfullname (part, num, name, sizeof (name));
+ if (ret)
+ errx (1, "vol_getname returned %d", ret);
+ printf ("volume full name is: %s\n", name);
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+salvage_cmd (int argc, char **argv)
+{
+ char *part_str = NULL;
+ int vol = 0;
+ struct dp_part *dp;
+ int ret, optind = 0;
+ struct volume_handle *volh;
+
+ struct getargs args[] = {
+ {"part", 0, arg_string, NULL,
+ "what part to use", NULL, arg_mandatory},
+ {"vol", 0, arg_integer, NULL,
+ "what vol-number to use", NULL, arg_mandatory},
+ { NULL, 0, arg_end, NULL }
+ }, *arg;
+
+ arg = args;
+ arg->value = &part_str; arg++;
+ arg->value = &vol; arg++;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ arg_printusage(args, "volvnode", NULL, ARG_AFSSTYLE);
+ INTER_RETURN(1);
+ }
+
+ if (part_str == NULL || vol == 0) {
+ warnx ("missing argument");
+ INTER_RETURN(1);
+ }
+
+ dp = dp_getpart (part_str);
+ if (dp == NULL) {
+ warnx ("erronous volume number");
+ INTER_RETURN(1);
+ }
+
+ ret = vld_open_volume_by_num (dp, vol, &volh);
+ if (ret) {
+ warnx ("salvage: vld_open_volume_by_num: %d", ret);
+ INTER_RETURN(1);
+ }
+
+ ret = salvage_volume (volh);
+ if (ret)
+ warnx ("salvage returned %d", ret);
+ else
+ printf ("volume %s (%u) is ok\n", volh->info.name, vol);
+
+ vld_free(volh);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+version_cmd (int argc, char **argv)
+{
+ printf ("sked - maintaing volumes the hard way\n");
+
+ printf ("Package: %s\n"
+ "Version: %s\n", PACKAGE, VERSION);
+ return 0;
+}
+
+
+static int help_cmd (int argc, char **argv);
+static int apropos_cmd (int argc, char **argv);
+
+/*
+ *
+ */
+
+static SL_cmd cmds[] = {
+ {"apropos", apropos_cmd, "apropos topic"},
+ {"help", help_cmd, "help text"},
+ {"volcreate", volcreate_cmd, "create a volume"},
+ {"volshow", volshow_cmd, "show a volume"},
+ {"vollist", vollist_cmd, "list volumes on part"},
+ {"volls", volls_cmd, "list files in volume,vnode pair"},
+ {"volvnode", volvnode_cmd, "list all vnodes"},
+ {"fvolcreate", fvolcreate_cmd, "create a fvolume"},
+ {"name", showvolname_cmd, "name of a volume"},
+ {"salvage", salvage_cmd, "salvage a volume"},
+ {"version", version_cmd, "show version of sked"},
+ { NULL, NULL, NULL}
+};
+
+/*
+ * Help command
+ */
+
+static int
+help_cmd (int argc, char **argv)
+{
+ sl_help (cmds, argc, argv);
+ return 0;
+}
+
+/*
+ * Apropos command
+ */
+
+static int
+apropos_cmd (int argc, char **argv)
+{
+ if (argc < 2)
+ printf ("apropos <topic>\n");
+ else
+ sl_apropos (cmds, argv[1]);
+ return 0;
+}
+
+/*
+ * Main
+ */
+
+int
+main (int argc, char **argv)
+{
+ int ret;
+ char *log_name = "/dev/stderr";
+
+ /*
+ * We only boot, not init since we dont want to read in all volumes
+ */
+ vld_boot ();
+ mnode_init (173);
+
+ mlog_loginit (log_name, milko_deb_units, MDEFAULT_LOG /* MDEBALL */);
+
+ /*
+ * Command loop or if command, eval.
+ */
+
+ if (argc < 2) {
+ interactivep = 1;
+ sl_loop (cmds, "sked (cmd): ");
+ } else {
+ ret = sl_command(cmds, argc - 1, argv + 1);
+ if (ret == SL_BADCOMMAND)
+ printf ("%s: Unknown command\n", argv[1]);
+ }
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/milko/bos/Makefile.in b/usr.sbin/afs/src/milko/bos/Makefile.in
new file mode 100644
index 00000000000..9f2fcc922b6
--- /dev/null
+++ b/usr.sbin/afs/src/milko/bos/Makefile.in
@@ -0,0 +1,117 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:12 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sysconfdir = @sysconfdir@
+transform = @program_transform_name@
+
+BOSSERVER_BIN = bosserver
+
+DEFS = @DEFS@ -DMILKO_LIBEXECDIR=\"$(libexecdir)\" -DMILKO_SYSCONFDIR=\"$(sysconfdir)\"
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+AFSWSROOT = /usr/afsws
+RXKADINC = -I$(srcdir)/../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I../../include \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib/msecurity \
+ -I../../rxdef \
+ $(RXKADINC)
+DEFINES = -DDEBUG
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) -DRXDEBUG
+RXKADLIB = @MILKO_RXKAD_LIBS@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIBS = -L../../rxdef -lrxvlserver \
+ -L../lib/msecurity -lmsecurity \
+ -L../../lib/acl -lacl \
+ -L../../rxdef -lrxvolserver -lrxfsserver -L../../rx -lrx \
+ -L../../lib/ko -lko \
+ -L../../util -lutil \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/roken -lroken $(RXKADLIB) \
+ $(KAFS_LIBS) \
+ -L../../rxdef -lbosserver \
+ @LIBS@
+LIBDEPENDS = ../../rxdef/libbosserver.a ../../rx/librx.a \
+ ../../lwp/liblwp.a ../../util/libutil.a \
+ ../../lib/roken/libroken.a ../../lib/ko/libko.a \
+ ../lib/msecurity/libmsecurity.a \
+ ../../rxdef/libbosserver.a
+PROGS = bosserver
+SRCS = \
+ kconf.c \
+ bosserver.c \
+ bosprocs.c
+
+HDRS = \
+ kconf.h
+
+bosserver_OBJS = \
+ kconf.o \
+ bosserver.o \
+ bosprocs.o
+
+.PHONY: all install uninstall depend tags clean
+
+all: $(PROGS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir)
+ PROG_BIN='$(BOSSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+uninstall:
+ PROG_BIN='$(BOSSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+bosserver: $(bosserver_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(bosserver_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=milko/bos/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(SRCS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/milko/bos/bos_locl.h b/usr.sbin/afs/src/milko/bos/bos_locl.h
new file mode 100644
index 00000000000..d1ebca44aa1
--- /dev/null
+++ b/usr.sbin/afs/src/milko/bos/bos_locl.h
@@ -0,0 +1,77 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+
+#include <ports.h>
+#include <ko.h>
+
+#include <ctype.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#endif
+
+#include <netinit.h>
+#include <msecurity.h>
+
+#include <service.h>
+
+#include <roken.h>
+#include <err.h>
+#include <getarg.h>
+
+#include <bos.h>
+#include <bos.ss.h>
+
+#include <kconf.h>
+
+void
+bosdebug (char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
diff --git a/usr.sbin/afs/src/milko/bos/bosprocs.c b/usr.sbin/afs/src/milko/bos/bosprocs.c
new file mode 100644
index 00000000000..991efe719b0
--- /dev/null
+++ b/usr.sbin/afs/src/milko/bos/bosprocs.c
@@ -0,0 +1,162 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "bos_locl.h"
+
+RCSID("$Id: bosprocs.c,v 1.1 2000/09/11 14:41:12 art Exp $");
+
+/*
+ *
+ */
+
+int
+BOZO_CreateBnode(struct rx_call *call,
+ const char *type,
+ const char *instance,
+ const char *p1,
+ const char *p2,
+ const char *p3,
+ const char *p4,
+ const char *p5,
+ const char *p6)
+{
+ bosdebug ("BOZO_CreateNode: %s %s\n", type, instance);
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+BOZO_DeleteBnode(struct rx_call *call,
+ const char *instance)
+{
+ bosdebug ("BOZO_DeleteBnode: %s\n", instance);
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+int
+BOZO_GetStatus(struct rx_call *call,
+ const char *instance,
+ int32_t *inStat,
+ char *statdescr)
+{
+ bosdebug ("BOZO_GetStatus: %s\n", instance);
+
+ strcpy (statdescr, "foo");
+ *inStat = 0;
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+int
+BOZO_SetStatus(struct rx_call *call,
+ const char *instance)
+{
+ bosdebug ("BOZO_SetStatus: %s\n", instance);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+BOZO_EnumerateInstance(struct rx_call *call,
+ const int32_t instance,
+ char **iname)
+{
+ bosdebug ("BOZO_EnumerateInstance: %d\n", instance);
+
+ return -1;
+}
+
+/*
+ *
+ */
+
+int
+BOZO_GetInstanceInfo(struct rx_call *call,
+ const char *instance,
+ char **type,
+ struct bozo_status *status)
+{
+ bosdebug ("BOZO_GetInstanceInfo: %s\n", instance);
+
+#if 0
+ strcpy (type, "simple");
+#endif
+ memset (status, 0, sizeof(*status));
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+int
+BOZO_GetInstanceParm(struct rx_call *call,
+ const char *instance,
+ const int32_t num,
+ char **param)
+{
+ bosdebug ("BOZO_GetInstanceParm: %s %d\n", instance, num);
+
+#if 0
+ strcpy (param, "foo");
+#endif
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/milko/bos/bosserver.c b/usr.sbin/afs/src/milko/bos/bosserver.c
new file mode 100644
index 00000000000..c7b5231d57c
--- /dev/null
+++ b/usr.sbin/afs/src/milko/bos/bosserver.c
@@ -0,0 +1,630 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "bos_locl.h"
+
+RCSID("$Id: bosserver.c,v 1.1 2000/09/11 14:41:12 art Exp $");
+
+static char *email = "root";
+static char *serverfile = MILKO_SYSCONFDIR "/server-file";
+
+
+typedef struct mtype {
+ char *name; /* context name */
+ char *program; /* program name */
+ char *path; /* path to program */
+ char *arg; /* string of arguments */
+ char *coredir; /* where the corefile is */
+ pid_t pid; /* pid of server */
+ time_t last_start; /* last started */
+ struct {
+ unsigned long email:1; /* email when event happens */
+ unsigned long savecore:1; /* try to save the corefile */
+ unsigned long trydebug:1; /* try to include debugging */
+ unsigned long restart_p:1; /* needs to be restarted */
+ unsigned long enablep:1; /* is enabled */
+ } flags;
+ struct mtype *next; /* next server on linked list */
+} mtype;
+
+struct mtype *servers = NULL;
+
+static int debug = 1;
+static char *bosserverprefix = NULL;
+
+/*
+ *
+ */
+
+void
+bosdebug (char *fmt, ...)
+{
+ va_list args;
+ if (!debug)
+ return ;
+
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end(args);
+}
+
+/*
+ * Send mail to irresponsible person
+ */
+
+static void
+sendmail (char *person, char *name, char **message)
+{
+ FILE *f;
+ char *cmd;
+ char hostname[400];
+ int i;
+
+ if (person == NULL) {
+ bosdebug ("sendmail: person == NULL");
+ return;
+ }
+
+ hostname[0] = '\0';
+ gethostname (hostname, sizeof(hostname));
+
+ asprintf (&cmd, "/usr/sbin/sendmail %s", person);
+
+ f = popen (cmd, "w");
+ if (f == NULL) {
+ bosdebug ("sendmail: %s", cmd);
+ free (cmd);
+ return;
+ }
+
+ fprintf (f, "From: <bos-watcher@%s>\n", hostname);
+ fprintf (f, "Subject: Death %s\n\n", name);
+
+ i = 0;
+ while (message[i]) {
+ fprintf (f, "%s\n", message[i]);
+ i++;
+ }
+
+ fflush (f);
+ pclose (f);
+
+ free (cmd);
+}
+
+/*
+ * find server named `name' in linked list `old_srv'. If found
+ * removed the found server from the list and return it.
+ * If `name' isn't found, return NULL.
+ */
+
+static struct mtype *
+find_and_remove_server (struct mtype **old_srv, const char *name)
+{
+ struct mtype *srv = *old_srv;
+
+ while (srv) {
+ if (srv->name && strcasecmp (name, srv->name) == 0) {
+ *old_srv = srv->next;
+ return srv;
+ }
+ old_srv = &srv->next;
+ srv = srv->next;
+ }
+ return NULL;
+}
+
+/*
+ *
+ */
+
+static void
+kill_server (struct mtype *s)
+{
+ if (s->pid)
+ kill (s->pid, SIGTERM);
+}
+
+
+/*
+ *
+ */
+
+static void
+shutdown_servers (struct mtype *old_server)
+{
+ while (old_server) {
+ struct mtype *s = old_server;
+ old_server = s->next;
+ kill_server (s);
+ if (s->arg)
+ free (s->arg);
+ free (s);
+ }
+}
+
+/*
+ *
+ */
+
+static struct mtype *
+new_server (char *name)
+{
+ struct mtype *s;
+
+ s = emalloc (sizeof(*s));
+ memset (s, 0, sizeof(*s));
+ s->name = estrdup (name);
+ return s;
+}
+
+/*
+ *
+ */
+
+static void
+write_serverfile (struct mtype *s, const char *fn)
+{
+ FILE *f;
+
+ f = fopen (fn, "w");
+ if (f) {
+ errx (1, "failed to open serverfile (%s) for writing",
+ serverfile);
+ }
+ while (s) {
+ fprintf (f, "%s %d\n",
+ s->name,
+ s->flags.enablep);
+ s = s->next;
+ }
+ fclose (f);
+}
+
+/*
+ *
+ */
+
+static void
+read_config_file (char *filename)
+{
+ kconf_context context;
+ kconf_config_section *c;
+ struct mtype *old_servers;
+ const char *str;
+ int lineno;
+ FILE *f;
+ int ret;
+
+ kconf_init (&context);
+
+ ret = kconf_config_parse_file (filename, &c);
+ if (ret) {
+ shutdown_servers (servers);
+ errx (1, "read_config_file");
+ }
+
+ email =
+ estrdup (kconf_config_get_string_default (context, c,
+ email,
+ "bos",
+ "email",
+ NULL));
+
+ serverfile =
+ estrdup (kconf_config_get_string_default (context, c,
+ serverfile,
+ "bos",
+ "serverfile",
+ NULL));
+ f = fopen (serverfile, "r");
+ if (f == NULL) {
+ shutdown_servers (servers);
+ err (1, "tried to open serverfile \"%s\"", serverfile);
+ }
+
+ /*
+ * Save the old list of servers
+ */
+
+ old_servers = servers;
+ servers = NULL;
+
+ /*
+ * reread server list copy over existing servers to new list, add
+ * new servers
+ */
+
+ lineno = 0;
+ while (!feof (f)) {
+ struct mtype *s;
+ char name[100];
+ int enablep;
+
+ lineno ++;
+ ret = fscanf (f, "%s %d", name, &enablep);
+ if (ret == EOF)
+ break;
+ if (ret != 2) {
+ shutdown_servers (servers);
+ shutdown_servers (old_servers);
+ errx (1, "error scaning line %d of serverfile (%s)",
+ lineno, serverfile);
+ }
+
+ str = kconf_config_get_string (context, c,
+ name,
+ "arguments",
+ NULL);
+
+ s = find_and_remove_server (&old_servers, name);
+ if (s) {
+ if (str && s->arg && strcmp (str, s->arg)) {
+ s->flags.restart_p = 1;
+ free (s->arg);
+ s->arg = estrdup (str);
+ }
+
+ } else {
+ s = new_server (name);
+ if (str)
+ s->arg = estrdup (str);
+ }
+ if (s->flags.enablep != enablep)
+ s->flags.restart_p = 1;
+ s->flags.enablep = enablep;
+
+ s->flags.email = kconf_config_get_bool_default (context, c,
+ KCONF_FALSE,
+ name,
+ "email",
+ NULL);
+ s->program =
+ estrdup (kconf_config_get_string_default (context, c,
+ name,
+ name,
+ "program",
+ NULL));
+
+ s->coredir =
+ estrdup (kconf_config_get_string_default (context, c,
+ MILKO_LIBEXECDIR,
+ name,
+ "coredir",
+ NULL));
+ s->flags.savecore =
+ kconf_config_get_bool_default (context, c,
+ KCONF_FALSE,
+ name,
+ "savecore",
+ NULL);
+
+
+ s->flags.trydebug =
+ kconf_config_get_bool_default (context, c,
+ KCONF_FALSE,
+ name,
+ "trydebug",
+ NULL);
+
+ s->next = servers;
+ servers = s;
+ }
+
+ fclose (f);
+
+ /*
+ * nuke the old ones and write down a new serverfile
+ */
+
+ shutdown_servers (old_servers);
+ write_serverfile (servers, serverfile);
+}
+
+/*
+ * start the server `server'
+ */
+
+static int
+start_server (struct mtype *server)
+{
+ int i;
+ time_t newtime = time(NULL);
+
+ bosdebug ("starting server %s (%s)\n", server->name,
+ server->path);
+
+ if (newtime + 10 < server->last_start
+ && server->last_start != 0) {
+ /* XXX */
+ bosdebug ("server %s looping, will try again in 10 min",
+ server->name);
+ return 0;
+ }
+ server->last_start = newtime;
+
+ i = fork();
+ switch (i) {
+ case 0: {
+ char *newargv[3];
+
+ newargv[0] = server->path;
+#if 1
+ newargv[1] = NULL;
+#else
+ XXX insert argv parser here
+#endif
+
+ if (debug == 0) {
+ close (0);
+ close (1);
+ close (2);
+ }
+
+ execvp (server->path, newargv);
+
+ bosdebug ("server %s failed with %s (%d)\n", server->path,
+ strerror (errno), errno);
+ exit (1);
+ break;
+ }
+ case -1:
+ bosdebug ("failed to fork with server %s with reson %s (%d)\n",
+ server->name, strerror (errno), errno);
+ server->pid = 0;
+ return errno;
+ break;
+ default:
+ server->pid = i;
+ bosdebug ("started server %s with pid %d\n",
+ server->name, server->pid);
+ break;
+ }
+
+ return 0;
+}
+
+
+/*
+ * GC processes, and start new if appropriate.
+ */
+
+static int dead_children = 0;
+
+static PROCESS riperprocess;
+
+static void
+theriper (char *no_arg)
+{
+ int status;
+ char *msg[3] = { NULL, NULL, NULL };
+ struct mtype *server = NULL;
+ pid_t pid;
+
+ while (1) {
+ if (dead_children == 0) {
+ bosdebug ("theriper: sleeping\n");
+ LWP_WaitProcess ((char *)theriper);
+ }
+
+ bosdebug ("theriper: running\n");
+
+ if (dead_children == 0) {
+ bosdebug ("theriper: called without a dead child\n");
+ continue;
+ }
+
+ if (dead_children < 0)
+ abort();
+
+ dead_children--;
+
+ pid = wait (&status);
+
+ if (WIFEXITED(status)) {
+ asprintf (&msg[1],
+ "normal exit: exit error %d", WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ asprintf (&msg[1],
+ "terminated by signal num %d %s", WTERMSIG(status),
+ WCOREDUMP(status) ? "coredumped\n" : "");
+ } else if (WIFSTOPPED(status)) {
+ asprintf (&msg[1],
+ "process stoped by signal %d", WSTOPSIG(status));
+ } else {
+ asprintf (&msg[1],
+ "by unknown reason");
+ }
+ bosdebug (msg[1]);
+
+ server = servers;
+ while (server) {
+ if (server->pid == pid) {
+ msg[0] = server->name;
+ if (server->flags.email)
+ sendmail (email, server->name, msg);
+ bosdebug ("%s was the killed, starting new", server->name);
+ start_server (server);
+ break;
+ }
+ server = server->next;
+ }
+ free (msg[1]);
+ }
+}
+
+/*
+ * Signal-handler for SIGCHLD
+ */
+
+static void
+sigchild (int foo)
+{
+ bosdebug ("child died\n");
+
+ dead_children++;
+
+ signal (SIGCHLD, sigchild);
+ LWP_NoYieldSignal ((char *) theriper);
+}
+
+/*
+ * bootstrap bosserver
+ * Create riper thread and start all servers.
+ */
+
+static int
+bosserver_init (void)
+{
+ struct mtype *server;
+ int i;
+
+ i = LWP_CreateProcess (theriper, 0, 1, NULL, "the-riper", &riperprocess);
+ if (i)
+ errx (1, "LWP_CreateProcess returned %d", i);
+
+ server = servers;
+ while (server) {
+ if (server->flags.enablep) {
+ i = start_server(server);
+ if (i)
+ bosdebug ("server_server: returned %s (%d)",
+ strerror (i), i);
+ }
+ server = server->next;
+ }
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+static struct rx_service *bosservice = NULL;
+
+static char *cell = NULL;
+static char *realm = NULL;
+static int do_help = 0;
+static char *srvtab_file = NULL;
+static int no_auth = 0;
+static char *configfile = MILKO_SYSCONFDIR "/bos.conf";
+
+static struct getargs args[] = {
+ {"cell", 0, arg_string, &cell, "what cell to use", NULL},
+ {"realm", 0, arg_string, &realm, "what realm to use"},
+ {"prefix",'p', arg_string, &bosserverprefix,
+ "directory where servers is stored", NULL},
+ {"noauth", 0, arg_flag, &no_auth, "disable authentication checks"},
+ {"debug", 'd', arg_flag, &debug, "output debugging"},
+ {"help", 'h', arg_flag, &do_help, "help"},
+ {"srvtab",'s', arg_string, &srvtab_file, "what srvtab to use"},
+ {"configfile", 'f', arg_string, &configfile, "configuration file"},
+ { NULL, 0, arg_end, NULL }
+};
+
+static void
+usage(int exit_code)
+{
+ arg_printusage(args, NULL, "", ARG_AFSSTYLE);
+ exit (exit_code);
+}
+
+/*
+ *
+ */
+
+int
+main (int argc, char **argv)
+{
+ int ret;
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage (1);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 1;
+ }
+
+ if (do_help)
+ usage(0);
+
+ if (bosserverprefix == NULL)
+ bosserverprefix = MILKO_LIBEXECDIR;
+
+ read_config_file (configfile);
+
+ ports_init();
+ cell_init(0);
+
+ if (no_auth)
+ sec_disable_superuser_check ();
+
+ if (cell)
+ cell_setthiscell (cell);
+
+ network_kerberos_init (srvtab_file);
+
+ signal (SIGCHLD, sigchild); /* XXX sigaction */
+
+ ret = network_init(htons(afsbosport), "bos", BOS_SERVICE_ID,
+ BOZO_ExecuteRequest, &bosservice, realm);
+ if (ret)
+ errx (1, "network_init failed with %d", ret);
+
+ ret = bosserver_init();
+ if (ret)
+ errx (1, "bosserver_init: error %d\n", ret);
+
+ printf("Milko bosserver %s-%s started\n", PACKAGE, VERSION);
+
+ rx_SetMaxProcs(bosservice,5) ;
+ rx_StartServer(1) ;
+
+ abort() ; /* should not get here */
+
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/milko/bos/kconf.c b/usr.sbin/afs/src/milko/bos/kconf.c
new file mode 100644
index 00000000000..35d0c534556
--- /dev/null
+++ b/usr.sbin/afs/src/milko/bos/kconf.c
@@ -0,0 +1,804 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+#include "config.h"
+#include "roken.h"
+#include <err.h>
+#include <parse_time.h>
+#include "kconf.h"
+
+/* $Heimdal: config_file.c,v 1.38 1999/12/02 17:05:08 joda Exp $ */
+
+#ifdef RCSID
+RCSID("$Id: kconf.c,v 1.1 2000/09/11 14:41:12 art Exp $");
+#endif
+
+static int parse_section(char *p, kconf_config_section **s,
+ kconf_config_section **res,
+ char **error_message);
+static int parse_binding(FILE *f, unsigned *lineno, char *p,
+ kconf_config_binding **b,
+ kconf_config_binding **parent,
+ char **error_message);
+static int parse_list(FILE *f, unsigned *lineno, kconf_config_binding **parent,
+ char **error_message);
+
+/*
+ * Parse a section:
+ *
+ * [section]
+ * foo = bar
+ * b = {
+ * a
+ * }
+ * ...
+ *
+ * starting at the line in `p', storing the resulting structure in
+ * `s' and hooking it into `parent'.
+ * Store the error message in `error_message'.
+ */
+
+static int
+parse_section(char *p, kconf_config_section **s, kconf_config_section **parent,
+ char **error_message)
+{
+ char *p1;
+ kconf_config_section *tmp;
+
+ p1 = strchr (p + 1, ']');
+ if (p1 == NULL) {
+ *error_message = "missing ]";
+ return -1;
+ }
+ *p1 = '\0';
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ tmp->name = strdup(p+1);
+ if (tmp->name == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ tmp->type = kconf_config_list;
+ tmp->u.list = NULL;
+ tmp->next = NULL;
+ if (*s)
+ (*s)->next = tmp;
+ else
+ *parent = tmp;
+ *s = tmp;
+ return 0;
+}
+
+/*
+ * Parse a brace-enclosed list from `f', hooking in the structure at
+ * `parent'.
+ * Store the error message in `error_message'.
+ */
+
+static int
+parse_list(FILE *f, unsigned *lineno, kconf_config_binding **parent,
+ char **error_message)
+{
+ char buf[BUFSIZ];
+ int ret;
+ kconf_config_binding *b = NULL;
+ unsigned beg_lineno = *lineno;
+
+ while(fgets(buf, sizeof(buf), f) != NULL) {
+ char *p;
+
+ ++*lineno;
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ p = buf;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '#' || *p == ';' || *p == '\0')
+ continue;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '}')
+ return 0;
+ if (*p == '\0')
+ continue;
+ ret = parse_binding (f, lineno, p, &b, parent, error_message);
+ if (ret)
+ return ret;
+ }
+ *lineno = beg_lineno;
+ *error_message = "unclosed {";
+ return -1;
+}
+
+/*
+ *
+ */
+
+static int
+parse_binding(FILE *f, unsigned *lineno, char *p,
+ kconf_config_binding **b, kconf_config_binding **parent,
+ char **error_message)
+{
+ kconf_config_binding *tmp;
+ char *p1, *p2;
+ int ret = 0;
+
+ p1 = p;
+ while (*p && *p != '=' && !isspace((unsigned char)*p))
+ ++p;
+ if (*p == '\0') {
+ *error_message = "no =";
+ return -1;
+ }
+ p2 = p;
+ while (isspace((unsigned char)*p))
+ ++p;
+ if (*p != '=') {
+ *error_message = "no =";
+ return -1;
+ }
+ ++p;
+ while(isspace((unsigned char)*p))
+ ++p;
+ tmp = malloc(sizeof(*tmp));
+ if (tmp == NULL) {
+ *error_message = "out of memory";
+ return -1;
+ }
+ *p2 = '\0';
+ tmp->name = strdup(p1);
+ tmp->next = NULL;
+ if (*p == '{') {
+ tmp->type = kconf_config_list;
+ tmp->u.list = NULL;
+ ret = parse_list (f, lineno, &tmp->u.list, error_message);
+ } else {
+ p1 = p;
+ p = p1 + strlen(p1);
+ while(p > p1 && isspace((unsigned char)*(p-1)))
+ --p;
+ *p = '\0';
+ tmp->type = kconf_config_string;
+ tmp->u.string = strdup(p1);
+ }
+ if (*b)
+ (*b)->next = tmp;
+ else
+ *parent = tmp;
+ *b = tmp;
+ return ret;
+}
+
+int
+kconf_init (kconf_context *context)
+{
+ *context = emalloc (sizeof(*context));
+ if (*context == NULL) return errno;
+ (*context)->cf = NULL;
+ return 0;
+}
+
+void
+kconf_free (kconf_context context)
+{
+ free (context);
+}
+
+/*
+ * Parse the config file `fname', generating the structures into `res'
+ * returning error messages in `error_message'
+ */
+
+int
+kconf_config_parse_file_debug (const char *fname,
+ kconf_config_section **res,
+ unsigned *lineno,
+ char **error_message)
+{
+ FILE *f;
+ kconf_config_section *s;
+ kconf_config_binding *b;
+ char buf[BUFSIZ];
+ int ret;
+
+ s = NULL;
+ b = NULL;
+ *lineno = 0;
+ f = fopen (fname, "r");
+ if (f == NULL) {
+ *error_message = "cannot open file";
+ return -1;
+ }
+ *res = NULL;
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ char *p;
+
+ ++*lineno;
+ if(buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = '\0';
+ p = buf;
+ while(isspace((unsigned char)*p))
+ ++p;
+ if (*p == '#' || *p == ';')
+ continue;
+ if (*p == '[') {
+ ret = parse_section(p, &s, res, error_message);
+ if (ret)
+ return ret;
+ b = NULL;
+ } else if (*p == '}') {
+ *error_message = "unmatched }";
+ return -1;
+ } else if(*p != '\0') {
+ ret = parse_binding(f, lineno, p, &b, &s->u.list, error_message);
+ if (ret)
+ return ret;
+ }
+ }
+ fclose (f);
+ return 0;
+}
+
+int
+kconf_config_parse_file (const char *fname, kconf_config_section **res)
+{
+ char *foo;
+ unsigned lineno;
+
+ return kconf_config_parse_file_debug (fname, res, &lineno, &foo);
+}
+
+
+static void
+free_binding (kconf_context context, kconf_config_binding *b)
+{
+ kconf_config_binding *next_b;
+
+ while (b) {
+ free (b->name);
+ if (b->type == kconf_config_string)
+ free (b->u.string);
+ else if (b->type == kconf_config_list)
+ free_binding (context, b->u.list);
+ else
+ errx (1, "unknown binding type (%d) in free_binding",
+ b->type);
+ next_b = b->next;
+ free (b);
+ b = next_b;
+ }
+}
+
+int
+kconf_config_file_free (kconf_context context, kconf_config_section *s)
+{
+ free_binding (context, s);
+ return 0;
+}
+
+const void *
+kconf_config_get_next (kconf_context context,
+ kconf_config_section *c,
+ kconf_config_binding **pointer,
+ int type,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, type);
+ ret = kconf_config_vget_next (context, c, pointer, type, args);
+ va_end(args);
+ return ret;
+}
+
+const void *
+kconf_config_vget_next (kconf_context context,
+ kconf_config_section *c,
+ kconf_config_binding **pointer,
+ int type,
+ va_list args)
+{
+ kconf_config_binding *b;
+ const char *p;
+
+ if(c == NULL)
+ c = context->cf;
+
+ if (c == NULL)
+ return NULL;
+
+ if (*pointer == NULL) {
+ b = (c != NULL) ? c : context->cf;
+ p = va_arg(args, const char *);
+ if (p == NULL)
+ return NULL;
+ } else {
+ b = *pointer;
+ p = b->name;
+ b = b->next;
+ }
+
+ while (b) {
+ if (strcmp (b->name, p) == 0) {
+ if (*pointer == NULL)
+ p = va_arg(args, const char *);
+ else
+ p = NULL;
+ if (type == b->type && p == NULL) {
+ *pointer = b;
+ return b->u.generic;
+ } else if(b->type == kconf_config_list && p != NULL) {
+ b = b->u.list;
+ } else {
+ return NULL;
+ }
+ } else {
+ b = b->next;
+ }
+ }
+ return NULL;
+}
+
+const void *
+kconf_config_get (kconf_context context,
+ kconf_config_section *c,
+ int type,
+ ...)
+{
+ const void *ret;
+ va_list args;
+
+ va_start(args, type);
+ ret = kconf_config_vget (context, c, type, args);
+ va_end(args);
+ return ret;
+}
+
+const void *
+kconf_config_vget (kconf_context context,
+ kconf_config_section *c,
+ int type,
+ va_list args)
+{
+ kconf_config_binding *foo = NULL;
+
+ return kconf_config_vget_next (context, c, &foo, type, args);
+}
+
+const kconf_config_binding *
+kconf_config_get_list (kconf_context context,
+ kconf_config_section *c,
+ ...)
+{
+ const kconf_config_binding *ret;
+ va_list args;
+
+ va_start(args, c);
+ ret = kconf_config_vget_list (context, c, args);
+ va_end(args);
+ return ret;
+}
+
+const kconf_config_binding *
+kconf_config_vget_list (kconf_context context,
+ kconf_config_section *c,
+ va_list args)
+{
+ return kconf_config_vget (context, c, kconf_config_list, args);
+}
+
+const char *
+kconf_config_get_string (kconf_context context,
+ kconf_config_section *c,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, c);
+ ret = kconf_config_vget_string (context, c, args);
+ va_end(args);
+ return ret;
+}
+
+const char *
+kconf_config_get_string_default (kconf_context context,
+ kconf_config_section *c,
+ const char *def,
+ ...)
+{
+ const char *ret;
+ va_list args;
+
+ va_start(args, def);
+ ret = kconf_config_vget_string (context, c, args);
+ va_end(args);
+ if (ret == NULL)
+ return def;
+ return ret;
+}
+
+const char *
+kconf_config_vget_string (kconf_context context,
+ kconf_config_section *c,
+ va_list args)
+{
+ return kconf_config_vget (context, c, kconf_config_string, args);
+}
+
+char **
+kconf_config_vget_strings(kconf_context context,
+ kconf_config_section *c,
+ va_list args)
+{
+ char **strings = NULL;
+ int nstr = 0;
+ kconf_config_binding *b = NULL;
+ const char *p;
+
+ while((p = kconf_config_vget_next(context, c, &b,
+ kconf_config_string, args))) {
+ char *tmp = strdup(p);
+ char *pos = NULL;
+ char *s;
+ if(tmp == NULL)
+ goto cleanup;
+ s = strtok_r(tmp, " \t", &pos);
+ while(s){
+ char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
+ if(tmp == NULL)
+ goto cleanup;
+ strings = tmp;
+ strings[nstr] = strdup(s);
+ nstr++;
+ if(strings[nstr-1] == NULL)
+ goto cleanup;
+ s = strtok_r(NULL, " \t", &pos);
+ }
+ free(tmp);
+ }
+ if(nstr){
+ char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings));
+ if(strings == NULL)
+ goto cleanup;
+ strings = tmp;
+ strings[nstr] = NULL;
+ }
+ return strings;
+ cleanup:
+ while(nstr--)
+ free(strings[nstr]);
+ free(strings);
+ return NULL;
+
+}
+
+char**
+kconf_config_get_strings(kconf_context context,
+ kconf_config_section *c,
+ ...)
+{
+ va_list ap;
+ char **ret;
+ va_start(ap, c);
+ ret = kconf_config_vget_strings(context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+void
+kconf_config_free_strings(char **strings)
+{
+ char **s = strings;
+ while(s && *s){
+ free(*s);
+ s++;
+ }
+ free(strings);
+}
+
+kconf_boolean
+kconf_config_vget_bool_default (kconf_context context,
+ kconf_config_section *c,
+ kconf_boolean def_value,
+ va_list args)
+{
+ const char *str;
+ str = kconf_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ if(strcasecmp(str, "yes") == 0 ||
+ strcasecmp(str, "true") == 0 ||
+ atoi(str)) return KCONF_TRUE;
+ return KCONF_FALSE;
+}
+
+kconf_boolean
+kconf_config_vget_bool (kconf_context context,
+ kconf_config_section *c,
+ va_list args)
+{
+ return kconf_config_vget_bool_default (context, c, KCONF_FALSE, args);
+}
+
+kconf_boolean
+kconf_config_get_bool_default (kconf_context context,
+ kconf_config_section *c,
+ kconf_boolean def_value,
+ ...)
+{
+ va_list ap;
+ kconf_boolean ret;
+ va_start(ap, def_value);
+ ret = kconf_config_vget_bool_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+kconf_boolean
+kconf_config_get_bool (kconf_context context,
+ kconf_config_section *c,
+ ...)
+{
+ va_list ap;
+ kconf_boolean ret;
+ va_start(ap, c);
+ ret = kconf_config_vget_bool (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+kconf_config_vget_time_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ va_list args)
+{
+ const char *str;
+ str = kconf_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ return parse_time (str, NULL);
+}
+
+int
+kconf_config_vget_time (kconf_context context,
+ kconf_config_section *c,
+ va_list args)
+{
+ return kconf_config_vget_time_default (context, c, -1, args);
+}
+
+int
+kconf_config_get_time_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, def_value);
+ ret = kconf_config_vget_time_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+kconf_config_get_time (kconf_context context,
+ kconf_config_section *c,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, c);
+ ret = kconf_config_vget_time (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+int
+kconf_config_vget_int_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ va_list args)
+{
+ const char *str;
+ str = kconf_config_vget_string (context, c, args);
+ if(str == NULL)
+ return def_value;
+ else {
+ char *endptr;
+ long l;
+ l = strtol(str, &endptr, 0);
+ if (endptr == str)
+ return def_value;
+ else
+ return l;
+ }
+}
+
+int
+kconf_config_vget_int (kconf_context context,
+ kconf_config_section *c,
+ va_list args)
+{
+ return kconf_config_vget_int_default (context, c, -1, args);
+}
+
+int
+kconf_config_get_int_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, def_value);
+ ret = kconf_config_vget_int_default(context, c, def_value, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+kconf_config_get_int (kconf_context context,
+ kconf_config_section *c,
+ ...)
+{
+ va_list ap;
+ int ret;
+ va_start(ap, c);
+ ret = kconf_config_vget_int (context, c, ap);
+ va_end(ap);
+ return ret;
+}
+
+#ifdef TEST
+
+static int print_list (kconf_context context, FILE *f,
+ kconf_config_binding *l, unsigned level);
+static int print_binding (kconf_context context, FILE *f,
+ kconf_config_binding *b, unsigned level);
+static int print_section (kconf_context context, FILE *f,
+ kconf_config_section *s, unsigned level);
+static int print_config (kconf_context context, FILE *f,
+ kconf_config_section *c);
+
+static void
+tab (FILE *f, unsigned count)
+{
+ while(count--)
+ fprintf (f, "\t");
+}
+
+static int
+print_list (kconf_context context,
+ FILE *f,
+ kconf_config_binding *l,
+ unsigned level)
+{
+ while(l) {
+ print_binding (context, f, l, level);
+ l = l->next;
+ }
+ return 0;
+}
+
+static int
+print_binding (kconf_context context,
+ FILE *f,
+ kconf_config_binding *b,
+ unsigned level)
+{
+ tab (f, level);
+ fprintf (f, "%s = ", b->name);
+ if (b->type == kconf_config_string)
+ fprintf (f, "%s\n", b->u.string);
+ else if (b->type == kconf_config_list) {
+ fprintf (f, "{\n");
+ print_list (context, f, b->u.list, level + 1);
+ tab (f, level);
+ fprintf (f, "}\n");
+ } else
+ errx (1, "unknown binding type (%d) in print_binding", b->type);
+ return 0;
+}
+
+static int
+print_section (kconf_context context, FILE *f, kconf_config_section *s,
+ unsigned level)
+{
+ fprintf (f, "[%s]\n", s->name);
+ print_list (context, f, s->u.list, level + 1);
+ return 0;
+}
+
+static int
+print_config (kconf_context context, FILE *f, kconf_config_section *c)
+{
+ while (c) {
+ print_section (context, f, c, 0);
+ c = c->next;
+ }
+ return 0;
+}
+
+
+int
+main(void)
+{
+ kconf_context context;
+ kconf_config_section *c;
+ int ret;
+
+ kconf_init (&context);
+
+ ret = kconf_config_parse_file ("/etc/krb5.conf", &c);
+ if (ret) errx (1, "kconf_config_parse_file");
+
+ print_config (context, stdout, c);
+ printf ("[libdefaults]ticket_lifetime = %s\n",
+ kconf_config_get_string (context, c,
+ "libdefaults",
+ "ticket_lifetime",
+ NULL));
+ printf ("[realms]foo = %s\n",
+ kconf_config_get_string (context, c,
+ "realms",
+ "foo",
+ NULL));
+ printf ("[realms]ATHENA.MIT.EDU/v4_instance_convert/lithium = %s\n",
+ kconf_config_get_string (context, c,
+ "realms",
+ "ATHENA.MIT.EDU",
+ "v4_instance_convert",
+ "lithium",
+ NULL));
+ kconf_free (context);
+ return 0;
+}
+
+#endif /* TEST */
diff --git a/usr.sbin/afs/src/milko/bos/kconf.h b/usr.sbin/afs/src/milko/bos/kconf.h
new file mode 100644
index 00000000000..9ca0fc01990
--- /dev/null
+++ b/usr.sbin/afs/src/milko/bos/kconf.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef KCONF_H
+#define KCONF_H 1
+
+struct kconf_config_binding {
+ enum { kconf_config_string, kconf_config_list } type;
+ char *name;
+ struct kconf_config_binding *next;
+ union {
+ char *string;
+ struct kconf_config_binding *list;
+ void *generic;
+ } u;
+};
+
+typedef struct kconf_config_binding kconf_config_binding;
+
+typedef kconf_config_binding kconf_config_section;
+
+struct kconf_context {
+ kconf_config_section *cf;
+};
+
+typedef struct kconf_context * kconf_context;
+
+typedef enum { KCONF_FALSE = 0, KCONF_TRUE = 1 } kconf_boolean;
+
+
+int
+kconf_init (kconf_context *context);
+
+void
+kconf_free (kconf_context context);
+
+int
+kconf_config_parse_file_debug (const char *fname,
+ kconf_config_section **res,
+ unsigned *lineno,
+ char **error_message);
+int
+kconf_config_parse_file (const char *fname, kconf_config_section **res);
+
+int
+kconf_config_file_free (kconf_context context, kconf_config_section *s);
+
+const void *
+kconf_config_get_next (kconf_context context,
+ kconf_config_section *c,
+ kconf_config_binding **pointer,
+ int type,
+ ...);
+const void *
+kconf_config_vget_next (kconf_context context,
+ kconf_config_section *c,
+ kconf_config_binding **pointer,
+ int type,
+ va_list args);
+const void *
+kconf_config_get (kconf_context context,
+ kconf_config_section *c,
+ int type,
+ ...);
+
+const void *
+kconf_config_vget (kconf_context context,
+ kconf_config_section *c,
+ int type,
+ va_list args);
+
+const kconf_config_binding *
+kconf_config_get_list (kconf_context context,
+ kconf_config_section *c,
+ ...);
+
+const kconf_config_binding *
+kconf_config_vget_list (kconf_context context,
+ kconf_config_section *c,
+ va_list args);
+
+const char *
+kconf_config_get_string (kconf_context context,
+ kconf_config_section *c,
+ ...);
+
+const char *
+kconf_config_get_string_default (kconf_context context,
+ kconf_config_section *c,
+ const char *def,
+ ...);
+
+const char *
+kconf_config_vget_string (kconf_context context,
+ kconf_config_section *c,
+ va_list args);
+
+
+char **
+kconf_config_vget_strings(kconf_context context,
+ kconf_config_section *c,
+ va_list args);
+
+
+char**
+kconf_config_get_strings(kconf_context context,
+ kconf_config_section *c,
+ ...);
+
+void
+kconf_config_free_strings(char **strings);
+
+kconf_boolean
+kconf_config_vget_bool_default (kconf_context context,
+ kconf_config_section *c,
+ kconf_boolean def_value,
+ va_list args);
+
+
+kconf_boolean
+kconf_config_vget_bool (kconf_context context,
+ kconf_config_section *c,
+ va_list args);
+
+kconf_boolean
+kconf_config_get_bool_default (kconf_context context,
+ kconf_config_section *c,
+ kconf_boolean def_value,
+ ...);
+
+kconf_boolean
+kconf_config_get_bool (kconf_context context,
+ kconf_config_section *c,
+ ...);
+
+int
+kconf_config_vget_time_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ va_list args);
+
+int
+kconf_config_vget_time (kconf_context context,
+ kconf_config_section *c,
+ va_list args);
+
+int
+kconf_config_get_time_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ ...);
+
+int
+kconf_config_get_time (kconf_context context,
+ kconf_config_section *c,
+ ...);
+
+int
+kconf_config_vget_int_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ va_list args);
+
+int
+kconf_config_vget_int (kconf_context context,
+ kconf_config_section *c,
+ va_list args);
+
+int
+kconf_config_get_int_default (kconf_context context,
+ kconf_config_section *c,
+ int def_value,
+ ...);
+
+int
+kconf_config_get_int (kconf_context context,
+ kconf_config_section *c,
+ ...);
+
+#endif /* KCONF_H */
diff --git a/usr.sbin/afs/src/milko/fs/Makefile.in b/usr.sbin/afs/src/milko/fs/Makefile.in
new file mode 100644
index 00000000000..ef9bc05ef5d
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/Makefile.in
@@ -0,0 +1,139 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:13 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sysconfdir = @sysconfdir@
+transform = @program_transform_name@
+
+FSERVER_BIN = fileserver
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+AFSWSROOT = /usr/afsws
+RXKADINC = -I$(srcdir)/../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I../../include \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../include \
+ -I$(srcdir)/../lib/ropa \
+ -I$(srcdir)/../../lib/bufdir \
+ -I$(srcdir)/../lib/voldb \
+ -I$(srcdir)/../lib/mlog \
+ -I$(srcdir)/../lib/msecurity \
+ -I$(srcdir)/../lib/dpart \
+ -I$(srcdir)/../lib/vld \
+ -I$(srcdir)/../lib/vstatus \
+ -I../lib/vstatus \
+ -I../../rxdef \
+ $(RXKADINC)
+DEFINES = -DDEBUG
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) -DRXDEBUG
+RXKADLIB = @MILKO_RXKAD_LIBS@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIBS = -L../lib/mlog -lmlog \
+ -L../lib/vld -lvld \
+ -L../lib/vstatus -lvstatus \
+ -L../lib/voldb -lvoldb \
+ -L../lib/dpart -ldpart \
+ -L../lib/msecurity -lmsecurity \
+ -L../lib/ropa -lropa \
+ -L../../lib/acl -lacl \
+ -L../../lib/bufdir -lbufdir \
+ -L../../rxdef -lrxfsserver \
+ -L../../rxdef -lptclient \
+ -L../../lib/ko -lko \
+ -L../../util -lutil \
+ -L../../rxdef -lrxvolserver -lrxfsserver -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/roken -lroken $(RXKADLIB) \
+ $(KAFS_LIBS) \
+ @LIBS@
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a \
+ ../../lwp/liblwp.a ../../util/libutil.a \
+ ../../lib/roken/libroken.a ../../lib/ko/libko.a \
+ ../lib/voldb/libvoldb.a ../lib/vld/libvld.a \
+ ../lib/msecurity/libmsecurity.a ../../lib/ko/libko.a \
+ ../lib/dpart/libdpart.a ../../rxdef/libptclient.a \
+ ../../lib/acl/libacl.a ../lib/ropa/libropa.a \
+ ../lib/mlog/libmlog.a
+PROGS = fileserver
+SRCS = \
+ fileserver.c \
+ fsprocs.c \
+ volprocs.c \
+ connsec.c
+
+HDRS = \
+ fs_def.h \
+ fsrv_locl.h
+
+fileserver_OBJS = \
+ fileserver.o \
+ fsprocs.o \
+ volprocs.o \
+ connsec.o
+
+.PHONY: all install uninstall depend tags clean
+
+all: $(PROGS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir)
+ PROG_BIN='$(FSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+uninstall:
+ PROG_BIN='$(FSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+fileserver: $(fileserver_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(fileserver_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=milko/fs/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(SRCS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/milko/fs/connsec.c b/usr.sbin/afs/src/milko/fs/connsec.c
new file mode 100644
index 00000000000..e8b4722b745
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/connsec.c
@@ -0,0 +1,265 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "fsrv_locl.h"
+
+#include "pts.cs.h"
+
+RCSID("$Id: connsec.c,v 1.1 2000/09/11 14:41:13 art Exp $");
+
+static struct rx_connection *
+get_conn(int32_t addr, int32_t port, int32_t servid)
+{
+ struct rx_securityClass *sec;
+ struct rx_connection *conn;
+
+ sec = netinit_client_getcred();
+ if (sec == NULL)
+ return NULL;
+
+ conn = rx_NewConnection (addr,
+ htons (port),
+ servid,
+ sec,
+ 2 /* secureindex */);
+ if (conn == NULL)
+ return NULL;
+
+ return conn;
+}
+
+static struct rx_connection *out_conn = NULL;
+
+int
+fs_connsec_nametoid(namelist *nlist, idlist *ilist)
+{
+ int error;
+ int first = 0;
+
+retry:
+ if (out_conn == NULL)
+ out_conn = get_conn(htonl(0x7f000001) /* XXX */,
+ afsprport,
+ PR_SERVICE_ID);
+
+ if (out_conn == NULL)
+ return ENETDOWN;
+
+ error = PR_NameToID(out_conn, nlist, ilist);
+ if (error == RXKADEXPIRED && first == 0) {
+ ++first;
+ rx_DestroyConnection (out_conn);
+ out_conn = NULL;
+ goto retry;
+ }
+
+
+ if (error) {
+ fprintf(stderr, "PR_NameToID error: %s(%d)\n",
+ koerr_gettext(error), error);
+ return error;
+ }
+
+ return 0;
+}
+
+int
+fs_connsec_idtoname(idlist *ilist, namelist *nlist)
+{
+ int error;
+
+ if (out_conn == NULL)
+ out_conn = get_conn(htonl(0x7f000001) /* XXX */,
+ afsprport,
+ PR_SERVICE_ID);
+
+ if (out_conn == NULL)
+ return ENETDOWN;
+
+ error = PR_IDToName(out_conn, ilist, nlist);
+
+ if (error) {
+ if (koerr_gettext(error))
+ fprintf(stderr, "PR_IDToName error: %s(%d)\n",
+ koerr_gettext(error), error);
+ else
+ fprintf(stderr, "PR_IDToName error: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
+static void
+fs_connsec_anonymous(struct fs_security_context *sec)
+{
+ sec->uid = PR_ANONYMOUSID;
+ sec->cps->len = 2;
+ sec->cps->val = malloc(2*sizeof(u_int32_t));
+ if (sec->cps->val == NULL) {
+ sec->cps->len = 0;
+ return; /* XXX */
+ }
+ sec->cps->val[0] = PR_ANYUSERID;
+ sec->cps->val[1] = PR_ANONYMOUSID;
+}
+
+static void
+fs_connsec_createconn(struct rx_connection *conn)
+{
+ struct fs_security_context *sec;
+ namelist nlist;
+ idlist ilist;
+ char rname[PR_MAXNAMELEN];
+ int error;
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ int32_t over;
+ int rnamelen;
+
+ if (conn->rock)
+ return;
+
+ sec = malloc(sizeof(struct fs_security_context));
+ if (sec == NULL)
+ return; /* XXX */
+
+ sec->ref = 1;
+ sec->cps = malloc(sizeof(prlist));
+ if (sec->cps == NULL)
+ return; /* XXX */
+
+
+ conn->rock = sec;
+
+ if (sec_getname(conn, aname, inst, realm)) {
+ fs_connsec_anonymous(sec);
+ return;
+ }
+
+ /*
+ * XXX This should retry with a new connection if the first one
+ * fails. It should also try all ptservers.
+ */
+
+ if (out_conn == NULL)
+ out_conn = get_conn(htonl(0x7f000001) /* XXX */,
+ afsprport,
+ PR_SERVICE_ID);
+
+ if (out_conn == NULL) {
+ fs_connsec_anonymous(sec);
+ return;
+ }
+
+ /*
+ * XXX It is not a good thing to truncate, allows for spoofing?
+ * Perhaps we should just deny access if fullname is to long.
+ */
+
+ strlcpy(rname, krb_unparse_name_long(aname, inst, realm), sizeof(rname));
+
+ nlist.len = 1;
+ nlist.val = &rname;
+ ilist.val = NULL;
+
+ error = PR_NameToID(out_conn, &nlist, &ilist);
+
+ if (error) {
+ fprintf(stderr, "PR_NameToID error: %s(%d)\n",
+ koerr_gettext(error), error);
+ free(ilist.val);
+
+ fs_connsec_anonymous(sec);
+ return;
+ }
+
+ fprintf(stderr, "ID is %d\n", ilist.val[0]);
+ sec->uid = ilist.val[0];
+ free(ilist.val);
+
+ error = PR_GetCPS(out_conn, sec->uid, sec->cps, &over);
+
+ if (error) {
+ fprintf(stderr, "PR_GetCPS error: %s(%d)\n",
+ koerr_gettext(error), error);
+ fs_connsec_anonymous(sec);
+ return;
+ }
+
+}
+
+void
+fs_connsec_destroyconn(struct rx_connection *conn)
+{
+ if (conn->rock == NULL)
+ return;
+
+ fs_connsec_context_put(conn->rock);
+ conn->rock = NULL;
+}
+
+struct fs_security_context *
+fs_connsec_context_get(struct rx_connection *conn)
+{
+ struct fs_security_context *sec;
+
+ fs_connsec_createconn(conn);
+
+ sec = conn->rock;
+
+ assert(sec);
+
+ sec->ref++;
+ return sec;
+}
+
+void
+fs_connsec_context_put(struct fs_security_context *sec)
+{
+ assert(sec->ref > 0);
+
+ sec->ref--;
+
+ if (sec->ref == 0) {
+ free(sec->cps->val);
+ free(sec->cps);
+ free(sec);
+ }
+}
diff --git a/usr.sbin/afs/src/milko/fs/connsec.h b/usr.sbin/afs/src/milko/fs/connsec.h
new file mode 100644
index 00000000000..e7e64e389ec
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/connsec.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+void
+fs_connsec_destroyconn(struct rx_connection *conn);
+
+struct fs_security_context *
+fs_connsec_context_get(struct rx_connection *conn);
+
+void
+fs_connsec_context_put(struct fs_security_context *sec);
+
+int
+fs_connsec_nametoid(namelist *nlist, idlist *ilist);
+
+int
+fs_connsec_idtoname(idlist *ilist, namelist *nlist);
diff --git a/usr.sbin/afs/src/milko/fs/fileserver.c b/usr.sbin/afs/src/milko/fs/fileserver.c
new file mode 100644
index 00000000000..f043010ae26
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/fileserver.c
@@ -0,0 +1,236 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "fsrv_locl.h"
+
+RCSID("$Id: fileserver.c,v 1.1 2000/09/11 14:41:13 art Exp $");
+
+typedef enum { NO_SALVAGE, NORMAL_SALVAGE, SALVAGE_ALL } salvage_options_e;
+
+/*
+ * Local varibles
+ */
+
+static struct rx_service *fsservice;
+static struct rx_service *volservice;
+
+static char *cell = NULL;
+static char *realm = NULL;
+static char *srvtab_file = NULL;
+static char *debug_levels = NULL;
+static char *log_name = "syslog";
+static int no_auth = 0;
+static int force_salvage = 0;
+static int salvage_options = NORMAL_SALVAGE;
+
+/*
+ *
+ */
+
+static void
+sigusr1 (int foo)
+{
+ printf ("sigusr1\n");
+ chdir ("/vicepa");
+ exit (2); /* XXX profiler */
+}
+
+/*
+ *
+ */
+
+static void
+mark_clean (volume_handle *vol)
+{
+ vol->flags.offlinep = FALSE;
+ vol->flags.salvaged = TRUE;
+ vol->flags.attacherr = FALSE;
+}
+
+
+static int
+do_salvage (volume_handle *vol)
+{
+ int ret;
+
+ ret = salvage_volume (vol);
+ if (ret == 0) {
+ mark_clean (vol);
+ } else {
+ vol->flags.offlinep = TRUE;
+ vol->flags.salvaged = TRUE;
+ vol->flags.attacherr = TRUE;
+ }
+ return 0;
+}
+
+static int
+salvage_and_attach (volume_handle *vol, void *arg)
+{
+ mlog_log (MDEBMISC, "salvaging and attatching to volume: %u",
+ (u_int32_t)vol->vol);
+
+ switch (salvage_options) {
+ case NORMAL_SALVAGE:
+ if (vol->flags.cleanp == FALSE)
+ do_salvage (vol);
+ break;
+ case NO_SALVAGE:
+ mark_clean (vol);
+ break;
+ case SALVAGE_ALL:
+ do_salvage (vol);
+ break;
+ default:
+ abort();
+ }
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+static void
+attach_volumes(void)
+{
+ mlog_log (MDEBMISC, "fileserver starting to attach to volumes");
+ vld_iter_vol (salvage_and_attach, NULL);
+ mlog_log (MDEBMISC, "fileserver done attaching to volumes");
+}
+
+/*
+ * Main
+ */
+
+static struct getargs args[] = {
+ {"cell", 0, arg_string, &cell, "what cell to use"},
+ {"realm", 0, arg_string, &realm, "what realm to use"},
+ {"noauth", 0, arg_flag, &no_auth, "disable authentication checks"},
+ {"debug", 0, arg_string, &debug_levels, "debug level"},
+ {"log", 0, arg_string, &log_name, "log device name"},
+ {"srvtab",'s', arg_string, &srvtab_file, "what srvtab to use"},
+ {"salvage", 0, arg_flag, &force_salvage, "Force a salvage for all vols"},
+ { NULL, 0, arg_end, NULL }
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, "fileserver", "", ARG_GNUSTYLE);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ int optind = 0;
+ PROCESS pid;
+
+ set_progname (argv[0]);
+
+ if (getarg (args, argc, argv, &optind, ARG_GNUSTYLE)) {
+ usage ();
+ return 1;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 1;
+ }
+
+ printf ("fileserver booting\n");
+
+ LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid);
+
+ mlog_loginit (log_name, milko_deb_units, MDEFAULT_LOG);
+ if (debug_levels)
+ mlog_log_set_level (debug_levels);
+
+ if (force_salvage)
+ salvage_options = SALVAGE_ALL;
+
+ ports_init();
+ cell_init(0);
+ ropa_init(400,1000);
+
+ if (no_auth)
+ sec_disable_superuser_check ();
+
+ if (cell)
+ cell_setthiscell (cell);
+
+ network_kerberos_init (srvtab_file);
+
+ ret = network_init(htons(afsport), "fs", FS_SERVICE_ID,
+ RXAFS_ExecuteRequest, &fsservice, NULL);
+ if (ret)
+ errx (1, "network_init failed with %d", ret);
+
+ fsservice->destroyConnProc = fs_connsec_destroyconn;
+
+ ret = network_init(htons(afsvolport), "volser", VOLSER_SERVICE_ID,
+ VOLSER_ExecuteRequest, &volservice, NULL);
+ if (ret)
+ errx (1, "network_init failed with %d", ret);
+
+ signal (SIGUSR1, sigusr1);
+ umask (S_IRWXG|S_IRWXO); /* 077 */
+
+ vld_boot();
+ vld_init();
+
+ mnode_init (4711); /* XXX */
+ attach_volumes();
+
+ rx_SetMaxProcs(fsservice,5) ;
+ rx_SetMaxProcs(volservice,5) ;
+
+ printf ("fileserver started, serving data\n");
+
+ rx_StartServer(1) ;
+
+ abort() ;
+ return 0;
+}
+
+
diff --git a/usr.sbin/afs/src/milko/fs/fs_def.h b/usr.sbin/afs/src/milko/fs/fs_def.h
new file mode 100644
index 00000000000..59fa433c578
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/fs_def.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * Fileserver global defines
+ */
+
+/* $Id: fs_def.h,v 1.1 2000/09/11 14:41:13 art Exp $ */
+
+#ifndef __FILBUNKE__FS_DEF_H
+#define __FILBUNKE__FS_DEF_H 1
+
+#define FS_MAX_ACL 8
+
+/* XXX */
+#define AFS_SERVER_SRVTAB_DIR "/usr/arla/etc"
+
+#define N_SECURITY_OBJECTS 3
+
+#define MAX_TRANSACTIONS 100
+
+#endif /* __FILBUNKE__FS_DEF_H */
diff --git a/usr.sbin/afs/src/milko/fs/fsprocs.c b/usr.sbin/afs/src/milko/fs/fsprocs.c
new file mode 100644
index 00000000000..6883bb75874
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/fsprocs.c
@@ -0,0 +1,1639 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "fsrv_locl.h"
+
+RCSID("$Id: fsprocs.c,v 1.1 2000/09/11 14:41:13 art Exp $");
+
+#define GETHOST(call) rx_HostOf(rx_PeerOf(rx_ConnectionOf((call))))
+#define GETPORT(call) rx_PortOf(rx_PeerOf(rx_ConnectionOf((call))))
+
+/*
+ * Initlize all fields of `m' except `m->flags'.
+ */
+
+static int
+fs_init_msec (struct rx_call *call, struct msec *m)
+{
+ volop_flags flags;
+ assert (call && m);
+ flags = m->flags;
+
+ memset (m, 0, sizeof (*m));
+ m->flags = flags;
+ if (call) {
+ m->sec = fs_connsec_context_get(call->conn);
+ } else {
+ m->sec = NULL;
+ }
+
+ m->loop = 0;
+ return 0;
+}
+
+/*
+ * Update FetchStatus `fs' to reflect `n' and `m'.
+ */
+
+static void
+fs_update_fs (const struct mnode *n, const struct msec *m,
+ AFSFetchStatus *fs)
+{
+ *fs = n->fs;
+ fs->CallerAccess = m->caller_access;
+ fs->AnonymousAccess = m->anonymous_access;
+}
+
+/*
+ * If check if the user have the rights to change `status' the way the
+ * user want to with the right `sec'. If the entry is about to be
+ * created, set owner if that isn't set.
+ */
+
+static int
+check_ss_bits (const struct msec *sec, const AFSStoreStatus *status,
+ Bool createp)
+{
+ /* check if member of system:administrators
+ * set VOLOP_ADMIN (might do this a tad earlier too)
+ */
+
+ if ((status->Mask & SS_OWNER) != 0) {
+ if (status->Owner != sec->sec->uid
+ && (sec->flags & VOLOP_ADMIN) != 0)
+ return EPERM;
+ } else if (createp) {
+ ((AFSStoreStatus *)status)->Mask |= SS_OWNER; /* XXX */
+ ((AFSStoreStatus *)status)->Owner = sec->sec->uid; /* XXX */
+ }
+
+ if ((status->Mask & SS_MODEBITS) != 0) {
+ if ((07000 & status->UnixModeBits) != 0
+ && (sec->flags & VOLOP_ADMIN) != 0)
+ return EPERM;
+ }
+ return 0;
+}
+
+/*
+ * Given `fid', `volh' and `m' open node `n'.
+ */
+
+static int
+fs_open_node (const AFSFid *fid, struct volume_handle *volh,
+ struct msec *m, struct mnode **n)
+{
+ int ret;
+
+ ret = mnode_find (fid, n);
+ if (ret)
+ return ret;
+
+ ret = vld_open_vnode (volh, *n, m);
+ if (ret)
+ mnode_free (*n, FALSE);
+ return ret;
+}
+
+
+/*
+ * Given `fid' and `call', init `m', `volh' and `n'.
+ *
+ * If function returns with 0, `volh' and `n' needs to be free:ed when
+ * no longer needed.
+ */
+
+
+static int
+fs_init_req (const AFSFid *fid, struct msec *m, struct volume_handle **volh,
+ struct rx_call *call, struct mnode **n)
+{
+ int ret;
+
+ ret = vld_check_busy(fid->Volume, -1);
+ if (ret)
+ return ret;
+
+ ret = fs_init_msec (call, m);
+ if (ret)
+ return ret;
+
+ ret = vld_find_vol (fid->Volume, volh);
+ if (ret)
+ return ret;
+
+ if ((*volh)->flags.offlinep == TRUE) {
+ int ret;
+ if ((*volh)->flags.attacherr)
+ ret = VOFFLINE;
+ else if ((*volh)->flags.salvaged)
+ ret = VSALVAGE;
+ else
+ ret = VOFFLINE;
+ vld_free (*volh);
+ return ret;
+ }
+
+ ret = vld_db_uptodate (*volh);
+ if (ret) {
+ vld_free (*volh);
+ return ret;
+ }
+
+ ret = fs_open_node (fid, *volh, m, n);
+ if (ret) {
+ vld_free (*volh);
+ return ret;
+ }
+
+ ret = vld_check_rights (*volh, *n, m);
+ if (ret) {
+ mnode_free (*n, FALSE);
+ vld_free (*volh);
+ }
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_FetchData(struct rx_call *call,
+ const struct AFSFid *a_fidToFetchP,
+ const int32_t a_offset,
+ const int32_t a_lenInBytes,
+ struct AFSFetchStatus *a_fidStatP,
+ struct AFSCallBack *a_callBackP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+
+ int32_t len, net_len;
+ struct mnode *n;
+ struct msec m;
+ int ret;
+ int haveData = 1;
+
+ mlog_log (MDEBFS, "FetchData: fid: %d.%d.%d, len = %d, offset = %d",
+ a_fidToFetchP->Volume, a_fidToFetchP->Vnode,
+ a_fidToFetchP->Unique, a_lenInBytes, a_offset);
+
+ m.flags = VOLOP_GETSTATUS | VOLOP_READ;
+
+ ret = fs_init_req (a_fidToFetchP, &m, &volh, call, &n);
+ if (ret) {
+ mlog_log (MDEBFS, "FetchData: fs_init_req returned %d", ret);
+ return ret;
+ }
+
+ if (n->fs.Length < a_offset) {
+/* ret = EINVAL; */
+ mlog_log (MDEBFS, "FetchData: invalid offset (%d < %d)",
+ n->fs.Length, a_offset);
+ haveData = 0;
+ len = 0;
+/* goto out; */
+ } else
+ len = min(a_lenInBytes, n->fs.Length - a_offset);
+
+ net_len = ntohl(len);
+
+ if (rx_Write (call, &net_len, sizeof(net_len)) != sizeof(net_len)) {
+ ret = errno;
+ mlog_log (MDEBFS, "FetchData: rx_Write returned %d", ret);
+ goto out;
+ }
+
+ if (haveData) {
+ ret = copyfd2rx (n->fd, call, a_offset, len);
+ if (ret) {
+ mlog_log (MDEBFS, "FetchData: copyfd2rx returned %d", ret);
+ goto out;
+ }
+ }
+
+ fs_update_fs (n, &m, a_fidStatP);
+ ropa_getcallback (GETHOST(call), GETPORT(call),
+ a_fidToFetchP, a_callBackP);
+ vld_vld2volsync (volh, a_volSyncP);
+
+out:
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_FetchACL(struct rx_call *call,
+ const struct AFSFid *a_dirFidP,
+ AFSOpaque *a_ACLP,
+ struct AFSFetchStatus *a_dirNewStatP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct msec m;
+ int ret;
+ int i;
+ char *tempacl, *tempacl_old;
+ int num_negacl, num_posacl;
+ namelist nlist;
+ idlist ilist;
+
+ mlog_log (MDEBFS, "FetchACL: fid: %d.%d.%d",
+ a_dirFidP->Volume, a_dirFidP->Vnode,
+ a_dirFidP->Unique);
+
+ m.flags = VOLOP_GETSTATUS;
+
+ ret = fs_init_req (a_dirFidP, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ fs_update_fs (n, &m, a_dirNewStatP);
+
+ assert (n->flags.ep);
+ assert (n->flags.fsp);
+
+ if (n->fs.FileType != TYPE_DIR) {
+ mnode_free (n, FALSE);
+ return EPERM;
+ }
+
+ nlist.len = 0;
+ nlist.val = NULL;
+ ilist.len = 2*FS_MAX_ACL;
+ ilist.val = malloc(2*FS_MAX_ACL*sizeof(int32_t));
+
+ for (i = 0; i < FS_MAX_ACL; i++) {
+ ilist.val[i] = n->e.u.dir.acl[i].owner;
+ }
+ for (i = 0; i < FS_MAX_ACL; i++) {
+ ilist.val[i+FS_MAX_ACL] = n->e.u.dir.negacl[i].owner;
+ }
+
+ ret = fs_connsec_idtoname(&ilist, &nlist);
+ if (ret)
+ goto err_out;
+
+ tempacl = NULL;
+ tempacl_old = strdup("");
+ num_negacl = 0;
+ num_posacl = 0;
+
+ /* Make string with all positive ACL:s */
+ for (i = 0; i < FS_MAX_ACL; i++) {
+ if (n->e.u.dir.acl[i].owner == 0)
+ continue;
+ if (asnprintf(&tempacl, AFSOPAQUEMAX, "%s%s %d\n",
+ tempacl_old,
+ nlist.val[i],
+ n->e.u.dir.acl[i].flags) == -1) {
+ ret = EINVAL /* XXX what is the error code? */;
+ free(tempacl_old);
+ goto err_out;
+ }
+ num_posacl++;
+ free(tempacl_old);
+ tempacl_old = tempacl;
+ tempacl = NULL;
+ }
+
+ /* Add negative ACL:s to string */
+ for (i = 0; i < FS_MAX_ACL; i++) {
+ if (n->e.u.dir.negacl[i].owner == 0)
+ continue;
+ if (asnprintf(&tempacl, AFSOPAQUEMAX, "%s%s %d\n",
+ tempacl_old,
+ nlist.val[i+FS_MAX_ACL],
+ n->e.u.dir.negacl[i].flags) == -1) {
+ ret = EINVAL /* XXX what is the error code? */;
+ free(tempacl_old);
+ goto err_out;
+ }
+ num_negacl++;
+ free(tempacl_old);
+ tempacl_old = tempacl;
+ tempacl = NULL;
+ }
+
+ asnprintf(&tempacl, AFSOPAQUEMAX, "%d\n%d\n%s",
+ num_posacl, num_negacl, tempacl_old);
+ free(tempacl_old);
+ tempacl_old = NULL;
+
+ a_ACLP->len = strlen(tempacl);
+ a_ACLP->val = tempacl;
+
+ err_out:
+ free(ilist.val);
+ free(nlist.val);
+
+ vld_vld2volsync (volh, a_volSyncP);
+
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_FetchStatus(struct rx_call *call,
+ const struct AFSFid *a_fidToStatP,
+ struct AFSFetchStatus *a_currStatP,
+ struct AFSCallBack *a_callBackP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct msec m;
+ int ret;
+
+ mlog_log (MDEBFS, "FetchStatus: fid: %u.%u.%u",
+ (u_int32_t)a_fidToStatP->Volume, (u_int32_t)a_fidToStatP->Vnode,
+ (u_int32_t)a_fidToStatP->Unique);
+
+ m.flags = VOLOP_GETSTATUS;
+
+ ret = fs_init_req (a_fidToStatP, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ fs_update_fs (n, &m, a_currStatP);
+ ropa_getcallback (GETHOST(call), GETPORT(call),
+ a_fidToStatP, a_callBackP);
+ vld_vld2volsync (volh, a_volSyncP);
+
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_StoreData(struct rx_call *call,
+ const struct AFSFid *a_fidToStoreP,
+ const struct AFSStoreStatus *a_fidStatusP,
+ const int32_t a_offset,
+ const int32_t a_lenInBytes,
+ const int32_t a_fileLenInBytes,
+ struct AFSFetchStatus *a_fidStatP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct msec m;
+ int32_t len;
+ int32_t *len_p;
+ int ret;
+
+ mlog_log (MDEBFS, "StoreData: fid: %d.%d.%d",
+ a_fidToStoreP->Volume, a_fidToStoreP->Vnode,
+ a_fidToStoreP->Unique);
+ mlog_log (MDEBFS, "StoreData: offset=%d, len=%d, total=%d",
+ a_offset, a_lenInBytes, a_fileLenInBytes);
+
+#if 0
+/* XXX what if offset > previous file length? */
+ if(a_offset + a_lenInBytes > a_fileLenInBytes) {
+ mlog_log (MDEBFS, "StoreData: ret = %d (wrong len)", EINVAL);
+ mlog_log (MDEBFS, "StoreData: offset=%d, len=%d, total=%d",
+ a_offset, a_lenInBytes, a_fileLenInBytes);
+ return EINVAL;
+ }
+#endif
+
+ m.flags = VOLOP_WRITE | VOLOP_GETSTATUS;
+
+ ret = fs_init_req (a_fidToStoreP, &m, &volh, call, &n);
+ if (ret) {
+ mlog_log (MDEBFS, "StoreData: ret = %d (fs_init_req)", ret);
+ return ret;
+ }
+
+ if (n->fs.FileType == TYPE_DIR) {
+ mnode_free (n, FALSE);
+ mlog_log (MDEBFS, "StoreData: ret = %d", EPERM);
+ return EPERM;
+ }
+
+ /*
+ * newlen = max(offset+length, min(afilelength, oldlen))?
+ */
+
+
+ len = min(a_fileLenInBytes, n->fs.Length);
+
+ if (a_offset + a_lenInBytes > len)
+ len = a_offset + a_lenInBytes;
+
+ if (len != n->fs.Length)
+ len_p = &len;
+ else
+ len_p = NULL;
+
+ ret = check_ss_bits (&m, a_fidStatusP, FALSE);
+ if (ret)
+ goto out;
+ ret = vld_modify_vnode (volh, n, &m, a_fidStatusP, len_p);
+
+ if (ret == 0 && a_lenInBytes != 0)
+ ret = copyrx2fd (call, n->fd, a_offset, a_lenInBytes);
+
+ if (ret == 0) {
+ fs_update_fs (n, &m, a_fidStatP);
+ vld_vld2volsync (volh, a_volSyncP);
+ }
+
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_fidToStoreP, FALSE);
+
+ out:
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ mlog_log (MDEBFS, "StoreData: ret = %d (at end), len = %d",
+ ret, a_fidStatP->Length);
+ return ret;
+}
+
+static void
+skipline(char **curptr)
+{
+ while(**curptr!='\n') (*curptr)++;
+ (*curptr)++;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_StoreACL(struct rx_call *call,
+ const struct AFSFid *a_dirFidP,
+ const AFSOpaque *a_ACLToStoreP,
+ struct AFSFetchStatus *a_dirNewStatP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct msec m;
+ int ret;
+ namelist nlist;
+ idlist ilist;
+ char *curptr;
+ struct acl_entry negacl[FS_MAX_ACL];
+ struct acl_entry acl[FS_MAX_ACL];
+ int num_posacl;
+ int num_negacl;
+ int i;
+
+ mlog_log (MDEBFS, "StoreACL: fid: %d.%d.%d",
+ a_dirFidP->Volume, a_dirFidP->Vnode,
+ a_dirFidP->Unique);
+
+ m.flags = VOLOP_WRITE | VOLOP_GETSTATUS | VOLOP_ADMIN;
+#if 1
+ m.flags |= VOLOP_NOCHECK; /* XXX */
+#endif
+
+ ret = fs_init_req (a_dirFidP, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ assert (n->flags.ep);
+ if (n->e.type != TYPE_DIR) {
+ ret = EINVAL /* XXX */;
+ goto err_out;
+ }
+
+#if 0
+ fprintf(stderr, "%.*s",
+ a_ACLToStoreP->len,
+ a_ACLToStoreP->val);
+#endif
+
+ /* parse acl into nlist, acl */
+
+ memset(acl, 0, sizeof(acl));
+ memset(negacl, 0, sizeof(negacl));
+
+ curptr = a_ACLToStoreP->val;
+ curptr[a_ACLToStoreP->len - 1] = '\0';
+
+ if (sscanf(curptr, "%d\n%d\n", &num_posacl, &num_negacl) != 2)
+ goto err_out;
+ skipline(&curptr);
+ skipline(&curptr);
+ ilist.len = 0;
+ ilist.val = NULL;
+ nlist.len = num_posacl + num_negacl;
+ nlist.val = malloc(PR_MAXNAMELEN * nlist.len);
+ for (i = 0; i < num_posacl; i++) {
+ sscanf(curptr, "%63s %d", nlist.val[i], &acl[i].flags);
+ skipline(&curptr);
+ }
+ for (i = 0; i < num_negacl; i++) {
+ sscanf(curptr, "%63s %d", nlist.val[i+num_posacl], &negacl[i].flags);
+ skipline(&curptr);
+ }
+
+ ret = fs_connsec_nametoid(&nlist, &ilist);
+ if (ret)
+ goto err_out;
+
+ assert(nlist.len == ilist.len);
+
+ for (i = 0; i < ilist.len; i++) {
+ if (ilist.val[i] == PR_ANONYMOUSID) {
+ ret = ENOENT;
+ goto err_out;
+ }
+ fprintf(stderr, "%d\n", ilist.val[i]);
+ }
+
+ for (i = 0; i < num_posacl; i++)
+ acl[i].owner = ilist.val[i];
+
+ for (i = 0; i < num_negacl; i++)
+ negacl[i].owner = ilist.val[i+num_posacl];
+
+ memcpy(&n->e.u.dir.acl, acl, sizeof(acl));
+ memcpy(&n->e.u.dir.negacl, negacl, sizeof(negacl));
+
+ ret = vld_put_acl(volh, n, &m);
+ if (ret)
+ goto err_out;
+
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_dirFidP, FALSE);
+
+ vld_vld2volsync (volh, a_volSyncP);
+
+ err_out:
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_StoreStatus(struct rx_call *call,
+ const struct AFSFid *a_fidP,
+ const struct AFSStoreStatus *a_currStatusP,
+ struct AFSFetchStatus *a_srStatusP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct msec m;
+ int ret;
+
+ mlog_log (MDEBFS, "StoreStatus: fid: %d.%d.%d",
+ a_fidP->Volume, a_fidP->Vnode,
+ a_fidP->Unique);
+
+ m.flags = VOLOP_GETSTATUS;
+
+ ret = fs_init_req (a_fidP, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ ret = check_ss_bits (&m, a_currStatusP, TRUE);
+ if (ret)
+ goto out;
+ ret = vld_modify_vnode (volh, n, &m, a_currStatusP, NULL);
+
+ if (ret == 0) {
+ fs_update_fs (n, &m, a_srStatusP);
+ vld_vld2volsync (volh, a_volSyncP);
+ }
+
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_fidP, FALSE);
+ out:
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ return ret;
+}
+
+
+/*
+ *
+ */
+
+static int
+removenode (struct rx_call *call,
+ const struct AFSFid *a_dirFidP,
+ const char *a_name,
+ struct AFSFetchStatus *a_srvStatusP,
+ struct AFSVolSync *a_volSyncP,
+ int dirp)
+{
+ fbuf the_fbuf;
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct msec m;
+ VenusFid fid;
+ int ret;
+ int32_t new_len;
+
+ m.flags = VOLOP_GETSTATUS|VOLOP_DELETE|VOLOP_PARENT;
+
+ ret = fs_init_req (a_dirFidP, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ assert (n->flags.fdp);
+ assert (n->flags.fsp);
+
+ if (n->fs.FileType != TYPE_DIR) {
+ mnode_free (n, FALSE);
+ return EPERM;
+ }
+
+ ret = fbuf_create (&the_fbuf, n->fd, n->fs.Length,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ if (dirp) {
+ fbuf dirfbuf;
+ struct mnode *parent_n;
+ struct msec pm;
+ VenusFid parentFid, fid;
+
+ parentFid.Cell = 0;
+ parentFid.fid = n->fid;
+
+ ret = fdir_lookup (&the_fbuf, &parentFid, a_name, &fid);
+ if (ret) {
+ fbuf_end (&the_fbuf);
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ pm.flags = VOLOP_GETSTATUS|VOLOP_READ|VOLOP_NOCHECK;
+ fs_init_msec (call, &pm);
+ pm.loop = m.loop + 1;
+
+ ret = fs_open_node (&fid.fid, volh, &pm, &parent_n);
+ if (ret) {
+ fbuf_end (&the_fbuf);
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ assert (parent_n->flags.fdp);
+ assert (parent_n->flags.fsp);
+
+ ret = fbuf_create (&dirfbuf, parent_n->fd, parent_n->fs.Length,
+ FBUF_READ|FBUF_PRIVATE);
+ if (ret) {
+ fbuf_end (&the_fbuf);
+ mnode_free (parent_n, FALSE);
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ ret = fdir_emptyp (&dirfbuf);
+ fbuf_end (&dirfbuf);
+ mnode_free (parent_n, TRUE);
+ if (!ret) {
+ fbuf_end (&the_fbuf);
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ENOTEMPTY;
+ }
+ }
+
+ ret = fdir_remove (&the_fbuf, a_name, &fid.fid);
+
+ new_len = fbuf_len (&the_fbuf);
+ fbuf_end (&the_fbuf);
+
+ if (ret) {
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ mnode_remove (&fid.fid);
+ ret = vld_remove_node (volh, fid.fid.Vnode);
+ if (ret) {
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+ if (dirp) {
+ ret = vld_adjust_linkcount (volh, n, -1);
+ if (ret) {
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+ }
+
+ ret = vld_modify_vnode (volh, n, NULL, NULL, &new_len);
+
+ fs_update_fs (n, &m, a_srvStatusP);
+
+ fid.fid.Volume = a_dirFidP->Volume;
+
+ if (ret == 0) {
+ ropa_break_callback (GETHOST(call), GETPORT(call), &fid.fid, TRUE);
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_dirFidP, FALSE);
+ }
+
+ mnode_free (n, FALSE);
+ vld_vld2volsync (volh, a_volSyncP);
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_RemoveFile(struct rx_call *call,
+ const struct AFSFid *a_dirFidP,
+ const char *a_name,
+ struct AFSFetchStatus *a_srvStatusP,
+ struct AFSVolSync *a_volSyncP)
+{
+ mlog_log (MDEBFS, "RemoveFile: fid: %d.%d.%d name: %s",
+ a_dirFidP->Volume, a_dirFidP->Vnode,
+ a_dirFidP->Unique, a_name);
+
+ return removenode (call, a_dirFidP, a_name, a_srvStatusP,
+ a_volSyncP, FALSE);
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_CreateFile(struct rx_call *call,
+ const struct AFSFid *DirFid,
+ const char *Name,
+ const struct AFSStoreStatus *InStatus,
+ struct AFSFid *OutFid,
+ struct AFSFetchStatus *OutFidStatus,
+ struct AFSFetchStatus *OutDirStatus,
+ struct AFSCallBack *CallBack,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct mnode *child_n;
+ struct msec m;
+ struct msec child_m;
+ AFSFid child;
+ int ret;
+
+ mlog_log (MDEBFS, "CreateFile: fid: %d.%d.%d name: %s",
+ DirFid->Volume, DirFid->Vnode,
+ DirFid->Unique, Name);
+
+ m.flags = VOLOP_GETSTATUS|VOLOP_INSERT|VOLOP_PARENT;
+
+ ret = fs_init_req (DirFid, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ assert (n->flags.fdp);
+ assert (n->flags.fsp);
+
+ if (n->fs.FileType != TYPE_DIR) {
+ mnode_free (n, FALSE);
+ return EPERM;
+ }
+
+ child.Volume = volh->vol;
+
+ child_m.flags = VOLOP_GETSTATUS;
+ fs_init_msec (call, &child_m);
+ child_m.caller_access = m.caller_access;
+ child_m.anonymous_access = m.anonymous_access;
+
+ ret = check_ss_bits (&m, InStatus, TRUE);
+ if (ret)
+ goto out_parent;
+
+ ret = vld_create_entry (volh, n, &child, TYPE_FILE,
+ InStatus, &child_n, &child_m);
+ if (ret)
+ goto out_parent;
+
+ /* XXX check name ! */
+ ret = mdir_creat (n, Name, child);
+
+ if (ret == 0) {
+ int32_t len = n->sb.st_size;
+ ret = vld_modify_vnode (volh, n, NULL, NULL, &len);
+ }
+
+ if (ret) {
+ mnode_free (n, TRUE);
+ mnode_free (child_n, TRUE);
+ vld_free (volh);
+ mnode_remove (&child);
+ vld_remove_node (volh, child.Vnode);
+ return ret;
+ }
+
+ fs_update_fs (child_n, &child_m, OutFidStatus);
+ fs_update_fs (n, &m, OutDirStatus);
+
+ if (ret == 0)
+ *OutFid = child;
+
+ if (ret == 0) {
+ ropa_getcallback (GETHOST(call), GETPORT(call),
+ OutFid, CallBack);
+ ropa_break_callback (GETHOST(call), GETPORT(call), DirFid, FALSE);
+
+ }
+
+ mnode_free (child_n, FALSE);
+ out_parent:
+ mnode_free (n, FALSE);
+ vld_vld2volsync (volh, a_volSyncP);
+ vld_free (volh);
+
+ mlog_log (MDEBFS, "CreateFile: created fid: %d.%d.%d",
+ OutFid->Volume, OutFid->Vnode,
+ OutFid->Unique);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_Rename(struct rx_call *call,
+ const struct AFSFid *a_origDirFidP,
+ const char *a_origNameP,
+ const struct AFSFid *a_newDirFidP,
+ const char *a_newNameP,
+ struct AFSFetchStatus *a_origDirStatusP,
+ struct AFSFetchStatus *a_newDirStatusP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ fbuf origfbuf;
+ fbuf newfbuf;
+ fbuf *newfbufP = &newfbuf;
+ VenusFid child, origVFid;
+ struct mnode *orig_n, *new_n;
+ struct msec orig_m;
+ struct msec new_m;
+ int ret;
+ int same_dir = FALSE;
+
+ mlog_log (MDEBFS, "Rename: orig_fid: %d.%d.%d orig_name: %s "
+ "new_fid: %d.%d.%d new_name: %s",
+ a_origDirFidP->Volume, a_origDirFidP->Vnode,
+ a_origDirFidP->Unique, a_origNameP,
+ a_newDirFidP->Volume, a_newDirFidP->Vnode,
+ a_newDirFidP->Unique, a_newNameP);
+
+ if (a_origDirFidP->Volume != a_newDirFidP->Volume)
+ return EXDEV;
+
+ orig_m.flags = VOLOP_GETSTATUS|VOLOP_DELETE|VOLOP_PARENT;
+ if (a_origDirFidP->Vnode == a_newDirFidP->Vnode
+ && a_origDirFidP->Unique == a_newDirFidP->Unique)
+ orig_m.flags |= VOLOP_INSERT;
+
+ ret = fs_init_req (a_origDirFidP, &orig_m, &volh, call, &orig_n);
+ if (ret)
+ return ret;
+
+ assert (orig_n->flags.fdp);
+ assert (orig_n->flags.fsp);
+
+ if (orig_n->fs.FileType != TYPE_DIR) {
+ mnode_free (orig_n, FALSE);
+ return EPERM;
+ }
+
+ origVFid.Cell = 0;
+ origVFid.fid = *a_origDirFidP;
+
+ ret = fbuf_create (&origfbuf, orig_n->fd, orig_n->sb.st_size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ mnode_free (orig_n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ ret = fdir_lookup(&origfbuf, &origVFid, a_origNameP, &child);
+ if (ret) {
+ fbuf_end (&origfbuf);
+ mnode_free (orig_n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ if (a_origDirFidP->Vnode == a_newDirFidP->Vnode &&
+ a_origDirFidP->Unique == a_newDirFidP->Unique) {
+
+ newfbufP = &origfbuf;
+ same_dir = TRUE;
+ } else {
+
+ new_m.flags = VOLOP_GETSTATUS|VOLOP_INSERT|VOLOP_PARENT;
+
+ /* XXX */
+ ret = fs_init_req (a_newDirFidP, &new_m, &volh, call, &new_n);
+ if (ret) {
+ fbuf_end (&origfbuf);
+ mnode_free (orig_n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ if (new_n->fs.FileType != TYPE_DIR) {
+ mnode_free (new_n, FALSE);
+ fbuf_end (&origfbuf);
+ mnode_free (orig_n, FALSE);
+ vld_free (volh);
+ return EPERM;
+ }
+
+ ret = fbuf_create (&newfbuf, new_n->fd,
+ new_n->sb.st_size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ mnode_free (new_n, FALSE);
+ fbuf_end (&origfbuf);
+ mnode_free (orig_n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+ }
+
+ {
+ VenusFid sentenced_file;
+ VenusFid dir;
+
+ dir.fid = *a_newDirFidP;
+ dir.Cell = 0;
+
+ if(fdir_lookup(newfbufP, &dir, a_newNameP, &sentenced_file)) {
+ ret = fdir_creat (newfbufP, a_newNameP, child.fid);
+ if (ret)
+ goto out1;
+ } else {
+ if (afs_dir_p (sentenced_file.fid.Vnode)) { /* XXX check properly */
+ ret = EISDIR;
+ goto out1;
+ }
+ mnode_remove (&sentenced_file.fid);
+ ret = fdir_changefid(newfbufP, a_newNameP, &child);
+ if (ret)
+ goto out1;
+ ret = vld_remove_node(volh, sentenced_file.fid.Vnode);
+ if (ret) {
+ /*
+ * Remove failed, try to recover.
+ * Do not check for error, things are bad anyway.
+ * Maybe this should cause a shutdown + salvage?
+ */
+ fdir_changefid(newfbufP, a_newNameP, &sentenced_file);
+ goto out1;
+ }
+ }
+ }
+
+ ret = fdir_remove (&origfbuf, a_origNameP, NULL);
+ if (ret == 0) {
+ int32_t len;
+ len = fbuf_len (&origfbuf);
+ vld_modify_vnode (volh, orig_n, NULL, NULL, &len);
+ if (!same_dir) {
+ len = fbuf_len (newfbufP);
+ vld_modify_vnode (volh, new_n, NULL, NULL, &len);
+ }
+ }
+
+ /* XXX Update linkcount on parents if directory move */
+
+ fs_update_fs (orig_n, &orig_m, a_origDirStatusP);
+ if (!same_dir)
+ fs_update_fs (new_n, &new_m, a_newDirStatusP);
+ else
+ fs_update_fs (orig_n, &orig_m, a_newDirStatusP);
+
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_origDirFidP, FALSE);
+ if (!same_dir)
+ ropa_break_callback (GETHOST(call),GETPORT(call), a_newDirFidP, FALSE);
+ /* Don't break child since data hasn't changed */
+
+
+ out1:
+ fbuf_end (&origfbuf);
+ mnode_free (orig_n, FALSE);
+ if (!same_dir) {
+ fbuf_end (&newfbuf);
+ mnode_free (new_n, FALSE);
+ }
+
+ if (ret == 0)
+ vld_vld2volsync (volh, a_volSyncP);
+
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_Symlink(struct rx_call *call,
+ const struct AFSFid *a_dirFidP,
+ const char *a_nameP,
+ const char *a_linkContentsP,
+ const struct AFSStoreStatus *a_origDirStatP,
+ struct AFSFid *a_newFidP,
+ struct AFSFetchStatus *a_newFidStatP,
+ struct AFSFetchStatus *a_newDirStatP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ VenusFid a_vchild, a_vdirFid;
+ AFSFid child;
+ fbuf the_fbuf;
+ struct mnode *n;
+ struct msec m;
+ struct mnode *child_n;
+ struct msec child_m;
+ int ret;
+ int len;
+
+ mlog_log (MDEBFS, "Symlink: fid: %d.%d.%d name: %s content: %s",
+ a_dirFidP->Volume, a_dirFidP->Vnode,
+ a_dirFidP->Unique, a_nameP, a_linkContentsP);
+
+ m.flags = VOLOP_GETSTATUS|VOLOP_INSERT|VOLOP_PARENT;
+
+ ret = fs_init_req (a_dirFidP, &m, &volh, call, &n);
+ if (ret) {
+ mlog_log (MDEBFS, "Symlink: ret = %d (init_req)", ret);
+ return ret;
+ }
+
+ assert (n->flags.fdp);
+ assert (n->flags.fsp);
+
+ if (n->fs.FileType != TYPE_DIR) {
+ mnode_free (n, FALSE);
+ mlog_log (MDEBFS, "Symlink: ret = %d (not DIR)", EPERM);
+ return EPERM;
+ }
+
+ ret = check_ss_bits (&m, a_origDirStatP, TRUE);
+ if (ret)
+ goto out_parent;
+
+ a_vdirFid.Cell = 0;
+ a_vdirFid.fid = *a_dirFidP;
+
+ ret = fbuf_create (&the_fbuf, n->fd, n->sb.st_size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret) {
+ mlog_log (MDEBFS, "Symlink: ret = %d (fbuf_create)", ret);
+ goto out_parent;
+ }
+
+ ret = fdir_lookup (&the_fbuf, &a_vdirFid, a_nameP, &a_vchild);
+ if (ret != ENOENT) {
+ fbuf_end (&the_fbuf);
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ if (ret == 0) {
+ mlog_log (MDEBFS, "Symlink: ret = %d (EEXIST)", EEXIST);
+ return EEXIST;
+ } else {
+ mlog_log (MDEBFS, "Symlink: ret = %d (fdir_lookup)", ret);
+ return ret;
+ }
+ }
+
+ child.Volume = volh->vol;
+
+ child_m.flags = VOLOP_GETSTATUS;
+ fs_init_msec (call, &child_m);
+
+ ret = vld_create_entry (volh, n, &child, TYPE_LINK,
+ a_origDirStatP, &child_n, &child_m);
+ if (ret) {
+ fbuf_end (&the_fbuf); /* XXX error ? */
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ mlog_log (MDEBFS, "Symlink: ret = %d (vld_create_entry)", ret);
+ return ret;
+ }
+ a_vchild.Cell = 0;
+ a_vchild.fid = child;
+
+ /* XXX check name ! */
+ ret = fdir_creat (&the_fbuf, a_nameP, child);
+ if (ret == 0) {
+ int32_t len = fbuf_len (&the_fbuf);
+ vld_modify_vnode (volh, n, NULL, NULL, &len);
+ }
+
+ fbuf_end (&the_fbuf); /* XXX error ? */
+
+ if (ret) {
+ mnode_remove (&child);
+ vld_remove_node (volh, child.Vnode);
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ mlog_log (MDEBFS, "Symlink: ret = %d (fdir_creat)", ret);
+ return ret;
+ }
+
+ assert (child_n->flags.fdp);
+
+ len = strlen (a_linkContentsP);
+ ret = write (child_n->fd, a_linkContentsP, len);
+ if (ret != len)
+ ret = errno;
+ else
+ ret = 0;
+
+ if (ret == 0) {
+ int32_t len32 = len;
+ *a_newFidP = child;
+ vld_modify_vnode (volh, child_n, NULL, NULL, &len32);
+ fs_update_fs (n, &m, a_newDirStatP);
+ fs_update_fs (child_n, &child_m, a_newFidStatP);
+ vld_vld2volsync (volh, a_volSyncP);
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_dirFidP, FALSE);
+ } else {
+ mlog_log (MDEBFS, "Symlink: ret = %d (write)", ret);
+ }
+
+ mnode_free (child_n, FALSE);
+ out_parent:
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_Link(struct rx_call *call,
+ const struct AFSFid *a_dirFidP,
+ const char *a_nameP,
+ const struct AFSFid *a_existingFidP,
+ struct AFSFetchStatus *a_newFidStatP,
+ struct AFSFetchStatus *a_newDirStatP,
+ struct AFSVolSync *a_volSyncP)
+{
+ return EPERM;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_MakeDir(struct rx_call *call,
+ const struct AFSFid *a_parentDirFidP,
+ const char *a_newDirNameP,
+ const struct AFSStoreStatus *a_currStatP,
+ struct AFSFid *a_newDirFidP,
+ struct AFSFetchStatus *a_dirFidStatP,
+ struct AFSFetchStatus *a_parentDirStatP,
+ struct AFSCallBack *a_newDirCallBackP,
+ struct AFSVolSync *a_volSyncP)
+{
+ struct volume_handle *volh;
+ struct mnode *n;
+ struct mnode *child_n;
+ struct msec m;
+ struct msec child_m;
+ int ret;
+ AFSFid child;
+
+ mlog_log (MDEBFS, "MakeDir: fid: %d.%d.%d name: %s",
+ a_parentDirFidP->Volume, a_parentDirFidP->Vnode,
+ a_parentDirFidP->Unique, a_newDirNameP);
+
+ m.flags = VOLOP_WRITE | VOLOP_INSERT | VOLOP_PARENT | VOLOP_GETSTATUS;
+
+ ret = fs_init_req (a_parentDirFidP, &m, &volh, call, &n);
+ if (ret)
+ return ret;
+
+ if (n->fs.FileType != TYPE_DIR) {
+ mnode_free (n, FALSE);
+ return EPERM;
+ }
+
+ child.Volume = volh->vol;
+
+ ret = check_ss_bits (&m, a_currStatP, TRUE);
+ if (ret)
+ goto out_parent;
+
+ child_m.flags = VOLOP_GETSTATUS;
+ fs_init_msec(call, &child_m);
+ ret = vld_create_entry (volh, n, &child, TYPE_DIR,
+ a_currStatP, &child_n, &child_m);
+ if (ret)
+ goto out_parent;
+
+
+ ret = vld_adjust_linkcount (volh, n, 1);
+ if (ret) {
+ mnode_free (n, FALSE);
+ mnode_free (child_n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ /* XXX check name ! */
+ ret = mdir_creat (n, a_newDirNameP, child);
+
+ if (ret) {
+ vld_adjust_linkcount (volh, n, -1);
+ mnode_remove (&child);
+ vld_remove_node (volh, child.Vnode);
+ mnode_free (n, FALSE);
+ mnode_free (child_n, TRUE);
+ vld_free (volh);
+ return ret;
+ }
+
+ ret = vld_modify_vnode (volh, n, NULL, NULL, NULL);
+ if (ret) {
+ /* XXX adjust directory size? */
+ vld_adjust_linkcount (volh, n, -1);
+ mnode_remove (&child);
+ vld_remove_node (volh, child.Vnode);
+ mnode_free (n, FALSE);
+ mnode_free (child_n, TRUE);
+ vld_free (volh);
+ return ret;
+ }
+
+ *a_newDirFidP = child;
+ fs_update_fs (n, &m, a_parentDirStatP);
+ fs_update_fs (child_n, &m, a_dirFidStatP);
+ vld_vld2volsync (volh, a_volSyncP);
+
+ memcpy(&child_n->e.u.dir.acl, &n->e.u.dir.acl,
+ sizeof(n->e.u.dir.acl));
+ memcpy(&child_n->e.u.dir.negacl, &n->e.u.dir.negacl,
+ sizeof(n->e.u.dir.negacl));
+
+ ret = vld_put_acl(volh, child_n, &child_m);
+ if (ret) {
+ /* XXX adjust directory size? */
+ vld_adjust_linkcount (volh, n, -1);
+ mnode_remove (&child);
+ vld_remove_node (volh, child.Vnode);
+ mnode_free (n, FALSE);
+ mnode_free (child_n, TRUE);
+ vld_free (volh);
+ return ret;
+ }
+ ropa_break_callback (GETHOST(call), GETPORT(call), a_parentDirFidP, FALSE);
+ ropa_getcallback (GETHOST(call), GETPORT(call),
+ a_newDirFidP, a_newDirCallBackP);
+
+ mlog_log (MDEBFS, "MakeDir: created child fid: %d.%d.%d",
+ a_newDirFidP->Volume, a_newDirFidP->Vnode,
+ a_newDirFidP->Unique);
+
+ mnode_free (child_n, FALSE);
+out_parent:
+ mnode_free (n, FALSE);
+ vld_free (volh);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_RemoveDir(struct rx_call *call,
+ const struct AFSFid *a_parentDirP,
+ const char *a_dirNameP,
+ struct AFSFetchStatus *a_newParentDirStatP,
+ struct AFSVolSync *a_volSyncP)
+{
+ mlog_log (MDEBFS, "RemoveDir: fid: %d.%d.%d name: %s",
+ a_parentDirP->Volume, a_parentDirP->Vnode,
+ a_parentDirP->Unique, a_dirNameP);
+
+ return removenode (call, a_parentDirP, a_dirNameP,
+ a_newParentDirStatP, a_volSyncP, TRUE);
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_GiveUpCallBacks(struct rx_call *call,
+ const AFSCBFids *a_fidArrayP,
+ const AFSCBs *a_callBackArrayP)
+{
+ int ret;
+
+ mlog_log (MDEBFS, "GiveUpCallBacks");
+
+ ret = ropa_drop_callbacks (GETHOST(call), GETPORT(call),
+ a_fidArrayP, a_callBackArrayP);
+ if (ret)
+ mlog_log (MDEBFS, "GiveUpCallBacks: returning %d", ret);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_GetVolumeStatus(struct rx_call *call,
+ const int32_t a_volIDP,
+ struct AFSFetchVolumeStatus *a_volFetchStatP,
+ char *a_volNameP,
+ char *a_offLineMsgP,
+ char *a_motdP)
+{
+ return EPERM;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_SetVolumeStatus(struct rx_call *call,
+ const int32_t a_volIDP,
+ const struct AFSStoreVolumeStatus *a_volStoreStatP,
+ const char *a_volNameP,
+ const char *a_offLineMsgP,
+ const char *a_motdP)
+{
+ return EPERM;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_GetRootVolume(struct rx_call *call,
+ char *a_rootVolNameP)
+{
+ mlog_log (MDEBFS, "GetRootVolume");
+
+ strlcpy (a_rootVolNameP, "root.cell", AFSNAMEMAX);
+ a_rootVolNameP[AFSNAMEMAX-1] = '\0';
+ return 0;
+}
+
+/*
+ * Get time, the poor mans ntp, used as probe by some clients
+ */
+
+int
+RXAFS_GetTime(struct rx_call *call,
+ u_int32_t *a_secondsP,
+ u_int32_t *a_uSecondsP)
+{
+ struct timeval tv;
+
+ mlog_log (MDEBFS, "GetTime");
+
+ gettimeofday (&tv, NULL);
+
+ *a_secondsP = tv.tv_sec;
+ *a_uSecondsP = tv.tv_usec;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_NGetVolumeInfo(struct rx_call *call,
+ const char *VolumeName,
+ struct AFSVolumeInfo *stuff)
+{
+ return EPERM;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_BulkStatus(struct rx_call *call,
+ const AFSCBFids *FidsArray,
+ AFSBulkStats *StatArray,
+ AFSCBs *CBArray,
+ struct AFSVolSync *Sync)
+{
+ struct volume_handle *volh = NULL;
+ struct mnode *n;
+ struct msec m;
+ int ret, i = 0;
+ int32_t oldvolume = -1;
+
+ mlog_log (MDEBFS, "BulkStatus");
+
+ CBArray->val = NULL;
+ CBArray->len = 0;
+ StatArray->val = NULL;
+ StatArray->len = 0;
+
+ if (FidsArray->len == 0)
+ return 0;
+
+ m.flags = VOLOP_GETSTATUS;
+
+ ret = fs_init_msec (call, &m);
+ if (ret)
+ return ret;
+
+ StatArray->len = FidsArray->len;
+ StatArray->val = malloc(StatArray->len * sizeof(StatArray->val[0]));
+ if (StatArray->val == NULL)
+ return ENOMEM;
+
+ CBArray->len = FidsArray->len;
+ CBArray->val = malloc(CBArray->len * sizeof(CBArray->val[0]));
+ if(CBArray->val == NULL) {
+ free(StatArray->val);
+ return ENOMEM;
+ }
+
+ for (i = 0; FidsArray->len > i ; i++) {
+
+ if (FidsArray->val[i].Volume != oldvolume) {
+ if (volh)
+ vld_free (volh);
+
+ ret = vld_find_vol (FidsArray->val[i].Volume, &volh);
+ if (ret)
+ return ret;
+
+ if (volh->flags.offlinep) {
+ vld_free (volh);
+ return VOFFLINE;
+ }
+
+ ret = vld_db_uptodate (volh);
+ if (ret) {
+ vld_free (volh);
+ return ret;
+ }
+ oldvolume = FidsArray->val[i].Volume;
+ }
+
+ ret = fs_open_node (&FidsArray->val[i], volh, &m, &n);
+ if (ret) {
+ vld_free (volh);
+ return ret;
+ }
+
+ ret = vld_check_rights (volh, n, &m);
+ if (ret) {
+ mnode_free (n, FALSE);
+ vld_free (volh);
+ return ret;
+ }
+
+ fs_update_fs (n, &m, &StatArray->val[i]);
+
+ mnode_free (n, FALSE);
+ n = NULL;
+
+ ropa_getcallback (GETHOST(call), GETPORT(call),
+ &FidsArray->val[i], &CBArray->val[i]);
+ }
+ vld_free (volh);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_SetLock(struct rx_call *call,
+ const struct AFSFid *Fid,
+ const ViceLockType Type,
+ struct AFSVolSync *Sync)
+{
+ return EPERM;
+}
+
+/*
+ *
+ */
+
+int
+RXAFS_ExtendLock(struct rx_call *call,
+ const struct AFSFid *Fid,
+ struct AFSVolSync *Sync)
+{
+ return EPERM;
+}
+
+
+/*
+ *
+ */
+
+int
+RXAFS_ReleaseLock(struct rx_call *call,
+ const struct AFSFid *Fid,
+ struct AFSVolSync *Sync)
+{
+ return EPERM;
+}
diff --git a/usr.sbin/afs/src/milko/fs/fsrv_locl.h b/usr.sbin/afs/src/milko/fs/fsrv_locl.h
new file mode 100644
index 00000000000..1e8ffd7f25b
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/fsrv_locl.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: fsrv_locl.h,v 1.1 2000/09/11 14:41:13 art Exp $
+ */
+
+
+#ifndef __FILBUNKE_FSRV_H
+#define __FILBUNKE_FSRV_H 1
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <err.h>
+#include <assert.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#endif
+
+#include <ports.h>
+#include <msecurity.h>
+#include <netinit.h>
+#include <ko.h>
+#include <service.h>
+#include <part.h>
+
+#include <getarg.h>
+
+#include <fs.ss.h>
+#include <volumeserver.ss.h>
+
+#include "fs_def.h"
+
+#include <pts.h>
+#include "connsec.h"
+
+#include <dpart.h>
+#include <voldb.h>
+#include <vld.h>
+
+#include <fbuf.h>
+#include <fdir.h>
+#include <mdir.h>
+
+#include <ropa.h>
+
+#include <mlog.h>
+#include <mdebug.h>
+
+#include <salvage.h>
+
+#endif /* __FILBUNKE_FSRV_H */
diff --git a/usr.sbin/afs/src/milko/fs/volprocs.c b/usr.sbin/afs/src/milko/fs/volprocs.c
new file mode 100644
index 00000000000..2a26fdb3743
--- /dev/null
+++ b/usr.sbin/afs/src/milko/fs/volprocs.c
@@ -0,0 +1,793 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "fsrv_locl.h"
+
+RCSID("$Id: volprocs.c,v 1.1 2000/09/11 14:41:13 art Exp $");
+
+/*
+ * Helper function
+ */
+
+static int
+volser_fetch_vh (int32_t partition, int32_t volid,
+ struct dp_part **dp, volume_handle **vh)
+{
+ int ret;
+
+ ret = dp_create (partition, dp);
+ if (ret) {
+ fprintf (stderr, "volser_fetch_vh: dp_create: %d\n", ret);
+ return VOLSERFAILEDOP; /* XXX */
+ }
+
+ ret = vld_open_volume_by_num (*dp, volid, vh);
+ if (ret) {
+ fprintf (stderr, "volser_fetch_vh: vld_open_volume_by_num: %d\n", ret);
+ dp_free (*dp);
+ return VOLSERFAILEDOP; /* XXX */
+ }
+
+ ret = vld_info_uptodatep (*vh);
+ if (ret) {
+ printf ("volser_fetch_vh: vld_info_uptodatep: %d\n", ret);
+ vld_free (*vh);
+ dp_free (*dp);
+ return VOLSERFAILEDOP; /* XXX */
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolCreateVolume(struct rx_call *call,
+ const int32_t partition,
+ const char *name,
+ const int32_t type,
+ const int32_t parent,
+ int32_t *volid,
+ int32_t *trans)
+{
+ int ret;
+ int32_t backstoretype = VLD_SVOL;
+ struct dp_part *dp;
+
+ mlog_log(MDEBVOLDB, "VOLSER_AFSVolCreateVolume "
+ "part %d name %s type %d parent %d volid %u",
+ partition, name, type, parent, *volid);
+
+ /* XXX parent should be used */
+
+ ret = vld_create_trans (partition, *volid, trans);
+
+ if (ret)
+ return ret;
+
+ ret = vld_trans_set_iflags (*trans, ITOffline);
+ if (ret)
+ return ret;
+
+ ret = dp_create (partition, &dp);
+ if (ret) {
+ vld_end_trans (*trans, NULL);
+ return ret;
+ }
+
+ ret = vld_create_volume (dp, *volid, name, backstoretype, type, 0);
+ if (ret) {
+ vld_end_trans (*trans, NULL);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolDeleteVolume(struct rx_call *call,
+ const int32_t trans)
+{
+ int ret;
+
+ ret = vld_verify_trans(trans);
+ if (ret)
+ return ret;
+
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolNukeVolume(struct rx_call *call,
+ const int32_t partID,
+ const int32_t volID)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolDump(struct rx_call *call,
+ const int32_t fromTrans,
+ const int32_t fromDate)
+{
+ int ret;
+ struct trans *trans;
+ struct dp_part *dp;
+ volume_handle *vh;
+
+ mlog_log (MDEBVOLDB,
+ "VOLSER_AFSVolDump trans %d fromdate %d",
+ fromTrans, fromDate);
+
+ ret = vld_verify_trans (fromTrans);
+ if (ret)
+ return ret;
+
+ ret = vld_get_trans (fromTrans, &trans);
+ if (ret)
+ return ret;
+
+ ret = volser_fetch_vh (trans->partition, trans->volid, &dp, &vh);
+ if (ret) {
+ vld_put_trans(trans);
+ return ret;
+ }
+
+ if (fromDate != 0) {
+ vld_put_trans(trans);
+ return VOLSERFAILEDOP;
+ }
+
+
+
+ vld_put_trans (trans);
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolSignalRestore(struct rx_call *call,
+ const char *name,
+ const int32_t type,
+ const int32_t pid,
+ const int32_t cloneid)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolRestore(struct rx_call *call,
+ const int32_t toTrans,
+ const int32_t flags,
+ const struct restoreCookie *cookie)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolForward(struct rx_call *call,
+ const int32_t fromTrans,
+ const int32_t fromData,
+ const struct destServer *destination,
+ const int32_t destTrans,
+ const struct restoreCookie *cookie)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolClone(struct rx_call *call,
+ const int32_t trans,
+ const int32_t purgeVol,
+ const int32_t newType,
+ const char *newName,
+ int32_t *newVol)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolReClone(struct rx_call *call,
+ const int32_t tid,
+ const int32_t cloneID)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolSetForwarding(struct rx_call *call,
+ const int32_t tid,
+ const int32_t newsite)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolTransCreate(struct rx_call *call,
+ const int32_t volume,
+ const int32_t partition,
+ const int32_t flags,
+ int32_t *trans)
+{
+ int ret;
+
+ ret = vld_create_trans(partition, volume, trans);
+ if (ret)
+ return ret;
+
+ ret = vld_trans_set_iflags(*trans, flags);
+ if (ret) {
+ vld_end_trans (*trans, NULL);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolEndTrans(struct rx_call *call,
+ const int32_t trans,
+ int32_t *rcode)
+{
+ int ret;
+
+ ret = vld_verify_trans(trans);
+ if (ret)
+ return ret;
+
+ ret = vld_end_trans(trans, rcode);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolGetFlags(struct rx_call *call,
+ const int32_t trans,
+ int32_t *flags)
+{
+ int ret;
+
+ ret = vld_verify_trans(trans);
+ if (ret)
+ return ret;
+
+ ret = vld_trans_get_vflags(trans, flags);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolSetFlags(struct rx_call *call,
+ const int32_t transid,
+ const int32_t flags)
+{
+ int ret;
+ struct trans *trans;
+ struct dp_part *dp;
+ volume_handle *vh;
+
+ mlog_log(MDEBVOLDB, "VOLSER_AFSVolSetFlags "
+ "trans %d flags %d", transid, flags);
+
+ ret = vld_verify_trans(transid);
+ if (ret)
+ return ret;
+
+ ret = vld_get_trans(transid, &trans);
+ if (ret)
+ return ret;
+
+ ret = volser_fetch_vh (trans->partition, trans->volid, &dp, &vh);
+ if (ret) {
+ vld_put_trans(trans);
+ return ret;
+ }
+
+ if (flags & VTDeleteOnSalvage)
+ vh->info.destroyMe = 's';
+ else
+ vh->info.destroyMe = 0;
+
+ assert ((flags & VTOutOfService) == 0); /* XXX */
+
+ vld_info_write(vh);
+
+ vld_free (vh);
+ dp_free (dp);
+
+ vld_put_trans(trans);
+
+ ret = vld_trans_set_vflags(transid, flags);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolGetName(struct rx_call *call,
+ const int32_t tid,
+ char tname[256])
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolGetStatus(struct rx_call *call,
+ const int32_t tid,
+ struct volser_status *status)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolSetIdsTypes(struct rx_call *call,
+ const int32_t tId,
+ const char *name,
+ const int32_t type,
+ const int32_t pId,
+ const int32_t cloneId,
+ const int32_t backupId)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolSetDate(struct rx_call *call,
+ const int32_t tid,
+ const int32_t newDate)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolListPartitions(struct rx_call *call,
+ struct pIDs *partIDs)
+{
+ int i;
+ struct dp_part *dp = NULL;
+ int ret;
+
+ i = 0;
+ do {
+ ret = dp_find(&dp);
+ if (dp == NULL)
+ break;
+ if (ret)
+ return ret;
+ partIDs->partIds[i] = dp->num;
+ i++;
+ } while (i < 26);
+
+ for (; i < 26; i++)
+ partIDs->partIds[i] = -1;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolPartitionInfo(struct rx_call *call,
+ const char *name,
+ struct diskPartition *partition)
+{
+ int num;
+ struct dp_part *dp;
+ int ret;
+
+ num = partition_name2num (name);
+ if (num == -1)
+ return 0; /* XXX */
+
+ ret = dp_create (num, &dp);
+ if (ret)
+ return ret;
+
+ memset(partition, 0, sizeof(*partition));
+ strlcpy(partition->name, dp->part, 32);
+
+ dp_free(dp);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolListVolumes(struct rx_call *call,
+ const int32_t partID,
+ const int32_t flags,
+ volEntries *resultEntries)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolListOneVolume(struct rx_call *call,
+ const int32_t partID,
+ const int32_t volid,
+ volEntries *resultEntries)
+{
+ volume_handle *vh;
+ int ret;
+ struct dp_part *dp;
+ struct volintInfo *volinfo;
+
+ fprintf(stderr,
+ "VOLSER_AFSVolListOneVolume partid: %d volid: %u\n",
+ partID, volid);
+
+ ret = volser_fetch_vh (partID, volid, &dp, &vh);
+ if (ret)
+ return ret;
+
+ resultEntries->len = 1;
+
+ volinfo = calloc(sizeof(struct volintInfo) * resultEntries->len, 1);
+ resultEntries->val = volinfo;
+ strlcpy(volinfo->name, vh->info.name, VNAMESIZE);
+ volinfo->volid = vh->info.volid;
+ volinfo->type = vh->info.type;
+ volinfo->backupID = vh->info.backupID;
+ volinfo->parentID = vh->info.parentID;
+ volinfo->cloneID = vh->info.cloneID;
+ if (vld_check_busy(volid, partID))
+ volinfo->status = VBUSY;
+ else
+ volinfo->status = VOK;
+ volinfo->copyDate = vh->info.copyDate;
+ volinfo->inUse = vh->info.inUse;
+ volinfo->creationDate = vh->info.creationDate;
+ volinfo->accessDate = vh->info.accessDate;
+ volinfo->updateDate = vh->info.updateDate;
+ volinfo->backupDate = vh->info.backupDate;
+ volinfo->dayUse = vh->info.dayUse;
+ volinfo->filecount = vh->info.filecount;
+ volinfo->maxquota = vh->info.maxquota;
+ volinfo->size = vh->info.size;
+ volinfo->needsSalvaged = 0;
+ volinfo->destroyMe = 0;
+
+ vld_free (vh);
+ dp_free (dp);
+
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolGetNthVolume(struct rx_call *call,
+ const int32_t index,
+ int32_t *volume,
+ int32_t *partition)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolMonitor(struct rx_call *call,
+ transDebugEntries *result)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolXListVolumes(struct rx_call *call,
+ const int32_t partID,
+ const int32_t flags,
+ xvolEntries *resultEntries)
+{
+ return VOLSERFAILEDOP;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolXListOneVolume(struct rx_call *call,
+ const int32_t partID,
+ const int32_t volid,
+ xvolEntries *resultEntries)
+{
+ volume_handle *vh;
+ int ret;
+ struct dp_part *dp;
+ struct xvolintInfo *volinfo;
+
+ fprintf(stderr,
+ "VOLSER_AFSVolXListOneVolume partid: %d volid: %u\n",
+ partID, volid);
+
+ ret = volser_fetch_vh (partID, volid, &dp, &vh);
+ if (ret)
+ return ret;
+
+ resultEntries->len = 1;
+
+ volinfo = calloc(sizeof(struct xvolintInfo) * resultEntries->len, 1);
+ resultEntries->val = volinfo;
+ strlcpy(volinfo->name, vh->info.name, VNAMESIZE);
+ volinfo->volid = vh->info.volid;
+ volinfo->type = vh->info.type;
+ volinfo->backupID = vh->info.backupID;
+ volinfo->parentID = vh->info.parentID;
+ volinfo->cloneID = vh->info.cloneID;
+ if (vld_check_busy(volid, partID))
+ volinfo->status = VBUSY;
+ else
+ volinfo->status = VOK;
+ volinfo->copyDate = vh->info.copyDate;
+ volinfo->inUse = vh->info.inUse;
+ volinfo->creationDate = vh->info.creationDate;
+ volinfo->accessDate = vh->info.accessDate;
+ volinfo->updateDate = vh->info.updateDate;
+ volinfo->backupDate = vh->info.backupDate;
+ volinfo->dayUse = vh->info.dayUse;
+ volinfo->filecount = vh->info.filecount;
+ volinfo->maxquota = vh->info.maxquota;
+ volinfo->size = vh->info.size;
+
+ vld_free (vh);
+ dp_free (dp);
+
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolSetInfo(struct rx_call *call,
+ const int32_t transid,
+ const struct volintInfo *volinfo)
+{
+ volume_handle *vh;
+ int ret;
+ struct dp_part *dp;
+ struct trans *trans;
+
+ mlog_log(MDEBVOLDB, "VOLSER_AFSVolSetInfo "
+ "trans %d name %s type %d parent %d volid %d backup %d",
+ transid, volinfo->name, volinfo->type, volinfo->parentID,
+ volinfo->volid, volinfo->backupID);
+
+ ret = vld_verify_trans(transid);
+ if (ret)
+ return ret;
+
+ ret = vld_get_trans(transid, &trans);
+ if (ret)
+ return ret;
+
+ ret = volser_fetch_vh (trans->partition, trans->volid, &dp, &vh);
+ if (ret) {
+ vld_put_trans(trans);
+ return ret;
+ }
+
+ if (volinfo->name[0])
+ strlcpy(vh->info.name, volinfo->name, VNAMESIZE);
+
+ if (volinfo->volid)
+ vh->info.volid = volinfo->volid;
+ if (volinfo->type)
+ vh->info.type = volinfo->type;
+ if (volinfo->backupID)
+ vh->info.backupID = volinfo->backupID;
+ if (volinfo->parentID)
+ vh->info.parentID = volinfo->parentID;
+ if (volinfo->cloneID)
+ vh->info.cloneID = volinfo->cloneID;
+ if (volinfo->status)
+ vh->info.status = volinfo->status;
+ if (volinfo->copyDate)
+ vh->info.copyDate = volinfo->copyDate;
+ if (volinfo->inUse)
+ vh->info.inUse = volinfo->inUse;
+ if (volinfo->creationDate)
+ vh->info.creationDate = volinfo->creationDate;
+ if (volinfo->backupDate)
+ vh->info.backupDate = volinfo->backupDate;
+ if (volinfo->dayUse != -1)
+ vh->info.dayUse = volinfo->dayUse;
+ if (volinfo->filecount)
+ vh->info.filecount = volinfo->filecount;
+ if (volinfo->maxquota != -1)
+ vh->info.maxquota = volinfo->maxquota;
+ if (volinfo->size)
+ vh->info.size = volinfo->size;
+
+ vld_info_write(vh);
+
+ vld_free (vh);
+ dp_free (dp);
+ vld_put_trans(trans);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolXListPartitions(struct rx_call *call,
+ part_entries *ent)
+{
+ int i;
+ struct dp_part *dp = NULL;
+ int ret;
+ int32_t partIDs[26]; /* XXX */
+
+ mlog_log(MDEBVOLDB, "VOLSER_AFSVolXListPartitions");
+
+ i = 0;
+ do {
+ ret = dp_find(&dp);
+ if (dp == NULL)
+ break;
+ if (ret)
+ return ret;
+ partIDs[i] = dp->num;
+ i++;
+ } while (i < 26);
+
+ ent->len = i;
+ ent->val = malloc(sizeof(int32_t) * ent->len);
+ memcpy(ent->val, partIDs, sizeof(int32_t) * ent->len);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VOLSER_AFSVolForwardMultiple(struct rx_call *call,
+ const int32_t fromTrans,
+ const int32_t fromData,
+ const replicas *destinations,
+ const int32_t spare0,
+ const struct restoreCookie *cookie,
+ const multi_results *results)
+{
+ return VOLSERFAILEDOP;
+}
+
+
diff --git a/usr.sbin/afs/src/milko/include/mdebug.h b/usr.sbin/afs/src/milko/include/mdebug.h
new file mode 100644
index 00000000000..466a9fe8d74
--- /dev/null
+++ b/usr.sbin/afs/src/milko/include/mdebug.h
@@ -0,0 +1,75 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: mdebug.h,v 1.1 2000/09/11 14:41:14 art Exp $
+ */
+
+#ifndef _mdebug_h
+#define _mdebug_h
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <log.h>
+
+#include <roken.h>
+
+/*
+ * Remeber to add any new logging class to fs/fileserver.c
+ */
+
+/* masks */
+#define MDEBANY 0xffffffff
+#define MDEBMISC 0x00000001 /* misc debugging */
+#define MDEBVOLDB 0x00000002 /* voldb debugging */
+#define MDEBVLD 0x00000004 /* vld debugging */
+#define MDEBSALVAGE 0x00000008 /* salvager debugging */
+#define MDEBFS 0x00000010 /* fs debugging */
+#define MDEBROPA 0x00000020 /* ropa debugging */
+
+#define MDEBWARN 0x08000000 /* don't ignore warning */
+#define MDEBERROR 0x10000000 /* don't ignore error */
+
+#define MDEBALL (MDEBMISC|MDEBVOLDB|MDEBVLD|MDEBWARN|MDEBERROR|MDEBSALVAGE|MDEBFS|MDEBROPA)
+
+extern struct units milko_deb_units[];
+
+#define MDEFAULT_LOG (MDEBERROR|MDEBWARN)
+
+
+#endif /* _mdebug_h */
diff --git a/usr.sbin/afs/src/milko/lib/Makefile.in b/usr.sbin/afs/src/milko/lib/Makefile.in
new file mode 100644
index 00000000000..f6aebe69405
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/Makefile.in
@@ -0,0 +1,48 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:14 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+SUBDIRS = mlog vstatus dpart voldb vld msecurity ropa
+
+all:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+clean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+realclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+distclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+mostlyclean:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+install:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+uninstall:
+ SUBDIRS='$(SUBDIRS)'; \
+ for i in $$SUBDIRS; \
+ do (cd $$i && $(MAKE) $(MFLAGS) $@) || exit 1; done
+
+Makefile: Makefile.in ../../config.status
+ cd ../.. ; CONFIG_FILES=milko/lib/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all clean realclean distclean mostlyclean install uninstall
diff --git a/usr.sbin/afs/src/milko/lib/dpart/Makefile.in b/usr.sbin/afs/src/milko/lib/dpart/Makefile.in
new file mode 100644
index 00000000000..74217053f53
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/dpart/Makefile.in
@@ -0,0 +1,103 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:14 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I$(srcdir)/../../fs \
+ -I$(srcdir)/../../.. \
+ -I../../../rxdef \
+ -I../../../include \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)dpart
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = dpart.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = dpart.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/dpart/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/dpart/dpart.c b/usr.sbin/afs/src/milko/lib/dpart/dpart.c
new file mode 100644
index 00000000000..ea4de472b6a
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/dpart/dpart.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <unistd.h>
+
+#include <atypes.h>
+
+#include <err.h>
+
+#include <dpart.h>
+
+RCSID("$Id: dpart.c,v 1.1 2000/09/11 14:41:14 art Exp $");
+
+/*
+ * Allocate a dp_part structure for partition `num' and
+ * return it in `dp'.
+ */
+
+int
+dp_create (u_int32_t num, struct dp_part **dp)
+{
+ struct dp_part *d;
+ int ret;
+ char str[3], *ptr = str;
+
+ assert (dp);
+
+ *dp = NULL;
+
+ if (num > ('z' - 'a' * 'z' - 'a'))
+ return EINVAL;
+
+ d = malloc (sizeof (*d));
+ if (d == NULL)
+ return ENOMEM;
+ memset (d, 0, sizeof(*d));
+
+ if (num > 'z' - 'a') {
+ ret = num / ('z' - 'a');
+ num -= ret * ('z' - 'a');
+ *ptr = ret + 'a';
+ ptr++;
+ }
+ ptr[0] = num + 'a';
+ ptr[1] = '\0';
+
+ ret = asprintf (&d->part, "/vicep%s", str);
+ if (ret != 7) {
+ free (d);
+ return EINVAL;
+ }
+
+ d->num = num;
+ d->ref = 1;
+
+ *dp = d;
+ return 0;
+}
+
+void
+dp_ref (struct dp_part *dp)
+{
+ if (dp)
+ ++dp->ref;
+}
+
+/*
+ * free the dpart structure in `dp'.
+ */
+
+void
+dp_free (struct dp_part *dp)
+{
+ if (dp) {
+ if (--dp->ref)
+ return;
+ if (dp->part)
+ free (dp->part);
+ free (dp);
+ }
+}
+
+/*
+ * Iterate over all local partition and returns when one found.
+ * `*dp' should one the first call be set to NULL. For each
+ * call next dpart is returned. When last entry is found `*dp' is
+ * set to NULL. On error != 0 is returned.
+ */
+
+int
+dp_find (struct dp_part **dp)
+{
+ u_int32_t num;
+ int found = 0, ret;
+ struct stat sb;
+
+ assert (dp);
+
+ if (*dp == NULL) {
+ num = -1;
+ } else {
+ num = (*dp)->num;
+ dp_free (*dp);
+ *dp = NULL;
+ }
+ do {
+ ++num;
+
+ if (*dp != NULL)
+ dp_free (*dp);
+
+ ret = dp_create (num, dp);
+ if (ret)
+ return ret;
+
+ if (stat ((*dp)->part, &sb) == 0 && S_ISDIR(sb.st_mode))
+ found = 1;
+
+ } while (!found);
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+int
+dp_findvol (struct dp_part *d, void (*cb)(void *, int), void *data)
+{
+ DIR *dir;
+ struct dirent *e;
+ int fd, ret;
+
+ assert (d);
+
+ ret = chdir (d->part);
+ if (ret)
+ return 0;
+
+ dir = opendir (d->part);
+ if (dir == NULL)
+ return 0;
+
+ while ((e = readdir (dir)) != NULL) {
+ if (strncmp (e->d_name, "vol", 3))
+ continue;
+
+ fd = open (e->d_name, O_RDWR, 0600);
+ if (fd < 0)
+ errx (1, "can't open %s/%s", d->part, e->d_name);
+
+ (cb) (data, fd);
+ close (fd);
+ }
+ closedir (dir);
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+dp_parse (const char *str, u_int32_t *num)
+{
+ int len;
+ u_int32_t part = 0;
+
+ assert (str && num);
+
+ len = strlen (str);
+ if (len == 0)
+ return EINVAL;
+ if (len > 6 && strncmp (str, "/vicep", 6) == 0) {
+ str += 6;
+ len -= 6;
+ }
+ if (len > 2)
+ return EINVAL;
+ if (len == 2) {
+ if (*str < 'a' || *str > 'z')
+ return EINVAL;
+ part += ('z' - 'a') * (*str - 'a' + 1);
+ str++;
+ len--;
+ }
+ if (*str < 'a' || *str > 'z')
+ return EINVAL;
+ part += *str - 'a';
+
+ *num = part;
+ return 0;
+}
+
+/*
+ *
+ */
+
+struct dp_part *
+dp_getpart (const char *str)
+{
+ int ret;
+ struct dp_part *dp;
+ u_int32_t part;
+
+ ret = dp_parse (str, &part);
+ if (ret)
+ return NULL;
+
+ ret = dp_create (part, &dp);
+ if (ret)
+ return NULL;
+
+ return dp;
+}
diff --git a/usr.sbin/afs/src/milko/lib/dpart/dpart.h b/usr.sbin/afs/src/milko/lib/dpart/dpart.h
new file mode 100644
index 00000000000..7a73fa39b85
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/dpart/dpart.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: dpart.h,v 1.1 2000/09/11 14:41:14 art Exp $ */
+
+#ifndef __FILBULKE_DPART_H
+#define __FILBULKE_DPART_H 1
+
+struct dp_part {
+ char *part;
+ int num;
+ int ref;
+};
+
+#define DP_NUMBER(dp) ((dp)->num)
+#define DP_NAME(dp) ((dp)->part)
+
+int
+dp_create (u_int32_t num, struct dp_part **dp);
+
+void
+dp_ref (struct dp_part *dp);
+
+void
+dp_free (struct dp_part *dp);
+
+int
+dp_find (struct dp_part **dp);
+
+int
+dp_findvol (struct dp_part *d, void (*cb)(void *, int), void *data);
+
+int
+dp_parse (const char *str, u_int32_t *num);
+
+struct dp_part *
+dp_getpart (const char *str);
+
+#endif /* __FILBULKE_DPART_H */
diff --git a/usr.sbin/afs/src/milko/lib/mlog/Makefile.in b/usr.sbin/afs/src/milko/lib/mlog/Makefile.in
new file mode 100644
index 00000000000..3b8557f422d
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/mlog/Makefile.in
@@ -0,0 +1,103 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:15 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I../../../rxdef \
+ -I$(srcdir) \
+ -I$(srcdir) \
+ -I../../../include \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)mlog
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = mlog.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = mlog.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/mlog/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/mlog/mlog.c b/usr.sbin/afs/src/milko/lib/mlog/mlog.c
new file mode 100644
index 00000000000..d3b961839e9
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/mlog/mlog.c
@@ -0,0 +1,203 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <assert.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <parse_units.h>
+#include <roken.h>
+#include <err.h>
+#include "ko.h"
+
+#include "mlog.h"
+
+RCSID("$Id: mlog.c,v 1.1 2000/09/11 14:41:15 art Exp $");
+
+static Log_method* mlog_log_method = NULL;
+static Log_unit* mlog_log_unit = NULL;
+static struct units *mlog_deb_units = NULL;
+
+void
+mlog_log(unsigned level, char *fmt, ...)
+{
+ va_list args;
+
+ assert (mlog_log_unit);
+
+ va_start(args, fmt);
+ log_vlog(mlog_log_unit, level, fmt, args);
+ va_end(args);
+}
+
+void
+mlog_loginit(char *log, struct units *deb_units, unsigned default_level)
+{
+ assert (log);
+
+ assert (deb_units && mlog_deb_units == NULL);
+
+ mlog_deb_units = deb_units;
+ mlog_log_method = log_open("milko", log);
+ if (mlog_log_method == NULL)
+ errx (1, "mlog_loginit: log_open failed with log `%s'", log);
+ mlog_log_unit = log_unit_init (mlog_log_method, "milko",
+ mlog_deb_units, default_level);
+ if (mlog_log_unit == NULL)
+ errx (1, "mlog_loginit: log_unit_init failed");
+}
+
+void
+mlog_log_set_level (const char *s)
+{
+ log_set_mask_str (mlog_log_method, NULL, s);
+}
+
+void
+mlog_log_set_level_num (unsigned level)
+{
+ log_set_mask (mlog_log_unit, level);
+}
+
+void
+mlog_log_get_level (char *s, size_t len)
+{
+ log_mask2str (mlog_log_method, NULL, s, len);
+}
+
+unsigned
+mlog_log_get_level_num (void)
+{
+ return log_get_mask (mlog_log_unit);
+}
+
+void
+mlog_log_print_levels (FILE *f)
+{
+ print_flags_table (mlog_deb_units, f);
+}
+
+/*
+ *
+ */
+
+void
+mlog_err (int eval, unsigned level, int error, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ mlog_verr (eval, level, error, fmt, args);
+ va_end (args);
+}
+
+void
+mlog_verr (int eval, unsigned level, int error, const char *fmt, va_list args)
+{
+ char *s;
+
+ vasprintf (&s, fmt, args);
+ if (s == NULL) {
+ log_log (mlog_log_unit, level,
+ "Sorry, no memory to print `%s'...", fmt);
+ exit (eval);
+ }
+ log_log (mlog_log_unit, level, "%s: %s", s, koerr_gettext (error));
+ free (s);
+ exit (eval);
+}
+
+void
+mlog_errx (int eval, unsigned level, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ mlog_verrx (eval, level, fmt, args);
+ va_end (args);
+}
+
+void
+mlog_verrx (int eval, unsigned level, const char *fmt, va_list args)
+{
+ log_vlog (mlog_log_unit, level, fmt, args);
+ exit (eval);
+}
+
+void
+mlog_warn (unsigned level, int error, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ mlog_vwarn (level, error, fmt, args);
+ va_end (args);
+}
+
+void
+mlog_vwarn (unsigned level, int error, const char *fmt, va_list args)
+{
+ char *s;
+
+ vasprintf (&s, fmt, args);
+ if (s == NULL) {
+ log_log (mlog_log_unit, level,
+ "Sorry, no memory to print `%s'...", fmt);
+ return;
+ }
+ log_log (mlog_log_unit, level, "%s: %s", s, koerr_gettext (error));
+ free (s);
+}
+
+void
+mlog_warnx (unsigned level, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ mlog_vwarnx (level, fmt, args);
+ va_end (args);
+}
+
+void
+mlog_vwarnx (unsigned level, const char *fmt, va_list args)
+{
+ log_vlog (mlog_log_unit, level, fmt, args);
+}
diff --git a/usr.sbin/afs/src/milko/lib/mlog/mlog.h b/usr.sbin/afs/src/milko/lib/mlog/mlog.h
new file mode 100644
index 00000000000..aa91230bdc6
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/mlog/mlog.h
@@ -0,0 +1,114 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: mlog.h,v 1.1 2000/09/11 14:41:15 art Exp $
+ */
+
+#ifndef _arladeb_h
+#define _arladeb_h
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <log.h>
+
+#include <roken.h>
+#include <parse_units.h>
+
+void mlog_log(unsigned level, char *fmt, ...);
+void mlog_loginit(char *log, struct units *deb_units, unsigned default_level);
+void mlog_log_set_level (const char *s);
+void mlog_log_set_level_num (unsigned level);
+void mlog_log_get_level (char *s, size_t len);
+unsigned mlog_log_get_level_num (void);
+void mlog_log_print_levels (FILE *f);
+
+void
+mlog_err (int eval, unsigned level, int error, const char *fmt, ...)
+__attribute__ ((noreturn))
+__attribute__ ((format (printf, 4, 5)))
+;
+
+void
+mlog_verr (int eval, unsigned level, int error, const char *fmt, va_list args)
+__attribute__ ((noreturn))
+__attribute__ ((format (printf, 4, 0)))
+;
+
+void
+mlog_errx (int eval, unsigned level, const char *fmt, ...)
+__attribute__ ((noreturn))
+__attribute__ ((format (printf, 3, 4)))
+;
+
+void
+mlog_verrx (int eval, unsigned level, const char *fmt, va_list args)
+__attribute__ ((noreturn))
+__attribute__ ((format (printf, 3, 0)))
+;
+
+void
+mlog_warn (unsigned level, int error, const char *fmt, ...)
+__attribute__ ((format (printf, 3, 4)))
+;
+
+void
+mlog_vwarn (unsigned level, int error, const char *fmt, va_list args)
+__attribute__ ((format (printf, 3, 0)))
+;
+
+void
+mlog_warnx (unsigned level, const char *fmt, ...)
+__attribute__ ((format (printf, 2, 3)))
+;
+
+void
+mlog_vwarnx (unsigned level, const char *fmt, va_list args)
+__attribute__ ((format (printf, 2, 0)))
+;
+
+void
+mlog_warnx_with_fid (unsigned level, const VenusFid *fid, const char *fmt, ...)
+__attribute__ ((format (printf, 3, 4)));
+
+void
+mlog_vwarnx_with_fid (unsigned level, const VenusFid *fid, const char *fmt,
+ va_list args)
+__attribute__ ((format (printf, 3, 0)));
+
+#endif /* _arladeb_h */
diff --git a/usr.sbin/afs/src/milko/lib/msecurity/Makefile.in b/usr.sbin/afs/src/milko/lib/msecurity/Makefile.in
new file mode 100644
index 00000000000..0fd6c27e993
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/msecurity/Makefile.in
@@ -0,0 +1,103 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:15 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I$(srcdir)/../../../rxkad \
+ -I$(srcdir)/../../.. \
+ -I../../../rxdef \
+ -I../../../include \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)msecurity
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@ -DMILKO_SYSCONFDIR=\"$(sysconfdir)\"
+
+LIB_SOURCES = msecurity.c netinit.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = msecurity.o netinit.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/msecurity/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/msecurity/msecurity.c b/usr.sbin/afs/src/milko/lib/msecurity/msecurity.c
new file mode 100644
index 00000000000..2eedb91d56a
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/msecurity/msecurity.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <rx/rx.h>
+#include <rx/rx_null.h>
+
+#include <assert.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#include <rxkad_locl.h>
+#else
+#define ANAME_SZ 40
+#define INST_SZ 40
+#define REALM_SZ 40
+#define MAX_K_NAME_SZ (2*ANAME_SZ + 2*INST_SZ + 2*REALM_SZ - 3)
+#endif
+
+#include <err.h>
+#include <ctype.h>
+
+#ifndef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <service.h>
+
+#include "rx/rxgencon.h"
+
+#include "msecurity.h"
+#include "acl.h"
+
+RCSID("$Id: msecurity.c,v 1.1 2000/09/11 14:41:15 art Exp $");
+
+static char acl_file[] = MILKO_SYSCONFDIR "/superuserlist"; /* XXX */
+
+/*
+ * Don't test for superuser if set
+ */
+
+static int superuser_check_disabled = FALSE;
+
+void
+sec_disable_superuser_check (void)
+{
+ superuser_check_disabled = TRUE;
+}
+
+/*
+ * Return 0 if the user is not a superuser
+ * 1 if the user is a superuser
+ */
+
+int
+sec_is_superuser(struct rx_call *call)
+{
+ char aname[ANAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ char fullname[MAX_K_NAME_SZ];
+
+ if (superuser_check_disabled)
+ return 1;
+
+ if (sec_getname(call->conn, aname, inst, realm))
+ return 0;
+#ifdef KERBEROS
+ if (call->conn->securityIndex == 2) {
+ krb_unparse_name_long_r(aname, inst, realm, fullname);
+ return acl_check(acl_file, fullname);
+ }
+#endif
+ return 0;
+}
+
+int
+sec_add_superuser(char *user)
+{
+#ifdef KERBEROS
+ return acl_add(acl_file, user);
+#else
+ return -1;
+#endif
+}
+
+int
+sec_del_superuser(char *user)
+{
+#ifdef KERBEROS
+ return acl_delete(acl_file, user);
+#else
+ return -1;
+#endif
+}
+
+/*
+ * Get the parsed name of a connection.
+ * name, instance and realm should be properly allocated
+ * Returns zero on success
+ */
+
+int
+sec_getname(struct rx_connection *conn,
+ char *name, char *instance, char *realm)
+{
+#ifdef KERBEROS
+ if (conn->securityIndex == 2) {
+ serv_con_data *cdat;
+
+ cdat = conn->securityData;
+ strlcpy(name, cdat->user->name, ANAME_SZ);
+ strlcpy(instance, cdat->user->instance, INST_SZ);
+ strlcpy(realm, cdat->user->realm, REALM_SZ);
+ return 0;
+ }
+#endif
+ return -1;
+}
+
diff --git a/usr.sbin/afs/src/milko/lib/msecurity/msecurity.h b/usr.sbin/afs/src/milko/lib/msecurity/msecurity.h
new file mode 100644
index 00000000000..fdac3c156fb
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/msecurity/msecurity.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: msecurity.h,v 1.1 2000/09/11 14:41:15 art Exp $ */
+
+void
+sec_disable_superuser_check (void);
+
+int
+sec_is_superuser(struct rx_call *call);
+
+int
+sec_add_superuser(char *user);
+
+int
+sec_del_superuser(char *user);
+
+int
+sec_getname(struct rx_connection *conn,
+ char *name, char *instance, char *realm);
diff --git a/usr.sbin/afs/src/milko/lib/msecurity/netinit.c b/usr.sbin/afs/src/milko/lib/msecurity/netinit.c
new file mode 100644
index 00000000000..2657b268f85
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/msecurity/netinit.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#endif
+
+#include <ko.h>
+
+#include <string.h>
+#include <assert.h>
+#include <err.h>
+#include <netinit.h>
+
+#ifndef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+RCSID("$Id: netinit.c,v 1.1 2000/09/11 14:41:15 art Exp $");
+
+/*
+ * Network functions
+ */
+
+static char *srvtab_filename = NULL;
+
+/*
+ * If srvtab == NULL, then default is used.
+ */
+
+void
+network_kerberos_init (char *srvtab)
+{
+ if (srvtab) {
+ srvtab_filename = strdup(srvtab);
+ } else {
+ srvtab_filename = MILKO_SYSCONFDIR "/srvtab";
+ }
+}
+
+#ifdef KERBEROS
+
+static char cell_name[REALM_SZ] = "";
+static char realm_name[REALM_SZ] = "";
+static des_cblock afskey;
+
+static int
+server_get_key(void *appl, int kvno, des_cblock *key)
+{
+ static int read_key = 0;
+ int ret;
+
+ assert (srvtab_filename != NULL);
+
+ if (!read_key) {
+ ret = read_service_key("afs", cell_name, realm_name,
+ 0, srvtab_filename,
+ (char *)&afskey);
+ if (ret) {
+ /*
+ * Try also afs.realm@REALM
+ */
+
+ strlcpy(cell_name, realm_name, sizeof(realm_name));
+ strlwr (cell_name);
+ ret = read_service_key("afs", cell_name, realm_name,
+ 0, srvtab_filename,
+ (char *)&afskey);
+ if (ret)
+ return ret;
+ }
+ read_key = 1;
+ }
+
+ memcpy (key, &afskey, sizeof (afskey));
+ return 0;
+}
+
+struct rx_securityClass *
+netinit_client_getcred(void)
+{
+ int k_errno;
+ CREDENTIALS c;
+ struct rx_securityClass *sec;
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+
+ k_errno = krb_get_cred("afs", cell_name, realm_name, &c);
+ if (krb_life_to_time (c.issue_date, c.lifetime) < tv.tv_sec - 100) {
+ dest_tkt();
+ k_errno = 4711;
+ }
+ if(k_errno != KSUCCESS) {
+ k_errno = krb_get_svc_in_tkt("afs", cell_name, realm_name,
+ "afs", cell_name, 0xFF /* XXX */,
+ srvtab_filename);
+ if (k_errno == KSUCCESS)
+ k_errno = krb_get_cred("afs", cell_name, realm_name, &c);
+ }
+
+ if (k_errno != KSUCCESS)
+ return NULL;
+
+ sec = rxkad_NewClientSecurityObject(rxkad_auth,
+ &c.session,
+ c.kvno,
+ c.ticket_st.length,
+ c.ticket_st.dat);
+
+ return sec;
+}
+#endif
+
+#define N_SECURITY_OBJECTS 3
+
+int
+network_init (int serviceport,
+ char *servicename,
+ int serviceid,
+ int32_t (*request) (struct rx_call *),
+ struct rx_service **service,
+ const char *realm)
+{
+ struct rx_service *serv;
+ int maxsec = 1;
+ struct rx_securityClass **secObjs;
+ static char krbtkfile[MaxPathLen];
+
+ secObjs = malloc(sizeof(*secObjs) * N_SECURITY_OBJECTS);
+ if (secObjs == NULL)
+ return errno;
+
+ if (rx_Init(0) != 0)
+ errx(1, "Cant open serverport port\n") ;
+
+ secObjs[0] = rxnull_NewServerSecurityObject(); /* XXX 0 */
+ if (secObjs[0] == NULL )
+ errx(1, "cant create security object") ;
+
+#ifdef KERBEROS
+ strlcpy (cell_name, cell_getthiscell(), sizeof (cell_name));
+
+ if (krbtkfile[0] == '\0') {
+ snprintf (krbtkfile, sizeof(krbtkfile),
+ "%sfileserver_%d", TKT_ROOT, (unsigned int)(getpid()*time(0)));
+ krb_set_tkt_string (krbtkfile);
+ }
+
+ if (realm) {
+ strlcpy(realm_name, realm, sizeof(realm_name));
+ } else if (*realm_name == '\0') {
+ int ret;
+
+ ret = krb_get_lrealm(realm_name, 1);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * if there is no diffrence between cell and realm name the afskey
+ * is named afs.''@REALM. in the other case afs.CELL@REALM is used
+ */
+
+ if (strcasecmp (realm_name, cell_name) == 0)
+ cell_name[0] = '\0';
+
+ maxsec = 3;
+ secObjs[1] = NULL;
+ secObjs[2] = rxkad_NewServerSecurityObject(rxkad_clear,
+ NULL,
+ server_get_key,
+ NULL);
+ if (secObjs[2] == NULL)
+ errx(1, "init_network: can't init rxkad server-security-object");
+#endif
+
+ serv = rx_NewService (serviceport, serviceid, servicename,
+ secObjs, maxsec,
+ request);
+
+ if (serv == NULL)
+ errx(1, "Cant create %s service", servicename);
+
+ if (service)
+ *service = serv;
+
+ return 0;
+}
+
+char *
+netinit_getrealm(void) {
+ return realm_name;
+}
diff --git a/usr.sbin/afs/src/milko/lib/msecurity/netinit.h b/usr.sbin/afs/src/milko/lib/msecurity/netinit.h
new file mode 100644
index 00000000000..ac37802e0bc
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/msecurity/netinit.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: netinit.h,v 1.1 2000/09/11 14:41:15 art Exp $ */
+
+void network_kerberos_init (char *srvtab);
+
+int
+network_init (int serviceport,
+ char *servicename,
+ int serviceid,
+ int32_t (*request) (struct rx_call *),
+ struct rx_service **service,
+ const char *realm);
+
+struct rx_securityClass *
+netinit_client_getcred(void);
+char *netinit_getrealm(void);
+
diff --git a/usr.sbin/afs/src/milko/lib/ropa/Makefile.in b/usr.sbin/afs/src/milko/lib/ropa/Makefile.in
new file mode 100644
index 00000000000..acf1ecdd093
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/ropa/Makefile.in
@@ -0,0 +1,108 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:16 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I$(srcdir)/../dpart \
+ -I$(srcdir)/../vld \
+ -I$(srcdir)/../voldb \
+ -I$(srcdir)/../mlog \
+ -I$(srcdir)/../../fs \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../../.. \
+ -I../../../rxdef \
+ -I../../../include \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)ropa
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = ropa.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = ropa.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/ropa/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/ropa/README b/usr.sbin/afs/src/milko/lib/ropa/README
new file mode 100644
index 00000000000..0cd566059ba
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/ropa/README
@@ -0,0 +1,79 @@
+Ropa - callbacks
+================
+
+Thoughts by Love <lha@stacken.kth.se>
+
+$Id: README,v 1.1 2000/09/11 14:41:16 art Exp $
+
+Design
+======
+
+Think before doing. This isn't that simple. Figure out a way to do
+everything in O(1) but with minium memory requirement.
+
+What sizes should we optimize for ? Linked list might be used for
+small datasets. W/o knowing anything, it seams many fids will have
+few clients, and few fids will have many clients.
+
+We need to have statistics. Guess we need to do it the simple way to get
+statistics, and then do it the right way. KISS!
+
+Data-storage
+============
+
+name = { contain } [ index1, index2, ... ]
+
+client = { uuid, port, interfaceAddr, callbacks[] }
+ [ interfaceAddr, uuid ( & port) ]
+callback = { fid, client[] (, times[], heapptr[]) }
+ [ fid ]
+
+LRU(clients);
+HEAP(callbacks);
+
+Resolve
+=======
+
+fid -> { RW -> time(#clients), RO -> time(history) }
+ [1]
+
+fid -> clients[] \ sender-client [2]
+
+{callback (* time) * client} (heap) --> clients [3]
+
+client -> fids[] [4]
+
+Comments
+========
+
+Use UUID for all clients ? Cook and mark cooked for pre 3.5 clients.
+
+[1] From a given fid we need to figure out a suitable time.
+
+ Without thinking:
+
+ * Callbacks on WR volumes should give
+ back callback-times based on number of clients using this fid.
+
+ * Callbacks on RO volumes should be based on how often volumes
+ are released (average - (timenow() - lasttime())) * rand(10).
+ The rand is to avoid fetch-storms.
+
+[2] When breaking callbacks we need to get all clients.
+ This need to be storted on UUID so we can avoid sending cb
+ to the client.
+
+[3] Should callbacks be given all to the same time, or should diffrent
+ clients have diffrent callbacks ? Will we get fetch-storms when
+ callbacks expire for wellused files (or RO volumes).
+
+[4] We need to query the client when i contacts us the first time
+ There is also need to break fids when clients fall out of the lru.
+
+Lock order and expiration
+=========================
+
+The easy way out might be to globallock the whole module except a
+expirationthread. In this module all enterence function must enter
+with complete data. There must also be a way to function to match
+(addr,port) -> uuid.
diff --git a/usr.sbin/afs/src/milko/lib/ropa/ropa.c b/usr.sbin/afs/src/milko/lib/ropa/ropa.c
new file mode 100644
index 00000000000..ba50b7f5be0
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/ropa/ropa.c
@@ -0,0 +1,1267 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * Callback module
+ *
+ * This module has no way for the rx module to get out stuff like
+ * netmasks and MTU, that should be very interesting to know
+ * performance-wise.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include <atypes.h>
+#include <fs.h>
+#include <cb.h>
+
+#include <hash.h>
+#include <heap.h>
+#include <list.h>
+
+#include <ports.h>
+#include <service.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+#include <rx/rxgencon.h>
+
+#include <cb.cs.h>
+
+#include <err.h>
+
+#include <mlog.h>
+#include <mdebug.h>
+
+#include <ropa.h>
+
+RCSID("$Id: ropa.c,v 1.1 2000/09/11 14:41:16 art Exp $");
+
+#ifndef DIAGNOSTIC
+#define DIAGNOSTIC 1
+#define DIAGNOSTIC_CLIENT 471114
+#define DIAGNOSTIC_CHECK_CLIENT(c) assert((c)->magic == DIAGNOSTIC_CLIENT)
+#define DIAGNOSTIC_ADDR 471197
+#define DIAGNOSTIC_CHECK_ADDR(a) assert((a)->magic == DIAGNOSTIC_ADDR)
+#define DIAGNOSTIC_CALLBACK 471134
+#define DIAGNOSTIC_CHECK_CALLBACK(c) assert((c)->magic == DIAGNOSTIC_CALLBACK)
+#define DIAGNOSTIC_CCPAIR 471110
+#define DIAGNOSTIC_CHECK_CCPAIR(c) assert((c)->magic == DIAGNOSTIC_CCPAIR)
+#else
+#define DIAGNOSTIC_CHECK_CLIENT(c)
+#define DIAGNOSTIC_CHECK_ADDR(a)
+#define DIAGNOSTIC_CHECK_CALLBACK(c)
+#define DIAGNOSTIC_CHECK_CCPAIR(c)
+#endif
+
+
+/*
+ * Declarations
+ */
+
+#define ROPA_STACKSIZE (16*1024)
+
+struct ropa_client;
+
+struct ropa_addr {
+#ifdef DIAGNOSTIC
+ int magic; /* magic */
+#endif
+ struct ropa_client *c; /* pointer to head */
+ u_int32_t addr_in; /* */
+ u_int32_t subnetmask; /* */
+ int mtu; /* */
+};
+
+struct ropa_client {
+#ifdef DIAGNOSTIC
+ int magic; /* magic */
+#endif
+ int numberOfInterfaces;
+ afsUUID uuid;
+ struct ropa_addr addr[AFS_MAX_INTERFACE_ADDR];
+ u_int16_t port; /* port of client in network byte order */
+ time_t lastseen; /* last got a message */
+ List *callbacks; /* list of ccpairs */
+ int ref; /* refence counter */
+ Listitem *li; /* where on lru */
+};
+
+struct ropa_ccpair { /* heap object */
+#ifdef DIAGNOSTIC
+ int magic; /* magic */
+#endif
+ struct ropa_client *client; /* pointer to client */
+ struct ropa_cb *cb; /* pointer to callback */
+ Listitem *cb_li; /* pointer to li on callback */
+ time_t expire; /* when this cb expire */
+ int32_t version; /* version of this callback */
+ heap_ptr heap; /* heap pointer */
+ Listitem *li; /* where on lru */
+};
+
+struct ropa_cb {
+#ifdef DIAGNOSTIC
+ int magic; /* magic */
+#endif
+ AFSFid fid; /* what fid this callback is on */
+ List *ccpairs; /* list of clients holding this cb */
+ int ref; /* refence counter */
+ Listitem *li; /* where on lru */
+};
+
+static void break_callback (struct ropa_cb *cb,struct ropa_client *caller,
+ Bool break_own);
+static void break_ccpair (struct ropa_ccpair *cc, Bool notify_clientp);
+static void break_client (struct ropa_client *c, Bool notify_clientp);
+static void create_callbacks (void);
+static void create_ccpairs (void);
+static int uuid_magic_eq (afsUUID *uuid1, afsUUID *uuid2);
+static void debug_print_callbacks(void);
+
+/*
+ * Module variables
+ */
+
+#define NUM_CLIENTS 100
+#define NUM_CALLBACKS 300
+#define NUM_CCPAIR 600
+
+#define ROPA_MTU 1500
+
+/*
+ *
+ */
+
+static Hashtab *ht_clients_ip = NULL;
+static Hashtab *ht_clients_uuid = NULL;
+static Hashtab *ht_callbacks = NULL;
+/* least recently used on tail */
+static List *lru_clients = NULL;
+static List *lru_ccpair = NULL;
+static List *lru_callback = NULL;
+static unsigned long num_clients = 0;
+static unsigned long num_callbacks = 0;
+static unsigned long num_ccpair = 0;
+
+static Heap *heap_ccpairs = NULL;
+static PROCESS cleaner_pid;
+
+static unsigned debuglevel;
+
+/*
+ *
+ */
+
+static int
+uuid_magic_eq (afsUUID *uuid1, afsUUID *uuid2)
+{
+ return memcmp (&uuid1->node,
+ &uuid2->node,
+ sizeof (uuid1->node));
+}
+
+/*
+ * help functions for the hashtab
+ */
+
+/*
+ * We compare using addresses
+ */
+
+static int
+clients_cmp_ip (void *p1, void *p2)
+{
+ struct ropa_client *c1 = ((struct ropa_addr *) p1)->c;
+ struct ropa_client *c2 = ((struct ropa_addr *) p2)->c;
+ int i,j;
+
+ for (i = 0; i < c1->numberOfInterfaces; i++) {
+ for (j = 0; j < c2->numberOfInterfaces; j++) {
+ if (c1->addr[i].addr_in == c2->addr[j].addr_in
+ && c1->port == c2->port) {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+/*
+ *
+ */
+
+static unsigned
+clients_hash_ip (void *p)
+{
+ struct ropa_addr *a = (struct ropa_addr *)p;
+
+ return a->addr_in + a->c->port;
+}
+
+/*
+ * We compare using uuid
+ */
+
+static int
+clients_cmp_uuid (void *p1, void *p2)
+{
+ return uuid_magic_eq (&((struct ropa_client *) p1)->uuid,
+ &((struct ropa_client *) p2)->uuid);
+}
+
+static unsigned
+clients_hash_uuid (void *p)
+{
+ struct ropa_client *c = (struct ropa_client *) p;
+
+ return
+ c->uuid.node[0] +
+ (c->uuid.node[1] << 6) +
+ (c->uuid.node[2] << 12) +
+ (c->uuid.node[3] << 18) +
+ (c->uuid.node[4] << 24) +
+ ((c->uuid.node[5] << 30) & 0x3);
+}
+
+/*
+ *
+ */
+
+static int
+callbacks_cmp (void *p1, void *p2)
+{
+ struct ropa_cb *c1 = (struct ropa_cb *) p1;
+ struct ropa_cb *c2 = (struct ropa_cb *) p2;
+
+ return c1->fid.Volume - c2->fid.Volume
+ || c1->fid.Vnode - c2->fid.Vnode
+ || c1->fid.Unique - c2->fid.Unique;
+}
+
+/*
+ *
+ */
+
+static unsigned
+callbacks_hash (void *p)
+{
+ struct ropa_cb *c = (struct ropa_cb *)p;
+
+ return c->fid.Volume + c->fid.Vnode +
+ c->fid.Unique;
+}
+
+/*
+ *
+ */
+
+static int
+ccpair_cmp (const void *p1, const void *p2)
+{
+ struct ropa_ccpair *c1 = (struct ropa_ccpair *) p1;
+ struct ropa_ccpair *c2 = (struct ropa_ccpair *) p2;
+
+ return c1->expire - c2->expire;
+}
+
+/*
+ *
+ */
+
+static Bool
+client_inuse_p (struct ropa_client *c)
+{
+ assert (c);
+ return c->port == 0 ? FALSE : TRUE ;
+}
+
+/*
+ *
+ */
+
+static Bool
+callback_inuse_p (struct ropa_cb *cb)
+{
+ assert (cb);
+ return !listemptyp (cb->ccpairs) ;
+}
+
+/*
+ *
+ */
+
+static Bool
+ccpairs_inuse_p (struct ropa_ccpair *cc)
+{
+ assert (cc);
+ return cc->client == NULL ? FALSE : TRUE ;
+}
+
+/*
+ *
+ */
+
+static void
+create_clients (void)
+{
+ struct ropa_client *c;
+ unsigned long i;
+
+ c = malloc (NUM_CLIENTS * sizeof (*c));
+ if (c == NULL)
+ err (1, "create_clients: malloc");
+ memset (c, 0, NUM_CLIENTS * sizeof (*c));
+
+ for (i = 0 ; i < NUM_CLIENTS; i++) {
+#ifdef DIAGNOSTIC
+ c[i].magic = DIAGNOSTIC_CLIENT;
+ {
+ int j;
+ for (j = 0; j < sizeof(c->addr)/sizeof(c->addr[0]); j++)
+ c[i].addr[j].magic = DIAGNOSTIC_ADDR;
+ }
+#endif
+
+ c[i].port = 0;
+ c[i].lastseen = 0;
+ c[i].callbacks = listnew();
+ if (c[i].callbacks == NULL)
+ err (1, "create_clients: listnew");
+ c[i].ref = 0;
+ c[i].li = listaddtail (lru_clients, &c[i]);
+ }
+ num_clients += NUM_CLIENTS;
+}
+
+/*
+ *
+ */
+
+static void
+create_callbacks (void)
+{
+ struct ropa_cb *c;
+ int i;
+
+ c = malloc (NUM_CALLBACKS * sizeof (*c));
+ if (c == NULL)
+ err (1, "create_callbacks: malloc");
+ memset (c, 0, NUM_CALLBACKS * sizeof (*c));
+
+ for (i = 0; i < NUM_CALLBACKS ; i++) {
+#ifdef DIAGNOSTIC
+ c[i].magic = DIAGNOSTIC_CALLBACK;
+#endif
+ c[i].ccpairs = listnew();
+ if (c[i].ccpairs == NULL)
+ err (1, "create_callbacks: listnew");
+ c[i].li = listaddtail (lru_callback, &c[i]);
+ }
+ num_callbacks += NUM_CALLBACKS;
+}
+
+/*
+ *
+ */
+
+void
+create_ccpairs (void)
+{
+ struct ropa_ccpair *c;
+ int i;
+
+ c = malloc (NUM_CCPAIR * sizeof (*c));
+ if (c == NULL)
+ err (1, "create_ccpairs: malloc");
+ memset (c, 0, NUM_CCPAIR * sizeof (*c));
+
+ for (i = 0; i < NUM_CCPAIR ; i++) {
+#ifdef DIAGNOSTIC
+ c[i].magic = DIAGNOSTIC_CCPAIR;
+#endif
+ c[i].li = listaddtail (lru_ccpair, &c[i]);
+ }
+ num_ccpair += NUM_CCPAIR;
+}
+
+/*
+ *
+ */
+
+static void
+client_ref (struct ropa_client *c)
+{
+ assert (c->ref >= 0);
+ if (c->li)
+ listdel (lru_clients, c->li);
+ c->ref++;
+ if (c->li)
+ c->li = listaddhead (lru_clients, c);
+}
+
+/*
+ *
+ */
+
+static void
+callback_ref (struct ropa_cb *cb)
+{
+ assert (cb->ref >= 0);
+ if (cb->li)
+ listdel (lru_callback, cb->li);
+ cb->ref++;
+
+ mlog_log (MDEBROPA, "cb_ref: %x.%x.%x (%d)",
+ cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, cb->ref);
+
+ if (cb->li)
+ cb->li = listaddhead (lru_callback, cb);
+}
+
+/*
+ *
+ */
+
+static void
+clear_addr (struct ropa_addr *addr)
+{
+ DIAGNOSTIC_CHECK_ADDR(addr);
+ addr->c = NULL;
+ addr->addr_in = 0;
+ addr->subnetmask = 0;
+ addr->mtu = 0;
+}
+/*
+ *
+ */
+
+static void
+client_deref (struct ropa_client *c)
+{
+ int i, ret;
+
+ c->ref--;
+
+ if (c->ref == 0) {
+ for (i = 0 ; i < c->numberOfInterfaces ; i++) {
+ int ret = hashtabdel (ht_clients_ip, &c->addr[i]);
+ assert (ret == 0);
+ clear_addr (&c->addr[i]);
+ }
+ c->numberOfInterfaces = 0;
+ c->port = 0;
+
+ ret = hashtabdel (ht_clients_uuid, c);
+ assert (ret == 0);
+ listdel (lru_clients, c->li);
+ c->li = listaddtail (lru_clients, c);
+ }
+}
+
+/*
+ *
+ */
+
+static void
+callback_deref (struct ropa_cb *cb)
+{
+ cb->ref--;
+
+ mlog_log (MDEBROPA, "cb_deref: %x.%x.%x (%d)",
+ cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, cb->ref);
+
+ if (cb->ref == 0) {
+ int ret = hashtabdel (ht_callbacks, cb);
+
+ mlog_log (MDEBROPA, "cb_deref: removing %x.%x.%x",
+ cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique);
+
+ assert (ret == 0);
+
+ if (cb->li)
+ listdel (lru_callback, cb->li);
+
+ assert (listemptyp (cb->ccpairs));
+ memset (&cb->fid, 0, sizeof(cb->fid));
+ cb->li = listaddtail (lru_callback, cb);
+ }
+}
+
+/*
+ *
+ */
+
+struct find_client_s {
+ struct ropa_ccpair *cc;
+ struct ropa_client *c;
+};
+
+static Bool
+find_client (List *list, Listitem *li, void *arg)
+{
+ struct find_client_s *fc = (struct find_client_s *)arg;
+ struct ropa_ccpair *cc = listdata (li);
+
+ mlog_log (MDEBROPA, "\tclient fc->c = 0x%x cc = 0x%x cc->client = 0x%d",
+ fc->c, cc, cc == NULL ? 0 : cc->client);
+ if (cc == NULL)
+ return FALSE;
+ if (cc->client == fc->c) {
+ fc->cc = cc;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static struct ropa_ccpair *
+add_client (struct ropa_cb *cb, struct ropa_client *c)
+{
+ struct timeval tv;
+ struct ropa_ccpair *cc;
+ struct find_client_s fc;
+
+ assert (cb && c);
+
+ fc.c = c;
+ fc.cc = NULL;
+ listiter (cb->ccpairs, find_client, &fc);
+ if (fc.cc) {
+ listdel (lru_ccpair, fc.cc->li);
+ fc.cc->li = listaddhead (lru_ccpair, fc.cc);
+ return fc.cc;
+ }
+
+ /* The reverse of these are in break_ccpair */
+ callback_ref (cb);
+ client_ref (c);
+
+ cc = listdeltail (lru_ccpair);
+ DIAGNOSTIC_CHECK_CCPAIR(cc);
+ cc->li = NULL;
+
+ if (ccpairs_inuse_p (cc))
+ break_ccpair (cc, TRUE);
+
+ /* XXX do it for real */
+ gettimeofday(&tv, NULL);
+ cc->expire = tv.tv_sec + 3600;
+ cc->version += 1;
+
+ heap_insert (heap_ccpairs, cc, &cc->heap);
+ LWP_NoYieldSignal (heap_ccpairs);
+ cc->cb_li = listaddtail (cb->ccpairs, cc);
+
+ cc->client = c;
+ cc->cb = cb;
+ cc->li = listaddhead (lru_ccpair, cc);
+
+ mlog_log (MDEBROPA, "add_client: added %x to callback %x.%x.%x",
+ c->addr[0].addr_in, cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique);
+
+ return cc;
+}
+
+/*
+ *
+ */
+
+static void
+uuid_init_simple (afsUUID *uuid, u_int32_t host)
+{
+ uuid->node[0] = 0xff & host;
+ uuid->node[1] = 0xff & (host >> 8);
+ uuid->node[2] = 0xff & (host >> 16);
+ uuid->node[3] = 0xff & (host >> 24);
+ uuid->node[4] = 0xaa;
+ uuid->node[5] = 0x77;
+}
+
+/*
+ *
+ */
+
+static struct ropa_client *
+client_query (u_int32_t host, u_int16_t port)
+{
+ struct ropa_client ckey;
+ struct ropa_addr *addr;
+ ckey.numberOfInterfaces = 1;
+ ckey.addr[0].c= &ckey;
+ ckey.addr[0].addr_in = host;
+ ckey.port = port;
+ addr = hashtabsearch (ht_clients_ip, &ckey.addr[0]);
+ if (addr) {
+ assert (addr->c->numberOfInterfaces);
+ return addr->c;
+ }
+ return NULL;
+}
+
+/*
+ *
+ */
+
+#if 0
+static struct ropa_client *
+uuid_query_simple (u_int32_t host)
+{
+ struct ropa_client ckey;
+ uuid_init_simple (&ckey.uuid, host);
+ return hashtabsearch (ht_clients_uuid, &ckey);
+}
+#endif
+
+/*
+ *
+ */
+
+static void
+client_update_interfaces (struct ropa_client *c,
+ u_int32_t host, interfaceAddr *addr)
+{
+ int i;
+ int found_addr = 0;
+
+ if (addr->numberOfInterfaces > AFS_MAX_INTERFACE_ADDR)
+ addr->numberOfInterfaces = AFS_MAX_INTERFACE_ADDR;
+
+ for (i = 0; i < c->numberOfInterfaces; i++) {
+ hashtabdel (ht_clients_ip, &c->addr[i]);
+ DIAGNOSTIC_CHECK_ADDR(&c->addr[i]);
+ }
+
+ for (i = 0; i < addr->numberOfInterfaces; i++) {
+ DIAGNOSTIC_CHECK_ADDR(&c->addr[i]);
+ c->addr[i].c = c;
+ c->addr[i].addr_in = addr->addr_in[i];
+ c->addr[i].subnetmask = addr->subnetmask[i];
+ c->addr[i].mtu = addr->mtu[i];
+ hashtabadd (ht_clients_ip, &c->addr[i]);
+ if (host == addr->addr_in[i])
+ found_addr = 1;
+ }
+ if (!found_addr && i < AFS_MAX_INTERFACE_ADDR) {
+ DIAGNOSTIC_CHECK_ADDR(&c->addr[i]);
+ c->addr[i].c = c;
+ c->addr[i].addr_in = host;
+ c->addr[i].subnetmask = 0xffffff00;
+ c->addr[i].mtu = ROPA_MTU;
+ hashtabadd (ht_clients_ip, &c->addr[i]);
+ i++;
+ }
+ c->numberOfInterfaces = i;
+ for (; i < AFS_MAX_INTERFACE_ADDR; i++)
+ clear_addr (&c->addr[i]);
+}
+
+/*
+ *
+ */
+
+static void
+client_init (struct ropa_client *c, u_int32_t host, u_int16_t port,
+ afsUUID *uuid, interfaceAddr *addr)
+{
+ assert (c->numberOfInterfaces == 0);
+
+ c->ref = 0;
+ c->port = port;
+ if (addr) {
+ client_update_interfaces (c, host, addr);
+ } else {
+ c->numberOfInterfaces = 1;
+ DIAGNOSTIC_CHECK_ADDR(&c->addr[0]);
+ c->addr[0].c = c;
+ c->addr[0].addr_in = host;
+ c->addr[0].subnetmask = 0xffffff00;
+ c->addr[0].mtu = ROPA_MTU;
+ hashtabadd (ht_clients_ip, &c->addr[0]);
+ }
+ if (uuid) {
+ c->uuid = *uuid;
+ } else {
+ uuid_init_simple (&c->uuid, host);
+ }
+ hashtabadd (ht_clients_uuid, c);
+
+}
+
+/*
+ * XXX race
+ */
+
+int
+ropa_getcallback (u_int32_t host, u_int16_t port, const struct AFSFid *fid,
+ AFSCallBack *callback)
+{
+ struct ropa_client *c;
+ struct ropa_cb cbkey, *cb;
+ struct ropa_ccpair *cc ;
+ int ret;
+
+ debug_print_callbacks();
+
+ c = client_query (host, port);
+ if (c == NULL) {
+ interfaceAddr remote;
+ struct rx_connection *conn;
+
+ conn = rx_NewConnection (host, port, CM_SERVICE_ID,
+ rxnull_NewClientSecurityObject(),
+ 0);
+
+ ret = RXAFSCB_WhoAreYou (conn, &remote);
+
+ /* XXX race, entry can be found, and inserted by other thread */
+
+ if (ret == RX_CALL_DEAD) {
+ rx_DestroyConnection (conn);
+ return ENETDOWN;
+ } else if (ret == RXGEN_OPCODE) {
+ /*
+ * This is an new client that doen't support WhoAreYou.
+ * Lets add it after a InitCallbackState
+ */
+
+ ret = RXAFSCB_InitCallBackState(conn);
+ /* XXX race, entry can be found, and inserted by other thread */
+ rx_DestroyConnection (conn);
+ if (ret)
+ return ret;
+
+ c = listdeltail (lru_clients);
+ DIAGNOSTIC_CHECK_CLIENT(c);
+ c->li = NULL;
+ if (client_inuse_p (c))
+ break_client (c, TRUE);
+ /* XXX race, entry can be found, and inserted by other thread */
+
+ client_init (c, host, port, NULL, NULL);
+
+ c->li = listaddhead (lru_clients, c);
+
+ } else if (ret == 0) {
+ struct ropa_client ckey;
+ ckey.uuid = remote.uuid;
+ c = hashtabsearch (ht_clients_uuid, &ckey);
+ if (c == NULL) {
+ afsUUID uuid;
+
+ /*
+ * This is a new clint that support WhoAreYou
+ * Lets add it after a InitCallbackState3.
+ */
+
+ c = listdeltail (lru_clients);
+ DIAGNOSTIC_CHECK_CLIENT(c);
+ if (client_inuse_p (c))
+ break_client (c, TRUE);
+ /* XXX race, entry can be found, and inserted by other thread */
+
+ ret = RXAFSCB_InitCallBackState3 (conn, &uuid);
+ rx_DestroyConnection (conn);
+ if (ret != 0) {
+ c->li = listaddtail (lru_clients, c);
+ return ENETDOWN;
+ }
+ /* XXX race, entry can be found, and inserted by other thread */
+ /* XXX check uuid */
+
+ client_init (c, host, port, &remote.uuid, &remote);
+ c->li = listaddhead (lru_clients, c);
+
+ mlog_log (MDEBROPA, "ropa_getcb: new client %x:%x", c, host);
+ } else {
+ /*
+ * We didn't find the client in the ip-hash, but the
+ * uuid hash, it have changed addresses. XXX If it's a bad
+ * client, break outstanding callbacks.
+ */
+
+ client_update_interfaces (c, host, &remote);
+
+ mlog_log (MDEBROPA, "ropa_getcb: updated %x", c);
+
+#if 0
+ if (c->have_outstanding_callbacks)
+ break_outstanding_callbacks (c);
+#endif
+ }
+ } else {
+ return ENETDOWN; /* XXX some unknown error */
+ }
+ }
+
+ cbkey.fid = *fid;
+
+ cb = hashtabsearch (ht_callbacks, &cbkey);
+ if (cb == NULL) {
+ cb = listdeltail (lru_callback);
+ DIAGNOSTIC_CHECK_CALLBACK(cb);
+ cb->li = NULL;
+ if (callback_inuse_p (cb)) {
+ break_callback (cb, NULL, FALSE);
+ callback_ref(cb);
+ } else {
+ callback_ref(cb);
+ cb->li = listaddhead (lru_callback, cb);
+ }
+ cb->fid = *fid;
+ hashtabadd (ht_callbacks, cb);
+
+ mlog_log (MDEBROPA, "ropa_getcallback: added callback %x.%x.%x:%x",
+ fid->Volume, fid->Vnode, fid->Unique, host);
+ } else {
+ mlog_log (MDEBROPA, "ropa_getcallback: found callback %x.%x.%x:%x",
+ fid->Volume, fid->Vnode, fid->Unique, host);
+ callback_ref(cb);
+ }
+
+ cc = add_client (cb, c);
+ if (cc == NULL)
+ abort();
+
+ callback_deref (cb);
+
+ callback->CallBackVersion = cc->version;
+ callback->ExpirationTime = cc->expire;
+ callback->CallBackType = CBSHARED;
+
+ debug_print_callbacks();
+
+ return 0;
+}
+
+/*
+ * Notify client
+ */
+
+static int
+notify_client (struct ropa_client *c, AFSCBFids *fids, AFSCBs *cbs)
+{
+ struct rx_connection *conn;
+ u_int16_t port = c->port;
+ int i, ret;
+
+ for (i = 0; i < c->numberOfInterfaces ; i++) {
+ DIAGNOSTIC_CHECK_ADDR(&c->addr[i]);
+ conn = rx_NewConnection (c->addr[i].addr_in,
+ port,
+ CM_SERVICE_ID,
+ rxnull_NewClientSecurityObject(),
+ 0);
+ mlog_log (MDEBROPA, "notify_client: notifying %x", c->addr[i].addr_in);
+
+ ret = RXAFSCB_CallBack (conn, fids, cbs);
+ rx_DestroyConnection (conn);
+ if (ret == 0)
+ break;
+
+ /* XXX warn */
+ }
+
+ return ret;
+}
+
+/*
+ * Break the callback `cc' that that clients holds. The client doesn't
+ * need to be removed from the callbacks list of ccpairs before this
+ * function is called.
+ */
+
+static void
+break_ccpair (struct ropa_ccpair *cc, Bool notify_clientp)
+{
+ AFSCBFids fids;
+ AFSCBs cbs;
+
+ debug_print_callbacks();
+
+ cc->expire = 0;
+
+ if (cc->li)
+ listdel (lru_ccpair, cc->li);
+
+ if (notify_clientp) {
+ AFSCallBack callback;
+ callback.CallBackVersion = cc->version;
+ callback.ExpirationTime = cc->expire;
+ callback.CallBackType = CBDROPPED;
+
+ fids.len = 1;
+ fids.val = &cc->cb->fid;
+ cbs.len = 1;
+ cbs.val = &callback;
+ notify_client (cc->client, &fids, &cbs);
+ }
+
+ if (cc->cb_li) {
+ listdel (cc->cb->ccpairs, cc->cb_li);
+ cc->cb_li = NULL;
+ }
+
+ /* The reverse of these are in add_client */
+ client_deref (cc->client);
+ cc->client = NULL;
+ callback_deref (cc->cb);
+ cc->cb = NULL;
+
+ heap_remove (heap_ccpairs, cc->heap);
+ cc->li = listaddtail (lru_ccpair, cc);
+
+ debug_print_callbacks();
+}
+
+static int
+add_to_cb (AFSFid *fid, AFSCallBack *cb, AFSCBFids *fids, AFSCBs *cbs)
+{
+ AFSFid *n_fid;
+ AFSCallBack *n_cb;
+
+ n_fid = realloc (fids->val, fids->len + 1);
+ if (n_fid == NULL)
+ return ENOMEM;
+ fids->val = n_fid;
+ n_cb = realloc (cbs->val, cbs->len + 1);
+ if (n_cb == NULL)
+ return ENOMEM;
+ cbs->val = n_cb;
+ fids->val[fids->len] = *fid;
+ cbs->val[cbs->len] = *cb;
+ ++fids->len;
+ ++cbs->len;
+ return 0;
+}
+
+static void
+break_ccpairs (struct ropa_client *c, Bool notify_clientp)
+{
+ AFSCBFids fids;
+ AFSCBs cbs;
+ struct ropa_ccpair *cc;
+ AFSCallBack callback;
+
+ DIAGNOSTIC_CHECK_CLIENT(c);
+
+ fids.val = NULL;
+ fids.len = 0;
+
+ cbs.val = NULL;
+ cbs.len = 0;
+
+ callback.CallBackType = CBDROPPED;
+ while ((cc = listdeltail (c->callbacks)) != NULL) {
+ DIAGNOSTIC_CHECK_CCPAIR(cc);
+ add_to_cb (&cc->cb->fid, &callback, &fids, &cbs);
+ break_ccpair (cc, FALSE);
+ }
+
+ if (notify_clientp)
+ notify_client (c, &fids, &cbs);
+}
+
+
+/*
+ * break the callback and remove it from the chain of clients.
+ * it the clients responsible for the callback is the caller
+ * don't break the callback.
+ */
+
+static void
+break_callback (struct ropa_cb *cb, struct ropa_client *caller, Bool break_own)
+{
+ struct ropa_ccpair *cc;
+ struct ropa_ccpair *own_cc = NULL;
+
+ assert (cb);
+ assert (cb->ccpairs);
+
+ mlog_log (MDEBROPA, "break_callback: breaking callback %x.%x.%x (%d)",
+ cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, break_own);
+
+ callback_ref (cb);
+ if (caller)
+ client_ref (caller);
+
+ while ((cc = listdelhead (cb->ccpairs)) != 0) {
+ assert (cc->cb == cb);
+ cc->cb_li = NULL;
+ if (break_own)
+ break_ccpair (cc, cc->client != caller);
+ else
+ if (cc->client == caller)
+ own_cc = cc;
+ else
+ break_ccpair (cc, TRUE);
+ }
+
+ if (own_cc)
+ own_cc->cb_li = listaddhead (cb->ccpairs, own_cc);
+
+ callback_deref (cb);
+ if (caller)
+ client_deref (caller);
+}
+
+/*
+ *
+ */
+
+void
+ropa_break_callback (u_int32_t addr, u_int16_t port,
+ const struct AFSFid *fid, Bool break_own)
+{
+ struct ropa_client *c = NULL;
+ struct ropa_cb cbkey, *cb;
+
+ debug_print_callbacks();
+
+ c = client_query (addr, port);
+ if (c == NULL) {
+ /* XXX warn */
+ mlog_log (MDEBROPA, "ropa_break_callback: didn't find client %x", addr);
+/* return;
+ XXX really no need to return, right? */
+ }
+
+ cbkey.fid = *fid;
+
+ cb = hashtabsearch (ht_callbacks, &cbkey);
+ if (cb == NULL) {
+ /* XXX warn */
+ mlog_log (MDEBROPA, "ropa_break_callback: didn't find callback %x.%x.%x:%x",
+ fid->Volume, fid->Vnode, fid->Unique, addr);
+ return;
+ }
+
+ break_callback (cb, c, break_own);
+
+ debug_print_callbacks();
+}
+
+/*
+ * ropa_drop_callbacks
+ */
+
+int
+ropa_drop_callbacks (u_int32_t addr, u_int16_t port,
+ const AFSCBFids *a_cbfids_p, const AFSCBs *a_cbs_p)
+{
+ struct ropa_client *c;
+ struct ropa_cb cbkey, *cb;
+ struct find_client_s fc;
+ int i;
+
+ debug_print_callbacks();
+
+ if (a_cbfids_p->len > AFSCBMAX) {
+/* || a_cbfids_p->len > a_cbs_p->len) */
+ abort();
+ return EINVAL;
+ }
+
+ c = client_query (addr, port);
+ if (c == NULL) {
+ /* XXX warn */
+ return EINVAL;
+ }
+
+ for (i = 0; i < a_cbfids_p->len; i++) {
+ cbkey.fid = a_cbfids_p->val[i];
+
+ cb = hashtabsearch (ht_callbacks, &cbkey);
+ if (cb == NULL) {
+ /* XXX warn */
+/* return EINVAL; not necessary? */
+ } else {
+ /* XXX check version */
+
+ fc.c = c;
+ fc.cc = NULL;
+ listiter (cb->ccpairs, find_client, &fc);
+ if (fc.cc == NULL) {
+ /* XXX warn */
+/* return EINVAL; not necessary? */
+ } else {
+ mlog_log (MDEBROPA, "ropa_drop: dropping %x.%x.%x:%x",
+ cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, addr);
+ break_ccpair (fc.cc, FALSE);
+ }
+ }
+ }
+
+ debug_print_callbacks();
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+static void
+break_client (struct ropa_client *c, Bool notify_clientp)
+{
+ assert (c);
+
+ client_ref (c);
+ break_ccpairs (c, notify_clientp);
+ client_deref (c);
+}
+
+void
+ropa_break_client (u_int32_t host, u_int16_t port)
+{
+ struct ropa_client *c;
+
+ c = client_query (host, port);
+ if (c == NULL) {
+ /* XXX warn */
+ return;
+ }
+
+ break_client (c, TRUE);
+}
+
+/*
+ *
+ */
+
+static void
+heapcleaner (char *arg)
+{
+ const void *head;
+ struct timeval tv;
+
+ while (1) {
+
+ while ((head = heap_head (heap_ccpairs)) == NULL)
+ LWP_WaitProcess (heap_ccpairs);
+
+ while ((head = heap_head (heap_ccpairs)) != NULL) {
+ struct ropa_ccpair *cc = (struct ropa_ccpair *)head;
+
+ gettimeofday (&tv, NULL);
+
+ if (tv.tv_sec < cc->expire) {
+ unsigned long t = cc->expire - tv.tv_sec;
+ IOMGR_Sleep (t);
+ } else {
+/* XXX should this be fixed?
+ listdel (cc->cb->ccpairs, cc->cb_li);
+ cc->cb_li = NULL; */
+ break_ccpair (cc, TRUE); /* will remove it from the heap */
+ }
+ }
+ }
+}
+
+
+/*
+ * init the ropa-module
+ */
+
+int
+ropa_init (unsigned long num_callback, unsigned long num_clients)
+{
+ ht_callbacks = hashtabnew (num_callback, callbacks_cmp, callbacks_hash);
+ if (ht_callbacks == NULL)
+ errx (1, "ropa_init: failed to create hashtable for callbacks");
+
+ ht_clients_ip = hashtabnew (num_clients, clients_cmp_ip, clients_hash_ip);
+ if (ht_clients_ip == NULL)
+ errx (1, "ropa_init: failed to create hashtable for clients_ip");
+
+ ht_clients_uuid = hashtabnew (num_clients, clients_cmp_uuid,
+ clients_hash_uuid);
+ if (ht_clients_uuid == NULL)
+ errx (1, "ropa_init: failed to create hashtable for clients_uuid");
+
+ lru_clients = listnew ();
+ if (lru_clients == NULL)
+ errx (1, "ropa_init: failed to create lru for clients");
+
+ lru_ccpair = listnew ();
+ if (lru_ccpair == NULL)
+ errx (1, "ropa_init: failed to create list for ccpairs");
+
+ lru_callback = listnew ();
+ if (lru_callback == NULL)
+ errx (1, "ropa_init: failed to create list for callback");
+
+ heap_ccpairs = heap_new (NUM_CCPAIR, ccpair_cmp);
+ if (heap_ccpairs == NULL)
+ errx (1, "ropa_init: failed to create heap for ccpairs");
+
+ create_clients();
+ create_callbacks();
+ create_ccpairs();
+
+ if (LWP_CreateProcess (heapcleaner, ROPA_STACKSIZE, 1,
+ NULL, "heap-invalidator", &cleaner_pid))
+ errx (1, "ropa_init: LWP_CreateProcess failed");
+
+ debuglevel = mlog_log_get_level_num(); /* XXX */
+
+ return 0;
+}
+
+static Bool
+print_callback_sub (void *ptr, void *arg)
+{
+ struct ropa_cb *cb = (struct ropa_cb *)ptr;
+ mlog_log (MDEBROPA, "\tfound %x.%x.%x (ref=%d)",
+ cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, cb->ref);
+ return FALSE;
+}
+
+static void
+debug_print_callbacks (void)
+{
+ if (debuglevel & MDEBROPA) {
+ mlog_log (MDEBROPA, "---callbacks left are---");
+
+ hashtabforeach (ht_callbacks, print_callback_sub, NULL);
+ }
+}
diff --git a/usr.sbin/afs/src/milko/lib/ropa/ropa.h b/usr.sbin/afs/src/milko/lib/ropa/ropa.h
new file mode 100644
index 00000000000..c553214ce56
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/ropa/ropa.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: ropa.h,v 1.1 2000/09/11 14:41:16 art Exp $ */
+
+int
+ropa_init (unsigned long num_callback, unsigned long num_clients);
+
+int
+ropa_getcallback (u_int32_t host, u_int16_t port, const struct AFSFid *fid,
+ AFSCallBack *callback);
+
+int
+ropa_drop_callbacks (u_int32_t host, u_int16_t port,
+ const AFSCBFids *a_cbfids_p, const AFSCBs *a_cbs_p);
+
+void
+ropa_break_callback (u_int32_t addr, u_int16_t port,
+ const struct AFSFid *fid, Bool break_own);
+
+void
+ropa_break_client (u_int32_t addr, u_int16_t port);
diff --git a/usr.sbin/afs/src/milko/lib/vld/Makefile.in b/usr.sbin/afs/src/milko/lib/vld/Makefile.in
new file mode 100644
index 00000000000..aad3d808818
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/Makefile.in
@@ -0,0 +1,110 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:16 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I$(srcdir)/../mlog \
+ -I$(srcdir)/../dpart \
+ -I$(srcdir)/../voldb \
+ -I$(srcdir)/../vstatus \
+ -I$(srcdir)/../../../lib/bufdir \
+ -I../vstatus \
+ -I$(srcdir)/../../fs \
+ -I$(srcdir)/../../.. \
+ -I../../../rxdef \
+ -I../../../include \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)vld
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = mnode.c vld.c mdir.c glue.c svol.c fvol.c common.c salvage.c debug.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = mnode.o vld.o mdir.o glue.o svol.o fvol.o common.o salvage.o debug.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/vld/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/vld/common.c b/usr.sbin/afs/src/milko/lib/vld/common.c
new file mode 100644
index 00000000000..1443145e6ff
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/common.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <sfvol_private.h>
+
+RCSID("$Id: common.c,v 1.1 2000/09/11 14:41:16 art Exp $");
+
+/*
+ * Translate the `opaque' to the `ino'.
+ */
+
+static int
+local_ino2opaque (ino_t *ino, onode_opaque *opaque)
+{
+ unsigned char *ptr = opaque->data;
+
+ opaque->size = sizeof(ino_t) + 1;
+
+ *ptr = 'L';
+ ptr++;
+
+ memcpy (ptr, ino, sizeof (*ino));
+ return 0;
+}
+
+/*
+ * The reverse
+ */
+
+static int
+local_opaque2ino (onode_opaque *opaque, ino_t *ino)
+{
+ unsigned char *ptr = opaque->data;
+
+ if (*ptr != 'L')
+ return EINVAL;
+
+ ptr++;
+
+ memcpy (ino, ptr, sizeof (*ino));
+ opaque->size = sizeof(ino_t) + 1;
+ return 0;
+}
+
+/*
+ *
+ */
+
+Bool
+local_opaquep (onode_opaque *opaque)
+{
+ unsigned char *ptr = opaque->data;
+
+ if (opaque->size < 1) return FALSE;
+ if (*ptr == 'L') return TRUE;
+ return FALSE;
+}
+
+/*
+ *
+ */
+
+int
+local_unlink_file (struct dp_part *dp, onode_opaque *o)
+{
+ char name[MAXPATHLEN];
+ int ret;
+ ino_t ino;
+
+ ret = local_opaque2ino (o, &ino);
+ if (ret)
+ return ret;
+
+ ret = local_create_name (dp, ino, name, sizeof (name));
+ if (ret)
+ return ret;
+
+ ret = unlink (name);
+ if (ret)
+ return errno;
+
+ return 0;
+
+}
+
+/*
+ *
+ */
+
+int
+local_open_file (struct dp_part *dp, onode_opaque *o,
+ int flags, int *fd)
+{
+ char p[MAXPATHLEN];
+ ino_t ino;
+ int ret;
+
+ ret = local_opaque2ino (o, &ino);
+ if (ret) return ret;
+
+ ret = local_create_name (dp, ino, p, sizeof(p));
+ if (ret) return ret;
+
+ ret = open (p, flags, 0600);
+ if (ret < 0) return errno;
+
+ *fd = ret;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+local_create_name (struct dp_part *dp, int32_t num, char *name, size_t sz)
+{
+ size_t i;
+
+ assert (name);
+
+ i = snprintf (name, sz, "%s/%02x/%02x/%02x/%02x",
+ DP_NAME(dp),
+ (unsigned int) (num >> 24) & 0xff,
+ (unsigned int) (num >> 16) & 0xff,
+ (unsigned int) (num >> 8) & 0xff,
+ (unsigned int) num & 0xff);
+
+ if (i >= sz)
+ abort();
+ return 0;
+}
+
+int
+local_create_file (struct dp_part *dp, onode_opaque *o,
+ struct mnode *n)
+{
+ char name[MAXPATHLEN];
+ char nodename[MAXPATHLEN];
+ int fd, ret;
+ struct stat sb;
+
+ snprintf(nodename, sizeof(nodename), "%s/inodeXXXXXX", DP_NAME(dp));
+ fd = mkstemp(nodename);
+ if (fd == -1)
+ return errno;
+ ret = fstat(fd, &sb);
+ if (ret < 0) {
+ close(fd);
+ unlink(nodename);
+ return errno;
+ }
+
+ if (n) {
+ n->fd = fd;
+ n->sb = sb;
+ n->flags.fdp = TRUE;
+ n->flags.sbp = TRUE;
+ } else {
+ close(fd);
+ }
+
+ snprintf(name, sizeof(name), "%s/%02x", DP_NAME(dp),
+ (unsigned int) (sb.st_ino >> 24) & 0xff);
+ mkdir(name, 0700);
+ snprintf(name, sizeof(name), "%s/%02x/%02x", DP_NAME(dp),
+ (unsigned int) (sb.st_ino >> 24) & 0xff,
+ (unsigned int) (sb.st_ino >> 16) & 0xff);
+ mkdir(name, 0700);
+ snprintf(name, sizeof(name), "%s/%02x/%02x/%02x", DP_NAME(dp),
+ (unsigned int) (sb.st_ino >> 24) & 0xff,
+ (unsigned int) (sb.st_ino >> 16) & 0xff,
+ (unsigned int) (sb.st_ino >> 8) & 0xff);
+ mkdir(name, 0700);
+ local_create_name (dp, sb.st_ino, name, sizeof(name));
+
+ ret = rename(nodename, name);
+ if (ret < 0) {
+ ret = errno;
+ unlink (nodename);
+ return ret;
+ }
+
+ ret = local_ino2opaque (&sb.st_ino, o);
+ if (ret) {
+ ret = errno;
+ unlink (name);
+ return ret;
+ }
+
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/debug.c b/usr.sbin/afs/src/milko/lib/vld/debug.c
new file mode 100644
index 00000000000..9848605ade8
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/debug.c
@@ -0,0 +1,68 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+
+RCSID("$Id: debug.c,v 1.1 2000/09/11 14:41:16 art Exp $");
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <fs.h>
+
+#include <mlog.h>
+#include <mdebug.h>
+
+/*
+ * Logging
+ */
+
+struct units milko_deb_units[] = {
+ { "all", MDEBALL },
+ { "almost-all", MDEBALL },
+ { "errors", MDEBERROR },
+ { "warnings", MDEBWARN },
+ { "voldb", MDEBVOLDB },
+ { "vld", MDEBVLD },
+ { "salvage", MDEBSALVAGE },
+ { "fs", MDEBFS },
+ { "default", MDEFAULT_LOG },
+ { "ropa", MDEBROPA },
+ { "none", 0 },
+ { NULL }
+};
diff --git a/usr.sbin/afs/src/milko/lib/vld/fvol.c b/usr.sbin/afs/src/milko/lib/vld/fvol.c
new file mode 100644
index 00000000000..6c4617d3fe3
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/fvol.c
@@ -0,0 +1,352 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <sfvol_private.h>
+
+RCSID("$Id: fvol.c,v 1.1 2000/09/11 14:41:16 art Exp $");
+
+/*
+ * Description:
+ * fvol is a simple volume to read-only files.
+ * It stores the complete filenames in a flat database.
+ */
+
+struct fvol {
+ int fd;
+ fbuf the_fbuf;
+};
+
+static int
+getfilename (struct fvol *f, int32_t off, char **name);
+
+static int
+opaque2num (onode_opaque *opaque, int32_t *num)
+{
+ char *c;
+
+ if (opaque->size < sizeof(*num) + 1)
+ return EINVAL;
+
+ c = (char *)opaque->data;
+ if (*c != 'F')
+ return EINVAL;
+
+ c++;
+ memcpy (num, c, sizeof (*num));
+ *num = ntohl(*num);
+ return 0;
+}
+
+static int
+num2opaque (int32_t num, onode_opaque *opaque)
+{
+ unsigned char *ptr = opaque->data;
+ num = htonl(num);
+
+ opaque->size = sizeof (int32_t) + 1;
+
+ *ptr = 'F';
+ ptr++;
+
+ memcpy (ptr, &num, sizeof (num));
+ return 0;
+}
+
+/*
+ *
+ */
+
+
+int
+fvol_offset2opaque (int32_t offset, onode_opaque *opaque)
+{
+ return num2opaque (offset, opaque);
+}
+
+
+/*
+ *
+ */
+
+static int
+getfilename (struct fvol *f, int32_t off, char **name)
+{
+ unsigned char *buf;
+
+ assert (f && name);
+
+ buf = (unsigned char *) fbuf_buf (&f->the_fbuf);
+
+ if (off > fbuf_len(&f->the_fbuf) - 1)
+ return ENOENT;
+
+ *name = buf + off;
+ return 0;
+}
+/*
+ *
+ */
+
+int
+fvol_addfile (struct fvol *f, const char *name, int32_t *off)
+{
+ size_t len = strlen(name);
+ char *ptr;
+ int ret;
+
+ *off = fbuf_len(&f->the_fbuf);
+ ptr = ((unsigned char *)fbuf_buf((&f->the_fbuf))) + *off;
+
+ ret = fbuf_truncate (&f->the_fbuf, *off + len + 1);
+ assert (ret == 0);
+
+ strcpy (ptr, name);
+
+ return 0;
+}
+
+static void
+create_fvol_name (struct dp_part *dp, int32_t volid, char *name, size_t len)
+{
+ snprintf (name, len, "%s/fvol-db-%d",
+ DP_NAME(dp),
+ volid);
+
+}
+
+/*
+ * Create a fvol and return it in `vol' that is generic volume.
+ * ignore the flags.
+ */
+
+static int
+fvol_open (struct dp_part *part, int32_t volid, int flags,
+ void **data)
+{
+ char p[MAXPATHLEN];
+ struct fvol *f;
+ int ret, openf;
+ int32_t magic;
+ struct stat sb;
+ fbuf_flags fflags;
+
+ *data = NULL;
+
+ create_fvol_name (part, volid, p, sizeof(p));
+
+ f = malloc (sizeof(*f));
+ if (f == NULL)
+ return EINVAL;
+
+ if ((VOLOP_CREATE & flags) == VOLOP_CREATE) {
+ fflags = FBUF_READ|FBUF_WRITE|FBUF_PRIVATE;
+ openf = O_RDWR|O_CREAT;
+ } else {
+ fflags = FBUF_READ|FBUF_WRITE|FBUF_SHARED;
+ openf = O_RDWR;
+ }
+
+ f->fd = open (p, openf, 0600);
+ if (f->fd < 0) {
+ ret = errno;
+ free (f);
+ return ret;
+ }
+
+ if ((VOLOP_CREATE & flags) == VOLOP_CREATE) {
+ magic = htonl(FVOL_MAGIC1);
+ ret = write (f->fd, &magic, sizeof (magic));
+ if (ret != sizeof (magic)) {
+ ret = errno;
+ close (f->fd);
+ free (f);
+ }
+ sb.st_size = sizeof (magic);
+ } else {
+ ret = read (f->fd, &magic, sizeof (magic));
+ if (ret != sizeof (magic)) {
+ ret = errno;
+ close (f->fd);
+ free (f);
+ return ret;
+ }
+
+ if (htonl(magic) != FVOL_MAGIC1) {
+ close (f->fd);
+ free (f);
+ return EINVAL;
+ }
+
+ ret = fstat (f->fd, &sb);
+ assert (ret == 0);
+ }
+ ret = fbuf_create (&f->the_fbuf, f->fd, sb.st_size, fflags);
+ assert (ret == 0);
+
+ *data = f;
+ return 0;
+}
+
+/*
+ * free all fvol related to the volume `vol'.
+ */
+
+void
+fvol_free_i (struct fvol *f)
+{
+ fbuf_end (&f->the_fbuf);
+ close (f->fd);
+ free (f);
+}
+
+/*
+ * create a inode on `vol', return onode_opaque in `o'.
+ */
+
+static int
+fvol_icreate (volume_handle *vol, onode_opaque *o, node_type type,
+ struct mnode *n)
+{
+ int ret;
+
+ switch (type) {
+ case NODE_VOL:
+ case NODE_META:
+ case NODE_DIR:
+ ret = local_create_file (vol->dp, o, n);
+ break;
+ case NODE_REG:
+ o->size= 0;
+ memset (o->data, 0, sizeof (o->data));
+ ret = 0;
+ break;
+ default:
+ abort();
+ }
+ return ret;
+}
+
+/*
+ * open `o' in `vol' with open(2) `flags', return filedescriptor in `fd'
+ */
+
+static int
+fvol_iopen (volume_handle *vol, onode_opaque *o, int flags, int *fd)
+{
+ char *name;
+ int32_t num;
+ int ret;
+
+ if (local_opaquep (o))
+ return local_open_file (vol->dp, o, flags, fd);
+
+ ret = opaque2num (o, &num);
+ if (ret) return ret;
+
+ ret = getfilename ((struct fvol *) vol->data, num, &name);
+ if (ret) return ret;
+
+ ret = open (name, O_RDONLY, 0600);
+ if (ret < 0)
+ return errno;
+
+ *fd = ret;
+ return 0;
+}
+
+static int
+fvol_unlink (volume_handle *vol, onode_opaque *o)
+{
+ return EROFS;
+}
+
+/*
+ *
+ */
+
+static void
+fvol_free (volume_handle *vol)
+{
+ if (vol->data)
+ fvol_free_i ((struct fvol *)vol->data);
+}
+
+/*
+ *
+ */
+
+int
+fvol_create_volume (struct dp_part *dp, int32_t volid, struct fvol **f)
+{
+ return fvol_open (dp, volid, VOLOP_CREATE, (void **) f);
+}
+
+/*
+ *
+ */
+
+static int
+fvol_remove (volume_handle *vol)
+{
+ char p[MAXPATHLEN];
+ int ret;
+
+ create_fvol_name (vol->dp, vol->vol, p, sizeof(p));
+ ret = unlink(p);
+ if (ret) return ret;
+
+ if (vol->data)
+ fvol_free_i ((struct fvol *)vol->data);
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+vol_op fvol_volume_ops = {
+ "fvol",
+ fvol_open,
+ fvol_free,
+ fvol_icreate,
+ fvol_iopen,
+ fvol_unlink,
+ fvol_remove
+};
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/fvol.h b/usr.sbin/afs/src/milko/lib/vld/fvol.h
new file mode 100644
index 00000000000..a2f59986208
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/fvol.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: fvol.h,v 1.1 2000/09/11 14:41:16 art Exp $
+ */
+
+#define FVOL_MAGIC1 0x1132
+
+struct fvol;
+
+int fvol_create_volume (struct dp_part *dp, int32_t volid,
+ struct fvol **f);
+int fvol_addfile (struct fvol *f, const char *name, int32_t *off);
+void fvol_free_i (struct fvol *vol);
+int fvol_offset2opaque (int32_t offset, onode_opaque *opaque);
+
+extern vol_op fvol_volume_ops;
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/glue.c b/usr.sbin/afs/src/milko/lib/vld/glue.c
new file mode 100644
index 00000000000..1e2d68c0408
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/glue.c
@@ -0,0 +1,240 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * This is glue between voldb and some vol-layer parts when there
+ * isn't a clean way to create them.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <dirent.h>
+
+#include <vldb.h>
+
+#include <voldb.h>
+#include <vld.h>
+#include <vld_ops.h>
+
+#include <vstatus.h>
+#include <voldb.h>
+#include <fvol.h>
+
+#include <mdir.h>
+#include <err.h>
+#include <errno.h>
+
+RCSID("$Id: glue.c,v 1.1 2000/09/11 14:41:16 art Exp $");
+
+/*
+ *
+ */
+
+static int
+add_entry (volume_handle *vol, const char *path, int32_t offset,
+ struct mnode *parent, AFSFid *fid,
+ struct stat *sb, int type, const char *name)
+{
+ int ret;
+ AFSStoreStatus ss;
+ struct mnode *child;
+
+ memset (&ss, 0, sizeof(ss));
+ ss.Mask = SS_MODTIME|SS_OWNER|SS_GROUP|SS_MODEBITS;
+ ss.ClientModTime = sb->st_mtime;
+ ss.UnixModeBits = sb->st_mode;
+ ss.Owner = sb->st_uid;
+ ss.Group = sb->st_gid;
+
+ ret = vld_create_entry (vol, parent, fid, type, &ss, &child, NULL);
+ assert (ret == 0);
+
+ if (type == TYPE_FILE || type == TYPE_LINK) {
+ onode_opaque opaque;
+
+ fvol_offset2opaque (offset, &opaque);
+
+ ret = vld_set_onode (vol, fid->Vnode, &opaque, NULL);
+ assert (ret == 0);
+ }
+
+ ret = mdir_creat (parent, name, *fid);
+ assert (ret == 0);
+
+ return 0;
+}
+
+static int
+add_file (volume_handle *vol, const char *path,
+ struct mnode *parent, AFSFid *fid, struct stat *sb,
+ int type, const char *name)
+{
+ int ret;
+ int32_t offset;
+
+ ret = fvol_addfile ((struct fvol *)vol->data, path, &offset);
+ if (ret) return ret;
+
+ ret = add_entry (vol, path, offset, parent, fid, sb, type, name);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+#if 0
+#ifndef S_ISLNK
+#ifdef S_IFLNK
+#define S_ISLNK(mode) (((mode) & S_IFLNK) == S_IFLNK)
+#endif /* S_IFLNK */
+#define S_ISLNK(mode) 0
+#endif /* I_ISLNK */
+#endif
+
+static int
+add_tree (volume_handle *vol, struct mnode *parent, const char *name)
+{
+ struct voldb_entry e;
+ char p[MAXPATHLEN];
+ struct dirent *dp;
+ struct stat sb;
+ int ret, fd;
+ AFSFid fid;
+ DIR *dir;
+
+ if (parent->flags.fdp == FALSE) {
+ ret = voldb_get_entry (vol->db[0],
+ dir_afs2local (parent->fid.Vnode),
+ &e);
+ if (ret) return ret;
+ parent->flags.fdp = TRUE;
+
+ ret = VOLOP_IOPEN(vol,&e.u.dir.ino, O_RDWR, &fd);
+ if (ret)
+ return ret;
+ }
+
+ dir = opendir (name);
+ if (dir == NULL) {
+ mnode_free (parent, FALSE);
+ return errno;
+ }
+
+ while ((dp = readdir (dir)) != NULL) {
+
+ if (strcmp (dp->d_name, ".") == 0
+ || strcmp (dp->d_name, "..") == 0)
+ continue;
+
+ snprintf (p, sizeof(p), "%s/%s", name, dp->d_name);
+
+ ret = stat (p, &sb);
+ if (ret < 0) {
+ mnode_free (parent, FALSE);
+ return errno;
+ }
+
+ if (S_ISDIR(sb.st_mode)) {
+ struct mnode *child_m;
+
+ add_file (vol, p, parent, &fid, &sb, TYPE_DIR,
+ dp->d_name);
+ ret = mnode_find (&fid, &child_m);
+ assert (ret == 0);
+
+ ret = add_tree (vol, child_m, p);
+ assert (ret == 0);
+ } else if (S_ISREG(sb.st_mode)) {
+ ret = add_file (vol, p, parent, &fid, &sb, TYPE_FILE,
+ dp->d_name);
+ assert (ret == 0);
+ } else if (S_ISLNK(sb.st_mode)) {
+ ret = add_file (vol, p, parent, &fid, &sb, TYPE_LINK,
+ dp->d_name);
+ assert (ret == 0);
+ } else {
+ printf ("ignoring %s\n", p);
+ }
+ }
+ closedir (dir);
+ mnode_free (parent, FALSE);
+ return 0;
+}
+
+int
+vld_fvol_create_volume_ondisk (struct dp_part *dp, int32_t volid,
+ const char *path)
+{
+ volume_handle *vol;
+ AFSFid fid;
+ struct mnode *m;
+ int ret;
+
+ ret = vld_create_volume (dp, volid, "foo", VLD_FVOL, ROVOL, 0);
+ if (ret)
+ return ret;
+
+ ret = vld_open_volume_by_num (dp, volid, &vol);
+ if (ret)
+ return ret;
+
+ ret = vld_db_uptodate (vol);
+ assert (ret == 0);
+
+ fid.Volume = volid;
+ fid.Vnode = fid.Unique = 1;
+
+ ret = mnode_find (&fid, &m);
+ assert (ret == 0);
+ ret = add_tree (vol, m, path);
+ assert (ret == 0);
+
+ vld_free (vol);
+
+ return ret;
+}
diff --git a/usr.sbin/afs/src/milko/lib/vld/mdir.c b/usr.sbin/afs/src/milko/lib/vld/mdir.c
new file mode 100644
index 00000000000..4db507da085
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/mdir.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * Interface to fdir directory handling routines
+ */
+
+#include <config.h>
+
+RCSID("$Id: mdir.c,v 1.1 2000/09/11 14:41:17 art Exp $");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include <fs.h>
+#include <rx/rx.h>
+#include <fbuf.h>
+#include <fdir.h>
+
+#include <mdir.h>
+
+
+int
+mdir_lookup (struct mnode *node, VenusFid *dir, const char *name, VenusFid *file)
+{
+ fbuf the_fbuf;
+ int ret, saved_ret;
+
+ assert (node->flags.sbp);
+ assert (node->flags.fdp);
+
+ ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size,
+ FBUF_READ|FBUF_PRIVATE);
+ if (ret)
+ return ret;
+
+ saved_ret = fdir_lookup (&the_fbuf, dir, name, file);
+
+ ret = fbuf_end (&the_fbuf);
+ if (ret)
+ return ret;
+
+ return saved_ret;
+}
+
+int
+mdir_emptyp (struct mnode *node)
+{
+ fbuf the_fbuf;
+ int ret, saved_ret;
+
+ assert (node->flags.sbp);
+ assert (node->flags.fdp);
+
+ ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size,
+ FBUF_READ|FBUF_PRIVATE);
+ if (ret)
+ return ret;
+
+ saved_ret = fdir_emptyp (&the_fbuf);
+
+ ret = fbuf_end (&the_fbuf);
+ if (ret)
+ return ret;
+
+ return saved_ret;
+}
+
+int
+mdir_readdir (struct mnode *node,
+ void (*func)(VenusFid *, const char *, void *),
+ void *arg,
+ VenusFid *dir)
+{
+ fbuf the_fbuf;
+ int ret, saved_ret;
+
+ assert (node->flags.sbp);
+ assert (node->flags.fdp);
+
+ ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size,
+ FBUF_READ|FBUF_PRIVATE);
+ if (ret)
+ return ret;
+
+ saved_ret = fdir_readdir (&the_fbuf, func, arg, dir);
+
+ ret = fbuf_end (&the_fbuf);
+ if (ret)
+ return ret;
+
+ return saved_ret;
+}
+
+
+int
+mdir_creat (struct mnode *node,
+ const char *filename,
+ AFSFid fid)
+{
+ fbuf the_fbuf;
+ int ret, saved_ret;
+ int32_t len;
+
+ assert (node->flags.sbp);
+ assert (node->flags.fdp);
+
+ ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret)
+ return ret;
+
+ saved_ret = fdir_creat (&the_fbuf, filename, fid);
+
+ if (ret == 0) {
+ len = fbuf_len (&the_fbuf);
+ mnode_update_size (node, &len);
+ }
+
+ ret = fbuf_end (&the_fbuf);
+ if (ret)
+ return ret;
+
+ return saved_ret;
+}
+
+
+int
+mdir_remove (struct mnode *node,
+ const char *name)
+{
+ fbuf the_fbuf;
+ int ret, saved_ret;
+ int32_t len;
+
+ assert (node->flags.sbp);
+ assert (node->flags.fdp);
+
+ ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret)
+ return ret;
+
+ saved_ret = fdir_remove (&the_fbuf, name, NULL);
+
+ if (ret == 0) {
+ len = fbuf_len (&the_fbuf);
+ mnode_update_size (node, &len);
+ }
+
+ ret = fbuf_end (&the_fbuf);
+ if (ret)
+ return ret;
+
+ return saved_ret;
+}
+
+int
+mdir_mkdir (struct mnode *node,
+ AFSFid dot,
+ AFSFid dot_dot)
+{
+ fbuf the_fbuf;
+ int ret, saved_ret;
+ int32_t len;
+
+ assert (node->flags.sbp);
+ assert (node->flags.fdp);
+
+ ret = fbuf_create (&the_fbuf, node->fd, node->sb.st_size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+ if (ret)
+ return ret;
+
+ saved_ret = fdir_mkdir (&the_fbuf, dot, dot_dot);
+
+ if (ret == 0) {
+ len = fbuf_len (&the_fbuf);
+ mnode_update_size (node, &len);
+ }
+
+ ret = fbuf_end (&the_fbuf);
+ if (ret)
+ return ret;
+
+ return saved_ret;
+}
+
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/mdir.h b/usr.sbin/afs/src/milko/lib/vld/mdir.h
new file mode 100644
index 00000000000..13a56aa9d00
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/mdir.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: mdir.h,v 1.1 2000/09/11 14:41:17 art Exp $ */
+
+/*
+ * Interface to fdir directory handling routines
+ */
+
+/* $Id: mdir.h,v 1.1 2000/09/11 14:41:17 art Exp $ */
+
+#ifndef _MDIR_H_
+#define _MDIR_H_
+
+#include <fs.h>
+#include <mnode.h>
+
+int
+mdir_lookup (struct mnode *node, VenusFid *dir, const char *name, VenusFid *file);
+
+int
+mdir_emptyp (struct mnode *node);
+
+int
+mdir_readdir (struct mnode *node,
+ void (*func)(VenusFid *, const char *, void *),
+ void *arg,
+ VenusFid *dir);
+
+int
+mdir_creat (struct mnode *node,
+ const char *filename,
+ AFSFid fid);
+
+int
+mdir_remove (struct mnode *node,
+ const char *name);
+
+int
+mdir_mkdir (struct mnode *node,
+ AFSFid dot,
+ AFSFid dot_dot);
+
+#endif /* _MDIR_H_ */
diff --git a/usr.sbin/afs/src/milko/lib/vld/mnode.c b/usr.sbin/afs/src/milko/lib/vld/mnode.c
new file mode 100644
index 00000000000..b7cd34c9382
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/mnode.c
@@ -0,0 +1,274 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * A module for caching of mnodes.
+ *
+ * Mnodes contain unix and afs structs to to aid in the conversion
+ * inbeteen. It also has the feature that data is never allocated.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: mnode.c,v 1.1 2000/09/11 14:41:17 art Exp $");
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <assert.h>
+
+#include <roken.h>
+#include <err.h>
+
+#include <list.h>
+#include <hash.h>
+
+#include <mnode.h>
+
+List *mnode_lru; /* least recently used on tail, ref == 0 */
+
+Hashtab *mnode_htab; /* hash of all valid nodes */
+
+unsigned long mnode_nodes; /* number of nodes in system */
+unsigned long mnode_numfree; /* number of free nodes in system */
+
+/*
+ * find out if two nodes `n1' and `n2' are the same
+ */
+
+static int
+mnode_cmp (void *n1, void *n2)
+{
+ struct mnode *rn1 = (struct mnode *)n1;
+ struct mnode *rn2 = (struct mnode *)n2;
+
+ return rn1->fid.Volume != rn1->fid.Volume
+ || rn1->fid.Vnode != rn2->fid.Vnode
+ || rn1->fid.Unique != rn2->fid.Unique;
+}
+
+/*
+ * calculate a uniq hashvalue for `node'
+ */
+
+static unsigned
+mnode_hash(void *node)
+{
+ struct mnode *n = (struct mnode *)node;
+ return n->fid.Volume + n->fid.Vnode;
+}
+
+/*
+ * The init function for the mnode cache
+ */
+
+void
+mnode_init (unsigned num)
+{
+ struct mnode *nodes = calloc (sizeof(struct mnode), num);
+ int i;
+
+ mnode_numfree = mnode_nodes = num;
+
+ if (nodes == NULL)
+ errx (1, "mnode_init: calloc failed");
+
+ mnode_lru = listnew();
+ if (mnode_lru == NULL)
+ errx (1, "mnode_init: listnew returned NULL");
+
+ for (i = 0; i < num ;i++) {
+ nodes[i].li = listaddhead (mnode_lru, &nodes[i]);
+ assert(nodes[i].li);
+ }
+ mnode_htab = hashtabnew (num * 2, /* XXX */
+ mnode_cmp,
+ mnode_hash);
+ if (mnode_htab == NULL)
+ errx (1, "mnode_init: hashtabnew returned NULL");
+}
+
+/*
+ * reset a mnode `res' to a new `fid'
+ */
+
+static void
+reset_node (struct mnode *n, const AFSFid *fid)
+{
+ assert (n->flags.fdp == FALSE);
+ memset (n, 0, sizeof (*n));
+ n->fid = *fid;
+}
+
+/*
+ * find the `fid' the the hashtable, if it isn't
+ * there use an entry on the lru.
+ *
+ *
+ * XXX fix end of nodes problem.
+ */
+
+int
+mnode_find (const AFSFid *fid, struct mnode **node)
+{
+ struct mnode ptr, *res;
+
+ ptr.fid = *fid;
+
+ res = hashtabsearch (mnode_htab, &ptr);
+
+ if (res) {
+ if (res->li)
+ listdel (mnode_lru, res->li);
+ if (res->ref == 0)
+ mnode_numfree--;
+ res->ref++;
+ } else if (mnode_numfree != 0) {
+ res = listdeltail (mnode_lru); assert (res);
+ assert (res->ref == 0);
+ hashtabdel (mnode_htab, res);
+ reset_node (res, fid);
+ hashtabadd (mnode_htab, res);
+ res->ref++;
+ } else {
+ /* XXX */
+ abort();
+ }
+ *node = res;
+ res->li = listaddhead (mnode_lru, *node);
+ return 0;
+}
+
+/*
+ * Free the `node'. If the node has gone bad (something has failed
+ * that shouldn't) its marked bad and things are uncached.
+ */
+
+void
+mnode_free (struct mnode *node, Bool bad)
+{
+ if (node->li)
+ listdel (mnode_lru, node->li);
+ /*
+ bad -> reread
+ 0 -> close
+ */
+
+ if (bad) {
+ if (node->flags.fdp)
+ close (node->fd);
+ memset (&node->flags, 0, sizeof (node->flags));
+ }
+ if (--node->ref == 0) {
+ if (node->flags.fdp) {
+ close (node->fd);
+ node->flags.fdp = FALSE;
+ }
+ mnode_numfree++;
+ }
+
+ node->li = listaddhead (mnode_lru, node);
+}
+
+/*
+ *
+ */
+
+void
+mnode_remove (const AFSFid *fid)
+{
+ struct mnode ptr, *res;
+
+ ptr.fid = *fid;
+
+ res = hashtabsearch (mnode_htab, &ptr);
+ if (res) {
+ if (res->ref == 0 && res->flags.fdp) {
+ close (res->fd);
+ res->flags.fdp = FALSE;
+ }
+ if (res->li)
+ listdel (mnode_lru, res->li);
+ res->li = listaddhead (mnode_lru, res);
+ mnode_numfree++;
+ }
+}
+
+/*
+ * always update the node `n' to reflect the size `len' or
+ * if `len' isn't given use the fd in `n'.
+ */
+
+int
+mnode_update_size (struct mnode *n, int32_t *len)
+{
+ int ret;
+
+ if (len) {
+ n->fs.Length = n->sb.st_size = *len;
+ } else {
+ assert (n->flags.fdp);
+
+ ret = fstat (n->fd, &n->sb);
+ if (ret)
+ return errno;
+ n->flags.sbp = TRUE;
+ n->fs.Length = n->sb.st_size;
+ }
+
+ return 0;
+}
+
+/*
+ * Update the size in `n' if the stat information in `n->sb' has
+ * changed. If there is no stat information call ``vld_update_size''.
+ */
+
+int
+mnode_update_size_cached (struct mnode *n)
+{
+ if (n->flags.sbp == FALSE) {
+ assert (n->flags.fdp);
+ return mnode_update_size (n, NULL);
+ }
+
+ n->fs.Length = n->sb.st_size;
+ return 0;
+}
diff --git a/usr.sbin/afs/src/milko/lib/vld/mnode.h b/usr.sbin/afs/src/milko/lib/vld/mnode.h
new file mode 100644
index 00000000000..2ecb715fc91
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/mnode.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: mnode.h,v 1.1 2000/09/11 14:41:17 art Exp $ */
+
+#ifndef MILKO_MNODE_H
+#define MILKO_MNODE_H 1
+
+#include <sys/types.h>
+
+#include <fs.h>
+#include <pts.h>
+#include <voldb.h>
+
+#include <list.h>
+
+typedef enum { VOLOP_READ = 0x001, /* read file */
+ VOLOP_WRITE = 0x002, /* write file */
+ VOLOP_INSERT = 0x004, /* insert file */
+ VOLOP_LOOKUP = 0x008, /* lookup fileentry */
+ VOLOP_DELETE = 0x010, /* delete entry */
+ VOLOP_LOCK = 0x020, /* lock file */
+ VOLOP_ADMIN = 0x040, /* modify bits */
+ VOLOP_GETSTATUS = 0x080, /* get status */
+ VOLOP_PARENT = 0x100, /* this is a parent */
+ VOLOP_NOCHECK = 0x200 /* do no check */
+} volop_flags ;
+
+struct mnode {
+ int fd;
+ int ref; /* reference counter */
+ struct stat sb; /* the status of the node */
+ AFSFetchStatus fs; /* fetchstatus */
+ AFSFid fid; /* only valid if on hashtable */
+ struct voldb_entry e; /* entry information */
+ struct {
+ unsigned usedp:1; /* if node is used */
+ unsigned fdp:1; /* if fd is open */
+ unsigned sbp:1; /* if stat sb is valid */
+ unsigned fsp:1; /* if afsfetchstatus fs is valid */
+ unsigned ep:1; /* if voldb entry is valid */
+ } flags;
+ Listitem *li; /* where we are placed in the mnode_lru */
+};
+
+struct msec {
+ struct fs_security_context *sec; /* security context */
+ int32_t caller_access; /* access of caller */
+ int32_t anonymous_access; /* anonymous access */
+ volop_flags flags; /* what we want to do with the node */
+ int loop; /* to detect loop */
+};
+
+struct fs_security_context {
+ prlist *cps; /* current proctection set */
+ int32_t uid; /* user id of caller */
+ int ref; /* reference counter */
+};
+
+void
+mnode_init (unsigned num);
+
+int
+mnode_find (const AFSFid *fid, struct mnode **node);
+
+void
+mnode_free (struct mnode *node, Bool bad);
+
+void
+mnode_remove (const AFSFid *fid);
+
+int
+mnode_update_size_cached (struct mnode *);
+
+int
+mnode_update_size (struct mnode *, int32_t *len);
+
+#endif /* MILKO_MNODE_H */
diff --git a/usr.sbin/afs/src/milko/lib/vld/salvage.c b/usr.sbin/afs/src/milko/lib/vld/salvage.c
new file mode 100644
index 00000000000..03552f3898f
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/salvage.c
@@ -0,0 +1,800 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <config.h>
+
+RCSID("$Id: salvage.c,v 1.1 2000/09/11 14:41:17 art Exp $");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include <fs.h>
+#include <rx/rx.h>
+#include <fbuf.h>
+#include <fdir.h>
+
+#include <vld.h>
+#include <afs_dir.h>
+
+#include <mlog.h>
+#include <mdebug.h>
+
+#include <salvage.h>
+
+
+struct inodeinfo {
+ struct inodeinfo *parentp, *childp, *siblingp;
+ struct inodeinfo *lfnodes;
+ int32_t inode_num;
+ int32_t parent_num;
+ int32_t parent_unique;
+ int32_t filetype;
+ int32_t num_indir;
+ struct { /* misc dir related flags */
+ unsigned dot:1; /* have a "." */
+ unsigned dotdot:1; /* have a ".." */
+ unsigned invalid_dot:1; /* . doesn't point to this node */
+ unsigned invalid_dotdot:1; /* .. doesn't point to this node */
+ unsigned no_data:1; /* this node doesn't have data */
+ } flags;
+ enum { IUNUSED = 0, /* not used */
+ IFOUND, /* is used */
+ ITREE, /* node-tree correct */
+ IDIR, /* exists in a directory tree */
+ IFREE } status;
+};
+
+enum { SALVAGE_RN_WRITE = 1, SALVAGE_RN_UNUSED = 2 };
+
+struct vinfo {
+ unsigned nnodes; /* number of nodes in array */
+ unsigned fsize; /* # of allocated file nodes */
+ unsigned dsize; /* # of allocated dir nodes */
+ struct inodeinfo **nodes; /* XXX add a hash */
+};
+
+/*
+ *
+ */
+
+static struct inodeinfo *
+find_node (struct vinfo *info, int32_t inode)
+{
+ u_int32_t i;
+ assert (info);
+
+ for (i = 0; i < info->nnodes; i++) {
+ if (info->nodes[i]->inode_num == inode)
+ return info->nodes[i];
+ }
+ return NULL;
+}
+
+/*
+ * Allocate a new node, if there isn't room the the table make room
+ * for it.
+ */
+
+static struct inodeinfo *
+allocate_node (struct vinfo *info, int32_t ino, int type)
+{
+ struct inodeinfo *n;
+ unsigned oldsize, i;
+
+ n = find_node (info, ino);
+ assert (n == NULL);
+ assert (info->nnodes >= info->fsize + info->dsize);
+
+ if (info->nnodes == info->fsize + info->dsize) {
+ oldsize = info->nnodes;
+ if (info->nnodes == 0)
+ info->nnodes = 1;
+ info->nodes = erealloc (info->nodes,
+ info->nnodes * 2 * sizeof(struct inodeinfo *));
+ info->nnodes = info->nnodes * 2;
+
+ for (i = oldsize; i < info->nnodes; i++) {
+ n = emalloc (sizeof(struct inodeinfo));
+ memset (n, 0, sizeof(struct inodeinfo));
+ info->nodes[i] = n;
+ }
+ }
+ n = info->nodes[info->fsize + info->dsize];
+ switch (type) {
+ case TYPE_FILE:
+ ++info->fsize;
+ break;
+ case TYPE_DIR:
+ ++info->dsize;
+ break;
+ default:
+ abort();
+ }
+ return n;
+}
+
+/*
+ *
+ */
+
+static void
+free_vinfo (struct vinfo *info)
+{
+ unsigned i;
+
+ for (i = 0; i < info->nnodes; i++)
+ free (info->nodes[i]);
+ free (info->nodes);
+}
+
+
+/*
+ *
+ */
+
+static int
+opennode (volume_handle *vol, struct vinfo *info, struct inodeinfo *node,
+ int (*func) (volume_handle *, struct vinfo *,
+ struct inodeinfo *, int, size_t))
+{
+ struct mnode *n;
+ struct msec m;
+ VenusFid fid;
+ int ret;
+
+ fid.Cell = 0;
+ fid.fid.Volume = VLD_VOLH_NUM(vol);
+ fid.fid.Vnode = node->inode_num;
+ fid.fid.Unique = 0;
+
+ mlog_log (MDEBSALVAGE, "opennode %u.%u",
+ fid.fid.Volume, fid.fid.Vnode);
+
+ memset (&n, 0, sizeof(n));
+
+ mnode_find (&fid.fid, &n);
+
+ m.flags = VOLOP_WRITE|VOLOP_GETSTATUS|VOLOP_NOCHECK;
+
+ ret = vld_open_vnode (vol, n, &m);
+ if (ret) {
+ mlog_log (MDEBSALVAGE, "opennode %u.%u: failed to open node",
+ fid.fid.Volume, fid.fid.Vnode);
+ node->flags.no_data = 1;
+ mnode_free (n, FALSE);
+ return 1;
+ }
+
+ if (func) {
+ ret = (*func) (vol, info, node, n->fd, n->sb.st_size);
+ }
+
+ mnode_free (n, FALSE);
+ return ret;
+}
+
+/*
+ *
+ */
+
+#define CHECK_VALUE_EQ(check_val,val,string,modified) \
+do { \
+ if ((val) != (check_val)) { \
+ (check_val) = (val); \
+ (modified) = 1; \
+ mlog_log (MDEBSALVAGE, "%s had a errorous value resetting", string); \
+ } \
+} while (0)
+
+#define CHECK_VALUE_BITMASK(check_val,val,mask,string,modified) \
+do { \
+ if (((~(mask) & (check_val)) & ~(val)) != 0) { \
+ (check_val) &= (val) + (~(mask) & (check_val)); \
+ (modified) = 1; \
+ mlog_log (MDEBSALVAGE, "%s had a errorous value resetting", string); \
+ } \
+} while (0)
+
+#define SET_VALUE_BITMASK(check_val,val,defval,string,modified) \
+do { \
+ if (((check_val) & (val)) == 0) { \
+ (check_val) |= (defval); \
+ (modified) = 1; \
+ mlog_log (MDEBSALVAGE, "%s had a missing value setting", string); \
+ } \
+} while (0)
+
+/*
+ *
+ */
+
+static int
+read_nodes_dir (u_int32_t num, struct voldb_entry *entry,
+ struct vinfo *info, struct inodeinfo **ret_node)
+{
+ struct inodeinfo *node;
+ int mod = 0;
+
+ assert (entry->type == TYPE_DIR);
+
+ if (entry->u.dir.FileType == 0 || entry->u.file.nextptr != 0) {
+ mlog_log (MDEBSALVAGE, "%d is a unused node (dir)", num);
+ return SALVAGE_RN_UNUSED;
+ }
+
+
+ CHECK_VALUE_EQ(entry->u.dir.InterfaceVersion,1, "InterfaceVersion",mod);
+ CHECK_VALUE_BITMASK(entry->u.dir.UnixModeBits,047777, 0777777,
+ "Unix rights",mod);
+ SET_VALUE_BITMASK(entry->u.dir.UnixModeBits,040000,040000,
+ "Directory bit",mod);
+
+ CHECK_VALUE_EQ(entry->u.dir.FileType,TYPE_DIR,"FileType",mod);
+
+ node = allocate_node (info, dir_local2afs(num), TYPE_DIR);
+ node->inode_num = dir_local2afs (num);
+ node->parent_num = entry->u.dir.ParentVnode;
+ node->parent_unique = entry->u.dir.ParentUnique;
+ if (entry->u.dir.nextptr)
+ node->status = IUNUSED;
+ else
+ node->status = IFOUND;
+ node->filetype = TYPE_DIR;
+
+ *ret_node = node;
+
+ if (mod)
+ return SALVAGE_RN_WRITE;
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+read_nodes_file (u_int32_t num, struct voldb_entry *entry,
+ struct vinfo *info, struct inodeinfo **ret_node)
+{
+ struct inodeinfo *node;
+ int mod = 0;
+
+ if (entry->u.file.FileType == 0 || entry->u.file.nextptr != 0) {
+ mlog_log (MDEBSALVAGE, "%d is a unused node (file)", num);
+ return 0; /* XXX ? */
+ }
+
+ CHECK_VALUE_EQ(entry->u.file.InterfaceVersion,1, "InterfaceVersion",mod);
+ CHECK_VALUE_BITMASK(entry->u.file.UnixModeBits,047777, 0777777,
+ "Unix rights",mod);
+ SET_VALUE_BITMASK(entry->u.file.UnixModeBits,0120000,0100000,
+ "Directory bit",mod);
+
+ switch (entry->u.file.FileType) {
+ case TYPE_FILE:
+ case TYPE_LINK:
+ break;
+ default:
+ CHECK_VALUE_EQ(entry->u.file.FileType,TYPE_FILE,"FileType",mod);
+ }
+
+ node = allocate_node (info, file_local2afs(num), TYPE_FILE);
+ node->inode_num = file_local2afs(num);
+ node->parent_num = entry->u.file.ParentVnode;
+ node->parent_unique = entry->u.file.ParentUnique;
+ if (entry->u.file.nextptr != 0)
+ node->status = IUNUSED;
+ else
+ node->status = IFOUND;
+ node->filetype = entry->u.file.FileType;
+
+ if (mod)
+ return SALVAGE_RN_WRITE;
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+read_nodes (struct volume_handle *volh, struct voldb *db,
+ u_int32_t size, struct vinfo *info,
+ int (*func) (u_int32_t, struct voldb_entry *, struct vinfo *,
+ struct inodeinfo **))
+{
+ u_int32_t i;
+ int ret;
+ int changed = 0;
+ int check_data;
+ struct inodeinfo *node;
+
+ for (i = 0; i < size; i++) {
+ struct voldb_entry entry;
+
+ ret = voldb_get_entry (db, i, &entry);
+ if (ret) {
+ mlog_warn (MDEBSALVAGE, ret, "tree_connectivity: "
+ "read_nodes: get_entry failed: %d.%d",
+ voldb_get_volume(db), i);
+ continue;
+ }
+
+ check_data = 0;
+ node = NULL;
+ ret = (*func) (i, &entry, info, &node);
+ switch (ret) {
+ case 0:
+ check_data = 1;
+ break;
+ case SALVAGE_RN_UNUSED:
+ break;
+ case SALVAGE_RN_WRITE:
+ ret = voldb_put_entry (db, i, &entry);
+ if (ret) {
+ mlog_warn (MDEBSALVAGE, ret, "tree_connectivity: "
+ "read_nodes: put_entry failed %d.%d",
+ voldb_get_volume(db), i);
+ }
+ changed = 1;
+ check_data = 1;
+ break;
+ default:
+ abort();
+ }
+ if (check_data && node) {
+ ret = opennode (volh, info, node, NULL);
+ if (ret) {
+ mlog_log (MDEBSALVAGE,
+ "reading node %u.%u: failed to open node",
+ VLD_VOLH_NUM(volh), node->inode_num);
+ node->flags.no_data = 1;
+ }
+ }
+ }
+ if (changed)
+ voldb_flush (db);
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+remove_node (struct volume_handle *volh, struct inodeinfo *node)
+{
+ u_int32_t ino;
+ struct voldb *db;
+
+ if (afs_dir_p (node->inode_num)) {
+ ino = dir_afs2local(node->inode_num);
+ db = VLD_VOLH_DIR(volh);
+ } else {
+ ino = file_afs2local(node->inode_num);
+ db = VLD_VOLH_FILE(volh);
+ }
+ return voldb_del_entry (db, ino, NULL);
+}
+
+/*
+ *
+ */
+
+struct dir_func_s {
+ struct inodeinfo *parent;
+ struct vinfo *info;
+ fbuf *parent_fbuf;
+ struct volume_handle *volh;
+};
+
+static void
+check_dir_func (VenusFid *fid, const char *name, void *arg)
+{
+ struct dir_func_s *f = (struct dir_func_s *)arg;
+ int ret;
+
+ /*
+ * XXX to make sure that the list node->childp and the content of
+ * the directory is right
+ */
+
+ mlog_warnx (MDEBSALVAGE, "check_dir_func: %s %u", name, fid->fid.Vnode);
+
+ if (strcmp (name, ".") == 0) {
+ f->parent->flags.dot = 1;
+ if (f->parent->inode_num != fid->fid.Vnode)
+ f->parent->flags.invalid_dot = 1;
+ } else if (strcmp (name, "..") == 0) {
+ f->parent->flags.dotdot = 1;
+ if (f->parent->parent_num != fid->fid.Vnode
+ || f->parent->parent_unique != fid->fid.Unique)
+ f->parent->flags.invalid_dotdot = 1;
+ } else if (strncmp (name, ".__afs", 6) == 0) {
+ struct inodeinfo *child;
+ ret = fdir_remove (f->parent_fbuf, name, NULL);
+ assert (ret == 0);
+ child = find_node (f->info, fid->fid.Vnode);
+ if (child)
+ remove_node (f->volh, child);
+ } else {
+ struct inodeinfo *child;
+
+ child = find_node (f->info, fid->fid.Vnode);
+ if (child == NULL || child->flags.no_data) {
+ mlog_log (MDEBSALVAGE,
+ "name `%s' found in %d.%d w/o node, removing",
+ name, fid->fid.Volume, f->parent->inode_num);
+ ret = fdir_remove (f->parent_fbuf, name, NULL);
+ if (ret != 0)
+ mlog_log (MDEBSALVAGE,
+ "removal of lost name `%s' failed in %d.%d with %d",
+ name, fid->fid.Volume, f->parent->inode_num, ret);
+ if (child)
+ remove_node (f->volh, child);
+ } else {
+ child->status = IDIR;
+
+ ++child->num_indir;
+
+ if (strchr (name, '/')) {
+ abort(); /* XXX check name better */
+ }
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static int
+check_content_dir_func (volume_handle *vol,
+ struct vinfo *info,
+ struct inodeinfo *node,
+ int fd,
+ size_t size)
+{
+ VenusFid fid;
+ fbuf the_fbuf;
+ struct dir_func_s f;
+ int ret;
+
+ if ((size % AFSDIR_PAGESIZE) != 0) {
+ mlog_log (MDEBSALVAGE, "check_content_dir_func: dir has wrong size");
+ ret = ftruncate (fd, size / AFSDIR_PAGESIZE);
+ if (ret != 0) {
+ mlog_log (MDEBSALVAGE,
+ "check_content_dir_func: ftruncate: %d",
+ errno);
+ return 1;
+ }
+ }
+
+ if (node->inode_num == 1)
+ node->status = IDIR;
+
+ fid.Cell = 0;
+ fid.fid.Volume = VLD_VOLH_NUM(vol);
+
+ f.info = info;
+ f.parent = node;
+ f.parent_fbuf = &the_fbuf;
+ f.volh = vol;
+
+ ret = fbuf_create (&the_fbuf, fd, size,
+ FBUF_READ|FBUF_WRITE|FBUF_SHARED);
+
+ ret = fdir_readdir (&the_fbuf, check_dir_func, &f, &fid);
+ if (ret)
+ mlog_log (MDEBSALVAGE, "check_content_dir_func: fbuf_readdir failed");
+
+ fbuf_end (&the_fbuf);
+ return ret;
+}
+
+/*
+ * Check that the `node' in `volume' have a sane content.
+ */
+
+static int
+check_dir (volume_handle *vol, struct vinfo *info, struct inodeinfo *node)
+{
+ int ret;
+
+ ret = opennode (vol, info, node, check_content_dir_func);
+ if (ret) {
+ mlog_log (MDEBSALVAGE, "check_dir failed with %d", ret);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+add_node_lf (struct volume_handle *volh,
+ struct inodeinfo *node)
+{
+ mlog_log (MDEBSALVAGE, "XXX add node to lost and found %u.%u",
+ voldb_get_volume (VLD_VOLH_DIR(volh)), node->inode_num);
+#if 0
+ /* XXX */
+ abort();
+#endif
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+readd_node (struct volume_handle *volh,
+ struct inodeinfo *node)
+{
+ mlog_log (MDEBSALVAGE, "XXX add node to tree again %u.%u",
+ voldb_get_volume (VLD_VOLH_DIR(volh)), node->inode_num);
+#if 0
+ /* XXX */
+ abort();
+#endif
+ return 0;
+}
+
+/*
+ *
+ */
+
+static void
+find_and_readd_node (struct volume_handle *volh,
+ struct vinfo *info,
+ int foundnodes)
+{
+ int i;
+
+ for (i = 0; i < foundnodes; i++) {
+ switch (info->nodes[i]->status) {
+ case IDIR:
+ if (info->nodes[i]->filetype == TYPE_DIR)
+ /* XXX check tree consistency */
+ ;
+ /* XXX check linkcount */
+ break;
+ case ITREE:
+ if (readd_node (volh, info->nodes[i]))
+ add_node_lf (volh, info->nodes[i]);
+ break;
+ case IUNUSED:
+ break;
+ case IFOUND:
+ default:
+ abort();
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static void
+mark_dir_node (struct volume_handle *volh,
+ struct vinfo *info,
+ int foundnodes)
+{
+ int i;
+
+ for (i = 0; i < foundnodes; i++) {
+ switch (info->nodes[i]->status) {
+ case IDIR:
+ case ITREE:
+ if (info->nodes[i]->filetype == TYPE_DIR)
+ check_dir (volh, info, info->nodes[i]);
+ break;
+ case IUNUSED:
+ break;
+ case IFOUND:
+ default:
+ abort();
+ }
+ }
+}
+
+/*
+ *
+ */
+
+static void
+find_list_tree_nodes (struct volume_handle *volh,
+ struct vinfo *info,
+ int foundnodes)
+{
+ int i;
+ int db_flush = 0;
+
+ for (i = 0; i < foundnodes; i++) {
+ switch (info->nodes[i]->status) {
+ case ITREE:
+ if (info->nodes[i]->flags.no_data) {
+ remove_node (volh, info->nodes[i]);
+ db_flush = 1;
+ }
+ break;
+ case IFOUND:
+ /*
+ * this is a lost node
+ * XXX attach it to the lost+found directory
+ */
+
+ mlog_log (MDEBSALVAGE, "lost inode found");
+
+ /* XXX make sure is on the lfnodes list */
+
+ if (info->nodes[i]->flags.no_data) {
+ remove_node (volh, info->nodes[i]);
+ db_flush = 1;
+ } else if (readd_node (volh, info->nodes[i])) {
+ add_node_lf (volh, info->nodes[i]);
+ }
+
+ break;
+ case IUNUSED:
+ break;
+ case IDIR:
+ default:
+ abort();
+ }
+ }
+ if (db_flush)
+ vld_db_flush (volh);
+}
+
+/*
+ *
+ */
+
+int
+salvage_volume (struct volume_handle *volh)
+{
+ u_int32_t dsize, fsize;
+ u_int32_t foundnodes;
+ int ret, i;
+ struct vinfo info;
+ struct inodeinfo *lfnodes;
+
+ memset (&info, 0, sizeof(info));
+
+ /* XXX check volintInfo */
+
+ ret = vld_db_uptodate (volh);
+ if (ret) {
+ mlog_warnx (MDEBERROR, "tree_connectity: vld_db_uptodate"
+ "failed with %d on volume %u",
+ ret, VLD_VOLH_NUM(volh));
+ return ret;
+ }
+
+ ret = voldb_header_info(VLD_VOLH_DIR(volh), &dsize, NULL);
+ if (ret) {
+ mlog_warnx (MDEBERROR, "tree_connectity: voldb_header_info "
+ "failed with %d on volume %u (dir)",
+ ret, VLD_VOLH_NUM(volh));
+ return ret;
+ }
+
+ ret = voldb_header_info(VLD_VOLH_FILE(volh), &fsize, NULL);
+ if (ret) {
+ mlog_warnx (MDEBERROR, "tree_connectity: voldb_header_info "
+ "failed with %d on volume %u (file)",
+ ret, VLD_VOLH_NUM(volh));
+ return ret;
+ }
+
+ ret = read_nodes (volh,
+ VLD_VOLH_DIR(volh),
+ dsize,
+ &info,
+ read_nodes_dir);
+ if (ret)
+ abort(); /* XXX */
+ ret = read_nodes (volh,
+ VLD_VOLH_FILE(volh),
+ fsize,
+ &info,
+ read_nodes_file);
+ if (ret)
+ abort(); /* XXX */
+
+ mlog_log (MDEBSALVAGE,
+ "tree_connectvity: status: found %d dirs, %d files",
+ info.dsize, info.fsize);
+
+ foundnodes = info.dsize + info.fsize;
+
+ for (i = 0; i < foundnodes; i++) {
+ struct inodeinfo *p, *n = info.nodes[i] ;
+
+ /* Skip root node */
+ if (i == 0) {
+ n->status = ITREE;
+ continue;
+ }
+
+ p = find_node (&info, n->parent_num);
+ if (p == NULL) {
+ mlog_log (MDEBSALVAGE, "tree_connectivity: lost node %u.%u",
+ VLD_VOLH_NUM(volh), i);
+ info.nodes[i]->lfnodes = lfnodes;
+ lfnodes = info.nodes[i];
+ } else {
+ if (n->parentp) {
+ struct inodeinfo **old_p = &n->parentp->childp;
+
+ /*
+ * Old parent, obviois something wrong. Let's remove
+ * the node from the old parent.
+ */
+
+ mlog_log (MDEBSALVAGE, "tree_connectivity: have a old parent");
+ while (*old_p != NULL || *old_p != n)
+ old_p = &(*old_p)->siblingp;
+ if (*old_p == NULL) /* Not on old parent\s child list, wrong */
+ abort();
+ *old_p = (*old_p)->siblingp;
+ }
+ n->status = ITREE;
+ n->siblingp = p->childp;
+ p->childp = n;
+ n->parentp = p;
+ }
+ }
+
+ find_list_tree_nodes (volh, &info, foundnodes);
+ mark_dir_node (volh, &info, foundnodes);
+ find_and_readd_node (volh, &info, foundnodes);
+
+ free_vinfo (&info);
+ return 0;
+}
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/salvage.h b/usr.sbin/afs/src/milko/lib/vld/salvage.h
new file mode 100644
index 00000000000..11d4f2c1995
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/salvage.h
@@ -0,0 +1,48 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: salvage.h,v 1.1 2000/09/11 14:41:17 art Exp $ */
+
+#ifndef MILKO_SALVAGE_H
+#define MILKO_SALVAGE_H 1
+
+int
+salvage_volume (struct volume_handle *volh);
+
+#endif /* MILKO_SALVAGE_H */
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/sfvol_private.h b/usr.sbin/afs/src/milko/lib/vld/sfvol_private.h
new file mode 100644
index 00000000000..903e1e6dc49
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/sfvol_private.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <atypes.h>
+
+#include <rx/rx.h>
+
+#include <pts.h>
+#include <dpart.h>
+#include <vld.h>
+
+#include <assert.h>
+
+#include <fvol.h>
+#include <svol.h>
+
+/*
+ * Prototypes
+ */
+
+int local_create_name (struct dp_part *dp, int32_t num,
+ char *name, size_t sz);
+int local_create_file (struct dp_part *dp, onode_opaque *o,
+ struct mnode *n);
+int local_open_file (struct dp_part *dp, onode_opaque *opaque,
+ int flags, int *fd);
+int local_unlink_file (struct dp_part *dp, onode_opaque *o);
+Bool local_opaquep (onode_opaque *opaque);
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/svol.c b/usr.sbin/afs/src/milko/lib/vld/svol.c
new file mode 100644
index 00000000000..971365802c9
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/svol.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <sfvol_private.h>
+
+RCSID("$Id: svol.c,v 1.1 2000/09/11 14:41:17 art Exp $");
+
+/*
+ * Description:
+ * svol is a simple (and dumb (and slow)) implementation of volume-
+ * operations. It store the files in a tree-structure where
+ * inode-number is used as ``key'' to where the node is stored in
+ * the tree.
+ */
+
+/*
+ * Create a svol and return it in `vol' that is generic volume.
+ * ignore the flags.
+ */
+
+static int
+svol_open (struct dp_part *part, int32_t volid, int flags,
+ void **data)
+{
+ *data = NULL;
+
+ return 0;
+}
+
+/*
+ * free all svol related to the volume `vol'.
+ */
+
+static void
+svol_free (volume_handle *vol)
+{
+ assert (vol->data == NULL);
+}
+
+/*
+ * create a inode on `vol', return onode_opaque in `o'.
+ */
+
+static int
+svol_icreate (volume_handle *vol, onode_opaque *o, node_type type,
+ struct mnode *n)
+{
+ return local_create_file (vol->dp, o, n);
+}
+
+/*
+ * open `o' in `vol' with open(2) `flags', return filedescriptor in `fd'
+ */
+
+static int
+svol_iopen (volume_handle *vol, onode_opaque *o, int flags, int *fd)
+{
+ return local_open_file (vol->dp, o, flags, fd);
+}
+
+static int
+svol_unlink (volume_handle *vol, onode_opaque *o)
+{
+ return local_unlink_file (vol->dp, o);
+}
+
+/*
+ *
+ */
+
+static int
+svol_remove (volume_handle *vol)
+{
+ /*
+ * We don't need to remove anything since we never created anything.
+ * There might be reson to try and keed track of all nodes to be able
+ * to remove lost nodes. But then, this wouldn't be the simple volume.
+ */
+
+ svol_free (vol);
+ return 0;
+}
+
+/*
+ *
+ */
+
+vol_op svol_volume_ops = {
+ "svol",
+ svol_open,
+ svol_free,
+ svol_icreate,
+ svol_iopen,
+ svol_unlink,
+ svol_remove
+};
diff --git a/usr.sbin/afs/src/milko/lib/vld/svol.h b/usr.sbin/afs/src/milko/lib/vld/svol.h
new file mode 100644
index 00000000000..f58f4100b38
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/svol.h
@@ -0,0 +1 @@
+extern vol_op svol_volume_ops;
diff --git a/usr.sbin/afs/src/milko/lib/vld/vld.c b/usr.sbin/afs/src/milko/lib/vld/vld.c
new file mode 100644
index 00000000000..388db77257f
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/vld.c
@@ -0,0 +1,1860 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: vld.c,v 1.1 2000/09/11 14:41:17 art Exp $ */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include <assert.h>
+
+#include <rx/rx.h>
+
+#include <vldb.h>
+#include <pts.h>
+
+#include <voldb.h>
+#include <vld.h>
+#include <vld_ops.h>
+
+#include <vstatus.h>
+
+#include <svol.h>
+#include <fvol.h>
+
+#include <mdir.h>
+
+#include <err.h>
+
+#include <hash.h>
+#include <list.h>
+
+#include <mlog.h>
+#include <mdebug.h>
+
+#include <errno.h>
+
+/*
+ * Local define and limitations
+ */
+
+int vld_storestatus_to_ent (struct voldb_entry *e, const AFSStoreStatus *ss,
+ struct msec *sec);
+static int vld_ent_to_fetchstatus (struct voldb_entry *e, struct mnode *n);
+static void vld_set_author(struct voldb_entry *e, struct msec *m);
+static int super_user (struct msec *m);
+
+
+/*
+ * Local variables
+ */
+
+/* hashtable of volumes */
+static Hashtab *volume_htab = NULL;
+static int volume_htab_sz = 1024;
+
+/* lru for db in use */
+static List *db_lru = NULL;
+
+/* list of volumes to be able to do sysbackup and salvage */
+static List *vol_list = NULL;
+
+/* volume types */
+vol_op *backstoretypes[VLD_MAX_BACKSTORE_TYPES];
+
+/*
+ * Useful macro's and short functions
+ */
+
+#define VLD_VALID_BACKSTORETYPE(backstoretype) (!(backstoretype >= 0 && backstoretype < VLD_MAX_BACKSTORE_TYPES && backstoretypes[backstoretype] != NULL))
+
+static int
+VLD_VALID_VOLNAME(const char *volname)
+{
+ while (volname && *volname) {
+ if (!((*volname >= 'a' && *volname <= 'z') ||
+ (*volname >= 'A' && *volname <= 'Z') ||
+ (*volname >= '0' && *volname <= '9') ||
+ *volname == '.'))
+ return *volname;
+ volname++;
+ }
+ return 0;
+}
+
+
+/*
+ * Translate to real-name
+ */
+
+const char *
+vld_backstoretype_name (int32_t backstoretype)
+{
+ if (VLD_VALID_BACKSTORETYPE(backstoretype))
+ return "UKWN";
+
+ return backstoretypes[backstoretype]->name;
+}
+
+/*
+ * Bootstrap
+ */
+
+int
+vld_boot (void)
+{
+ memset(backstoretypes, 0, sizeof (backstoretypes));
+ backstoretypes[VLD_SVOL] = &svol_volume_ops;
+ backstoretypes[VLD_FVOL] = &fvol_volume_ops;
+ return 0;
+}
+
+/*
+ * Free volume `vol'
+ */
+
+void
+vld_free (volume_handle *vol)
+{
+ if (--vol->ref == 0) {
+ VOLOP_FREE(vol);
+ if (vol->flags.voldbp) {
+ voldb_close (VLD_VOLH_DIR(vol));
+ voldb_close (VLD_VOLH_FILE(vol));
+ vol->flags.voldbp = FALSE;
+ } else {
+ assert (VLD_VOLH_DIR(vol) == NULL);
+ assert (VLD_VOLH_FILE(vol) == NULL);
+ }
+ dp_free (vol->dp);
+ free (vol);
+ }
+}
+
+/*
+ * Ref `vol'
+ */
+
+void
+vld_ref (volume_handle *vol)
+{
+ assert (vol->ref);
+ vol->ref++;
+}
+
+/*
+ * create a `vol' from the bootstrap infomation in `vs'.
+ */
+
+static int
+vstatus2volume_handle (vstatus *vs, struct dp_part *dp, volume_handle **vol)
+{
+ volume_handle *v;
+
+ assert (vs && dp && vol);
+
+ v = malloc (sizeof(*v));
+ if (v == NULL)
+ return ENOMEM;
+
+ memset (v, 0, sizeof(*v));
+ v->ref = 1;
+ v->vol = vs->volid;
+ dp_ref (dp);
+ v->dp = dp;
+ memcpy (&v->sino, &vs->volinfoinode, sizeof(vs->volinfoinode));
+ memcpy (&v->dino, &vs->dirinode, sizeof(vs->dirinode));
+ memcpy (&v->fino, &vs->fileinode, sizeof(vs->fileinode));
+ v->flags.infop = FALSE;
+ v->flags.voldbp = FALSE;
+ v->flags.offlinep = FALSE;
+ v->voldbtype = vs->voldbtype;
+ v->type = vs->bstype;
+
+ *vol = v;
+
+ return 0;
+}
+
+/*
+ * Read in all partitions and register all volumes.
+ */
+
+static void
+register_vols_cb (void *data, int fd)
+{
+ struct dp_part *dp = (struct dp_part *)data;
+ vstatus vs;
+ int ret;
+ volume_handle *vol;
+
+ ret = vstatus_read (fd, &vs);
+ if (ret)
+ return;
+
+ ret = vstatus2volume_handle (&vs, dp, &vol);
+ if (ret) {
+ mlog_log (MDEBERROR,
+ "register_vols_cb: failed to convert vstatus");
+ return;
+ }
+
+ ret = VOLOP_OPEN(vol->type, dp, vol->vol,
+ VOLOP_NOFLAGS, &vol->data);
+ if (ret) {
+ mlog_log (MDEBERROR,
+ "register_vols_cb: failed to open volume");
+ vol->flags.attacherr = TRUE;
+ } else {
+ vol->flags.attacherr = FALSE;
+ }
+ vol->flags.offlinep = TRUE;
+ vol->flags.salvaged = FALSE;
+ vol->li = listaddtail (vol_list, vol);
+ if (vol->li == NULL)
+ errx (1, "register_vols_cb: listaddtail failed");
+
+ hashtabadd (volume_htab, vol);
+
+ return;
+}
+
+/*
+ *
+ */
+
+static int
+volume_cmp (void *ptr1, void *ptr2)
+{
+ volume_handle *v1 = (volume_handle *) ptr1;
+ volume_handle *v2 = (volume_handle *) ptr2;
+
+ return v1->vol - v2->vol;
+}
+
+/*
+ *
+ */
+
+static unsigned
+volume_hash (void *ptr)
+{
+ volume_handle *v = (volume_handle *) ptr;
+
+ return v->vol;
+}
+
+/*
+ *
+ */
+
+int
+vld_init (void)
+{
+ struct dp_part *dp;
+ int ret, partnum, i;
+
+
+ db_lru = listnew();
+ if (db_lru == NULL)
+ errx (1, "vld_init: db_lru == NULL");
+
+ for (i = 0; i < 100 /* XXX */ ; i++)
+ listaddhead (db_lru, NULL);
+
+ vol_list = listnew();
+ if (vol_list == NULL)
+ errx (1, "vld_init: vol_list == NULL");
+
+ volume_htab = hashtabnew(volume_htab_sz, volume_cmp, volume_hash);
+ if (volume_htab == NULL)
+ errx (1, "vld_init: volume_htab == NULL");
+
+ for (partnum = 0; partnum < 'z'-'a'; partnum++) {
+
+ ret = dp_create (partnum , &dp);
+ if (ret) {
+ warnx ("vld_init: dp_create(%d) returned %d", partnum, ret);
+ continue;
+ }
+
+ ret = dp_findvol (dp, register_vols_cb, dp);
+ if (ret)
+ warnx ("vld_init: dp_findvol returned: %d", ret);
+
+ dp_free (dp);
+ }
+ return 0;
+}
+
+struct iter_vol_s {
+ int (*func) (volume_handle *vol, void *arg);
+ void *arg;
+};
+
+static int
+iter_vol (List *list, Listitem *li, void *arg)
+{
+ struct iter_vol_s *vof = (struct iter_vol_s *)arg;
+ volume_handle *vol = listdata (li);
+ int ret;
+
+ vld_ref (vol);
+ ret = (vof->func) (vol, vof->arg);
+ vld_free (vol);
+ return ret;
+}
+
+void
+vld_iter_vol (int (*func)(volume_handle *vol, void *arg), void *arg)
+{
+ struct iter_vol_s vof;
+
+ vof.func = func;
+ vof.arg = arg;
+
+ listiter (vol_list, iter_vol, &vof);
+}
+
+/*
+ *
+ */
+
+int
+vld_create_entry (volume_handle *vol, struct mnode *parent, AFSFid *child,
+ int type, const AFSStoreStatus *ss, struct mnode **ret_n,
+ struct msec *m)
+{
+ struct voldb_entry e;
+ onode_opaque child_ino;
+ onode_opaque dummy; /* used when removing when failed */
+ int ret;
+ struct mnode *n;
+ u_int32_t real_mnode, unique;
+ struct voldb *db;
+ int (*convert_local2afs)(int32_t);
+ node_type ntype;
+ time_t now;
+
+ switch (type) {
+ case TYPE_DIR:
+ db = VLD_VOLH_DIR(vol);
+ convert_local2afs = dir_local2afs;
+ ntype = NODE_DIR;
+ break;
+ case TYPE_FILE:
+ case TYPE_LINK:
+ db = VLD_VOLH_FILE(vol);
+ convert_local2afs = file_local2afs;
+ ntype = NODE_REG;
+ break;
+ default:
+ abort();
+ }
+
+ ret = voldb_new_entry (db, &real_mnode, &unique);
+ if (ret)
+ return ret;
+
+ ret = voldb_get_entry (db, real_mnode, &e);
+ if (ret)
+ goto out_bad_icreate;
+
+ e.type = type;
+
+ child->Volume = parent->fid.Volume;
+ child->Vnode = (convert_local2afs)(real_mnode);
+ child->Unique = unique;
+
+ ret = mnode_find (child, &n);
+ if (ret)
+ goto out_bad_icreate;
+
+ ret = VOLOP_ICREATE(vol, &child_ino, ntype, n);
+ if (ret) {
+ mnode_free (n, FALSE);
+ goto out_bad_icreate;
+ }
+
+ if (type == TYPE_DIR) {
+ AFSFid dot, dot_dot;
+
+ dot_dot.Volume = dot.Volume = vol->vol;
+ dot_dot.Vnode = parent->fid.Vnode;
+ dot_dot.Unique = parent->fid.Unique;
+ dot.Vnode = child->Vnode;
+ dot.Unique = child->Unique;
+
+ ret = mdir_mkdir (n, dot, dot_dot);
+ if (ret) {
+ ret = EIO;
+ goto out_bad_put;
+ }
+ }
+
+ now = time(NULL);
+
+ if (type == TYPE_DIR) {
+ e.u.dir.ino = child_ino;
+ e.u.dir.FileType = type;
+ e.u.dir.LinkCount = 2;
+ e.u.dir.DataVersion = now;
+ e.u.dir.ParentVnode = parent->fid.Vnode;
+ e.u.dir.ParentUnique = parent->fid.Unique;
+ memcpy (&e.u.dir.negacl, &parent->e.u.dir.negacl,
+ sizeof(parent->e.u.dir.negacl));
+ memcpy (&e.u.dir.acl, &parent->e.u.dir.acl,
+ sizeof(parent->e.u.dir.acl));
+ } else {
+ e.u.file.ino = child_ino;
+ e.u.file.FileType = type;
+ e.u.file.LinkCount = 1;
+ e.u.file.DataVersion = now;
+ e.u.file.ParentVnode = parent->fid.Vnode;
+ e.u.file.ParentUnique = parent->fid.Unique;
+ }
+
+ voldb_update_time(&e, now);
+ vld_set_author(&e, m);
+
+ ret = vld_storestatus_to_ent (&e, ss, m);
+ if (ret)
+ goto out_bad_put;
+
+ ret = voldb_put_entry (db, real_mnode, &e);
+ if (ret) {
+ ret = EIO;
+ goto out_bad_put;
+ }
+
+ if (type == TYPE_DIR) {
+ ret = voldb_put_acl (db, real_mnode, &e.u.dir);
+ if (ret)
+ goto out_bad_put;
+ }
+
+
+ if (ret_n) {
+ if (m && (m->flags & VOLOP_GETSTATUS) == VOLOP_GETSTATUS) {
+ assert(n->flags.fdp);
+
+ if (n->flags.ep == FALSE) {
+ ret = voldb_get_entry (db, real_mnode, &n->e);
+ if (ret)
+ goto out_bad_put;
+ n->flags.ep = TRUE;
+ }
+
+ ret = vld_ent_to_fetchstatus(&e, n);
+ if (ret)
+ goto out_bad_put;
+ }
+
+ *ret_n = n;
+ } else
+ mnode_free (n, FALSE);
+
+ return 0;
+
+ out_bad_put:
+ mnode_free (n, TRUE);
+ VOLOP_IUNLINK(vol, &child_ino);
+ out_bad_icreate:
+ voldb_del_entry (db, real_mnode, &dummy);
+
+ return ret;
+}
+
+/*
+ *
+ */
+
+int
+vld_set_onode (volume_handle *vol, int32_t vno, onode_opaque *new,
+ onode_opaque *old)
+{
+ int32_t real_mnode;
+ struct voldb_entry e;
+ struct voldb *db;
+ onode_opaque *onode;
+ int ret;
+
+ assert (vol && new);
+
+ if (afs_dir_p (vno)) {
+ real_mnode = dir_afs2local(vno);
+ db = VLD_VOLH_DIR(vol);
+ onode = &e.u.dir.ino;
+ } else {
+ real_mnode = file_afs2local(vno);
+ db = VLD_VOLH_FILE(vol);
+ onode = &e.u.file.ino;
+ }
+
+ ret = voldb_get_entry (db, real_mnode, &e);
+ if (ret)
+ return ret;
+
+ if (old)
+ *old = *onode;
+
+ *onode = *new;
+
+ ret = voldb_put_entry (db, real_mnode, &e);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+vld_adjust_linkcount (volume_handle *vol, struct mnode *n, int adjust)
+{
+ int32_t real_mnode;
+ struct voldb *db;
+ int32_t *LinkCount;
+ int32_t vno;
+ int ret;
+
+ assert (vol && n);
+
+ vno = n->fid.Vnode;
+ if (afs_dir_p (vno)) {
+ real_mnode = dir_afs2local(vno);
+ db = VLD_VOLH_DIR(vol);
+ LinkCount = &n->e.u.dir.LinkCount;
+ } else {
+ real_mnode = file_afs2local(vno);
+ db = VLD_VOLH_FILE(vol);
+ LinkCount = &n->e.u.file.LinkCount;
+ }
+
+ if (n->flags.ep == FALSE) {
+ ret = voldb_get_entry (db, real_mnode, &n->e);
+ if (ret)
+ return ret;
+ }
+
+ *LinkCount += adjust;
+
+ /* XXX is this necessary? */
+ ret = voldb_put_entry (db, real_mnode, &n->e);
+ if (ret)
+ return ret;
+
+ n->fs.LinkCount += adjust;
+ n->flags.ep = TRUE;
+
+ return 0;
+}
+
+static struct trans *transactions[MAX_TRANSACTIONS] = {NULL};
+static int32_t perm_tid = 1;
+
+
+int
+vld_create_trans(int32_t partition, int32_t volume, int32_t *trans)
+{
+ time_t now = time(NULL);
+ int i;
+ int ret;
+
+ ret = vld_check_busy(volume, partition);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] == NULL)
+ break;
+ }
+ if (transactions[i] == NULL) {
+ transactions[i] = malloc(sizeof(struct trans));
+ if (transactions[i] == NULL)
+ return ENOMEM;
+ *trans = perm_tid++;
+ transactions[i]->tid = *trans; /* XXX */
+ transactions[i]->time = now;
+ transactions[i]->creationTime = now;
+ transactions[i]->returnCode = 0;
+ transactions[i]->volume = NULL;
+ transactions[i]->volid = volume;
+ transactions[i]->partition = partition;
+ transactions[i]->refCount = 1;
+ transactions[i]->iflags = 0;
+ transactions[i]->vflags = 0;
+ transactions[i]->tflags = 0;
+ transactions[i]->incremental = 0;
+ return 0;
+ } else
+ return ENOMEM;
+}
+
+int
+vld_get_trans(int32_t transid, struct trans **trans)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] && transactions[i]->tid == transid) {
+ *trans = transactions[i];
+ transactions[i]->refCount++;
+ return 0;
+ }
+ }
+ return EINVAL;
+}
+
+int
+vld_put_trans(struct trans *trans)
+{
+ trans->refCount--;
+ if (trans->refCount < 1)
+ free(trans);
+ return 0;
+}
+
+int
+vld_verify_trans(int32_t trans)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] && transactions[i]->tid == trans)
+ return 0;
+ }
+ return VOLSERBAD_ACCESS;
+}
+
+int
+vld_end_trans(int32_t trans, int32_t *rcode)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] && transactions[i]->tid == trans) {
+ if (rcode)
+ *rcode = transactions[i]->returnCode;
+ vld_put_trans(transactions[i]);
+ transactions[i] = NULL;
+ return 0;
+ }
+ }
+ return ENOENT;
+}
+
+int
+vld_trans_set_iflags(int32_t trans, int32_t iflags)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] && transactions[i]->tid == trans) {
+ transactions[i]->iflags = iflags;
+ return 0;
+ }
+ }
+ return EINVAL;
+}
+
+int
+vld_trans_set_vflags(int32_t trans, int32_t vflags)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] && transactions[i]->tid == trans) {
+ transactions[i]->vflags = vflags;
+ return 0;
+ }
+ }
+ return EINVAL;
+}
+
+int
+vld_trans_get_vflags(int32_t trans, int32_t *vflags)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i] && transactions[i]->tid == trans) {
+ *vflags = transactions[i]->vflags;
+ return 0;
+ }
+ }
+ return EINVAL;
+}
+
+/*
+ * Check if the {volume, partition} pair is busy. If it is, return the
+ * appropriate error code. Otherwise, return 0. If the partition
+ * argument is -1, any partition will do (this is for fsprocs).
+ */
+
+int
+vld_check_busy(int32_t volid, int32_t partition)
+{
+ int i;
+
+ for (i = 0; i < MAX_TRANSACTIONS; i++) {
+ if (transactions[i]
+ && (partition == -1 || transactions[i]->partition == partition)
+ && transactions[i]->volid == volid) {
+ if (transactions[i]->iflags & ITOffline)
+ return VOFFLINE;
+ if (transactions[i]->iflags & ITBusy)
+ return VBUSY;
+ return EINVAL;
+ }
+ }
+ return 0;
+}
+
+/*
+ * create a new volume on partition `part' with volume id `volid' and name
+ * `name' of type `backstoretype'
+ */
+
+int
+vld_create_volume (struct dp_part *dp, int32_t volid,
+ const char *name, int32_t backstoretype, int32_t voltype,
+ int flags)
+{
+ volume_handle *vol;
+ int ret;
+
+ if (VLD_VALID_BACKSTORETYPE(backstoretype) ||
+ VLD_VALID_VOLNAME(name))
+ return EINVAL;
+
+ if (volume_htab) {
+ ret = vld_find_vol (volid, &vol);
+ if (ret == 0) {
+ vld_free (vol);
+ return EEXIST;
+ } else if (ret != ENOENT)
+ return ret;
+ } else {
+ ret = vld_open_volume_by_num (dp, volid, &vol);
+ if (ret == 0) {
+ vld_free (vol);
+ return EEXIST;
+ } else if (ret != ENOENT)
+ return ret;
+ }
+
+ vol = malloc (sizeof(*vol));
+ if (vol == NULL)
+ return ENOMEM;
+
+ memset (vol, 0, sizeof (*vol));
+ vol->vol = volid;
+ dp_ref (dp);
+ vol->dp = dp;
+
+ vol->ref = 1;
+
+ ret = VOLOP_OPEN(backstoretype, dp, volid, VOLOP_CREATE, &vol->data);
+ if (ret) {
+ dp_free (dp);
+ return ret;
+ }
+
+ ret = VOLOP_ICREATE(vol, &vol->fino, NODE_VOL, NULL);
+ if (ret) {
+ VOLOP_REMOVE (vol);
+ dp_free (dp);
+ return ret;
+ }
+
+ ret = VOLOP_ICREATE(vol, &vol->dino, NODE_VOL, NULL);
+ if (ret) {
+ VOLOP_IUNLINK(vol, &vol->fino);
+ VOLOP_REMOVE(vol);
+ dp_free (dp);
+ return ret;
+ }
+
+ ret = VOLOP_ICREATE(vol, &vol->sino, NODE_VOL, NULL);
+ if (ret) {
+ VOLOP_IUNLINK(vol, &vol->fino);
+ VOLOP_IUNLINK(vol, &vol->dino);
+ VOLOP_REMOVE(vol);
+ dp_free (dp);
+ return ret;
+ }
+
+ {
+ int fd;
+
+ ret = VOLOP_IOPEN(vol,&vol->sino,O_RDWR,&fd);
+ if (ret)
+ abort();
+
+ ret = vol_create (fd, volid, name, voltype, 0);
+ if (ret) {
+ VOLOP_IUNLINK(vol, &vol->fino);
+ VOLOP_IUNLINK(vol, &vol->dino);
+ VOLOP_IUNLINK(vol, &vol->sino);
+ VOLOP_REMOVE (vol);
+ close (fd);
+ dp_free (dp);
+ return ret;
+ }
+ close (fd);
+ }
+
+ {
+ char path[MAXPATHLEN];
+ int fd = -1;
+ vstatus vs;
+
+#define ERR_OUT_VSTATUS(ret) \
+ do { \
+ VOLOP_IUNLINK(vol, &vol->fino); \
+ VOLOP_IUNLINK(vol, &vol->dino); \
+ VOLOP_IUNLINK(vol, &vol->sino); \
+ VOLOP_REMOVE (vol); \
+ dp_free (dp); \
+ if (fd != -1) \
+ close (fd); \
+ return ret; \
+ } while (0)
+
+ ret = vol_getfullname (DP_NUMBER(dp), volid, path, sizeof(path));
+ if (ret)
+ ERR_OUT_VSTATUS(ret);
+
+ fd = open (path, O_RDWR|O_CREAT, 0600);
+ if (fd < 0)
+ ERR_OUT_VSTATUS(errno);
+
+ if (sizeof (vs.volinfoinode) != sizeof(vol->sino))
+ abort();
+
+ vol->type = backstoretype;
+ vol->vol = volid;
+ vol->voldbtype = VOLDB_DEFAULT_TYPE;
+
+ memset (&vs, 0, sizeof(vs));
+ vs.volid = volid;
+ vs.type = voltype;
+ vs.bstype = backstoretype;
+ vs.voldbtype = VOLDB_DEFAULT_TYPE;
+ memcpy (&vs.volinfoinode, &vol->sino, sizeof(vol->sino));
+ memcpy (&vs.dirinode, &vol->dino, sizeof(vol->dino));
+ memcpy (&vs.fileinode, &vol->fino, sizeof(vol->fino));
+
+ ret = vstatus_write (fd, &vs);
+ if (ret)
+ ERR_OUT_VSTATUS(ret);
+
+ close (fd);
+#undef ERR_OUT_VSTATUS
+ }
+
+ {
+ int fd;
+ ret = VOLOP_IOPEN(vol,&vol->fino,O_RDWR,&fd);
+ if (ret)
+ abort();
+
+ ret = voldb_create_header (fd, VOLDB_DEFAULT_TYPE, VOLDB_FILE);
+ if (ret)
+ abort();
+
+ ret = VOLOP_IOPEN(vol,&vol->dino,O_RDWR,&fd);
+ if (ret)
+ abort();
+
+ ret = voldb_create_header (fd, VOLDB_DEFAULT_TYPE, VOLDB_DIR);
+ if (ret)
+ abort();
+
+ /* voldb_create_header will close `fd' */
+ }
+ {
+ AFSFid child;
+ AFSStoreStatus ss;
+ struct mnode *n;
+ struct mnode parent_n;
+
+ memset (&ss, 0, sizeof (ss));
+ ss.Mask = SS_MODEBITS;
+ ss.UnixModeBits = 0755;
+
+ ret = vld_db_uptodate (vol);
+ if (ret)
+ abort();
+
+ parent_n.fid.Volume = vol->vol;
+ parent_n.fid.Vnode = 1;
+ parent_n.fid.Unique = 1;
+
+
+ memset (parent_n.e.u.dir.acl, 0,
+ sizeof (parent_n.e.u.dir.acl));
+ memset (parent_n.e.u.dir.negacl, 0,
+ sizeof (parent_n.e.u.dir.negacl));
+ parent_n.e.u.dir.acl[0].owner = PR_SYSADMINID;
+ parent_n.e.u.dir.acl[0].flags =
+ PRSFS_LOOKUP |
+ PRSFS_READ |
+ PRSFS_WRITE |
+ PRSFS_INSERT |
+ PRSFS_DELETE |
+ PRSFS_LOCK |
+ PRSFS_ADMINISTER;
+ parent_n.e.u.dir.acl[1].owner = PR_ANYUSERID;
+ parent_n.e.u.dir.acl[1].flags = PRSFS_LOOKUP | PRSFS_READ;
+ parent_n.e.u.dir.acl[2].owner = PR_ANONYMOUSID;
+ parent_n.e.u.dir.acl[2].flags = PRSFS_LOOKUP | PRSFS_READ;
+
+ ret = vld_create_entry (vol, &parent_n, &child,
+ TYPE_DIR, &ss, &n, NULL);
+ if (ret)
+ abort();
+
+ mnode_free(n, FALSE);
+
+ assert (child.Vnode == 1 && child.Unique == 1);
+
+ ret = vld_db_flush (vol);
+ if (ret)
+ abort();
+ }
+
+ if (volume_htab)
+ hashtabadd (volume_htab, vol);
+ else
+ vld_free(vol);
+
+ return 0;
+}
+
+/*
+ * Register a new volume type
+ */
+
+int
+vld_register_vol_type (const int32_t backstoretype, vol_op *ops)
+{
+ if (backstoretype < 0 || backstoretype >= VLD_MAX_BACKSTORE_TYPES)
+ return EINVAL;
+
+ assert (ops);
+
+ backstoretypes[backstoretype] = ops;
+
+ return 0;
+}
+
+/*
+ * Find volume in incore db
+ */
+
+int
+vld_find_vol (const int32_t volid, struct volume_handle **vol)
+{
+ volume_handle key, *r;
+
+ key.vol = volid;
+
+ r = hashtabsearch (volume_htab, &key);
+ if (r == NULL) {
+ *vol = NULL;
+ return ENOENT;
+ } else {
+ vld_ref (r);
+ *vol = r;
+ }
+
+ return 0;
+}
+
+/*
+ * return a non zero value if the user is the superuser.
+ */
+
+#define SUPER_USER 0
+
+static int
+super_user (struct msec *m)
+{
+ int i;
+ prlist *entries = m->sec->cps;
+ int lim = min(PR_MAXLIST, entries->len);
+ for (i = 0; i < lim; i++) {
+ if (entries->val[i] == PR_SYSADMINID)
+ return 1;
+ }
+
+ return 0;
+
+}
+
+/*
+ *
+ */
+
+static int
+vld_storestatus_to_dent (struct voldb_dir_entry *e,
+ const AFSStoreStatus *ss,
+ struct msec *m)
+{
+ if (ss->Mask & SS_OWNER) {
+ if (ss->Owner == SUPER_USER && !super_user (m))
+ return EPERM;
+ e->Owner = ss->Owner;
+ }
+ if (ss->Mask & SS_MODTIME) {
+ e->ServerModTime = ss->ClientModTime; /* XXX should modify
+ ClientModTime */
+ }
+ if (ss->Mask & SS_GROUP)
+ e->Group = ss->Group;
+ if (ss->Mask & SS_MODEBITS)
+ e->UnixModeBits = 07777 & ss->UnixModeBits;
+ if (ss->Mask & SS_SEGSIZE)
+ e->SegSize = ss->SegSize;
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+vld_storestatus_to_fent (struct voldb_file_entry *e,
+ const AFSStoreStatus *ss,
+ struct msec *m)
+{
+ if (ss->Mask & SS_OWNER) {
+ if (ss->Owner == SUPER_USER && !super_user (m))
+ return EPERM;
+ e->Owner = ss->Owner;
+ }
+ if (ss->Mask & SS_MODTIME) {
+ e->ServerModTime = ss->ClientModTime; /* XXX should modify
+ ClientModTime */
+ }
+ if (ss->Mask & SS_GROUP)
+ e->Group = ss->Group;
+ if (ss->Mask & SS_MODEBITS)
+ e->UnixModeBits = 0777 & ss->UnixModeBits;
+ if (ss->Mask & SS_SEGSIZE)
+ e->SegSize = ss->SegSize;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+vld_storestatus_to_ent (struct voldb_entry *e,
+ const AFSStoreStatus *ss,
+ struct msec *m)
+{
+ switch (e->type) {
+ case TYPE_DIR:
+ return vld_storestatus_to_dent (&e->u.dir, ss, m);
+ case TYPE_FILE:
+ case TYPE_LINK:
+ return vld_storestatus_to_fent (&e->u.file, ss, m);
+ }
+ abort();
+}
+
+/*
+ *
+ */
+
+static int
+vld_dent_to_fetchstatus (struct voldb_dir_entry *e,
+ struct mnode *n)
+{
+ int ret;
+ AFSFetchStatus *fs;
+
+ ret = mnode_update_size_cached (n);
+ if (ret)
+ return ret;
+
+ fs = &n->fs;
+
+ fs->InterfaceVersion = 1;
+ fs->FileType = e->FileType;
+ fs->LinkCount = e->LinkCount;
+ fs->DataVersion = e->DataVersion;
+
+ fs->ParentVnode = e->ParentVnode;
+ fs->ParentUnique = e->ParentUnique;
+
+ fs->SegSize = e->SegSize;
+ fs->ClientModTime = e->ServerModTime;
+ fs->ServerModTime = e->ServerModTime;
+ fs->SyncCount = 4711;
+ fs->spare1 = 0;
+ fs->spare2 = 0;
+ fs->spare3 = 0;
+ fs->spare4 = 0;
+ fs->Author = e->Author;
+ fs->Owner = e->Owner;
+ fs->Group = e->Group;
+ fs->UnixModeBits = e->UnixModeBits;
+
+ /*
+ * Dummy
+ */
+
+ fs->CallerAccess = 0;
+ fs->AnonymousAccess = 0;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+vld_fent_to_fetchstatus (struct voldb_file_entry *e,
+ struct mnode *n)
+{
+ int ret;
+ AFSFetchStatus *fs;
+
+ ret = mnode_update_size_cached (n);
+ if (ret)
+ return ret;
+
+ fs = &n->fs;
+
+ fs->InterfaceVersion = 1;
+ fs->FileType = e->FileType;
+ fs->LinkCount = e->LinkCount;
+ fs->DataVersion = e->DataVersion;
+
+ fs->ParentVnode = e->ParentVnode;
+ fs->ParentUnique = e->ParentUnique;
+
+ fs->SegSize = e->SegSize;
+ fs->ClientModTime = e->ServerModTime;
+ fs->ServerModTime = e->ServerModTime;
+ fs->SyncCount = 4711;
+ fs->spare1 = 0;
+ fs->spare2 = 0;
+ fs->spare3 = 0;
+ fs->spare4 = 0;
+ fs->Author = e->Author;
+ fs->Owner = e->Owner;
+ fs->Group = e->Group;
+ fs->UnixModeBits = e->UnixModeBits;
+
+ /*
+ * Dummy
+ */
+
+ fs->CallerAccess = 0;
+ fs->AnonymousAccess = 0;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+vld_ent_to_fetchstatus (struct voldb_entry *e, struct mnode *n)
+{
+ int ret;
+
+ if (n->flags.fsp)
+ return 0;
+
+ assert (n->flags.ep);
+
+ switch (e->type) {
+ case TYPE_DIR:
+ ret = vld_dent_to_fetchstatus (&e->u.dir, n);
+ break;
+ case TYPE_FILE:
+ case TYPE_LINK:
+ ret = vld_fent_to_fetchstatus (&e->u.file, n);
+ break;
+ default:
+ abort();
+ break;
+ }
+ if (ret == 0)
+ n->flags.fsp = TRUE;
+ return ret;
+}
+
+/*
+ *
+ */
+
+static void
+vld_set_author(struct voldb_entry *e, struct msec *m)
+{
+ if (m == NULL)
+ return;
+ assert (m->sec);
+ switch (e->type) {
+ case TYPE_DIR:
+ e->u.dir.Author = m->sec->uid;
+ break;
+ case TYPE_FILE:
+ case TYPE_LINK:
+ e->u.file.Author = m->sec->uid;
+ break;
+ default:
+ abort();
+ break;
+ }
+}
+
+/*
+ *
+ */
+
+int
+volop_iopen (volume_handle *vol, onode_opaque *o, struct mnode *n)
+{
+ int ret;
+
+ if (n->flags.fdp)
+ return 0;
+
+ ret = VOLOP_IOPEN(vol, o, O_RDWR, &n->fd);
+ if (ret)
+ return ret;
+ n->flags.fdp = TRUE;
+ return 0;
+}
+
+/*
+ *
+ */
+
+#if 0
+int
+foo(void)
+{
+ *callers_right = 0;
+ *anonymous_right = 0;
+
+ foreach (parent_n->e.positive_acl) {
+ if (member ($_.uid, anonymous))
+ *anonymous_right = $_.rights;
+ if (member ($_.uid, m->cps)) {
+ *callers_right |= $_.rights:
+ }
+ }
+ foreach (parent_n->e.negative_acl) {
+ if (member ($_.uid, anonymous))
+ *anonymous_right &= ~ $_.rights;
+ if (member ($_.uid, m->cps)
+ *callers_rights &= ~ $_.rights;
+ }
+ }
+ if (validop_p(*callers_rights, operation))
+ return TRUE;
+ return FALSE;
+}
+#endif
+
+/*
+ * check the right to use `n'
+ *
+ * We also need to take care of the special case (1,1) since it
+ * doesn't have a parent directory.
+ */
+
+struct {
+ volop_flags op;
+ int32_t afsprivs;
+} check_flags[] = {
+ { VOLOP_READ, PRSFS_READ },
+ { VOLOP_WRITE, PRSFS_WRITE },
+ { VOLOP_INSERT, PRSFS_INSERT },
+ { VOLOP_DELETE, PRSFS_DELETE },
+ { VOLOP_LOOKUP, PRSFS_LOOKUP},
+ { VOLOP_LOCK, PRSFS_LOCK },
+ { VOLOP_ADMIN, PRSFS_ADMINISTER },
+ { VOLOP_GETSTATUS, PRSFS_READ }
+};
+
+
+
+int
+vld_check_rights (volume_handle *vol, struct mnode *n,
+ struct msec *m)
+{
+ struct mnode *parent_n;
+ AFSFid parent_fid;
+ struct msec pm;
+ int ret, i, j;
+ int right_ret = 0;
+
+ assert (n->flags.fsp);
+ assert (n->flags.ep);
+
+ if (m->loop > 1)
+ abort();
+
+#if 0
+ if ((m->flags & VOLOP_NOCHECK) == VOLOP_NOCHECK)
+ return 0;
+#else
+/* m->caller_access = m->anonymous_access =
+ PRSFS_READ | PRSFS_WRITE | PRSFS_INSERT |
+ PRSFS_LOOKUP | PRSFS_DELETE |
+ PRSFS_LOCK | PRSFS_ADMINISTER;
+ return 0;*/
+#endif
+
+
+ assert(m->sec);
+
+ if (m->sec->cps == NULL)
+ return EPERM;
+
+ /*
+ * The root node has itself as parent
+ */
+
+ if ((n->fid.Vnode == 1 && n->fid.Unique == 1)
+ || (m->flags & VOLOP_PARENT) == VOLOP_PARENT) {
+ assert(n->e.type == TYPE_DIR);
+ parent_n = n;
+ } else {
+ memset (&pm, 0, sizeof (pm));
+ pm.sec = m->sec;
+ pm.caller_access = 0;
+ pm.anonymous_access = 0;
+ pm.flags = VOLOP_GETSTATUS;
+ pm.loop = m->loop + 1;
+
+ parent_fid.Volume = n->fid.Volume;
+ parent_fid.Vnode = n->fs.ParentVnode;
+ parent_fid.Unique = n->fs.ParentUnique;
+
+ ret = mnode_find (&parent_fid, &parent_n);
+ if (ret)
+ return EACCES;
+
+ ret = vld_open_vnode (vol, parent_n, &pm);
+ if (ret) {
+ mnode_free (parent_n, FALSE);
+ return EACCES;
+ }
+ assert (parent_n->flags.ep);
+
+ }
+
+ m->caller_access = m->anonymous_access = 0;
+
+ for (i = 0; i < FS_MAX_ACL; i++)
+ for (j = 0; j < m->sec->cps->len; j++)
+ if (parent_n->e.u.dir.acl[i].owner == m->sec->cps->val[j])
+ m->caller_access |= parent_n->e.u.dir.acl[i].flags;
+ for (i = 0; i < FS_MAX_ACL; i++)
+ for (j = 0; j < m->sec->cps->len; j++)
+ if (parent_n->e.u.dir.negacl[i].owner == m->sec->cps->val[j])
+ m->caller_access &= ~parent_n->e.u.dir.negacl[i].flags;
+
+ for (i = 0;
+ i < sizeof(check_flags)/sizeof(*check_flags)
+ && right_ret == 0;
+ i++)
+ {
+ if ((m->flags &
+ check_flags[i].op) == check_flags[i].op
+ && (check_flags[i].afsprivs &
+ m->caller_access) != check_flags[i].afsprivs)
+ right_ret = EACCES;
+ }
+
+ if (parent_n != n)
+ mnode_free (parent_n, FALSE);
+
+ return right_ret;
+}
+
+/*
+ * open an mnode `n' in volume `vol' with `flags' in `m' as specifed above.
+ */
+
+int
+vld_open_vnode (volume_handle *vol, struct mnode *n, struct msec *m)
+{
+ int ret = 0;
+ int32_t real_mnode;
+ struct voldb *db;
+ onode_opaque *o;
+
+ assert (vol);
+
+ /*
+ * is everything cached ?
+ */
+
+ if ((m->flags & VOLOP_GETSTATUS) == 0
+ && n->flags.fsp == TRUE
+ && n->flags.ep == TRUE)
+ return 0;
+
+ if (afs_dir_p (n->fid.Vnode)) {
+ real_mnode = dir_afs2local (n->fid.Vnode);
+ db = VLD_VOLH_DIR(vol);
+ o = &n->e.u.dir.ino;
+ } else {
+ real_mnode = file_afs2local (n->fid.Vnode);
+ db = VLD_VOLH_FILE(vol);
+ o = &n->e.u.file.ino;
+ }
+
+ if (n->flags.ep == FALSE) {
+ ret = voldb_get_entry (db, real_mnode, &n->e);
+ if (ret)
+ return ret;
+ n->flags.ep = TRUE;
+ }
+
+ if (n->flags.fdp == FALSE) {
+ ret = volop_iopen (vol, o, n);
+ if (ret)
+ return ret;
+ }
+
+ n->flags.fdp = TRUE;
+
+ if ((m->flags & VOLOP_GETSTATUS) == VOLOP_GETSTATUS)
+ ret = vld_ent_to_fetchstatus (&n->e, n);
+
+ return ret;
+}
+
+
+/*
+ * Modify node `n' in volume `vol' with context bits `m'
+ * with StoreStatus bits `ss' and length `len'.
+ */
+
+int
+vld_modify_vnode (volume_handle *vol, struct mnode *n, struct msec *m,
+ const AFSStoreStatus *ss, int32_t *len)
+{
+ int ret;
+ int32_t real_mnode;
+ struct voldb *db;
+
+ assert (vol);
+ assert (n->flags.fdp);
+ assert (n->flags.ep);
+
+ if (afs_dir_p (n->fid.Vnode)) {
+ real_mnode = dir_afs2local (n->fid.Vnode);
+ db = VLD_VOLH_DIR(vol);
+ } else {
+ real_mnode = file_afs2local (n->fid.Vnode);
+ db = VLD_VOLH_FILE(vol);
+ }
+
+ if (ss && ss->Mask) {
+ ret = vld_storestatus_to_ent (&n->e, ss, m);
+ if (ret)
+ return ret;
+ }
+
+ if (len) {
+ ret = ftruncate (n->fd, *len);
+ if (ret)
+ return ret;
+
+ if (n->e.type == TYPE_DIR)
+ n->e.u.dir.Length = *len;
+ else
+ n->e.u.file.Length = *len;
+
+ n->sb.st_size = *len;
+ }
+
+ if (n->e.type == TYPE_DIR)
+ n->e.u.dir.DataVersion++;
+ else
+ n->e.u.file.DataVersion++;
+
+ ret = voldb_put_entry (db, real_mnode, &n->e);
+ if (ret)
+ return ret;
+
+ n->flags.fsp = FALSE; /* Force vld_ent_to_fetchstatus
+ to fill in the field */
+ ret = vld_ent_to_fetchstatus (&n->e, n);
+
+ return ret;
+}
+
+/*
+ * Put acl for node `n' in volume `vol' with context bits `m'.
+ */
+
+int
+vld_put_acl (volume_handle *vol, struct mnode *n, struct msec *m)
+{
+ int ret;
+ int32_t real_mnode;
+ struct voldb *db;
+
+ assert (vol);
+ assert (n->flags.fdp);
+ assert (n->flags.ep);
+
+ if (afs_dir_p (n->fid.Vnode)) {
+ real_mnode = dir_afs2local (n->fid.Vnode);
+ db = VLD_VOLH_DIR(vol);
+ } else {
+ return EINVAL;
+ }
+
+ ret = voldb_put_acl (db, real_mnode, &n->e.u.dir);
+ if (ret)
+ return ret;
+
+ n->flags.fsp = FALSE; /* Force vld_ent_to_fetchstatus
+ to fill in the field */
+
+ if ((m->flags & VOLOP_GETSTATUS) == VOLOP_GETSTATUS)
+ ret = vld_ent_to_fetchstatus (&n->e, n);
+
+ return ret;
+}
+
+
+/*
+ * Convert a volume handle to AFS volsync
+ */
+
+int
+vld_vld2volsync (const struct volume_handle *vld, AFSVolSync *volsync)
+{
+ if (volsync)
+ memset (volsync, 0, sizeof (*volsync));
+ return 0;
+}
+
+/*
+ * Make sure the db is stored to disk
+ */
+
+int
+vld_db_flush (volume_handle *vol)
+{
+ int ret;
+ if (vol->flags.voldbp) {
+ assert (VLD_VOLH_DIR(vol) != NULL && VLD_VOLH_FILE(vol) != NULL);
+
+ ret = voldb_flush (VLD_VOLH_DIR(vol));
+ assert (ret == 0);
+ ret = voldb_flush (VLD_VOLH_FILE(vol));
+ assert (ret == 0);
+ } else {
+ assert (VLD_VOLH_DIR(vol) == NULL && VLD_VOLH_FILE(vol) == NULL);
+ }
+ return 0;
+}
+
+/*
+ * Bring db in volume uptodate
+ *
+ * XXX when failing bring volume offline
+ */
+
+int
+vld_db_uptodate (volume_handle *vol)
+{
+ int ret, fd;
+
+ if (vol->flags.voldbp) {
+ if (db_lru) {
+ listdel (db_lru, vol->db_li);
+ vol->db_li = listaddhead (db_lru, vol);
+ if (vol->db_li == NULL)
+ abort (); /* XXX */
+ } else {
+ assert (vol->db_li == NULL);
+ }
+ return 0;
+ }
+ assert (VLD_VOLH_DIR(vol) == NULL && VLD_VOLH_FILE(vol) == NULL);
+
+ if (db_lru && !listemptyp(db_lru)) {
+ volume_handle *old_vol;
+
+ old_vol = listdeltail (db_lru);
+ if (old_vol) {
+ assert (VLD_VOLH_DIR(old_vol) && VLD_VOLH_FILE(old_vol));
+
+ voldb_close (VLD_VOLH_DIR(old_vol));
+ voldb_close (VLD_VOLH_FILE(old_vol));
+ VLD_VOLH_DIR(old_vol) = VLD_VOLH_FILE(old_vol) = NULL;
+ old_vol->db_li = NULL;
+ }
+ }
+
+ /*
+ * Note there isn't a fd-leek here, they are picked up
+ * by voldb_init, and closed at will by voldb.
+ */
+
+ ret = VOLOP_IOPEN(vol, &vol->dino, O_RDWR, &fd);
+ if (ret)
+ return ret;
+
+ ret = voldb_init (fd, vol->voldbtype, vol->vol, &VLD_VOLH_DIR(vol));
+ if (ret) {
+ close (fd);
+ VLD_VOLH_DIR(vol) = NULL;
+ return ret;
+ }
+
+ ret = VOLOP_IOPEN(vol, &vol->fino, O_RDWR, &fd);
+ if (ret) {
+ voldb_close (VLD_VOLH_DIR(vol));
+ VLD_VOLH_DIR(vol) = NULL;
+ return ret;
+ }
+
+ ret = voldb_init (fd, vol->voldbtype, vol->vol, &VLD_VOLH_FILE(vol));
+ if (ret) {
+ close (fd);
+ voldb_close (VLD_VOLH_DIR(vol));
+ VLD_VOLH_DIR(vol) = NULL;
+ VLD_VOLH_FILE(vol) = NULL;
+ return ret;
+ }
+
+ vol->flags.voldbp = TRUE;
+
+ if (db_lru)
+ vol->db_li = listaddhead (db_lru, vol);
+
+ return 0;
+}
+
+/*
+ * Open volume on partition `dp' with volume id `volid'
+ * and return it ref:ed in `vol'.
+ */
+
+int
+vld_open_volume_by_num (struct dp_part *dp, int32_t volid,
+ volume_handle **vol)
+{
+ int ret, fd;
+ char path[MAXPATHLEN];
+ vstatus vs;
+
+ if (volume_htab) {
+ volume_handle *r, key;
+ key.vol = volid;
+
+ r = hashtabsearch (volume_htab, &key);
+ if (r == NULL)
+ return ENOENT;
+ else
+ vld_ref (r);
+ *vol = r;
+ return 0;
+ }
+
+ ret = vol_getfullname (DP_NUMBER(dp), volid, path, sizeof (path));
+ if (ret)
+ return ret;
+
+ fd = open (path, O_RDONLY, 0600);
+ if (fd < 0)
+ return errno;
+
+ ret = vstatus_read (fd, &vs);
+ if (ret) {
+ close (fd);
+ return ret;
+ }
+ close (fd);
+
+ ret = vstatus2volume_handle (&vs, dp, vol);
+ if (ret)
+ return ret;
+
+ ret = VOLOP_OPEN((*vol)->type, (*vol)->dp, (*vol)->vol,
+ VOLOP_NOFLAGS, &(*vol)->data);
+ if (ret)
+ vld_free (*vol);
+
+ return ret;
+}
+
+int
+vld_remove_node (volume_handle *vol, int32_t node)
+{
+ int ret;
+ onode_opaque o;
+
+ if (afs_dir_p (node)) {
+ dir_afs2local(node);
+ ret = voldb_del_entry (VLD_VOLH_DIR(vol), dir_afs2local(node), &o);
+ if (ret)
+ return ret;
+
+ } else {
+ ret = voldb_del_entry (VLD_VOLH_FILE(vol), file_afs2local(node), &o);
+ if (ret)
+ return ret;
+
+ }
+
+ return VOLOP_IUNLINK (vol, &o);
+}
+
+
+/*
+ * Open volume that `fd' points to, if volume_hash is loaded try to
+ * find the volume in the hash.
+ */
+
+int
+vld_open_volume_by_fd (struct dp_part *dp, int fd,
+ volume_handle **vol)
+{
+ int ret;
+ vstatus vs;
+
+ ret = vstatus_read (fd, &vs);
+ if (ret)
+ return ret;
+
+ if (volume_htab) {
+ volume_handle *r, key;
+ key.vol = vs.volid;
+
+ r = hashtabsearch (volume_htab, &key);
+ if (r == NULL)
+ return ENOENT;
+ else
+ vld_ref (r);
+ *vol = r;
+ return 0;
+ }
+
+ ret = vstatus2volume_handle (&vs, dp, vol);
+ if (ret)
+ return ret;
+
+ ret = VOLOP_OPEN((*vol)->type, (*vol)->dp, (*vol)->vol,
+ VOLOP_NOFLAGS, &(*vol)->data);
+ if (ret)
+ vld_free (*vol);
+
+ return ret;
+}
+
+/*
+ * Make sure info is uptodate
+ */
+
+int
+vld_info_uptodatep (volume_handle *vol)
+{
+ int ret, fd;
+
+ assert (vol);
+
+ if (vol->flags.infop)
+ return 0;
+
+ ret = VOLOP_IOPEN(vol, &vol->sino, O_RDONLY, &fd);
+ if (ret)
+ return ret;
+
+ ret = vol_read_header (fd, &vol->info);
+
+ close (fd);
+ if (ret == 0)
+ vol->flags.infop = TRUE;
+ return ret;
+}
+
+int
+vld_info_write (volume_handle *vol)
+{
+ int ret, fd;
+
+ assert (vol);
+
+ ret = VOLOP_IOPEN(vol, &vol->sino, O_WRONLY, &fd);
+ if (ret)
+ return ret;
+
+ ret = vol_write_header (fd, &vol->info);
+
+ close (fd);
+
+ return ret;
+}
+
+/*
+ * Shutdown time
+ */
+
+void
+vld_end (void)
+{
+ /* XXX flush volume_htab to disk */
+
+ return;
+}
diff --git a/usr.sbin/afs/src/milko/lib/vld/vld.h b/usr.sbin/afs/src/milko/lib/vld/vld.h
new file mode 100644
index 00000000000..94a132c0ebe
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/vld.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: vld.h,v 1.1 2000/09/11 14:41:18 art Exp $ */
+
+#ifndef MILKO_VLD_H
+#define MILKO_VLD_H 1
+
+#include <dpart.h>
+#include <voldb.h>
+
+#include <fs.h>
+#include <volumeserver.h>
+
+#include <fbuf.h>
+#include <list.h>
+
+#include <mnode.h>
+
+/*
+ * Type of volumes
+ */
+
+#define VLD_SVOL 0
+#define VLD_FVOL 1
+
+/*
+ * structures
+ */
+
+#define VLD_VOLH_DIR(volh) ((volh)->db[0])
+#define VLD_VOLH_FILE(volh) ((volh)->db[1])
+
+#define VLD_VOLH_NUM(volh) ((volh)->vol)
+
+typedef struct volume_handle {
+ int type; /* type of volume backstore */
+ int voldbtype; /* type of voldb structures */
+ u_int32_t vol; /* volume number */
+ int ref; /* refcount */
+ struct dp_part *dp; /* on what partition the volume resides */
+ void *data; /* data blob for volume type */
+ volintInfo info; /* info struct */
+ struct {
+ unsigned infop:1; /* if there is valid info in node */
+ unsigned voldbp:1; /* if voldb has been read in */
+ unsigned offlinep:1; /* if volume is offline */
+ unsigned salvaged:1; /* if volume is salvaged */
+ unsigned attacherr:1; /* volume had an error when attaching */
+ unsigned cleanp:1; /* volume was cleanly mounted */
+ } flags ;
+ onode_opaque sino; /* inode number of volume entry */
+ onode_opaque dino; /* inode number of db of dirs */
+ onode_opaque fino; /* inode number of db of files */
+ struct voldb *db[2]; /* large and small mnode tables */
+ Listitem *db_li; /* position in db_lru */
+ Listitem *li; /* position on the vol_list */
+} volume_handle;
+
+struct trans {
+ int32_t tid;
+ int32_t time; /* last active */
+ int32_t creationTime;
+ int32_t returnCode;
+ volume_handle *volume;
+ int32_t volid;
+ int32_t partition;
+ int16_t refCount;
+ int16_t iflags;
+ int8_t vflags;
+ int8_t tflags;
+ int8_t incremental;
+};
+
+typedef enum { NODE_REG = 1, NODE_DIR = 2,
+ NODE_META = 3, NODE_VOL = 4 } node_type;
+
+typedef struct volume_operations {
+ char *name;
+ int (*open)(struct dp_part *part, int32_t volid,
+ int flags, void **vol);
+#define VOLOP_NOFLAGS 0x0
+#define VOLOP_CREATE 0x1
+ void (*free)(volume_handle *vol);
+ int (*icreate)(volume_handle *vol, onode_opaque *o, node_type type,
+ struct mnode *node);
+ int (*iopen)(volume_handle *vol, onode_opaque *o, int flags, int *fd);
+ int (*iunlink)(volume_handle *vol, onode_opaque *o);
+ int (*remove)(volume_handle *vol);
+} vol_op;
+
+enum { VOLCREAT_NOOP = 0, /* noop */
+ VOLCREAT_CREATE_ROOT = 1 /* create rootnode */
+};
+
+
+int
+vld_boot (void);
+
+int
+vld_init (void);
+
+void
+vld_iter_vol (int (*func)(volume_handle *vol, void *arg), void *arg);
+
+void
+vld_free (volume_handle *vol);
+
+void
+vld_ref (volume_handle *vol);
+
+int
+vld_register_backstore_type (const int32_t backstoretype, vol_op *ops);
+
+int
+vld_create_trans(int32_t partition, int32_t volume, int32_t *trans);
+
+int
+vld_get_trans(int32_t transid, struct trans **trans);
+
+int
+vld_put_trans(struct trans *trans);
+
+int
+vld_verify_trans(int32_t trans);
+
+int
+vld_check_busy(int32_t volid, int32_t partition);
+
+int
+vld_trans_set_iflags(int32_t trans, int32_t iflags);
+
+int
+vld_trans_set_vflags(int32_t trans, int32_t vflags);
+
+int
+vld_trans_get_vflags(int32_t trans, int32_t *vflags);
+
+int
+vld_register_vol_type (const int32_t backstoretype, vol_op *ops);
+
+int
+vld_end_trans(int32_t trans, int32_t *rcode);
+
+int
+vld_find_vol (const int32_t volid, struct volume_handle **vld);
+
+int
+vld_create_volume (struct dp_part *dp, int32_t volid,
+ const char *name, int32_t backstoretype, int32_t voltype,
+ int flags);
+
+const char *
+vld_backstoretype_name (int32_t backstoretype);
+
+int
+vld_vld2volsync (const struct volume_handle *vld, AFSVolSync *volsync);
+
+int
+vld_open_volume_by_num (struct dp_part *dp, int32_t volid,
+ volume_handle **vol);
+
+int
+vld_open_volume_by_fd (struct dp_part *dp, int fd,
+ volume_handle **vol);
+
+int
+vld_open_inode (volume_handle *vol, onode_opaque *o, int flags, int *fd);
+
+int
+vld_info_uptodatep (volume_handle *vol);
+
+int
+vld_info_write (volume_handle *vol);
+
+int
+vld_db_uptodate (volume_handle *vol);
+
+int
+vld_open_vnode (volume_handle *vol, struct mnode *n, struct msec *m);
+
+int
+vld_modify_vnode (volume_handle *vol, struct mnode *n, struct msec *m,
+ const AFSStoreStatus *ss, int32_t *len);
+
+int
+vld_put_acl (volume_handle *vol, struct mnode *n, struct msec *m);
+
+int
+vld_check_rights (volume_handle *vol, struct mnode *n,
+ struct msec *m);
+
+int
+vld_adjust_linkcount (volume_handle *vol, struct mnode *n, int adjust);
+
+int
+vld_set_onode (volume_handle *vol, int32_t vno, onode_opaque *new,
+ onode_opaque *old);
+
+int
+vld_create_entry (volume_handle *vol, struct mnode *parent, AFSFid *child,
+ int type, const AFSStoreStatus *ss, struct mnode **ret_n,
+ struct msec *m);
+
+int
+vld_remove_node (volume_handle *vol, int32_t node);
+
+int
+vld_db_flush (volume_handle *vol);
+
+void
+vld_end (void);
+
+int
+vld_fvol_create_volume_ondisk (struct dp_part *dp, int32_t volid,
+ const char *path);
+
+/*
+ * This function is internal to vld and vol modules.
+ *
+ * Use otherwise and die.
+ */
+
+int
+volop_iopen (volume_handle *vol, onode_opaque *o, struct mnode *n);
+
+#endif /* MILKO_VLD_H */
+
diff --git a/usr.sbin/afs/src/milko/lib/vld/vld_ops.h b/usr.sbin/afs/src/milko/lib/vld/vld_ops.h
new file mode 100644
index 00000000000..97ae56a630e
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vld/vld_ops.h
@@ -0,0 +1,24 @@
+#define VOLOP_OPEN(type,part,volid,flags,vol) \
+ ((backstoretypes[(type)]->open)((part),(volid),(flags),(vol)))
+#define VOLOP_FREE(vol) \
+ ((backstoretypes[(vol)->type]->free)(vol))
+#define VOLOP_ICREATE(vol,ino,ntype,node) \
+ ((backstoretypes[(vol)->type]->icreate)((vol),(ino),(ntype),(node)))
+#define VOLOP_IOPEN(vol,ino,flags,fd) \
+ ((backstoretypes[(vol)->type]->iopen)((vol),(ino),(flags),(fd)))
+#define VOLOP_IUNLINK(vol,ino) \
+ ((backstoretypes[(vol)->type]->iunlink)(vol,ino))
+#define VOLOP_REMOVE(vol) \
+ ((backstoretypes[(vol)->type]->remove)(vol))
+#define VOLOP_TRUNCATE(vol,len) \
+ ((backstoretypes[(vol)->type]->truncate)(vol,len))
+
+
+#define VLD_MAX_BACKSTORE_TYPES 10
+
+extern vol_op *backstoretypes[VLD_MAX_BACKSTORE_TYPES];
+
+int32_t dir_afs2local (int32_t vno);
+int32_t dir_local2afs (int32_t vno);
+int32_t file_afs2local (int32_t vno);
+int32_t file_local2afs (int32_t vno);
diff --git a/usr.sbin/afs/src/milko/lib/voldb/Makefile.in b/usr.sbin/afs/src/milko/lib/voldb/Makefile.in
new file mode 100644
index 00000000000..b09ed37e004
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/Makefile.in
@@ -0,0 +1,105 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:18 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I$(srcdir) \
+ -I$(srcdir)/../../fs \
+ -I$(srcdir)/../../.. \
+ -I../../../rxdef \
+ -I../../../include \
+ -I../vstatus \
+ -I$(srcdir)/../vstatus \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+ARLACACHEDIR = @ARLACACHEDIR@
+ARLACONFFILE = @ARLACONFFILE@
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)voldb
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = voldb.c vdb_flat.c vol.c
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = voldb.o vdb_flat.o vol.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/voldb/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/voldb/vdb_flat.c b/usr.sbin/afs/src/milko/lib/voldb/vdb_flat.c
new file mode 100644
index 00000000000..010694f264d
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/vdb_flat.c
@@ -0,0 +1,944 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+
+/*
+ * simple flat db for the vnodes
+ */
+
+#include "voldb_locl.h"
+#include "voldb_internal.h"
+
+RCSID("$Id: vdb_flat.c,v 1.1 2000/09/11 14:41:18 art Exp $");
+
+
+static int vdbflat_init (int fd, struct voldb *db, int createp);
+static int vdbflat_close (struct voldb *db);
+static int vdbflat_get_dir (struct voldb *db, const u_int32_t num,
+ struct voldb_dir_entry *e);
+static int vdbflat_put_dir (struct voldb *db, const u_int32_t num,
+ struct voldb_dir_entry *e);
+static int vdbflat_put_acl (struct voldb *db, u_int32_t num,
+ struct voldb_dir_entry *e);
+static int vdbflat_get_file (struct voldb *db, const u_int32_t num,
+ struct voldb_file_entry *e);
+static int vdbflat_put_file (struct voldb *db, const u_int32_t num,
+ struct voldb_file_entry *e);
+static int vdbflat_extend_db (struct voldb *db, unsigned int num);
+static int vdbflat_flush (struct voldb *db);
+static int vdbflat_new_entry (struct voldb *db, u_int32_t *num,
+ u_int32_t *unique);
+static int vdbflat_del_entry (struct voldb *db, const u_int32_t num,
+ onode_opaque *ino);
+static int vdbflat_write_header (struct voldb *db, void *d, size_t sz);
+
+/*
+ * Various internal data definitions
+ */
+
+#define VOLDB_FILE_SIZE (19*4+404)
+#define VOLDB_DIR_SIZE (VOLDB_FILE_SIZE+(FS_MAX_ACL*2*2*4))
+/* (negative + positive) * 2 entries * int32_t */
+
+/*
+ * Various internal data structures
+ */
+
+typedef struct vdbflat {
+ int32_t freeptr;
+ void *ptr;
+ union {
+ struct voldb_file_entry *file;
+ struct voldb_dir_entry *dir;
+ } u;
+} vdbflat;
+
+static void
+set_volhdr_union_ptr (struct voldb *db)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+
+ if (db->hdr.flags & VOLDB_DIR)
+ vdb->u.dir = (struct voldb_dir_entry *)
+ ((unsigned char *) ((vdbflat *)db->ptr)->ptr + VOLDB_HEADER_SIZE);
+ else if (db->hdr.flags & VOLDB_FILE)
+ vdb->u.file = (struct voldb_file_entry *)
+ ((unsigned char *) ((vdbflat *)db->ptr)->ptr + VOLDB_HEADER_SIZE);
+ else
+ abort();
+}
+
+/*
+ * boot up the db
+ * `fd' is a file descriptor to a db that is returned in `db'.
+ * `fd' is saved if everythings works out ok, otherwise its
+ * up to the caller to close it.
+ */
+
+static int
+vdbflat_init (int fd, struct voldb *db, int createp)
+{
+ vdbflat *vdb;
+ u_int32_t i;
+ int size;
+ int ret;
+ unsigned char *data;
+
+ assert (db);
+ assert (db->size >= VOLDB_HEADER_SIZE);
+
+ vdb = calloc (1, sizeof(*vdb));
+ if (vdb == NULL)
+ return ENOMEM; /* XXX */
+
+ vdb->ptr = mmap (NULL, db->size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (vdb->ptr == (void *)MAP_FAILED) {
+ free (vdb);
+ return (errno);
+ }
+
+ /* If we are being created, there is no sane data on disk */
+ if (createp) {
+ vdb->freeptr = 0;
+ } else {
+ /* Let the above layer parse the header */
+ voldb_parse_header (db, vdb->ptr, VOLDB_HEADER_HALF);
+
+ /* Now parse the second half */
+ data = ((unsigned char *)vdb->ptr) + VOLDB_HEADER_HALF;
+ memcpy (&i, data, sizeof(i));
+ vdb->freeptr = ntohl (i);
+ }
+
+ /* Do some sanity checking */
+ if ((db->hdr.flags & (VOLDB_FILE|VOLDB_DIR)) == VOLDB_FILE)
+ size = VOLDB_FILE_SIZE;
+ else if ((db->hdr.flags & (VOLDB_FILE|VOLDB_DIR)) == VOLDB_DIR)
+ size = VOLDB_DIR_SIZE;
+ else {
+ ret = munmap (vdb->ptr, db->size);
+ assert (ret == 0);
+ free (vdb);
+ return EIO;
+ }
+
+ if ((db->size - VOLDB_HEADER_SIZE) % size != 0) {
+ ret = munmap (vdb->ptr, db->size);
+ assert (ret == 0);
+ free(vdb);
+ return EIO;
+ }
+
+ if (db->hdr.num != (db->size - VOLDB_HEADER_SIZE) / size) {
+ ret = munmap (vdb->ptr, db->size);
+ assert (ret == 0);
+ free(vdb);
+ return EINVAL;
+ }
+
+ /* All done setup pointers */
+
+ db->ptr = vdb;
+
+ set_volhdr_union_ptr (db);
+
+ return 0;
+}
+
+/*
+ * closes the db
+ * The saved `fd' is also closed.
+ */
+
+static int
+vdbflat_close (struct voldb *db)
+{
+ vdbflat *vdb;
+ int ret;
+
+ assert (db);
+
+ assert (db->hdr.magic = VOLDB_MAGIC_HEADER);
+
+ vdb = (vdbflat *) db->ptr;
+ db->ptr = NULL;
+
+ ret = msync (vdb->ptr, db->size, MS_SYNC);
+ assert (ret == 0);
+ ret = munmap (vdb->ptr, db->size);
+
+ free (vdb);
+ if (ret)
+ return errno;
+
+ close (db->fd);
+
+ return 0;
+}
+
+
+/*
+ * fetch num'th dir entry (n is 0 based), convert it
+ * to hostorder and store it in `e'.
+ */
+
+static int
+vdbflat_get_dir (struct voldb *db,
+ const u_int32_t num,
+ struct voldb_dir_entry *e)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+ size_t len;
+
+ assert (db && e);
+
+ if ((db->hdr.flags & VOLDB_DIR) == 0)
+ return EINVAL; /* XXX */
+
+ if (db->hdr.num < num)
+ return EINVAL; /* XXX */
+
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN && 0
+ memcpy (e, &vdb->u.dir[num], sizeof (*e));
+#else
+ {
+ u_int32_t tmp;
+ int i;
+ unsigned char *ptr =
+ ((unsigned char *)vdb->u.dir) +
+ VOLDB_DIR_SIZE * num;
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->nextptr = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->unique = ntohl(tmp); ptr += sizeof(tmp);
+
+ len = ONODE_OPAQUE_SIZE;
+ ydr_decode_onode_opaque (&e->ino, ptr, &len);
+ ptr += ONODE_OPAQUE_SIZE - len;
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare2 = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->InterfaceVersion = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->FileType = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->LinkCount = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Length = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare3 = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->DataVersion = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Author = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Owner = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->UnixModeBits = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->ParentVnode = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->ParentUnique = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->SegSize = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->ServerModTime = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare4 = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Group = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare5 = ntohl(tmp); ptr += sizeof(tmp);
+
+ for (i = 0 ; i < FS_MAX_ACL; i++) {
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->negacl[i].owner = ntohl(tmp); ptr += sizeof(tmp);
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->negacl[i].flags = ntohl(tmp); ptr += sizeof(tmp);
+ }
+ for (i = 0 ; i < FS_MAX_ACL; i++) {
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->acl[i].owner = ntohl(tmp); ptr += sizeof(tmp);
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->acl[i].flags = ntohl(tmp); ptr += sizeof(tmp);
+ }
+ }
+#endif
+ return 0;
+}
+
+/*
+ * store e as num'th dir entry (n is 0 based), convert it to
+ * network order. DO NOT STORE the ACL.
+ */
+
+int
+vdbflat_put_dir (struct voldb *db,
+ const u_int32_t num,
+ struct voldb_dir_entry *e)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+
+ assert (db && e);
+
+ if ((db->hdr.flags & VOLDB_DIR) == 0)
+ return EINVAL; /* XXX */
+
+ if (db->hdr.num < num)
+ return EINVAL; /* XXX */
+
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN && 0
+ memcpy (&vdb->u.dir[num], e, sizeof (*e));
+#else
+ {
+ u_int32_t tmp;
+ size_t len;
+ unsigned char *ptr =
+ ((unsigned char *)vdb->u.dir) +
+ VOLDB_DIR_SIZE * num;
+
+ tmp = htonl(e->nextptr);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->unique);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ len = ONODE_OPAQUE_SIZE;
+ ydr_encode_onode_opaque (&e->ino, ptr, &len);
+ ptr += ONODE_OPAQUE_SIZE - len;
+
+ tmp = htonl(e->spare2);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->InterfaceVersion);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->FileType);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->LinkCount);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Length);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->spare3);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->DataVersion);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Author);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Owner);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->UnixModeBits);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->ParentVnode);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->ParentUnique);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->SegSize);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->ServerModTime);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->spare4);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Group);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->spare5);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * store e as num'th acl entry (n is 0 based), convert it to
+ * network order.
+ */
+
+static int
+vdbflat_put_acl (struct voldb *db, u_int32_t num, struct voldb_dir_entry *e)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+
+ assert (db && e);
+
+ if ((db->hdr.flags & VOLDB_DIR) == 0)
+ return EINVAL; /* XXX */
+
+ if (db->hdr.num < num)
+ return EINVAL; /* XXX */
+
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN && 0
+ memcpy ((char *)&vdb->u.dir[num] + VOLDB_FILE_SIZE, &e->acl,
+ sizeof (*e->negacl) + sizeof (*e->acl));
+#else
+ {
+ u_int32_t tmp;
+ unsigned char *ptr =
+ ((unsigned char *)vdb->u.dir) +
+ VOLDB_DIR_SIZE * num;
+ int i;
+
+ ptr += VOLDB_FILE_SIZE;
+
+ for (i = 0 ; i < FS_MAX_ACL; i++) {
+ tmp = htonl(e->negacl[i].owner);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+ tmp = htonl(e->negacl[i].flags);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+ }
+ for (i = 0 ; i < FS_MAX_ACL; i++) {
+ tmp = htonl(e->acl[i].owner);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+ tmp = htonl(e->acl[i].flags);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+ }
+ }
+#endif
+ return 0;
+}
+
+
+/*
+ * fetch num'th file entry (n is 0 based), convert it
+ * to hostorder and store it in `e'.
+ */
+
+static int
+vdbflat_get_file (struct voldb *db, u_int32_t num, struct voldb_file_entry *e)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+
+ assert (db && e);
+
+ if ((db->hdr.flags & VOLDB_FILE) == 0)
+ return EINVAL; /* XXX */
+
+ if (db->hdr.num < num)
+ return EINVAL; /* XXX */
+
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN && 0
+ memcpy (e, &vdb->u.file[num], sizeof (*e));
+#else
+ {
+ u_int32_t tmp;
+ size_t len;
+ unsigned char *ptr =
+ ((unsigned char *)vdb->u.file) +
+ VOLDB_FILE_SIZE * num;
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->nextptr = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->unique = ntohl(tmp); ptr += sizeof(tmp);
+
+ len = ONODE_OPAQUE_SIZE;
+ ydr_decode_onode_opaque (&e->ino, ptr, &len);
+ ptr += ONODE_OPAQUE_SIZE - len;
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare2 = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->InterfaceVersion = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->FileType = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->LinkCount = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Length = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare3 = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->DataVersion = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Author = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Owner = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->UnixModeBits = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->ParentVnode = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->ParentUnique = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->SegSize = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->ServerModTime = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare4 = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->Group = ntohl(tmp); ptr += sizeof(tmp);
+
+ memcpy (&tmp, ptr, sizeof(tmp));
+ e->spare5 = ntohl(tmp); ptr += sizeof(tmp);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * store e as num'th file entry (n is 0 based), convert it to
+ * network order.
+ */
+
+int
+vdbflat_put_file (struct voldb *db, u_int32_t num, struct voldb_file_entry *e)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+
+ assert (db && e);
+
+ if ((db->hdr.flags & VOLDB_FILE) == 0)
+ return EINVAL; /* XXX */
+
+ if (db->hdr.num < num)
+ return EINVAL; /* XXX */
+
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN && 0
+ memcpy (&vdb->u.file[num], e, sizeof (*e));
+#else
+ {
+ u_int32_t tmp;
+ size_t len;
+ unsigned char *ptr =
+ ((unsigned char *)vdb->u.file) +
+ VOLDB_FILE_SIZE * num;
+
+ tmp = htonl(e->nextptr);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->unique);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ len = ONODE_OPAQUE_SIZE;
+ ydr_encode_onode_opaque (&e->ino, ptr, &len);
+ ptr += ONODE_OPAQUE_SIZE - len;
+
+ tmp = htonl(e->spare2);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->InterfaceVersion);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->FileType);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->LinkCount);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Length);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->spare3);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->DataVersion);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Author);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Owner);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->UnixModeBits);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->ParentVnode);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->ParentUnique);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->SegSize);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->ServerModTime);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->spare4);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->Group);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+
+ tmp = htonl(e->spare5);
+ memcpy (ptr, &tmp, sizeof(tmp)); ptr += sizeof(tmp);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Extend the db and add more entries.
+ */
+
+static int
+vdbflat_extend_db (struct voldb *db, unsigned int num)
+{
+ int dirp = 0, ret;
+ size_t newsize;
+ u_int32_t oldnum = db->hdr.num;
+ vdbflat *vdb = db->ptr;
+
+ if (db->hdr.magic != VOLDB_MAGIC_HEADER)
+ return EINVAL; /* XXX */
+
+ if ((db->hdr.flags & (VOLDB_FILE|VOLDB_DIR)) == VOLDB_DIR) {
+ dirp = 1;
+ newsize = db->size + num * VOLDB_DIR_SIZE;
+ } else if ((db->hdr.flags & (VOLDB_FILE|VOLDB_DIR)) == VOLDB_FILE)
+ newsize = db->size + num * VOLDB_FILE_SIZE;
+ else
+ return EINVAL; /* XXX */
+
+ ret = munmap (vdb->ptr, db->size);
+ if (ret)
+ return errno;
+
+ ret = ftruncate (db->fd, newsize);
+ if (ret)
+ return errno;
+
+ db->size = newsize;
+ db->hdr.num += num;
+
+ vdb->ptr = mmap (NULL, db->size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, db->fd, 0);
+ if (vdb->ptr == (void *)MAP_FAILED)
+ return errno; /* XXX */
+
+ set_volhdr_union_ptr (db);
+
+ if (dirp) {
+ u_int32_t i = oldnum;
+ struct voldb_dir_entry e;
+
+ memset (&e, 0, sizeof (e));
+ e.FileType = 0;
+
+ while (i < db->hdr.num) {
+ if (i < db->hdr.num - 1)
+ e.nextptr = i + 1;
+ else
+ e.nextptr = vdb->freeptr;
+ ret = voldb_put_dir (db, i, &e);
+ i++;
+ if (ret) {
+ abort(); /* XXX need ftruncate and remap */
+ return ret;
+ }
+ }
+ } else {
+ u_int32_t i = oldnum;
+ struct voldb_file_entry e;
+
+ memset (&e, 0, sizeof (e));
+ e.FileType = 0;
+
+ while (i < db->hdr.num) {
+ if (i < db->hdr.num - 1)
+ e.nextptr = i + 1;
+ else
+ e.nextptr = vdb->freeptr;
+ ret = voldb_put_file (db, i, &e);
+ i++;
+ if (ret) {
+ abort(); /* XXX need ftruncate and remap */
+ return ret;
+ }
+ }
+ }
+
+ vdb->freeptr = oldnum;
+
+ ret = voldb_write_hdr (db->fd, db);
+ if (ret)
+ return errno;
+
+ return 0;
+}
+
+int
+vdbflat_new_entry (struct voldb *db, u_int32_t *num, u_int32_t *unique)
+{
+ u_int32_t oldfreeptr, newfreeptr, newunique;
+ vdbflat *vdb = db->ptr;
+ int ret;
+
+ if (vdb->freeptr == 0) {
+ ret = vdbflat_extend_db (db, VOLDB_ENTEND_NUM);
+ if (ret)
+ return ret;
+ }
+
+ oldfreeptr = vdb->freeptr;
+
+ if ((db->hdr.flags & VOLDB_DIR) == VOLDB_DIR) {
+ struct voldb_dir_entry e;
+
+ ret = voldb_get_dir (db, oldfreeptr, &e);
+ if (ret)
+ return ret;
+
+ newfreeptr = e.nextptr;
+ newunique = ++e.unique;
+ e.nextptr = 0;
+ e.FileType = TYPE_DIR;
+
+ ret = voldb_put_dir (db, oldfreeptr, &e);
+ if (ret)
+ return ret;
+
+ } else if ((db->hdr.flags & VOLDB_FILE) == VOLDB_FILE) {
+ struct voldb_file_entry e;
+
+ ret = voldb_get_file (db, oldfreeptr, &e);
+ if (ret)
+ return ret;
+
+ newfreeptr = e.nextptr;
+ newunique = ++e.unique;
+ e.nextptr = 0;
+ e.FileType = TYPE_FILE;
+
+ ret = voldb_put_file (db, oldfreeptr, &e);
+ if (ret)
+ return ret;
+ } else
+ abort();
+
+ vdb->freeptr = newfreeptr;
+
+ ret = voldb_write_hdr (db->fd, db);
+ if (ret)
+ return ret;
+
+ *num = oldfreeptr;
+ *unique = newunique;
+
+ return 0;
+}
+
+/*
+ * In database `db' add entry `num' to the freelist,
+ * return the allocated inode `ino' that was associated
+ * with `num'.
+ */
+
+static int
+vdbflat_del_entry (struct voldb *db,
+ const u_int32_t num,
+ onode_opaque *ino)
+{
+ vdbflat *vdb = db->ptr;
+ int ret;
+
+ if ((db->hdr.flags & (VOLDB_DIR|VOLDB_FILE)) == VOLDB_DIR) {
+ struct voldb_dir_entry e;
+
+ ret = voldb_get_dir (db, num, &e);
+ if (ret)
+ return ret;
+
+ e.FileType = 0;
+ e.ParentVnode = e.ParentUnique = 0;
+ e.LinkCount = 0;
+ assert (e.nextptr == 0);
+ e.nextptr = vdb->freeptr;
+ if (ino)
+ memcpy (ino, &e.ino, sizeof (e.ino));
+ memset (&e.ino, 0, sizeof(e.ino));
+
+ ret = voldb_put_dir (db, num, &e);
+ if (ret)
+ return ret;
+
+ } else if ((db->hdr.flags & (VOLDB_DIR|VOLDB_FILE)) == VOLDB_FILE) {
+ struct voldb_file_entry e;
+
+ ret = voldb_get_file (db, num, &e);
+ if (ret)
+ return ret;
+
+ e.FileType = 0;
+ e.ParentVnode = e.ParentUnique = 0;
+ e.LinkCount = 0;
+ assert (e.nextptr == 0);
+ e.nextptr = vdb->freeptr;
+ if (ino)
+ memcpy (ino, &e.ino, sizeof (e.ino));
+ memset (&e.ino, 0, sizeof(e.ino));
+
+ ret = voldb_put_file (db, num, &e);
+ if (ret)
+ return ret;
+ } else
+ return EINVAL; /* XXX */
+
+ vdb->freeptr = num;
+
+ ret = voldb_write_hdr (db->fd, db);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+vdbflat_flush (struct voldb *db)
+{
+ vdbflat *vdb = db->ptr;
+
+ if (msync (vdb->ptr, db->size, MS_SYNC) < 0)
+ return errno;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+vdbflat_write_header (struct voldb *db,
+ void *d,
+ size_t sz)
+{
+ vdbflat *vdb = (vdbflat *) db->ptr;
+ unsigned char *data = d;
+ size_t size = sz;
+ u_int32_t i;
+ int ret;
+
+ assert (sz == VOLDB_HEADER_SIZE);
+
+ /*
+ * Make sure we don't overwrite the voldb header
+ */
+
+ data += VOLDB_HEADER_HALF;
+ size -= VOLDB_HEADER_HALF;
+
+ assert (size >= sizeof (i));
+
+ if (vdb == NULL) {
+ i = htonl (0);
+ } else {
+ i = htonl(vdb->freeptr);
+ }
+ memcpy (data, &i, sizeof (i));
+
+ /* Now store it to the mmap file */
+ memcpy (vdb->ptr, d, sz);
+
+ ret = msync (vdb->ptr, sz, MS_SYNC);
+ if (ret)
+ return errno;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+struct voldb_type vdb_flat = {
+ vdbflat_init,
+ vdbflat_close,
+ vdbflat_get_dir,
+ vdbflat_put_dir,
+ vdbflat_put_acl,
+ vdbflat_get_file,
+ vdbflat_put_file,
+ vdbflat_flush,
+ vdbflat_new_entry,
+ vdbflat_del_entry,
+ vdbflat_write_header
+};
diff --git a/usr.sbin/afs/src/milko/lib/voldb/vol.c b/usr.sbin/afs/src/milko/lib/voldb/vol.c
new file mode 100644
index 00000000000..89a98058dd0
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/vol.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * the volume data file
+ */
+
+#include "voldb_locl.h"
+
+RCSID("$Id: vol.c,v 1.1 2000/09/11 14:41:18 art Exp $");
+
+/*
+ * get the partial name of the volume
+ * `num' points out the volume and the name is passed back in the
+ * string `str' that has size `sz'.
+ */
+
+int
+vol_getname (u_int32_t num, char *str, size_t sz)
+{
+ int i;
+ i = snprintf (str, sz, "vol%08u", num);
+ assert (i > 0);
+ return 0;
+}
+
+/*
+ * get the full name of the volume.
+ * `part' and `num' points out the volume, the named of passed back in
+ * `str' that has the size of `sz'.
+ */
+
+int
+vol_getfullname (u_int32_t part, u_int32_t num, char *str, size_t sz)
+{
+ int ret;
+ char volname[VOLSER_MAXVOLNAME];
+
+ ret = vol_getname (num, volname, sizeof (volname));
+ if (ret)
+ return ret;
+
+ if (part <= 'z' - 'a')
+ ret = snprintf (str, sz, "/vicep%c/%s", 'a' + part, volname);
+#if 0
+ else if (part <= ('z' - 'a') * ('z' - 'a'))
+ ret = snprintf (str, sz, "/vicep%c%c/%s",
+ 'a' + part / ('z' - 'a'),
+ 'a' + part % ('z' - 'a'),
+ volname);
+#endif
+ else
+ return EINVAL; /* XXX */
+
+ assert (ret > 0);
+ return 0;
+}
+
+/*
+ * read header from stable storage
+ */
+
+int
+vol_read_header (int fd, volintInfo *info)
+{
+ struct stat sb;
+ char *buf, *ptr;
+ size_t size;
+ int ret;
+
+ assert (info);
+
+ ret = fstat (fd, &sb);
+ if (ret)
+ return errno; /* XXX */
+
+ if (sb.st_size != VOLINTINFO_SIZE)
+ return EINVAL;
+
+ ret = lseek (fd, 0, SEEK_SET);
+ if (ret)
+ return errno; /* XXX */
+
+ buf = malloc (VOLINTINFO_SIZE);
+ if (buf == NULL)
+ return ENOMEM; /* XXX */
+
+ ret = read (fd, buf, VOLINTINFO_SIZE);
+ if (ret <= 0) {
+ free (buf);
+ return ret;
+ }
+
+ size = VOLINTINFO_SIZE;
+ ptr = ydr_decode_volintInfo(info, buf, &size);
+ if (ptr == NULL) {
+ free (buf);
+ return errno; /* XXX */
+ }
+
+ free (buf);
+
+ return 0;
+}
+
+/*
+ * write header to stable storage
+ */
+
+int
+vol_write_header (int fd, volintInfo *info)
+{
+ char *buf, *ptr;
+ size_t size;
+ int ret;
+
+ assert (info);
+
+ ret = lseek (fd, 0, SEEK_SET);
+ if (ret)
+ return errno; /* XXX */
+
+ size = VOLINTINFO_SIZE;
+ buf = malloc (size);
+ if (buf == NULL)
+ return ENOMEM; /* XXX */
+
+ ptr = ydr_encode_volintInfo(info, buf, &size);
+ if (ptr == NULL) {
+ free (buf);
+ return errno; /* XXX */
+ }
+
+ size = ptr - buf;
+ ret = write (fd, buf, size);
+ if (ret != size)
+ ret = errno;
+ else
+ ret = 0;
+
+ free (buf);
+
+ return ret;
+
+}
+
+/*
+ * create a partition `part' with number `num', name `name'
+ * of type `type' that has `parent' as parent.
+ */
+
+int
+vol_create (int fd, u_int32_t num, const char *name,
+ u_int32_t type, u_int32_t parent)
+{
+ int ret;
+ struct timeval tv;
+ volintInfo info;
+
+ gettimeofday (&tv, NULL);
+
+ strlcpy (info.name, name, sizeof (info.name));
+ info.name[sizeof (info.name)-1] = '\0';
+ info.type = type;
+ info.volid = num;
+ info.backupID = 0;
+ info.parentID = parent;
+ info.cloneID = 0;
+ info.status = 0;
+ info.copyDate = 0;
+ info.inUse = 1;
+ info.needsSalvaged = 0;
+ info.destroyMe = 'c';
+ info.creationDate = tv.tv_sec;
+ info.accessDate = tv.tv_sec;
+ info.updateDate = tv.tv_sec;
+ info.backupDate = tv.tv_sec;
+ info.dayUse = 0;
+ info.filecount = 1;
+ info.maxquota = 5000; /* XXX */
+ info.size = 0;
+ info.flags = 0;
+ info.spare0 = 0;
+ info.spare1 = 0;
+ info.spare2 = 0;
+ info.spare3 = 0;
+
+ ret = vol_write_header (fd, &info);
+ close (fd);
+ return ret;
+}
+
+
+/*
+ * Pretty print the volintInfo structure
+ */
+
+void
+vol_pretty_print_info (FILE *out, volintInfo *info)
+{
+ assert (info);
+
+ fprintf (out, "name:\t\t%-32s\n", info->name);
+ fprintf (out, "type:\t\t%d\n", info->type);
+ fprintf (out, "volid: %d backupID: %d parentID: %d cloneID: %d\n",
+ info->volid, info->backupID, info->parentID, info->cloneID);
+ fprintf (out, "status:\t\t0x%x\n", info->status);
+ fprintf (out, "copyDate:\t%d\n", info->copyDate);
+ fprintf (out, "inUse:\t\t%d\n", info->inUse);
+ fprintf (out, "needsSalvaged:\t%d\n", info->needsSalvaged);
+ fprintf (out, "destroyMe:\t%d\n", info->destroyMe);
+
+ fprintf (out, " XXX \n");
+}
+
+/*
+ *
+ */
+
+static char *type_array[] = {
+ "RW",
+ "RO",
+ "BACK",
+};
+
+const char *
+vol_voltype2name (int32_t type)
+{
+ if (type < 0 || type > 2)
+ return "UNKN";
+ return type_array[type];
+}
+
diff --git a/usr.sbin/afs/src/milko/lib/voldb/voldb.c b/usr.sbin/afs/src/milko/lib/voldb/voldb.c
new file mode 100644
index 00000000000..dad554e2f70
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/voldb.c
@@ -0,0 +1,507 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+
+/*
+ * simple flat db for the vnodes
+ */
+
+#include "voldb_locl.h"
+#include "voldb_internal.h"
+
+RCSID("$Id: voldb.c,v 1.1 2000/09/11 14:41:18 art Exp $");
+
+struct voldb_type *voltypes[] = {
+ &vdb_flat,
+};
+
+
+/*
+ * afs_dir_p: returns true if vno is for a dir
+ */
+
+int
+afs_dir_p (int32_t vno) {
+ return vno & 1;
+}
+
+/*
+ * Conversion
+ */
+
+int32_t
+dir_afs2local (int32_t vno)
+{
+ assert (vno);
+ return (vno - 1) >> 1;
+}
+
+int32_t
+dir_local2afs (int32_t vno)
+{
+ return (vno << 1 ) + 1;
+}
+
+int32_t
+file_afs2local (int32_t vno)
+{
+ assert (vno);
+ return (vno >> 1) - 1;
+}
+
+int32_t
+file_local2afs (int32_t vno)
+{
+ return (vno + 1) << 1 ;
+}
+
+/*
+ *
+ */
+
+int
+voldb_parse_header (struct voldb *db, void *d, size_t sz)
+{
+ u_int32_t i;
+ unsigned char *data = d;
+
+ assert (sz >= VOLDB_HEADER_HALF);
+
+ memcpy (&i, data, sizeof (i));
+ db->hdr.magic = ntohl (i);
+ data += sizeof (u_int32_t);
+
+ memcpy (&i, data, sizeof (i));
+ db->hdr.num = ntohl (i);
+ data += sizeof (u_int32_t);
+
+ memcpy (&i, data, sizeof (i));
+ db->hdr.flags = ntohl (i);
+ data += sizeof (u_int32_t);
+
+ return 0;
+}
+
+/*
+ * boot up the db
+ * `fd' is a file descriptor to a db that is returned in `db'.
+ * `fd' is saved if everythings works out ok, otherwise its
+ * up to the caller to close it.
+ */
+
+int
+voldb_init (int fd, int32_t type, int32_t volume, struct voldb **db)
+{
+ struct stat sb;
+ int ret;
+
+ assert (db);
+ *db = NULL;
+
+ if (type < 0 ||
+ type >= sizeof (**voltypes)/ sizeof(*voltypes))
+ return EINVAL;
+
+ ret = fstat (fd, &sb);
+ if (ret)
+ return errno; /* XXX */
+
+ if (!S_ISREG(sb.st_mode))
+ return EINVAL; /* XXX */
+
+ *db = calloc (1, sizeof (**db));
+ if (*db == NULL)
+ return ENOMEM; /* XXX */
+
+ (*db)->size = sb.st_size;
+
+ (*db)->fd = fd;
+ (*db)->volume = volume;
+
+ ret = VOLDB_FUNC((*db),init)(fd, *db, 0);
+ if (ret) {
+ free (*db);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * closes the db
+ * The saved `fd' is also closed.
+ */
+
+int
+voldb_close (struct voldb *db)
+{
+ int ret;
+
+ assert (db);
+
+ ret = VOLDB_FUNC(db,close)(db);
+
+ free (db);
+ return 0;
+}
+
+
+/*
+ * store e as num'th acl entry (n is 0 based), convert it to
+ * network order.
+ *
+ * This one is special, where is where we should add acl's on file.
+ * Guess it's will be a configuration option.
+ */
+
+int
+voldb_put_acl (struct voldb *db, u_int32_t num, struct voldb_dir_entry *e)
+{
+ assert (db && e);
+ assert ((db->hdr.flags & VOLDB_DIR) == VOLDB_DIR);
+
+ return VOLDB_FUNC(db,put_acl)(db, num, e);
+}
+
+/*
+ * store a entry `e' in aproproate database `db'
+ */
+
+int
+voldb_put_entry (struct voldb *db, int32_t num, struct voldb_entry *e)
+{
+ assert (db && e);
+
+ switch (e->type) {
+ case TYPE_DIR:
+ assert ((db->hdr.flags & VOLDB_DIR) == VOLDB_DIR);
+ assert (e->u.dir.FileType == e->type);
+ return voldb_put_dir (db, num, &e->u.dir);
+ case TYPE_FILE:
+ case TYPE_LINK:
+ assert ((db->hdr.flags & VOLDB_FILE) == VOLDB_FILE);
+ assert (e->u.file.FileType == e->type);
+ return voldb_put_file (db, num, &e->u.file);
+ default:
+ abort();
+ }
+}
+
+/*
+ *
+ */
+
+int
+voldb_get_size (struct voldb *db, int32_t *total_size, int32_t *num_entries)
+{
+ assert (db);
+
+ *total_size = db->size;
+ *num_entries = db->hdr.num;
+
+ return 0;
+}
+
+/*
+ * Retrive a entry `e' from the database `db'
+ *
+ * We use the db to figure out what type e might have. In the case of
+ * a FILE/LINK we have to look at the content of `e' after the fetch.
+ */
+
+int
+voldb_get_entry (struct voldb *db, int32_t num, struct voldb_entry *e)
+{
+ assert (db && e);
+
+ if ((db->hdr.flags & VOLDB_DIR) == VOLDB_DIR) {
+ e->type = TYPE_DIR;
+ return voldb_get_dir (db, num, &e->u.dir);
+ }
+ if ((db->hdr.flags & VOLDB_FILE) == VOLDB_FILE) {
+ int ret;
+ ret = voldb_get_file (db, num, &e->u.file);
+ if (ret == 0)
+ e->type = e->u.file.FileType;
+ return ret;
+ } else
+ abort();
+}
+
+/*
+ * Fill out the data we need to have stored and the
+ * let the lower layer store it.
+ */
+
+int
+voldb_write_hdr (int fd, struct voldb *db)
+{
+ int ret;
+ u_int32_t i;
+ unsigned char data[VOLDB_HEADER_SIZE], *ptr;
+
+ ptr = data;
+
+ i = htonl (db->hdr.magic);
+ memcpy (ptr, &i, sizeof (i));
+ ptr += sizeof (u_int32_t);
+
+ i = htonl (db->hdr.num);
+ memcpy (ptr, &i, sizeof (i));
+ ptr += sizeof (u_int32_t);
+
+ i = htonl (db->hdr.flags);
+ memcpy (ptr, &i, sizeof (i));
+ ptr += sizeof (u_int32_t);
+
+ /* Here is space for yet other 2 int32_t */
+
+ ret = VOLDB_FUNC(db,write_header)(db, data, VOLDB_HEADER_SIZE);
+
+ return ret;
+}
+
+
+/*
+ * create a db header in a empty existing file pointed by `fd'
+ * with flags set to `flags'.
+ */
+
+int
+voldb_create_header (int fd, int type, int flags)
+{
+ struct stat sb;
+ struct voldb db;
+ int ret;
+
+ ret = fstat (fd, &sb);
+ if (ret)
+ return errno; /* XXX */
+
+ if (sb.st_size != 0)
+ return EINVAL; /* XXX */
+
+ ret = ftruncate (fd, VOLDB_HEADER_SIZE);
+ if (ret)
+ return errno; /* XXX */
+
+ db.type = type;
+ db.hdr.magic = VOLDB_MAGIC_HEADER;
+ db.hdr.num = 0;
+ db.hdr.flags = flags;
+ db.ptr = NULL;
+ db.size = VOLDB_HEADER_SIZE;
+
+ ret = VOLDB_FUNC(&db,init)(fd, &db, 1);
+ if (ret) abort();
+
+ ret = voldb_write_hdr (fd, &db);
+ if (ret) abort();
+
+ ret = VOLDB_FUNC(&db,close)(&db);
+ if (ret) abort();
+ return ret;
+}
+
+/*
+ * Assure `db' is stored to disk.
+ */
+
+int
+voldb_flush (struct voldb *db)
+{
+ int ret;
+ assert (db);
+ ret = voldb_write_hdr (db->fd, db);
+ if (ret) return ret;
+ return VOLDB_FUNC(db,flush)(db);
+}
+
+
+int
+voldb_new_entry (struct voldb *db, u_int32_t *num, u_int32_t *unique)
+{
+ assert (db && unique);
+
+ assert ((db->hdr.flags & (VOLDB_FILE|VOLDB_DIR)) !=
+ (VOLDB_FILE|VOLDB_DIR));
+ assert ((db->hdr.flags & (VOLDB_FILE|VOLDB_DIR)) != 0);
+
+ return VOLDB_FUNC(db,new_entry)(db, num, unique);
+}
+
+/*
+ *
+ */
+
+int
+voldb_del_entry (struct voldb *db, u_int32_t num, onode_opaque *ino)
+{
+ assert (db);
+
+ return VOLDB_FUNC(db,del_entry)(db, num, ino);
+}
+
+
+/*
+ *
+ */
+
+int
+voldb_header_info (struct voldb *db,
+ u_int32_t *num,
+ u_int32_t *flags)
+{
+ if (num)
+ *num = db->hdr.num;
+ if (flags)
+ *flags = db->hdr.flags;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+u_int32_t
+voldb_get_volume (struct voldb *db)
+{
+ return db->volume;
+}
+
+/*
+ *
+ */
+
+int
+voldb_pretty_print_file (struct voldb_file_entry *e)
+{
+ printf (" nextptr = %d\n", e->nextptr);
+ printf (" unique = %d\n", e->unique);
+ printf (" ino = ");
+ vstatus_print_onode (stdout, &e->ino);
+ printf (" InterfaceVersion = %d\n", e->InterfaceVersion);
+ printf (" FileType = %d\n", e->FileType);
+ printf (" LinkCount = %d\n", e->LinkCount);
+ printf (" Length = %d\n", e->Length);
+ printf (" DataVersion = %d\n", e->DataVersion);
+ printf (" Author = %d\n", e->Author);
+ printf (" Owner = %d\n", e->Owner);
+ printf (" UnixModeBits = 0%o\n", e->UnixModeBits);
+ printf (" ParentVnode = %d\n", e->ParentVnode);
+ printf (" ParentUnique = %d\n", e->ParentUnique);
+ printf (" SegSize = %d\n", e->SegSize);
+ printf (" ServerModTime = %d\n", e->ServerModTime);
+ printf (" Group = %d\n", e->Group);
+
+ return 0;
+}
+
+int
+voldb_pretty_print_dir (struct voldb_dir_entry *e)
+{
+ int i;
+
+ printf (" nextptr = %d\n", e->nextptr);
+ printf (" unique = %d\n", e->unique);
+ printf (" ino = ");
+ vstatus_print_onode (stdout, &e->ino);
+ printf (" InterfaceVersion = %d\n", e->InterfaceVersion);
+ printf (" FileType = %d\n", e->FileType);
+ printf (" LinkCount = %d\n", e->LinkCount);
+ printf (" Length = %d\n", e->Length);
+ printf (" DataVersion = %d\n", e->DataVersion);
+ printf (" Author = %d\n", e->Author);
+ printf (" Owner = %d\n", e->Owner);
+ printf (" UnixModeBits = 0%o\n", e->UnixModeBits);
+ printf (" ParentVnode = %d\n", e->ParentVnode);
+ printf (" ParentUnique = %d\n", e->ParentUnique);
+ printf (" SegSize = %d\n", e->SegSize);
+ printf (" ServerModTime = %d\n", e->ServerModTime);
+ printf (" Group = %d\n", e->Group);
+
+ printf (" ACL:");
+ printf (" negative:\n");
+ for (i = 0; i < FS_MAX_ACL; i++)
+ printf (" owner %d flags 0x%x\n",
+ e->negacl[i].owner, e->negacl[i].flags);
+ printf (" positive:\n");
+ for (i = 0; i < FS_MAX_ACL; i++)
+ printf (" owner %d flags 0x%x\n",
+ e->acl[i].owner, e->acl[i].flags);
+
+ return 0;
+}
+
+int
+voldb_pretty_print_header (struct voldb *db)
+{
+ printf ("type:\t%d", db->type);
+ printf ("size:\t%d", db->size);
+ printf ("magic:\t0x%x (should be 0x%x)\n",
+ db->hdr.magic, VOLDB_MAGIC_HEADER);
+ printf ("num:\t%d\n", db->hdr.num);
+ printf ("flags:\t0x%x", db->hdr.flags);
+ return 0;
+}
+
+/*
+ * voldb_update_time
+ *
+ * Should be called upon creation and when data is modified.
+ * Should be called before any call to vld_storestatus_to_ent().
+ * Should _not_ be called when metadata is changed.
+ */
+
+void
+voldb_update_time(struct voldb_entry *e, time_t t)
+{
+ switch (e->type) {
+ case TYPE_DIR:
+ e->u.dir.ServerModTime = t; /* XXX update ClientModTime also */
+ break;
+ case TYPE_FILE:
+ case TYPE_LINK:
+ e->u.file.ServerModTime = t; /* XXX update ClientModTime also */
+ break;
+ default:
+ abort();
+ break;
+ }
+}
diff --git a/usr.sbin/afs/src/milko/lib/voldb/voldb.h b/usr.sbin/afs/src/milko/lib/voldb/voldb.h
new file mode 100644
index 00000000000..4f277182ad8
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/voldb.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: voldb.h,v 1.1 2000/09/11 14:41:18 art Exp $ */
+
+#ifndef FILBUNKE_VOLDB_H
+#define FILBUNKE_VOLDB_H 1
+
+#include <volumeserver.h>
+#include <fs_def.h>
+#include <vstatus.h>
+
+/*
+ * Of this space half is shared of the voldb and the underlaying
+ * layer.
+ */
+
+#define VOLDB_HEADER_SIZE (10*4)
+#define VOLDB_HEADER_HALF (VOLDB_HEADER_SIZE/2)
+
+/*
+ * Data structure for a file (link is same)
+ */
+
+struct voldb_file_entry {
+ u_int32_t nextptr;
+ u_int32_t unique;
+ onode_opaque ino;
+ u_int32_t spare2; /* Must be zero */
+ u_int32_t InterfaceVersion;
+ u_int32_t FileType;
+ u_int32_t LinkCount;
+ u_int32_t Length;
+ u_int32_t spare3; /* Must be zero */
+ u_int32_t DataVersion;
+ u_int32_t Author;
+ u_int32_t Owner;
+ u_int32_t UnixModeBits;
+ u_int32_t ParentVnode;
+ u_int32_t ParentUnique;
+ u_int32_t SegSize;
+ u_int32_t ServerModTime;
+ u_int32_t spare4; /* Must be zero */
+ u_int32_t Group;
+ u_int32_t spare5; /* Must be zero */
+};
+
+/*
+ * Data structure for an acl_entry
+ */
+
+struct acl_entry {
+ u_int32_t owner;
+ u_int32_t flags;
+};
+
+/*
+ * Data structure for a dir
+ */
+
+struct voldb_dir_entry {
+ u_int32_t nextptr;
+ u_int32_t unique;
+ onode_opaque ino;
+ u_int32_t spare2; /* Must be zero */
+ u_int32_t InterfaceVersion;
+ u_int32_t FileType;
+ u_int32_t LinkCount;
+ u_int32_t Length;
+ u_int32_t spare3; /* Must be zero */
+ u_int32_t DataVersion;
+ u_int32_t Author;
+ u_int32_t Owner;
+ u_int32_t UnixModeBits;
+ u_int32_t ParentVnode;
+ u_int32_t ParentUnique;
+ u_int32_t SegSize;
+ u_int32_t ServerModTime;
+ u_int32_t spare4; /* Must be zero */
+ u_int32_t Group;
+ u_int32_t spare5; /* Must be zero */
+ struct acl_entry negacl[FS_MAX_ACL];
+ struct acl_entry acl[FS_MAX_ACL];
+};
+
+struct voldb_entry {
+ int32_t type;
+ union {
+ struct voldb_dir_entry dir;
+ struct voldb_file_entry file;
+ } u;
+};
+
+/* defines */
+
+#define VOLDB_FILE 0x1
+#define VOLDB_DIR 0x2
+
+#define VOLDB_DEFAULT_TYPE 0
+
+/* forward declarations */
+
+struct voldb;
+
+/* prototypes */
+
+int
+voldb_init (int fd, int32_t type, int32_t volume, struct voldb **db);
+
+int
+voldb_close (struct voldb *db);
+
+int
+voldb_put_entry (struct voldb *db, int32_t num, struct voldb_entry *e);
+
+int
+voldb_get_size (struct voldb *db, int32_t *total_size, int32_t *num_entries);
+
+int
+voldb_get_entry (struct voldb *db, int32_t num, struct voldb_entry *e);
+
+int
+voldb_put_acl (struct voldb *db, u_int32_t num, struct voldb_dir_entry *e);
+
+int
+voldb_pretty_print_file (struct voldb_file_entry *e);
+
+int
+voldb_pretty_print_dir (struct voldb_dir_entry *e);
+
+int
+voldb_pretty_print_header (struct voldb *db);
+
+int
+voldb_create_header (int fd, int type, int flags);
+
+int
+voldb_flush (struct voldb *db);
+
+int
+voldb_new_entry (struct voldb *db, u_int32_t *num, u_int32_t *unique);
+
+int
+voldb_del_entry (struct voldb *db, u_int32_t num, onode_opaque *ino);
+
+int
+voldb_header_info (struct voldb *db,
+ u_int32_t *num,
+ u_int32_t *flags);
+
+u_int32_t
+voldb_get_volume (struct voldb *db);
+
+int
+voldb_write_hdr (int fd, struct voldb *db);
+
+void
+voldb_update_time(struct voldb_entry *e, time_t t);
+
+/* vol.c */
+
+int
+vol_getname (u_int32_t num, char *str, size_t sz);
+
+int
+vol_getfullname (u_int32_t part, u_int32_t num, char *str, size_t sz);
+
+int
+vol_read_header (int fd, volintInfo *info);
+
+int
+vol_write_header (int fd, volintInfo *info);
+
+int
+vol_create (int fd, u_int32_t num, const char *name,
+ u_int32_t type, u_int32_t parent);
+
+void
+vol_pretty_print_info (FILE *out, volintInfo *info);
+
+enum voldb_newnum_sizes { VOLDB_ENTEND_NUM = 10 } ;
+
+const char *
+vol_voltype2name (int32_t type);
+
+
+int
+afs_dir_p (int32_t vno);
+
+int32_t
+dir_afs2local (int32_t vno);
+
+int32_t
+dir_local2afs (int32_t vno);
+
+int32_t
+file_afs2local (int32_t vno);
+
+int32_t
+file_local2afs (int32_t vno);
+
+#endif /* FILBUNKE_VOLDB_H 1 */
diff --git a/usr.sbin/afs/src/milko/lib/voldb/voldb_internal.h b/usr.sbin/afs/src/milko/lib/voldb/voldb_internal.h
new file mode 100644
index 00000000000..614a7abea69
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/voldb_internal.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+
+#ifndef _VOLDB_INTERNAL_H
+#define _VOLDB_INTERNAL_H
+
+/*
+ * Various internal data structures
+ */
+
+struct voldb_header {
+ u_int32_t magic; /* network order */
+#define VOLDB_MAGIC_HEADER 0x47111147
+ u_int32_t num; /* Number of entries in the db */
+ u_int32_t flags; /* flags */
+};
+
+struct voldb {
+ struct voldb_header hdr; /* header of voldb */
+ int32_t type; /* type of voldb */
+ size_t size; /* Size of file */
+ int fd; /* fd to volume */
+ int32_t volume; /* volume */
+ void *ptr; /* type owned data */
+};
+
+struct voldb_type {
+ int (*init) (int fd, struct voldb *db, int createp);
+ int (*close) (struct voldb *db);
+ int (*get_dir) (struct voldb *db,
+ const u_int32_t num,
+ struct voldb_dir_entry *e);
+ int (*put_dir) (struct voldb *db,
+ const u_int32_t num,
+ struct voldb_dir_entry *e);
+ int (*put_acl) (struct voldb *db,
+ u_int32_t num,
+ struct voldb_dir_entry *e);
+ int (*get_file) (struct voldb *db,
+ u_int32_t num,
+ struct voldb_file_entry *e);
+ int (*put_file) (struct voldb *db,
+ u_int32_t num,
+ struct voldb_file_entry *e);
+ int (*flush) (struct voldb *db);
+ int (*new_entry) (struct voldb *db,
+ u_int32_t *num,
+ u_int32_t *unique);
+ int (*del_entry) (struct voldb *db,
+ const u_int32_t num,
+ onode_opaque *ino);
+ int (*write_header) (struct voldb *db,
+ void *data,
+ size_t sz);
+};
+
+
+#define VOLDB_FUNC(db,name) (voltypes[(db)->type])->name
+
+extern struct voldb_type *voltypes[];
+
+static inline int __attribute__ ((unused))
+voldb_get_dir (struct voldb *db, u_int32_t num, struct voldb_dir_entry *e)
+{
+ return VOLDB_FUNC(db,get_dir)(db, num, e);
+}
+
+static inline int __attribute__ ((unused))
+voldb_get_file (struct voldb *db, u_int32_t num, struct voldb_file_entry *e)
+{
+ return VOLDB_FUNC(db,get_file)(db, num, e);
+}
+
+static inline int __attribute__ ((unused))
+voldb_put_dir (struct voldb *db, u_int32_t num, struct voldb_dir_entry *e)
+{
+ return VOLDB_FUNC(db,put_dir)(db, num, e);
+}
+
+static inline int __attribute__ ((unused))
+voldb_put_file (struct voldb *db, u_int32_t num, struct voldb_file_entry *e)
+{
+ return VOLDB_FUNC(db,put_file)(db, num, e);
+}
+
+int
+voldb_parse_header (struct voldb *db, void *d, size_t sz);
+
+/*
+ * Diffrent types of db's
+ */
+
+extern struct voldb_type vdb_flat;
+
+#endif /* _VOLDB_INTERNAL_H */
+
diff --git a/usr.sbin/afs/src/milko/lib/voldb/voldb_locl.h b/usr.sbin/afs/src/milko/lib/voldb/voldb_locl.h
new file mode 100644
index 00000000000..ec6a1c0f8c6
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/voldb/voldb_locl.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: voldb_locl.h,v 1.1 2000/09/11 14:41:18 art Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <unistd.h>
+
+#include <atypes.h>
+
+#include <err.h>
+
+#include <fs_def.h>
+#include <fs.h>
+#include <voldb.h>
+
+#include <volumeserver.h>
+
+#if !defined(MAP_FAILED)
+#define MAP_FAILED ((void *)(-1))
+#endif
+
diff --git a/usr.sbin/afs/src/milko/lib/vstatus/Makefile.in b/usr.sbin/afs/src/milko/lib/vstatus/Makefile.in
new file mode 100644
index 00000000000..7d4481451bd
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vstatus/Makefile.in
@@ -0,0 +1,105 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:19 art Exp $
+#
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+INCLUDES = -I. \
+ -I../../../include \
+ -I$(srcdir) \
+ $(KRB4_INC_FLAGS) \
+ -I$(srcdir)/../../../include
+
+CFLAGS = @CFLAGS@
+KRB4_INC_FLAGS= @KRB4_INC_FLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+YDR = ../../../ydr/ydr
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+sysconfdir = @sysconfdir@
+
+
+#PICFLAGS = @PICFLAGS@
+
+LIBNAME = $(LIBPREFIX)vstatus
+#LIBEXT = @LIBEXT@
+LIBEXT = a
+#SHLIBEXT = @SHLIBEXT@
+#LIBPREFIX = @LIBPREFIX@
+LIBPREFIX = lib
+#LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+DEFS = @DEFS@
+
+LIB_SOURCES = vstatus.c vstat.ydr.o
+
+SOURCES = $(LIB_SOURCES)
+
+LIB_OBJECTS = vstatus.o vstat.ydr.o
+
+OBJECTS = $(LIB_OBJECTS)
+
+all: $(LIB)
+
+vstat.ydr.c vstat.cs.c vstat.ss.c vstat.h vstat.ss.h vstat.cs.h: vstat.xg
+ $(YDR) $(srcdir)/vstat.xg
+
+vstatus.o: vstatus.h
+vstatus.h: vstat.h
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $(PICFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+check:
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a vstat.h vstat.ydr.c vstat.ss.h vstat.ss.c vstat.cs.h vstat.cs.c
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIBNAME).a: $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+#$(LIBNAME).$(SHLIBEXT): $(LIB_OBJECTS)
+# rm -f $@
+# $(LDSHARED) -o $@ $(LIB_OBJECTS)
+
+$(OBJECTS): ../../../include/config.h
+
+Makefile: Makefile.in ../../../config.status
+ cd ../../..; CONFIG_FILES=milko/lib/vstatus/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all install uninstall check clean mostlyclean distclean realclean
diff --git a/usr.sbin/afs/src/milko/lib/vstatus/vstat.xg b/usr.sbin/afs/src/milko/lib/vstatus/vstat.xg
new file mode 100644
index 00000000000..bb9484ee9c8
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vstatus/vstat.xg
@@ -0,0 +1,67 @@
+/* hej emacs, det h}r }r en -*-c-*- fil */
+
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+package VSTATUS_
+
+%#include <config.h>
+%#include <roken.h>
+
+const ONODE_OPAQUE_SZ = 100;
+
+struct onode_opaque {
+ int32_t size; /* sizeof(content(data)) */
+ char data[100]; /* opaque */
+};
+
+const VSTATUS_MAGIC = 0xCAFE4711;
+
+const VSTATUS_VERSION = 4;
+
+struct vstatus {
+ u_int32_t version; /* version */
+ u_int32_t magic; /* must be VSTATUS_MAGIC */
+ int32_t volid; /* The AFS-volume id */
+ int32_t type; /* Type of volume */
+ int32_t bstype; /* Type of backstore */
+ int32_t voldbtype; /* Type of voldb */
+ onode_opaque volinfoinode; /* The inode to volinfo */
+ onode_opaque dirinode; /* The inode to dirlist */
+ onode_opaque fileinode; /* The inode to filelist */
+};
diff --git a/usr.sbin/afs/src/milko/lib/vstatus/vstatus.c b/usr.sbin/afs/src/milko/lib/vstatus/vstatus.c
new file mode 100644
index 00000000000..e203b16bddb
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vstatus/vstatus.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+/*
+ * This module contains the code that parse the file /vice.+/vol\d{8}
+ * file. The file is have the following fields:
+ * see vstat.xg file.
+ */
+
+#include <config.h>
+
+RCSID("$Id: vstatus.c,v 1.1 2000/09/11 14:41:19 art Exp $");
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <assert.h>
+
+#include <err.h>
+
+#include <vstatus.h>
+
+/*
+ * Read in the volume status from `fd' and return it in `vs'
+ */
+
+int
+vstatus_read (int fd, vstatus *v)
+{
+ char *ptr = NULL;
+ char *ret_ptr;
+ size_t len;
+ int ret;
+
+ assert (v);
+
+ ptr = malloc (VSTATUS_SIZE);
+ if (ptr == NULL) {
+ ret = errno;
+ goto err_out;
+ }
+ len = VSTATUS_SIZE;
+
+ ret = lseek (fd, SEEK_SET, 0);
+ if (ret) {
+ ret = errno;
+ goto err_out;
+ }
+
+ ret = read (fd, ptr, VSTATUS_SIZE);
+ if (ret != VSTATUS_SIZE) {
+ ret = errno;
+ goto err_out;
+ }
+
+ ret_ptr = ydr_decode_vstatus (v, ptr, &len);
+ if (len != 0) {
+ ret = errno;
+ goto err_out;
+ }
+ free (ptr);
+
+ if (v->magic != VSTATUS_MAGIC ||
+ v->version != VSTATUS_VERSION)
+ return EINVAL;
+
+ return 0;
+
+ err_out:
+ if (ptr)
+ free (ptr);
+
+ return ret;
+}
+
+/*
+ * Write `vs' to `fd'
+ */
+
+int
+vstatus_write (int fd, vstatus *v)
+{
+ char *ptr = NULL;
+ char *ret_ptr;
+ size_t len;
+ int ret;
+
+ assert (v);
+
+ v->magic = VSTATUS_MAGIC;
+ v->version = VSTATUS_VERSION;
+
+ ptr = malloc (VSTATUS_SIZE);
+ if (ptr == NULL) {
+ ret = errno;
+ goto err_out;
+ }
+ len = VSTATUS_SIZE;
+
+ ret = lseek (fd, SEEK_SET, 0);
+ if (ret) {
+ ret = errno;
+ goto err_out;
+ }
+
+ ret_ptr = ydr_encode_vstatus (v, ptr, &len);
+ if (len != 0 || ret_ptr == NULL) {
+ ret = errno;
+ goto err_out;
+ }
+
+ ret = write (fd, ptr, VSTATUS_SIZE);
+ if (ret != VSTATUS_SIZE) {
+ ret = errno;
+ goto err_out;
+ }
+ free (ptr);
+
+ return 0;
+
+ err_out:
+ if (ptr)
+ free (ptr);
+
+ return ret;
+}
+
+void
+vstatus_print_onode (FILE *out, onode_opaque *o)
+{
+ int i;
+ assert (o);
+
+ fprintf (out, "%d:0x", o->size);
+ for (i = 0; i < o->size; i++) {
+ fprintf (out, "%02x", (int) o->data[i] & 0xff);
+ }
+ fprintf (out, "\n");
+
+}
diff --git a/usr.sbin/afs/src/milko/lib/vstatus/vstatus.h b/usr.sbin/afs/src/milko/lib/vstatus/vstatus.h
new file mode 100644
index 00000000000..0cd0daa4a06
--- /dev/null
+++ b/usr.sbin/afs/src/milko/lib/vstatus/vstatus.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: vstatus.h,v 1.1 2000/09/11 14:41:19 art Exp $ */
+
+#ifndef __FILBUNKE_VSTATUS_H
+#define __FILBUNKE_VSTATUS_H 1
+
+#include <vstat.h>
+
+int vstatus_init (void) ;
+int vstatus_read (int fd, vstatus *v);
+int vstatus_write (int fd, vstatus *v);
+void vstatus_print_onode (FILE *out, onode_opaque *o);
+
+#endif /* __FILBUNKE_VSTATUS_H */
diff --git a/usr.sbin/afs/src/milko/pts/Makefile.in b/usr.sbin/afs/src/milko/pts/Makefile.in
new file mode 100644
index 00000000000..72b3f76b860
--- /dev/null
+++ b/usr.sbin/afs/src/milko/pts/Makefile.in
@@ -0,0 +1,115 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:19 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sysconfdir = @sysconfdir@
+transform = @program_transform_name@
+
+PTSERVER_BIN = ptserver
+
+DEFS = @DEFS@ -DMILKO_SYSCONFDIR=\"$(sysconfdir)\"
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+AFSWSROOT = /usr/afsws
+RXKADINC = -I$(srcdir)/../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I../../include \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../../rxkad \
+ -I$(srcdir)/../../lib/acl \
+ -I$(srcdir)/../lib/msecurity \
+ -I../../rxdef \
+ $(RXKADINC)
+DEFINES = -DDEBUG
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) -DRXDEBUG
+RXKADLIB = @MILKO_RXKAD_LIBS@
+KAFS_LIBS = @AIX_EXTRA_KAFS@ @KAFS_LIBS@
+LIBS = -L../lib/msecurity -lmsecurity \
+ -L../../rxdef -lrxfsserver \
+ -L../../lib/acl -lacl \
+ -L../../lib/ko -lko \
+ -L../../util -lutil \
+ -L../../rxdef -lptserver -L../../rx -lrx \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/roken -lroken $(RXKADLIB) \
+ $(KAFS_LIBS) \
+ @LIBS@
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a \
+ ../../lwp/liblwp.a ../../util/libutil.a \
+ ../../lib/roken/libroken.a ../../lib/ko/libko.a \
+ ../lib/voldb/libvoldb.a ../lib/vld/libvld.a \
+ ../lib/msecurity/libmsecurity.a
+PROGS = ptserver
+SRCS = \
+ ptserver.c \
+ pr.c
+
+HDRS =
+
+ptserver_OBJS = \
+ ptserver.o \
+ pr.o
+
+.PHONY: all install uninstall depend tags clean
+
+all: $(PROGS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir)
+ PROG_BIN='$(PTSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+uninstall:
+ PROG_BIN='$(PTSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+ptserver: $(ptserver_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(ptserver_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=milko/pts/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(SRCS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/milko/pts/pr.c b/usr.sbin/afs/src/milko/pts/pr.c
new file mode 100644
index 00000000000..0b96f0337e1
--- /dev/null
+++ b/usr.sbin/afs/src/milko/pts/pr.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <ctype.h>
+#include <assert.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+
+#include <ports.h>
+#include <bool.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#include "rxkad_locl.h"
+#endif
+
+#include <err.h>
+
+#ifndef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <service.h>
+
+#include "pts.h"
+#include "pts.ss.h"
+#include "ptserver.h"
+#include "pts.ss.h"
+
+#include "msecurity.h"
+
+RCSID("$Id: pr.c,v 1.1 2000/09/11 14:41:19 art Exp $");
+
+int PR_NameToID(struct rx_call *call,
+ const namelist *nlist,
+ idlist *ilist)
+{
+ int i;
+ int status;
+ char *localname;
+
+ printf("PR_NameToID\n");
+/* printf(" securityIndex: %d\n", call->conn->securityIndex);*/
+#ifdef KERBEROS
+ if (call->conn->securityIndex == 2) {
+ serv_con_data *cdat = call->conn->securityData;
+ printf(" user: %s.%s@%s\n",
+ cdat->user->name,
+ cdat->user->instance,
+ cdat->user->realm);
+ }
+#endif
+
+ ilist->len = nlist->len;
+ ilist->val = malloc(sizeof(int) * ilist->len);
+ if (ilist->val == NULL)
+ return PRDBBAD;
+
+ for (i = 0; i < nlist->len; i++) {
+ printf(" name: %s\n", nlist->val[i]);
+
+ localname = localize_name(nlist->val[i]);
+
+ status = conv_name_to_id(localname, &ilist->val[i]);
+ if (status == PRNOENT)
+ ilist->val[i] = PR_ANONYMOUSID;
+ else if (status)
+ return status;
+ }
+ return 0;
+}
+
+int
+PR_IDToName(struct rx_call *call,
+ const idlist *ilist,
+ namelist *nlist)
+{
+ int i;
+ int status;
+
+ printf("PR_IDToName\n");
+
+
+ if (ilist->len < 0 || ilist->len >= PR_MAXLIST)
+ return PRTOOMANY;
+
+ nlist->len = ilist->len;
+
+ if (ilist->len == 0) {
+ nlist->val = NULL;
+ return 0;
+ }
+
+ nlist->val = calloc(1, sizeof(prname) * nlist->len);
+ if (nlist->val == NULL)
+ return PRDBBAD;
+
+ for (i = 0; i < ilist->len; i++) {
+/* printf(" id: %d\n", ilist->val[i]);*/
+ status = conv_id_to_name(ilist->val[i], nlist->val[i]);
+ if (status == PRNOENT)
+ snprintf (nlist->val[i], PR_MAXNAMELEN, "%d", ilist->val[i]);
+ else if (status)
+ return status;
+ }
+ return 0;
+}
+
+int PR_NewEntry(struct rx_call *call
+ , const char name[ 64 ]
+ , const int32_t flag
+ , const int32_t oid
+ , int32_t *id
+ )
+{
+ int error;
+ char *localname;
+
+ printf("PR_NewEntry\n");
+ printf(" securityIndex: %d\n", call->conn->securityIndex);
+ printf(" name:%s oid:%d\n", name, oid);
+
+
+/* XXX should be authuser? */
+ if (!sec_is_superuser(call))
+ return PRPERM;
+
+ localname = localize_name(name);
+ if ((flag & PRTYPE) == PRUSER) {
+ error = conv_name_to_id(localname, id);
+ if (error == PRNOENT) {
+ *id = next_free_user_id();
+ error = create_user(localname, *id, oid, PR_SYSADMINID); /* XXX */
+ } else
+ error = PREXIST;
+ } else if ((flag & PRTYPE) == PRGRP) {
+ error = conv_name_to_id(localname, id);
+ if (error == PRNOENT) {
+ *id = next_free_group_id();
+ error = create_group(localname, *id, oid, PR_SYSADMINID); /* XXX */
+ } else
+ error = PREXIST;
+ } else {
+ error = PRPERM;
+ }
+
+ return error;
+}
+
+int PR_INewEntry(
+ struct rx_call *call
+ , const char name[ 64 ]
+ , const int32_t id
+ , const int32_t oid
+ )
+{
+ int error;
+ int tempid;
+ char *localname;
+
+ if (!sec_is_superuser(call))
+ return PRPERM;
+
+ printf("PR_INewEntry\n");
+ printf(" securityIndex: %d\n", call->conn->securityIndex);
+ printf(" name:%s oid:%d\n", name, oid);
+
+ localname = localize_name(name);
+ if (id > 0) {
+ error = conv_name_to_id(localname, &tempid);
+ if (error == PRNOENT) {
+ error = create_user(localname, id, oid, PR_SYSADMINID); /* XXX */
+ } else
+ error = PREXIST;
+ } else if (id < 0) {
+ error = conv_name_to_id(localname, &tempid);
+ if (error == PRNOENT) {
+ error = create_group(localname, id, oid, PR_SYSADMINID); /* XXX */
+ } else
+ error = PREXIST;
+ } else {
+ error = PRPERM;
+ }
+
+ return error;
+}
+
+int PR_ListEntry(
+ struct rx_call *call
+ , const int32_t id
+ , struct prcheckentry *entry
+ )
+{
+ prentry pr_entry;
+ int status;
+
+ printf("PR_ListEntry\n");
+ printf(" securityIndex: %d\n", call->conn->securityIndex);
+ printf(" id:%d\n", id);
+#ifdef KERBEROS
+ if (call->conn->securityIndex == 2) {
+ serv_con_data *cdat = call->conn->securityData;
+ printf(" user: %s.%s@%s\n",
+ cdat->user->name,
+ cdat->user->instance,
+ cdat->user->realm);
+ }
+#endif
+
+ memset(&pr_entry, 0, sizeof(pr_entry));
+ status = get_pr_entry_by_id(id, &pr_entry);
+ if (status)
+ return status;
+ entry->flags = pr_entry.flags;
+ entry->id = pr_entry.id;
+ entry->owner = pr_entry.owner;
+ entry->creator = pr_entry.creator;
+ entry->ngroups = pr_entry.ngroups;
+ entry->nusers = pr_entry.nusers;
+ entry->count = pr_entry.count;
+ memcpy(entry->reserved, pr_entry.reserved, sizeof(pr_entry.reserved));
+ strlcpy(entry->name, pr_entry.name, PR_MAXNAMELEN);
+
+ return 0;
+}
+
+int PR_DumpEntry(
+ struct rx_call *call
+ , const int32_t pos
+ , struct prdebugentry *entry
+ )
+{
+ printf("PR_DumpEntry\n");
+ return -1;
+}
+
+int PR_ChangeEntry(
+ struct rx_call *call
+ , const int32_t id
+ , const char name[ 64 ]
+ , const int32_t oid
+ , const int32_t newid
+ )
+{
+ printf("PR_ChangeEntry\n");
+ return -1;
+}
+
+
+int PR_SetFieldsEntry(
+ struct rx_call *call
+ , const int32_t id
+ , const int32_t mask
+ , const int32_t flags
+ , const int32_t ngroups
+ , const int32_t nusers
+ , const int32_t spare1
+ , const int32_t spare2
+ )
+{
+ printf("PR_SetFieldsEntry\n");
+ return -1;
+}
+
+
+int PR_Delete(
+ struct rx_call *call
+ , const int32_t id
+ )
+{
+ printf("PR_Delete\n");
+ return -1;
+}
+
+
+int PR_WhereIsIt(
+ struct rx_call *call
+ , const int32_t id
+ , int32_t *ps
+ )
+{
+ printf("PR_WhereIsIt\n");
+ return -1;
+}
+
+
+int PR_AddToGroup(
+ struct rx_call *call
+ , const int32_t uid
+ , const int32_t gid
+ )
+{
+ printf("PR_AddToGroup\n");
+
+ if (!sec_is_superuser(call))
+ return PRPERM;
+
+ return addtogroup(uid,gid);
+}
+
+
+int PR_RemoveFromGroup(
+ struct rx_call *call
+ , const int32_t id
+ , const int32_t gid
+ )
+{
+ printf("PR_RemoveFromGroup\n");
+
+ if (!sec_is_superuser(call))
+ return PRPERM;
+
+ return removefromgroup(id, gid);
+}
+
+
+int PR_ListMax(
+ struct rx_call *call
+ , int32_t *uid
+ , int32_t *gid
+ )
+{
+ printf("PR_ListMax\n");
+ *uid = pr_header.maxID;
+ *gid = pr_header.maxGroup;
+ return 0;
+}
+
+
+int PR_SetMax(
+ struct rx_call *call
+ , const int32_t uid
+ , const int32_t gflag
+ )
+{
+ printf("PR_SetMax\n");
+ return -1;
+}
+
+
+int PR_ListElements(
+ struct rx_call *call
+ , const int32_t id
+ , prlist *elist
+ , int32_t *over
+ )
+{
+ printf("PR_ListElements\n");
+
+ return listelements(id, elist, FALSE);
+}
+
+
+int PR_GetCPS(
+ struct rx_call *call
+ , const int32_t id
+ , prlist *elist
+ , int32_t *over
+ )
+{
+ printf("PR_GetCPS\n");
+
+ return listelements(id, elist, TRUE);
+}
+
+
+int PR_ListOwned(
+ struct rx_call *call
+ , const int32_t id
+ , prlist *elist
+ , int32_t *over
+ )
+{
+ printf("PR_ListOwned\n");
+ return -1;
+}
+
+
+int PR_IsAMemberOf(
+ struct rx_call *call
+ , const int32_t uid
+ , const int32_t gid
+ , int32_t *flag
+ )
+{
+ printf("PR_IsAMemberOf\n");
+ return -1;
+}
diff --git a/usr.sbin/afs/src/milko/pts/ptserver.c b/usr.sbin/afs/src/milko/pts/ptserver.c
new file mode 100644
index 00000000000..cd5a3925aea
--- /dev/null
+++ b/usr.sbin/afs/src/milko/pts/ptserver.c
@@ -0,0 +1,788 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <rx/rx.h>
+#include <rx/rx_null.h>
+
+#include <ports.h>
+#include <ko.h>
+#include <netinit.h>
+#include <msecurity.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#endif
+
+#include <err.h>
+#include <assert.h>
+#include <ctype.h>
+#include <getarg.h>
+
+#ifndef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <service.h>
+
+#include "pts.h"
+#include "pts.ss.h"
+#include "ptserver.h"
+#include "pts.ss.h"
+
+RCSID("$Id: ptserver.c,v 1.1 2000/09/11 14:41:19 art Exp $");
+
+static struct rx_service *prservice;
+
+static int pr_database = -1;
+static off_t file_length;
+prheader pr_header;
+
+char pr_header_ydr[PRHEADER_SIZE];
+
+
+static int ptdebug = 0;
+
+int
+pt_setdebug (int debug)
+{
+ int odebug = ptdebug;
+ ptdebug = debug;
+ return odebug;
+}
+
+void
+pt_debug (char *fmt, ...)
+{
+ va_list args;
+ if (!ptdebug)
+ return ;
+
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end(args);
+}
+
+
+static void
+write_header(void)
+{
+ off_t pos;
+ int length = PRHEADER_SIZE;
+
+ if (ydr_encode_prheader(&pr_header, pr_header_ydr, &length) == NULL)
+ err(1, "write_header");
+
+ pos = lseek(pr_database, 0, SEEK_SET);
+ assert(pos == 0);
+
+ length = write(pr_database, pr_header_ydr, PRHEADER_SIZE);
+ assert (length == PRHEADER_SIZE);
+}
+
+static void
+read_header(void)
+{
+ char pr_header_ydr[PRHEADER_SIZE];
+ int length = PRHEADER_SIZE;
+
+ if (lseek(pr_database, 0, SEEK_SET) == -1)
+ err(1, "lseek");
+
+ length = read(pr_database, pr_header_ydr, PRHEADER_SIZE);
+ if (length == -1)
+ err(1, "read");
+ if (length != PRHEADER_SIZE)
+ errx(1, "read_header read failed");
+
+ if (ydr_decode_prheader(&pr_header, pr_header_ydr, &length) == NULL)
+ err(1, "read_header");
+}
+
+static void
+get_file_length(void)
+{
+ file_length = lseek(pr_database, 0, SEEK_END);
+ if (file_length == -1) {
+ err(1, "lseek");
+ }
+}
+
+
+char *
+localize_name(const char *name)
+{
+ static prname localname;
+ char *tmp;
+
+ strlcpy(localname, name, sizeof(localname));
+ strlwr(localname);
+
+ if (tmp = strchr(localname, '@'))
+ if (!strcasecmp(tmp + 1, netinit_getrealm()))
+ *tmp = '\0';
+
+ return localname;
+}
+
+static void
+create_database(void)
+{
+ pr_header.version = 0;
+ pr_header.headerSize = PRHEADER_SIZE;
+ pr_header.freePtr = 0;
+ pr_header.eofPtr = PRHEADER_SIZE;
+ pr_header.maxGroup = -210; /* XXX */
+ pr_header.maxID = 0;
+ pr_header.maxForeign = 65536; /* XXX */
+ pr_header.maxInst = 0;
+ pr_header.orphan = 0;
+ pr_header.usercount = 0;
+ pr_header.groupcount = 0;
+ pr_header.foreigncount = 0;
+ pr_header.instcount = 0;
+ memset(pr_header.reserved, 0, 5 * sizeof(int32_t));
+ memset(pr_header.nameHash, 0, 8191 * sizeof(int32_t));
+ memset(pr_header.idHash, 0, 8191 * sizeof(int32_t));
+ write_header();
+ get_file_length();
+}
+
+static off_t
+find_first_free(void)
+{
+ off_t pos;
+
+ if (pr_header.freePtr == 0) { /* if there are no free entries */
+ pos = lseek(pr_database, 0, SEEK_END);
+ if (pos == -1)
+ err(1, "lseek");
+ if (ftruncate(pr_database, pos + PRENTRY_DISK_SIZE) == -1)
+ err(1, "ftruncate");
+ return pos;
+ } else { /* there are free entries */
+ /* Not implemented yet */
+ assert(0);
+ }
+ return 0;
+}
+
+static int
+write_entry(off_t offset, prentry *pr_entry)
+{
+ off_t pos;
+ char pr_entry_disk_ydr[PRENTRY_DISK_SIZE];
+ int length = PRENTRY_DISK_SIZE;
+
+ if (ydr_encode_prentry_disk((prentry_disk *) pr_entry, pr_entry_disk_ydr, &length) == NULL)
+ err(1, "write_entry");
+
+ pos = lseek(pr_database, offset, SEEK_SET);
+ assert(pos == offset);
+
+ length = write(pr_database, pr_entry_disk_ydr, PRENTRY_DISK_SIZE);
+ assert (length == PRENTRY_DISK_SIZE);
+
+ return 0;
+}
+
+static int
+read_entry(off_t offset, prentry *pr_entry)
+{
+ off_t pos;
+ char pr_entry_disk_ydr[PRENTRY_DISK_SIZE];
+ int length = PRENTRY_DISK_SIZE;
+
+ pos = lseek(pr_database, offset, SEEK_SET);
+ assert(pos == offset);
+
+ length = read(pr_database, pr_entry_disk_ydr, PRENTRY_DISK_SIZE);
+ assert (length == PRENTRY_DISK_SIZE);
+
+ if (ydr_decode_prentry_disk((prentry_disk *) pr_entry, pr_entry_disk_ydr, &length) == NULL)
+ err(1, "write_entry");
+
+ return 0;
+}
+
+static unsigned long
+get_id_hash(long id)
+{
+ return ((unsigned long) id) % HASHSIZE;
+}
+
+static unsigned long
+get_name_hash(const char *name)
+{
+ int i;
+ unsigned long hash = 0x47114711;
+
+ for (i = 0; name[i] && i < 32; i++)
+ hash *= name[i];
+
+ return hash % HASHSIZE;
+}
+
+static int
+get_first_id_entry(unsigned long hash_id, prentry *pr_entry)
+{
+ off_t offset = pr_header.idHash[hash_id];
+ int status;
+
+ pt_debug ("get_first_id_entry hash_id: %lu offset: %ld\n",
+ hash_id, (long)offset);
+ if (offset == 0)
+ return PRNOENT;
+
+ status = read_entry(offset, pr_entry);
+
+ return status;
+}
+
+static int
+get_first_name_entry(unsigned long hash_name, prentry *pr_entry)
+{
+ off_t offset = pr_header.nameHash[hash_name];
+ int status;
+
+ pt_debug ("get_first_name_entry hash_name: %lu offset: %ld\n",
+ hash_name, (long)offset);
+ if (offset == 0)
+ return PRNOENT;
+
+ status = read_entry(offset, pr_entry);
+
+ return status;
+}
+
+static int
+update_entry(prentry *pr_entry)
+{
+ off_t offset;
+ int status;
+ unsigned long hash_id;
+ prentry old_pr_entry;
+
+ fprintf(stderr, "update_entry\n");
+
+ hash_id = get_id_hash(pr_entry->id);
+
+ offset = pr_header.idHash[hash_id];
+
+ status = get_first_id_entry(hash_id, &old_pr_entry);
+ if (status)
+ return PRNOENT;
+
+ while (old_pr_entry.id != pr_entry->id) {
+ if (old_pr_entry.nextID == 0)
+ return PRNOENT;
+ offset=old_pr_entry.nextID;
+ status = read_entry(offset, &old_pr_entry);
+ }
+
+ return write_entry(offset, pr_entry);
+}
+
+static int
+insert_entry(prentry *pr_entry)
+{
+ off_t offset;
+ int status;
+ unsigned long hash_id, hash_name;
+ prentry first_id_entry;
+ prentry first_name_entry;
+
+ /* Allokera plats i filen */
+ offset = find_first_free();
+
+ /* Hitta plats i hashtabell */
+ hash_id = get_id_hash(pr_entry->id);
+ hash_name = get_name_hash(pr_entry->name);
+
+ status = get_first_id_entry(hash_id, &first_id_entry);
+ pr_entry->nextID = status ? 0 : first_id_entry.nextID;
+
+ status = get_first_name_entry(hash_name, &first_name_entry);
+ pr_entry->nextName = status ? 0 : first_name_entry.nextName;
+
+ /* XXX: uppdatera owned och nextOwned */
+
+ /* Lägg in entryt i filen */
+ status = write_entry(offset, pr_entry);
+ if (status)
+ return status;
+
+ /* Uppdatera hashtabell */
+ pr_header.idHash[hash_id] = offset;
+ pr_header.nameHash[hash_name] = offset;
+ write_header();
+ return 0;
+}
+
+int
+create_group(const char *name,
+ int32_t id,
+ int32_t owner,
+ int32_t creator)
+{
+ int status;
+ prentry pr_entry;
+
+ memset(&pr_entry, 0, sizeof(pr_entry));
+ pr_entry.flags = PRGRP;
+ pr_entry.id = id;
+ pr_entry.owner = owner;
+ pr_entry.creator = creator;
+ strlcpy(pr_entry.name, name, PR_MAXNAMELEN);
+
+ status = insert_entry(&pr_entry);
+ if (status)
+ return status;
+
+ return 0;
+}
+
+int
+create_user(const char *name,
+ int32_t id,
+ int32_t owner,
+ int32_t creator)
+{
+ int status;
+ prentry pr_entry;
+
+ memset(&pr_entry, 0, sizeof(pr_entry));
+ pr_entry.flags = 0;
+ pr_entry.id = id;
+ pr_entry.owner = owner;
+ pr_entry.creator = creator;
+ strlcpy(pr_entry.name, name, PR_MAXNAMELEN);
+
+ status = insert_entry(&pr_entry);
+ if (status)
+ return status;
+
+ return 0;
+}
+
+int
+addtogroup (int32_t uid, int32_t gid) {
+ prentry uid_entry;
+ prentry gid_entry;
+ int error,i;
+
+ fprintf(stderr, "addtogroup\n");
+
+ if (error = get_pr_entry_by_id(uid, &uid_entry))
+ return error;
+
+ if (error = get_pr_entry_by_id(gid, &gid_entry))
+ return error;
+
+ /* XXX should allocate contentry block */
+
+ if (uid_entry.count >= PRSIZE || gid_entry.count >= PRSIZE)
+ return PRNOENT;
+
+ assert (uid_entry.entries[uid_entry.count] == 0);
+ uid_entry.entries[uid_entry.count] = gid;
+ uid_entry.count++;
+
+ assert (gid_entry.entries[gid_entry.count] == 0);
+ gid_entry.entries[gid_entry.count] = uid;
+ gid_entry.count++;
+
+ if ((error = update_entry(&uid_entry)) != 0)
+ return error;
+
+ if ((error = update_entry(&gid_entry)) != 0)
+ return error;
+
+ return 0;
+
+}
+int
+removefromgroup (int32_t uid, int32_t gid) {
+ prentry uid_entry;
+ prentry gid_entry;
+ int error, i, offset;
+
+ fprintf(stderr, "removefromgroup\n");
+
+ if (error = get_pr_entry_by_id(uid, &uid_entry))
+ return error;
+
+ if (error = get_pr_entry_by_id(gid, &gid_entry))
+ return error;
+
+ /* XXX No check for full list */
+
+ /* XXX should the list be sorted? */
+
+ error = PRNOENT; /* XXX */
+ for (i = 0; i < PRSIZE; i++)
+ if (uid_entry.entries[i] == gid) {
+ uid_entry.count--;
+ uid_entry.entries[i] = uid_entry.entries[uid_entry.count];
+ uid_entry.entries[uid_entry.count] = 0;
+ error = 0;
+ }
+ if (error)
+ return error;
+
+
+ error = PRNOENT; /* XXX */
+ for (i = 0; i < PRSIZE; i++)
+ if (gid_entry.entries[i] == uid) {
+ gid_entry.count--;
+ gid_entry.entries[i] = gid_entry.entries[gid_entry.count];
+ gid_entry.entries[gid_entry.count] = 0;
+ error = 0;
+ }
+ if (error)
+ return error;
+
+
+ /* XXX may leave database inconsistent ?? */
+
+ if ((error = update_entry(&uid_entry)) != 0)
+ return error;
+
+ if ((error = update_entry(&gid_entry)) != 0)
+ return error;
+
+ return 0;
+
+}
+
+int
+listelements (int32_t id, prlist *elist, Bool default_id_p)
+{
+ prentry pr_entry;
+ int i = 0, error;
+
+ if (error = get_pr_entry_by_id (id, &pr_entry))
+ return error;
+
+ elist->val = malloc(sizeof(*elist->val)
+ * (pr_entry.count + (default_id_p ? 3 : 1)));
+ if (elist->val == NULL)
+ return ENOMEM; /* XXX */
+
+
+ /* XXX contentry blocks... */
+ /* XXX should be sorted */
+
+ for (i = 0; i < pr_entry.count; i++)
+ elist->val[i] = pr_entry.entries[i];
+
+ elist->val[i] = id;
+ if (default_id_p) {
+ elist->val[++i] = PR_ANYUSERID;
+ elist->val[++i] = PR_AUTHUSERID;
+ elist->len = pr_entry.count + 3;
+ } else
+ elist->len = pr_entry.count + 1;
+
+ return 0;
+}
+
+
+int
+get_pr_entry_by_id(int id, prentry *pr_entry)
+{
+ unsigned long hash_id = get_id_hash(id);
+ int status;
+
+ pt_debug ("get_pr_entry_by_id id:%d hash_id: %ld\n", id, hash_id);
+
+ status = get_first_id_entry(hash_id, pr_entry);
+ pt_debug ("get_pr_entry_by_id status:%d\n", status);
+ if (status)
+ return PRNOENT;
+
+ while (pr_entry->id != id) {
+ if (pr_entry->nextID == 0)
+ return PRNOENT;
+ status = read_entry(pr_entry->nextID, pr_entry);
+ }
+
+ pt_debug ("pr_entry->id: %d\n", pr_entry->id);
+ pt_debug ("pr_entry->owner: %d\n", pr_entry->owner);
+ pt_debug ("pr_entry->creator: %d\n", pr_entry->creator);
+ pt_debug ("pr_entry->name: %s\n", pr_entry->name);
+
+ return 0;
+}
+
+int
+get_pr_entry_by_name(const char *name, prentry *pr_entry)
+{
+ int hash_name = get_name_hash(name);
+ int status;
+
+ status = get_first_name_entry(hash_name, pr_entry);
+ if (status)
+ return PRNOENT;
+
+ while (strcmp(pr_entry->name, name)) {
+ if (pr_entry->nextName == 0)
+ return PRNOENT;
+ status = read_entry(pr_entry->nextName, pr_entry);
+ }
+
+ fprintf(stderr, " pr_entry->id: %d\n", pr_entry->id);
+ fprintf(stderr, " pr_entry->owner: %d\n", pr_entry->owner);
+ fprintf(stderr, " pr_entry->creator: %d\n", pr_entry->creator);
+ fprintf(stderr, " pr_entry->name: %s\n", pr_entry->name);
+
+ return 0;
+}
+
+int
+conv_name_to_id(const char *name, int *id)
+{
+ prentry pr_entry;
+ int status;
+
+ status = get_pr_entry_by_name(name, &pr_entry);
+ if (status)
+ return status;
+ *id = pr_entry.id;
+ return 0;
+}
+
+int
+conv_id_to_name(int id, char *name)
+{
+ prentry pr_entry;
+ int status;
+
+ status = get_pr_entry_by_id(id, &pr_entry);
+ if (status)
+ return status;
+ strlcpy(name, pr_entry.name, PR_MAXNAMELEN);
+ return 0;
+}
+
+int
+next_free_group_id(void)
+{
+ pr_header.maxGroup--; /* XXX */
+ write_header();
+ return pr_header.maxGroup;
+}
+
+int
+next_free_user_id()
+{
+ pr_header.maxID++; /* XXX */
+ write_header();
+ return pr_header.maxID;
+}
+
+
+/*
+ * Open the pr database that lives in ``databaseprefix''
+ * with open(2) ``flags''. Returns 0 or errno.
+ */
+
+static int
+open_db(char *databaseprefix, int flags)
+{
+ char database[MAXPATHLEN];
+
+ assert (pr_database == -1);
+
+ if (databaseprefix == NULL)
+ databaseprefix = MILKO_SYSCONFDIR;
+
+ snprintf (database, sizeof(database), "%s/pr_database",
+ databaseprefix);
+
+ pr_database = open(database, flags, S_IRWXU);
+ if (pr_database < 0)
+ return errno;
+ return 0;
+}
+
+static int
+prserver_create(char *databaseprefix)
+{
+ int status;
+
+ printf ("Creating a new pr-database.\n");
+
+ status = open_db(databaseprefix, O_RDWR|O_CREAT|O_BINARY|O_EXCL);
+ if (status)
+ errx (1, "failed open_db with error: %s (%d)",
+ strerror(status), status);
+
+ create_database();
+
+#define M(N,I,O,G) \
+ do { \
+ status = create_group((N), (I), (O), (G)); \
+ if (status) \
+ errx (1, "failed when creating %s with error %d", \
+ (N), status); \
+ } while (0)
+
+ M("system:administrators", PR_SYSADMINID, PR_SYSADMINID, PR_SYSADMINID);
+ M("system:anyuser", PR_ANYUSERID, PR_SYSADMINID, PR_SYSADMINID);
+ M("system:authuser", PR_AUTHUSERID, PR_SYSADMINID, PR_SYSADMINID);
+ M("anonymous", PR_ANONYMOUSID, PR_SYSADMINID, PR_SYSADMINID);
+
+#undef M
+
+ return 0;
+}
+
+static int
+prserver_init(char *databaseprefix)
+{
+ int status;
+
+ status = open_db(databaseprefix, O_RDWR|O_BINARY);
+ if (status)
+ errx (1, "failed open_db with error: %s (%d)",
+ strerror(status), status);
+
+ read_header();
+ get_file_length();
+
+ return 0;
+}
+
+static char *cell = NULL;
+static char *realm = NULL;
+static char *databasedir = NULL;
+static char *srvtab_file = NULL;
+static int no_auth = 0;
+static int do_help = 0;
+static int do_debug = 0;
+static int do_create = 0;
+
+static struct getargs args[] = {
+ {"create", 0, arg_flag, &do_create, "create new databas"},
+ {"cell", 0, arg_string, &cell, "what cell to use"},
+ {"realm", 0, arg_string, &realm, "what realm to use"},
+ {"prefix",'p', arg_string, &databasedir, "what dir to store the db"},
+ {"noauth", 0, arg_flag, &no_auth, "disable authentication checks"},
+ {"srvtab",'s', arg_string, &srvtab_file, "what srvtab to use"},
+ {"debug", 'd', arg_flag, &do_debug, "enable debug messages"},
+ {"help", 'h', arg_flag, &do_help, "help"},
+ { NULL, 0, arg_end, NULL }
+};
+
+static void
+usage(int exit_code)
+{
+ arg_printusage(args, NULL, "", ARG_AFSSTYLE);
+ exit (exit_code);
+}
+
+/*
+ *
+ */
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ int optind = 0;
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage (1);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 1;
+ }
+
+ if (do_help)
+ usage(0);
+
+ if (do_debug)
+ pt_setdebug (1);
+
+ if (do_create) {
+ prserver_create (databasedir);
+ return 0;
+ }
+
+ if (no_auth)
+ sec_disable_superuser_check ();
+
+ printf ("ptserver booting\n");
+
+ ports_init();
+ cell_init(0);
+
+ if (cell)
+ cell_setthiscell (cell);
+
+ network_kerberos_init (srvtab_file);
+
+ ret = prserver_init(databasedir);
+ if (ret)
+ errx (1, "prserver_init: error %d\n", ret);
+
+ ret = network_init(htons(afsprport), "pr", PR_SERVICE_ID,
+ PR_ExecuteRequest, &prservice, NULL);
+ if (ret)
+ errx (1, "network_init returned %d", ret);
+
+ printf("started\n");
+
+ rx_SetMaxProcs(prservice,5) ;
+ rx_StartServer(1) ;
+
+ abort();
+ return 0;
+}
diff --git a/usr.sbin/afs/src/milko/pts/ptserver.h b/usr.sbin/afs/src/milko/pts/ptserver.h
new file mode 100644
index 00000000000..95c66f96de5
--- /dev/null
+++ b/usr.sbin/afs/src/milko/pts/ptserver.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1998 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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: ptserver.h,v 1.1 2000/09/11 14:41:19 art Exp $ */
+
+int get_pr_entry_by_id(int id, prentry *pr_entry);
+int get_pr_entry_by_name(const char *name, prentry *pr_entry);
+int conv_name_to_id(const char *name, int *id);
+int conv_id_to_name(int id, char *name);
+int next_free_group_id(void);
+int next_free_user_id(void);
+int create_user(const char *name, int32_t id, int32_t owner, int32_t creator);
+int create_group(const char *name, int32_t id, int32_t owner, int32_t creator);
+int addtogroup(int32_t uid, int32_t gid);
+int removefromgroup(int32_t uid, int32_t gid);
+int listelements(int32_t id, prlist *elist, Bool default_id_p);
+char *localize_name(const char *name);
+extern prheader pr_header;
diff --git a/usr.sbin/afs/src/milko/vldb/Makefile.in b/usr.sbin/afs/src/milko/vldb/Makefile.in
new file mode 100644
index 00000000000..b13ef6603a9
--- /dev/null
+++ b/usr.sbin/afs/src/milko/vldb/Makefile.in
@@ -0,0 +1,123 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:20 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+bindir = @bindir@
+sysconfdir = @sysconfdir@
+transform = @program_transform_name@
+
+VLDBSERVER_BIN = vldbserver
+
+DEFS = @DEFS@ -DMILKO_SYSCONFDIR=\"$(sysconfdir)\"
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+ETAGS = etags
+MAKEDEPEND = makedepend
+AFSWSROOT = /usr/afsws
+RXKADINC = -I$(srcdir)/../rxkad
+INCLUDES = -I$(srcdir)/../.. \
+ -I../../include \
+ -I$(srcdir)/../../include \
+ -I$(srcdir)/../lib/msecurity \
+ -I../../rxdef \
+ $(RXKADINC)
+DEFINES = -DDEBUG
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS) -DRXDEBUG
+RXKADLIB = @MILKO_RXKAD_LIBS@
+LIBS = -L../../rxdef -lrxvlserver \
+ -L../lib/msecurity -lmsecurity \
+ -L../../lib/acl -lacl \
+ -L../../rxdef -lrxvolserver -lrxfsserver -L../../rx -lrx \
+ -L../../lib/ko -lko \
+ -L../../util -lutil \
+ -L../../lwp -llwp @PLWP_LIB_FLAGS@ \
+ -L../../lib/roken -lroken $(RXKADLIB) \
+ @LIBS@
+LIBDEPENDS = ../../rxdef/librxdefclient.a ../../rx/librx.a \
+ ../../lwp/liblwp.a ../../util/libutil.a \
+ ../../lib/roken/libroken.a ../../lib/ko/libko.a \
+ ../lib/voldb/libvoldb.a ../lib/vld/libvld.a \
+ ../lib/msecurity/libmsecurity.a
+PROGS = vldbserver vled
+
+SRCS = \
+ vled.c \
+ vld_db.c \
+ vldbserver.c \
+ ubikprocs.c
+
+HDRS =
+
+vldbserver_OBJS = \
+ vl_db.o \
+ vldbserver.o \
+ ubikprocs.o
+
+vled_OBJS = \
+ vled.o \
+ vl_db.o
+
+
+.PHONY: all install uninstall depend tags clean
+
+all: $(PROGS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libexecdir)
+ PROG_BIN='$(VLDBSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+uninstall:
+ PROG_BIN='$(VLDBSERVER_BIN)'; for x in $$PROG_BIN; do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(libexecdir)/$$f; \
+ done
+
+vldbserver: $(vldbserver_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(vldbserver_OBJS) $(LIBS)
+
+vled: $(vled_OBJS) $(LIBDEPENDS)
+ $(CC) $(LDFLAGS) -o $@ $(vled_OBJS) $(LIBS)
+
+Makefile: Makefile.in ../../config.status
+ cd ../..; CONFIG_FILES=milko/vldb/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(SRCS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(PROGS) $(OBJS) *~ *.o core *.core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/milko/vldb/ubikprocs.c b/usr.sbin/afs/src/milko/vldb/ubikprocs.c
new file mode 100644
index 00000000000..830fae7fb68
--- /dev/null
+++ b/usr.sbin/afs/src/milko/vldb/ubikprocs.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "ubik.ss.h"
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#ifdef KERBEROS
+#include <krb.h>
+#endif
+
+RCSID("$Id: ubikprocs.c,v 1.1 2000/09/11 14:41:20 art Exp $");
+
+int Ubik_Beacon(struct rx_call *call,
+ const int32_t state,
+ const int32_t voteStart,
+ const net_version *Version,
+ const struct net_tid *tid)
+{
+ return -1;
+}
+
+int Ubik_Debug(struct rx_call *call,
+ struct ubik_debug *db)
+{
+#ifdef KERBEROS
+ {
+ struct in_addr *ina;
+ int ret;
+
+ ret = k_get_all_addrs(&ina);
+ if (ret < 1)
+ return -1;
+ db->syncHost = ntohl(ina[0].s_addr); /* XXX */
+ }
+#else
+ {
+ char name[MAXHOSTNAMELEN];
+ struct hostent *he;
+ struct in_addr tmp;
+
+ if (gethostname (name, sizeof(name) < 0))
+ return -1;
+ he = gethostbyname (name);
+ if (he == NULL)
+ return -1;
+ memcpy (&tmp, he->h_addr_list[0], sizeof(struct in_addr));
+ db->syncHost = ntohl(tmp.s_addr);
+ }
+#endif
+
+ return 0;
+}
+
+int Ubik_SDebug(struct rx_call *call,
+ const int32_t which,
+ struct ubik_sdebug *db)
+{
+ return -1;
+}
+
+int Ubik_GetSyncSite(struct rx_call *call,
+ int32_t *site)
+{
+ return -1;
+}
diff --git a/usr.sbin/afs/src/milko/vldb/vl_db.c b/usr.sbin/afs/src/milko/vldb/vl_db.c
new file mode 100644
index 00000000000..6dd4b025aae
--- /dev/null
+++ b/usr.sbin/afs/src/milko/vldb/vl_db.c
@@ -0,0 +1,376 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "vldb_locl.h"
+
+RCSID("$Id: vl_db.c,v 1.1 2000/09/11 14:41:20 art Exp $");
+
+static void open_db (char *databaseprefix, int flags);
+
+int vl_database;
+vlheader vl_header;
+off_t file_length;
+
+static char vl_header_ydr[VLHEADER_SIZE];
+
+void
+vldb_write_header(void)
+{
+ off_t pos;
+ int length = VLHEADER_SIZE;
+
+ if (ydr_encode_vlheader(&vl_header, vl_header_ydr, &length) == NULL)
+ err(1, "write_header");
+
+ pos = lseek(vl_database, 0, SEEK_SET);
+ assert(pos == 0);
+
+ length = write(vl_database, vl_header_ydr, VLHEADER_SIZE);
+ assert (length == VLHEADER_SIZE);
+}
+
+void
+vldb_read_header(void)
+{
+ char vl_header_ydr[VLHEADER_SIZE];
+ int length = VLHEADER_SIZE;
+
+ if (lseek(vl_database, 0, SEEK_SET) == -1)
+ err(1, "lseek");
+
+ length = read(vl_database, vl_header_ydr, VLHEADER_SIZE);
+ if (length == -1)
+ err(1, "read");
+ if (length != VLHEADER_SIZE)
+ errx(1, "read_header read failed");
+
+ if (ydr_decode_vlheader(&vl_header, vl_header_ydr, &length) == NULL)
+ err(1, "read_header");
+}
+
+void
+vldb_get_file_length(void)
+{
+ file_length = lseek(vl_database, 0, SEEK_END);
+ if (file_length == -1) {
+ err(1, "lseek");
+ }
+}
+
+off_t
+vldb_find_first_free(void)
+{
+ off_t pos;
+
+ if (vl_header.vital_header.freePtr == 0) {
+ /* if there are no free entries */
+ pos = lseek(vl_database, 0, SEEK_END);
+ if (pos == -1)
+ err(1, "lseek");
+ if (ftruncate(vl_database, pos + DISK_VLENTRY_SIZE) == -1)
+ err(1, "ftruncate");
+ return pos;
+ } else { /* there are free entries */
+ /* Not implemented yet */
+ assert(0);
+ }
+ return 0;
+}
+
+int
+vldb_write_entry(off_t offset, disk_vlentry *vl_entry)
+{
+ off_t pos;
+ char vl_entry_ydr[DISK_VLENTRY_SIZE];
+ int length = DISK_VLENTRY_SIZE;
+
+ if (ydr_encode_disk_vlentry(vl_entry, vl_entry_ydr, &length) == NULL)
+ err(1, "write_entry");
+
+ pos = lseek(vl_database, offset, SEEK_SET);
+ assert(pos == offset);
+
+ length = write(vl_database, vl_entry_ydr, DISK_VLENTRY_SIZE);
+ assert (length == DISK_VLENTRY_SIZE);
+
+ return 0;
+}
+
+int
+vldb_read_entry(off_t offset, disk_vlentry *vl_entry)
+{
+ off_t pos;
+ char vl_entry_ydr[DISK_VLENTRY_SIZE];
+ int length = DISK_VLENTRY_SIZE;
+
+ pos = lseek(vl_database, offset, SEEK_SET);
+ assert(pos == offset);
+
+ length = read(vl_database, vl_entry_ydr, DISK_VLENTRY_SIZE);
+ assert (length == DISK_VLENTRY_SIZE);
+
+ if (ydr_decode_disk_vlentry((disk_vlentry *) vl_entry,
+ vl_entry_ydr, &length) == NULL)
+ err(1, "write_entry");
+
+ return 0;
+}
+
+static void
+create_database(void)
+{
+ int i;
+
+ vl_header.vital_header.vldbversion = 0;
+ vl_header.vital_header.headersize = VLHEADER_SIZE;
+ vl_header.vital_header.freePtr = 0;
+ vl_header.vital_header.eofPtr = VLHEADER_SIZE;
+ vl_header.vital_header.allocs = 0;
+ vl_header.vital_header.frees = 0;
+ vl_header.vital_header.MaxVolumeId = 0xA0000000 - 1;
+ for (i = 0; i < MAXTYPES; i++)
+ vl_header.vital_header.totalEntries[i] = 0;
+
+ for (i = 0; i < MAXSERVERID+1; i++)
+ vl_header.IpMappedAddr[i] = 0;
+
+ memset(vl_header.VolnameHash, 0, HASHSIZE * sizeof(int32_t));
+ memset(vl_header.VolidHash, 0, HASHSIZE * MAXTYPES * sizeof(int32_t));
+ vldb_write_header();
+ vldb_get_file_length();
+}
+
+unsigned long
+vldb_get_id_hash(long id)
+{
+ return ((unsigned long) id) % HASHSIZE;
+}
+
+unsigned long
+vldb_get_name_hash(const char *name)
+{
+ int i;
+ unsigned long hash = 0x47114711;
+
+ for (i = 0; name[i] && i < 32; i++)
+ hash *= name[i];
+
+ return hash % HASHSIZE;
+}
+
+int
+vldb_get_first_id_entry(unsigned long hash_id, long type,
+ disk_vlentry *vl_entry)
+{
+ off_t offset = vl_header.VolidHash[type][hash_id];
+ int status;
+
+ vldb_debug (" get_first_id_entry hash_id: %lu type: %ld offset: %d\n",
+ hash_id, type, (int) offset);
+
+ if (offset == 0)
+ return VL_NOENT;
+
+ status = vldb_read_entry(offset, vl_entry);
+
+ return status;
+}
+
+int
+vldb_get_first_name_entry(unsigned long hash_name, disk_vlentry *vl_entry)
+{
+ off_t offset = vl_header.VolnameHash[hash_name];
+ int status;
+
+ vldb_debug (" get_first_name_entry hash_name: %lu offset: %d\n",
+ hash_name, (int) offset);
+ if (offset == 0)
+ return VL_NOENT;
+
+ status = vldb_read_entry(offset, vl_entry);
+
+ return status;
+}
+
+int
+vldb_insert_entry(disk_vlentry *vl_entry)
+{
+ off_t offset;
+ int status;
+ unsigned long hash_id, hash_name;
+ disk_vlentry first_id_entry;
+ disk_vlentry first_name_entry;
+
+ /* Allokera plats i filen */
+ offset = vldb_find_first_free();
+
+ /* Allocate new volume id? */
+ /*id = vl_header.vital_header.MaxVolumeId++;*/
+
+ /* Hitta plats i hashtabellerna */
+ /* XXX At present, only RW is handled */
+ hash_id = vldb_get_id_hash(vl_entry->volumeId[RWVOL]);
+ hash_name = vldb_get_name_hash(vl_entry->name);
+
+ status = vldb_get_first_id_entry(hash_id, vl_entry->volumeType,
+ &first_id_entry);
+
+/* XXX vl_entry->nextIDHash[vldb_entry->type] = status ? 0 : first_id_entry.nextID;*/
+ vl_entry->nextIdHash[vl_entry->volumeType] = status ? 0 : vl_header.VolidHash[vl_entry->volumeType][hash_id];
+
+ status = vldb_get_first_name_entry(hash_name, &first_name_entry);
+/* XXX pr_entry->nextName = status ? 0 : first_name_entry.nextName;*/
+ vl_entry->nextNameHash = status ? 0 : vl_header.VolnameHash[hash_name];
+
+ /* XXX: uppdatera owned och nextOwned */
+
+ /* Lägg in entryt i filen */
+ status = vldb_write_entry(offset, vl_entry);
+ if (status)
+ return status;
+
+ /* Uppdatera hashtabell */
+ vl_header.VolidHash[vl_entry->volumeType][hash_id] = offset;
+ vl_header.VolnameHash[hash_name] = offset;
+ vldb_write_header();
+ return 0;
+}
+
+int
+vldb_print_entry (struct disk_vlentry *entry, int long_print)
+{
+ int i;
+ printf ("name: %s\n"
+ "\tid: rw: %u ro: %u bu: %u\n",
+ entry->name,
+ entry->volumeId[RWVOL],
+ entry->volumeId[ROVOL],
+ entry->volumeId[BACKVOL]);
+ if (!long_print)
+ return 0;
+ printf ("\tservers:\n");
+ for (i = 0; i < MAXNSERVERS; i++) {
+ struct in_addr in;
+ in.s_addr = ntohl(entry->serverNumber[i]);
+ if (entry->serverFlags[i])
+ printf ("\t\t%2d: %-16s %d %s %s %s %s\n",
+ i,
+ inet_ntoa (in),
+ entry->serverPartition[i],
+ entry->serverFlags[i] & VLSF_RWVOL ? "RW" : " ",
+ entry->serverFlags[i] & VLSF_ROVOL ? "RO" : " ",
+ entry->serverFlags[i] & VLSF_BACKVOL ? "BU" : " ",
+ entry->serverFlags[i] & VLSF_NEWREPSITE ? "New site" : "");
+ }
+
+#if 0
+ u_long volumeId[MAXTYPES];
+ long flags;
+ long LockAfsId;
+ long LockTimestamp;
+ long cloneId;
+ long AssociatedChain;
+ long nextIdHash[MAXTYPES];
+ long nextNameHash;
+ long spares1[2];
+ char name[VLDB_MAXNAMELEN];
+ u_char volumeType;
+ u_char RefCount;
+ char spares2[1];
+#endif
+ return 0;
+}
+
+static void
+open_db (char *databaseprefix, int flags)
+{
+ char database[MAXPATHLEN];
+
+ if (databaseprefix == NULL)
+ databaseprefix = MILKO_SYSCONFDIR;
+
+ snprintf (database, sizeof(database), "%s/vl_database",
+ databaseprefix);
+
+ vldb_debug ("Loading db from file %s\n", database);
+
+ vl_database = open(database, flags, S_IRWXU);
+
+ if (vl_database == -1)
+ err(1, "failed open (%s)", database);
+}
+
+void
+vldb_create (char *databaseprefix)
+{
+ open_db (databaseprefix, O_RDWR|O_CREAT|O_EXCL|O_BINARY);
+
+ printf ("Creating a new vl-database.\n");
+ create_database();
+}
+
+void
+vldb_init(char *databaseprefix)
+{
+ open_db (databaseprefix, O_RDWR|O_BINARY);
+ vldb_read_header();
+ vldb_get_file_length();
+}
+
+static int vldbdebug = 0;
+
+int
+vldb_setdebug (int debug)
+{
+ int odebug = vldbdebug;
+ vldbdebug = debug;
+ return odebug;
+}
+
+void
+vldb_debug (char *fmt, ...)
+{
+ va_list args;
+ if (!vldbdebug)
+ return ;
+
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end(args);
+}
+
diff --git a/usr.sbin/afs/src/milko/vldb/vldb_locl.h b/usr.sbin/afs/src/milko/vldb/vldb_locl.h
new file mode 100644
index 00000000000..c916595a83b
--- /dev/null
+++ b/usr.sbin/afs/src/milko/vldb/vldb_locl.h
@@ -0,0 +1,109 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+
+#include <ports.h>
+#include <ko.h>
+
+#ifdef KERBEROS
+#include <des.h>
+#include <krb.h>
+#include <rxkad.h>
+#endif
+
+#include <err.h>
+#include <assert.h>
+#include <ctype.h>
+
+#ifndef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <service.h>
+#include <msecurity.h>
+#include <netinit.h>
+
+#include <getarg.h>
+
+#include "rx/rxgencon.h"
+#include "vldb.h"
+#include "vldb.ss.h"
+#include "ubik.ss.h"
+
+
+extern int vl_database;
+extern vlheader vl_header;
+extern off_t file_length;
+
+void
+vlservdebug (char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+
+void vldb_write_header (void);
+void vldb_read_header (void);
+void vldb_get_file_length (void);
+off_t vldb_find_first_free (void);
+int vldb_write_entry (off_t offset, disk_vlentry *vl_entry);
+int vldb_read_entry (off_t offset, disk_vlentry *vl_entry);
+unsigned long vldb_get_id_hash (long id);
+unsigned long vldb_get_name_hash (const char *name);
+int vldb_get_first_id_entry (unsigned long hash_id, long type,
+ disk_vlentry *vl_entry);
+int vldb_get_first_name_entry (unsigned long hash_name,
+ disk_vlentry *vl_entry);
+int vldb_insert_entry (disk_vlentry *vl_entry);
+
+void vldb_create (char *databaseprefix);
+void vldb_init (char *databaseprefix);
+int vldb_print_entry (struct disk_vlentry *entry, int long_print);
+int vldb_setdebug (int debug);
+void vldb_debug (char *fmt, ...);
+
+
diff --git a/usr.sbin/afs/src/milko/vldb/vldbserver.c b/usr.sbin/afs/src/milko/vldb/vldbserver.c
new file mode 100644
index 00000000000..31903a258fd
--- /dev/null
+++ b/usr.sbin/afs/src/milko/vldb/vldbserver.c
@@ -0,0 +1,820 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "vldb_locl.h"
+
+RCSID("$Id: vldbserver.c,v 1.1 2000/09/11 14:41:20 art Exp $");
+
+static void make_vldb_from_vl(struct vldbentry *vldb_entry,
+ struct disk_vlentry *vl_entry);
+
+static void
+make_vldb_from_vl(struct vldbentry *vldb_entry, struct disk_vlentry *vl_entry)
+{
+ int i;
+
+ strlcpy(vldb_entry->name, vl_entry->name, VLDB_MAXNAMELEN);
+ vldb_entry->volumeType = vl_entry->volumeType;
+ vldb_entry->nServers = 1; /* XXX What is this supposed to be? */
+
+ for (i = 0; i < MAXNSERVERS; i++) {
+ vldb_entry->serverNumber[i] = vl_entry->serverNumber[i];
+ vldb_entry->serverPartition[i] = vl_entry->serverPartition[i];
+ vldb_entry->serverFlags[i] = vl_entry->serverFlags[i];
+ }
+
+ for (i = 0; i < MAXTYPES; i++)
+ vldb_entry->volumeId[i] = vl_entry->volumeId[i];
+
+ vldb_entry->cloneId = vl_entry->cloneId;
+ vldb_entry->flags = vl_entry->flags;
+}
+
+/*
+ * The rpc - calls
+ */
+
+int
+VL_CreateEntry(struct rx_call *call,
+ const vldbentry *newentry)
+{
+ struct disk_vlentry vl_entry;
+ int32_t nServers;
+ int i;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ memset (&vl_entry, 0, sizeof(vl_entry));
+
+ vldb_debug ("VL_CreateEntry (name=%s, type=%d, ids=%d,%d,%d flags=%d)\n",
+ newentry->name, newentry->volumeType,
+ newentry->volumeId[RWVOL],
+ newentry->volumeId[ROVOL],
+ newentry->volumeId[BACKVOL],
+ newentry->flags);
+
+ strlcpy(vl_entry.name, newentry->name, VLDB_MAXNAMELEN);
+ vl_entry.volumeType = newentry->volumeType;
+
+ /* XXX All fields mustn't be set */
+ nServers = newentry->nServers;
+ if (nServers > MAXNSERVERS)
+ nServers = MAXNSERVERS;
+ for (i = nServers - 1 ; i >= 0 ; i--) {
+ vl_entry.serverNumber[i] = newentry->serverNumber[i];
+ vl_entry.serverPartition[i] = newentry->serverPartition[i];
+ vl_entry.serverFlags[i] = newentry->serverFlags[i];
+ }
+
+ for (i = 0; i < MAXTYPES; i++)
+ vl_entry.volumeId[i] = newentry->volumeId[i];
+
+ vl_entry.cloneId = newentry->cloneId;
+ vl_entry.flags = newentry->flags;
+
+ vldb_insert_entry(&vl_entry);
+ return 0;
+}
+
+int
+VL_DeleteEntry(struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype)
+{
+ vldb_debug ("VL_DeleteEntry\n") ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM ;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetEntryByID(struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype,
+ vldbentry *entry)
+{
+ struct disk_vlentry vl_entry;
+
+ vldb_debug ("VL_GetEntryByID (Volid=%d,Voltype=%d)\n",
+ Volid, voltype);
+
+ if (vldb_get_first_id_entry(vldb_get_id_hash(Volid),
+ voltype, &vl_entry) != 0)
+ return VL_NOENT;
+
+ while (1) {
+ /* Return entry if match found */
+ if (vl_entry.volumeId[voltype] == Volid) {
+ make_vldb_from_vl(entry, &vl_entry);
+ return 0;
+ }
+
+ if (vl_entry.nextIdHash[voltype] == 0)
+ break;
+
+ vldb_read_entry(vl_entry.nextIdHash[voltype], &vl_entry);
+ }
+ return VL_NOENT;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetEntryByName(struct rx_call *call,
+ const char *volumename,
+ vldbentry *entry)
+{
+ struct disk_vlentry vl_entry;
+
+ vldb_debug ("VL_GetEntryByName %s\n", volumename) ;
+
+ if (isdigit(volumename[0])) {
+ return VL_GetEntryByID(call, atol(volumename), 0 /* XXX */, entry);
+ }
+
+ if (vldb_get_first_name_entry(vldb_get_name_hash(volumename),
+ &vl_entry) == 0) {
+ while (1) {
+ /* Return entry if match found */
+ if (strcmp(vl_entry.name, volumename) == 0) {
+ make_vldb_from_vl(entry, &vl_entry);
+ return 0;
+ }
+
+ if (vl_entry.nextNameHash == 0)
+ break;
+
+ vldb_read_entry(vl_entry.nextNameHash, &vl_entry);
+ }
+ }
+
+ return VL_NOENT;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetNewVolumeId (struct rx_call *call,
+ const int32_t bumpcount,
+ int32_t *newvolumid)
+{
+ vldb_debug ("VL_GetNewVolumeId(bumpcount=%d)\n", bumpcount) ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ *newvolumid = vl_header.vital_header.MaxVolumeId;
+ vldb_debug (" returning low volume id = %d\n", *newvolumid);
+ vl_header.vital_header.MaxVolumeId += bumpcount;
+ vldb_write_header();
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_ReplaceEntry (struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype,
+ const vldbentry *newentry,
+ const int32_t ReleaseType)
+{
+ vldb_debug ("VL_ReplaceEntry\n") ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM ;
+}
+
+/*
+ *
+ */
+
+int
+VL_UpdateEntry (struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype,
+ const VldbUpdateEntry *UpdateEntry,
+ const int32_t ReleaseType)
+{
+ vldb_debug ("VL_UpdateEntry\n") ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM ;
+}
+
+/*
+ *
+ */
+
+int
+VL_SetLock (struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype,
+ const int32_t voloper)
+{
+ vldb_debug ("VL_SetLock\n") ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_ReleaseLock (struct rx_call *call,
+ const int32_t volid,
+ const int32_t voltype,
+ const int32_t ReleaseType)
+{
+ vldb_debug ("VL_ReleaseLock\n") ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_ListEntry (struct rx_call *call,
+ const int32_t previous_index,
+ int32_t *count,
+ int32_t *next_index,
+ vldbentry *entry)
+{
+ vldb_debug ("VL_ListEntry\n") ;
+ return VL_PERM ;
+}
+
+/*
+ *
+ */
+
+int
+VL_ListAttributes (struct rx_call *call,
+ const VldbListByAttributes *attributes,
+ int32_t *nentries,
+ bulkentries *blkentries)
+{
+ vldb_debug ("VL_ListAttributes\n") ;
+ return VL_PERM ;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetStats (struct rx_call *call,
+ vldstats *stats,
+ vital_vlheader *vital_header)
+{
+ vldb_debug ("VL_GetStats") ;
+ return VL_PERM ;
+}
+
+/*
+ *
+ */
+
+int
+VL_Probe(struct rx_call *call)
+{
+ vldb_debug ("VL_Probe\n") ;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_CreateEntryN(struct rx_call *call,
+ const nvldbentry *entry)
+{
+ int i;
+ struct vldbentry vldb_entry;
+
+ vldb_debug ("VL_CreateEntryN\n") ;
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ memset (&vldb_entry, 0, sizeof (vldb_entry));
+
+ strncpy(vldb_entry.name, entry->name, VLDB_MAXNAMELEN);
+ vldb_entry.volumeType = RWVOL;
+ vldb_entry.nServers = entry->nServers;
+
+ for (i = 0; i < MAXNSERVERS; i++) {
+ vldb_entry.serverNumber[i] = entry->serverNumber[i];
+ vldb_entry.serverPartition[i] = entry->serverPartition[i];
+ vldb_entry.serverFlags[i] = entry->serverFlags[i];
+ }
+
+ for (i = 0; i < MAXTYPES; i++)
+ vldb_entry.volumeId[i] = entry->volumeId[i];
+
+ vldb_entry.cloneId = entry->cloneId;
+ vldb_entry.flags = entry->flags;
+
+ return VL_CreateEntry(call, &vldb_entry);
+}
+
+/*
+ *
+ */
+
+int
+VL_GetEntryByIDN(struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype,
+ nvldbentry *entry)
+{
+ struct vldbentry vldb_entry;
+ int status, i;
+ int32_t type = voltype;
+
+ vldb_debug ("VL_GetEntryByIDN (Volid=%d,Voltype=%d)\n", Volid, type);
+
+ memset (&vldb_entry, 0, sizeof(vldb_entry));
+
+ if (type == -1)
+ type = RWVOL;
+
+ status = VL_GetEntryByID(call, Volid, type, &vldb_entry);
+
+ if (status)
+ return status;
+
+ strlcpy(entry->name, vldb_entry.name, VLDB_MAXNAMELEN);
+ entry->nServers = vldb_entry.nServers;
+ for (i = 0; i < MAXNSERVERS; i++) {
+ entry->serverNumber[i] = vldb_entry.serverNumber[i];
+ entry->serverPartition[i] = vldb_entry.serverPartition[i];
+ entry->serverFlags[i] = vldb_entry.serverFlags[i];
+ }
+
+ for (i = 0; i < MAXTYPES; i++)
+ entry->volumeId[i] = vldb_entry.volumeId[i];
+
+ entry->cloneId = vldb_entry.cloneId;
+ entry->flags = vldb_entry.flags;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetEntryByNameN(struct rx_call *call,
+ const char *volumename,
+ nvldbentry *entry)
+{
+ struct vldbentry vldb_entry;
+ int status, i;
+
+ memset (&vldb_entry, 0, sizeof(vldb_entry));
+
+ vldb_debug ("VL_GetEntryByNameN(volumename=%s)\n", volumename) ;
+ status = VL_GetEntryByName(call, volumename, &vldb_entry);
+
+ if (status)
+ return status;
+
+ memset (entry, 0, sizeof(*entry));
+ strlcpy(entry->name, vldb_entry.name, VLDB_MAXNAMELEN);
+ entry->nServers = vldb_entry.nServers;
+ for (i = 0; i < MAXNSERVERS; i++) {
+ entry->serverNumber[i] = vldb_entry.serverNumber[i];
+ entry->serverPartition[i] = vldb_entry.serverPartition[i];
+ entry->serverFlags[i] = vldb_entry.serverFlags[i];
+ }
+
+ for (i = 0; i < MAXTYPES; i++)
+ entry->volumeId[i] = vldb_entry.volumeId[i];
+
+ entry->cloneId = vldb_entry.cloneId;
+ entry->flags = vldb_entry.flags;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetEntryByNameU(struct rx_call *call,
+ const char *volumename,
+ uvldbentry *entry)
+{
+ vldb_debug ("VL_GetEntryByNameU %s\n", volumename);
+ memset(entry, 0, sizeof(*entry));
+
+ return RXGEN_OPCODE;
+}
+
+/*
+ *
+ */
+
+int
+VL_ListAttributesN (struct rx_call *call,
+ const VldbListByAttributes *attributes,
+ int32_t *nentries,
+ nbulkentries *blkentries)
+{
+ vldb_debug ("VL_ListAttributesN\n");
+ vldb_debug (" attributes: Mask=(%d=", attributes->Mask);
+
+ if (attributes->Mask & VLLIST_SERVER)
+ vldb_debug ("SERVER ");
+ if (attributes->Mask & VLLIST_PARTITION)
+ vldb_debug ("PARTITION ");
+ if (attributes->Mask & VLLIST_VOLUMETYPE)
+ vldb_debug ("VOLUMETYPE ");
+ if (attributes->Mask & VLLIST_VOLUMEID)
+ vldb_debug ("VOLUMEID ");
+ if (attributes->Mask & VLLIST_FLAG)
+ vldb_debug ("FLAG");
+
+ vldb_debug (") server=%d partition=%d volumetype=%d volumeid=%d flag=%d\n",
+ attributes->server,
+ attributes->partition,
+ attributes->volumetype,
+ attributes->volumeid,
+ attributes->flag);
+
+ *nentries = 1;
+
+ blkentries->len = 0;
+ blkentries->val = NULL;
+
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_ListAttributesU(struct rx_call *call,
+ const VldbListByAttributes *attributes,
+ int32_t *nentries,
+ ubulkentries *blkentries)
+{
+ vldb_debug ("VL_ListAttributesU\n") ;
+ *nentries = 0;
+ blkentries->len = 0;
+ blkentries->val = NULL;
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_UpdateEntryByName(struct rx_call *call,
+ const char volname[65],
+ const struct VldbUpdateEntry *UpdateEntry,
+ const int32_t ReleaseType)
+{
+ vldb_debug ("VL_UpdateEntryByName (not implemented)\n");
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetAddrsU(struct rx_call *call,
+ const struct ListAddrByAttributes *inaddr,
+ struct afsUUID *uuid,
+ int32_t *uniq,
+ int32_t *nentries,
+ bulkaddrs *addrs)
+{
+ vldb_debug ("VL_GetAddrsU (not implemented)\n");
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_RegisterAddrs(struct rx_call *call,
+ const struct afsUUID *uid,
+ const int32_t spare,
+ const bulkaddrs *addrs)
+{
+ vldb_debug ("VL_RegistersAddrs (not implemented)\n");
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+int
+VL_CreateEntryU(struct rx_call *call,
+ const struct uvldbentry *newentry)
+{
+ vldb_debug ("VL_CreateEntryU (not implemented)\n");
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_ReplaceEntryU(struct rx_call *call)
+{
+ vldb_debug ("VL_ReplaceEntryU (not implemented)\n");
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_ReplaceEntryN(struct rx_call *call,
+ const int32_t Volid,
+ const int32_t voltype,
+ const struct vldbentry *newentry,
+ const int32_t ReleaseType)
+{
+ vldb_debug ("VL_ReplaceEntryN (not implemented)\n");
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_ChangeAddrs(struct rx_call *call,
+ const int32_t old_ip,
+ const int32_t new_ip)
+{
+ vldb_debug ("VL_ChangeAddrs (not implemented)\n");
+
+ if (!sec_is_superuser(call))
+ return VL_PERM;
+
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetEntryByIDU(struct rx_call *call)
+{
+ vldb_debug ("VL_GetEntryByIDU (not implemented)\n");
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_ListEntryN(struct rx_call *call)
+{
+ vldb_debug ("VL_ListEntryN (not implemented)\n");
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_ListEntryU(struct rx_call *call)
+{
+ vldb_debug ("VL_ListEntryU (not implemented)\n");
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_GetAddrs(struct rx_call *call,
+ const int32_t handle,
+ const int32_t spare,
+ struct VL_Callback *spare3,
+ const int32_t *nentries,
+ bulkaddrs *blkaddr)
+{
+ vldb_debug ("VL_GetAddrs (not implemented)\n");
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_LinkedListN(struct rx_call *call)
+{
+ vldb_debug ("VL_LinkedListN (not implemented)\n");
+ return VL_PERM;
+}
+
+/*
+ *
+ */
+
+int
+VL_LinkedListU(struct rx_call *call)
+{
+ vldb_debug ("VL_LinkedListU (not implemented)\n");
+ return VL_PERM;
+}
+
+
+/*
+ *
+ */
+
+static struct rx_service *vldbservice = NULL;
+static struct rx_service *ubikservice = NULL;
+
+static char *cell = NULL;
+static char *realm = NULL;
+static char *databasedir = NULL;
+static char *srvtab_file = NULL;
+static int no_auth = 0;
+static int do_create = 0;
+static int vlsrv_debug = 0;
+
+static struct getargs args[] = {
+ {"create", 0, arg_flag, &do_create, "create new database"},
+ {"cell", 0, arg_string, &cell, "what cell to use"},
+ {"realm", 0, arg_string, &realm, "what realm to use"},
+ {"prefix",'p', arg_string, &databasedir, "what dir to store the db"},
+ {"noauth", 0, arg_flag, &no_auth, "disable authentication checks"},
+ {"debug", 'd', arg_flag, &vlsrv_debug, "output debugging"},
+ {"srvtab",'s', arg_string, &srvtab_file, "what srvtab to use"},
+ { NULL, 0, arg_end, NULL }
+};
+
+static void
+usage(void)
+{
+ arg_printusage(args, NULL, "", ARG_AFSSTYLE);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+ if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) {
+ usage ();
+ return 1;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc) {
+ printf("unknown option %s\n", *argv);
+ return 1;
+ }
+
+ if (vlsrv_debug)
+ vldb_setdebug (vlsrv_debug);
+
+ if (no_auth)
+ sec_disable_superuser_check ();
+
+ if (do_create) {
+ vldb_create (databasedir);
+ return 0;
+ }
+
+ ports_init();
+ cell_init(0);
+
+ if (cell)
+ cell_setthiscell (cell);
+
+ network_kerberos_init (srvtab_file);
+
+ vldb_init(databasedir);
+
+ ret = network_init(htons(afsvldbport), "vl", VLDB_SERVICE_ID,
+ VL_ExecuteRequest, &vldbservice, realm);
+ if (ret)
+ errx (1, "network_init failed with %d", ret);
+
+ ret = network_init(htons(afsvldbport), "ubik", VOTE_SERVICE_ID,
+ Ubik_ExecuteRequest, &ubikservice, NULL);
+ if (ret)
+ errx (1, "network_init failed with %d", ret);
+
+ printf("Milko vldbserver %s-%s started\n", PACKAGE, VERSION);
+
+ rx_SetMaxProcs(vldbservice,5) ;
+ rx_SetMaxProcs(ubikservice,5) ;
+ rx_StartServer(1) ;
+
+ abort() ; /* should not get here */
+ return 0;
+}
diff --git a/usr.sbin/afs/src/milko/vldb/vled.c b/usr.sbin/afs/src/milko/vldb/vled.c
new file mode 100644
index 00000000000..eb86da17f24
--- /dev/null
+++ b/usr.sbin/afs/src/milko/vldb/vled.c
@@ -0,0 +1,454 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include "vldb_locl.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <limits.h>
+
+RCSID("$Id: vled.c,v 1.1 2000/09/11 14:41:20 art Exp $");
+
+struct ed_context {
+ long begin;
+ long end;
+ long current;
+ struct ed_command *cmds;
+};
+
+typedef int (*ed_pcmd)(struct ed_context *context,
+ const char *str, size_t len);
+
+
+struct ed_command {
+ char ed_c;
+ ed_pcmd ed_cmd;
+ char *ed_help;
+};
+
+typedef enum { ED_NOERR = 0, ED_SYNTAX, ED_NOCMD, ED_FATAL, ED_EOF,
+ ED_EXIT } ed_ret;
+typedef enum { ED_RANGE_END = -1 } ed_val;
+
+static ed_ret get_string (FILE *f, char *buf, size_t len);
+static ed_ret findexec_cmd (struct ed_command *cmds, const char *buf,
+ size_t len, struct ed_context *context);
+static ed_ret parse_addr (struct ed_context *context, char **p, size_t *len);
+
+
+int ed_loop (struct ed_command *cmds);
+int ed_help (struct ed_context *context, const char *str, size_t len);
+
+/*
+ *
+ */
+
+static int
+local_common (struct ed_context *context,
+ const char *str, size_t len,
+ int (*func) (disk_vlentry *, long num, const char *,
+ size_t, void *),
+ void *ptr)
+{
+ disk_vlentry vlentry;
+ int ret;
+ long i;
+
+ if (context->begin == ED_RANGE_END || context->begin > HASHSIZE)
+ context->begin = HASHSIZE;
+ if (context->end == ED_RANGE_END || context->end > HASHSIZE-1)
+ context->end = HASHSIZE;
+ else
+ context->end++;
+
+ for (i = context->begin ; i < context->end ; i++) {
+ ret = vldb_get_first_id_entry(i, 0, &vlentry);
+ if (ret == 0) {
+ context->current = i;
+ if ((*func) (&vlentry, i, str, len, ptr))
+ return 0;
+ } else if (ret == VL_NOENT)
+ continue;
+ else
+ err (1, "got strange return-code from "
+ "vldb_get_first_id_entry: %d\n", ret);
+ }
+
+ return 0;
+}
+
+static int
+print_func (disk_vlentry *entry, long num,
+ const char *str, size_t len, void *ptr)
+{
+ printf ("pos: %ld\n ", num);
+ vldb_print_entry (entry, 1);
+ return 0;
+}
+
+static int
+local_print (struct ed_context *context,
+ const char *str, size_t len)
+{
+ return local_common (context, str, len, print_func, NULL);
+}
+
+static int
+search_func (disk_vlentry *entry, long num,
+ const char *str, size_t len, void *ptr)
+{
+ if (strstr (entry->name, str) == NULL)
+ return 0;
+ printf ("pos: %ld\n ", num);
+ vldb_print_entry (entry, 0);
+ return 0;
+}
+
+static int
+local_search (struct ed_context *context,
+ const char *str, size_t len)
+{
+ if (len == 0) {
+ context->begin = context->current;
+ } else {
+ context->begin = 0;
+ context->end = ED_RANGE_END;
+ }
+ return local_common (context, str, len, search_func, NULL);
+}
+
+static int
+local_add (struct ed_context *context, const char *str, size_t len)
+{
+ printf ("not implemented yet\n");
+ return ED_NOERR;
+}
+
+static int
+local_addserver (struct ed_context *context, const char *str, size_t len)
+{
+ disk_vlentry vlentry;
+ int ret;
+
+ if (len == 0)
+ return ED_SYNTAX;
+
+ ret = vldb_get_first_id_entry(context->begin, 0, &vlentry);
+ if (ret) {
+ printf ("addserver: vldb_get_first_id_entry failed %d\n", ret);
+ return ED_NOERR;
+ }
+
+#if 0
+ vldb_print_entry (&vlentry, 1);
+#endif
+
+ printf ("not implemented yet\n");
+ return ED_NOERR;
+}
+
+static int
+backup_func (disk_vlentry *entry, long num,
+ const char *str, size_t len, void *ptr)
+{
+ int i;
+
+ printf ("%dd\n%dd\n%dd\n",
+ entry->volumeId[RWVOL],
+ entry->volumeId[ROVOL],
+ entry->volumeId[BACKVOL]);
+
+ printf ("a %s %d %d %d 0x0\n",
+ entry->name,
+ entry->volumeId[RWVOL],
+ entry->volumeId[ROVOL],
+ entry->volumeId[BACKVOL]);
+ for (i = 0; i < MAXNSERVERS; i++) {
+ struct in_addr in;
+ if (entry->serverNumber[i] == 0)
+ break;
+ in.s_addr = entry->serverNumber[i];
+ printf ("A %s %d 0x%x\n",
+ inet_ntoa(in),
+ entry->serverPartition[i],
+ entry->serverFlags[i]);
+ }
+ printf ("f 0x%d\n", entry->flags);
+ return 0;
+}
+
+static int
+local_backup (struct ed_context *context, const char *str, size_t len)
+{
+ return local_common (context, str, len, backup_func, NULL);
+}
+
+static int
+local_delete (struct ed_context *context, const char *str, size_t len)
+{
+ printf ("not implemented yet\n");
+ return ED_NOERR;
+}
+
+static int
+local_deleteserver (struct ed_context *context, const char *str, size_t len)
+{
+ printf ("not implemented yet\n");
+ return ED_NOERR;
+}
+
+static int
+local_modify (struct ed_context *context, const char *str, size_t len)
+{
+ printf ("not implemented yet\n");
+ return ED_NOERR;
+}
+
+static int
+local_rename (struct ed_context *context, const char *str, size_t len)
+{
+ printf ("not implemented yet\n");
+ return ED_NOERR;
+}
+
+static int
+quit (struct ed_context *context, const char *str, size_t len)
+{
+ return ED_EXIT;
+}
+
+struct ed_command vled[] = {
+ { 'p', local_print, "print vldb entry" },
+ { '/', local_search, "search vldb entry" },
+ { 'a', local_add, "add new entry"},
+ { 'A', local_addserver, "add new server to entry"},
+ { 'b', local_backup, "backup/dump a entry"},
+ { 'd', local_delete, "delete entry"},
+ { 'D', local_deleteserver, "delete server from entry"},
+ { 'm', local_modify, "modify entry"},
+ { 'n', local_rename, "rename entry"},
+ { '?', ed_help, "help" },
+ { 'q', quit, "exit" },
+ { 0, NULL, NULL }
+};
+
+/*
+ *
+ */
+
+static ed_ret
+get_string (FILE *f, char *buf, size_t len)
+{
+ char *str;
+
+ str = fgets (buf, len, f);
+ if (str == NULL) {
+ if (feof(f))
+ return ED_EOF;
+ return ED_FATAL;
+ }
+ buf[strlen(buf)-1] = '\0';
+ return ED_NOERR;
+}
+
+static ed_ret
+parse_element (char **p, size_t *len, long *raddr, long current, int first)
+{
+ long addr;
+ char *old = *p;
+
+ while (1) {
+ if (*len < 1)
+ return ED_SYNTAX;
+
+ switch (**p) {
+ case '^':
+ *raddr = 0;
+ (*p)++;
+ *len -= 1;
+ return ED_NOERR;
+ case '$':
+ *raddr = ED_RANGE_END;
+ (*p)++;
+ *len -= 1;
+ return ED_NOERR;
+ case ',':
+ if (first) {
+ *raddr = 0;
+ return ED_NOERR;
+ }
+ (*p)++;
+ *len -= 1;
+ break;
+ case '1': case '2': case '3' :case '4': case '5':
+ case '6': case '7': case '8': case '9' :case '0':
+ addr = strtol (*p, p, 0);
+ if ((addr == LONG_MAX || addr == LONG_MIN) && errno == ERANGE) {
+ *len -= *p - old;
+ return ED_SYNTAX;
+ }
+ *raddr = addr;
+ return ED_NOERR;
+ default:
+ if (!first)
+ *raddr = ED_RANGE_END;
+ else
+ *raddr = current;
+ return ED_NOERR;
+ }
+ }
+ return ED_NOERR;
+}
+
+
+static ed_ret
+parse_addr (struct ed_context *context, char **p, size_t *len)
+{
+ long addr;
+ int num_el = 0;
+ ed_ret ret;
+
+ context->begin = context->end = context->current;
+
+ if (*len < 1)
+ return ED_SYNTAX;
+
+ while (num_el < 2) {
+ ret = parse_element (p, len, &addr, context->current, !num_el);
+ if (ret != ED_NOERR)
+ break;
+ num_el++;
+
+ context->begin = context->end;
+ context->end = addr;
+
+ if (**p != ',' && **p != ';')
+ break;
+ else if (**p == ';') {
+ (*p)++;
+ context->current = addr;
+ }
+ }
+ if (num_el == 1 || context->end != addr)
+ context->begin = context->end;
+ return ED_NOERR;
+}
+
+static ed_ret
+findexec_cmd (struct ed_command *cmds, const char *buf, size_t len,
+ struct ed_context *context)
+{
+ struct ed_command *c;
+
+ if (len == 0)
+ return ED_SYNTAX;
+
+ for (c = cmds; c->ed_cmd; c++) {
+ if (c->ed_c == *buf)
+ return (c->ed_cmd) (context, (buf+1), (len-1));
+ }
+ return ED_NOCMD;
+}
+
+#define HANDLE_ERROR(ret) \
+ switch (ret) { \
+ case ED_NOERR: \
+ break; \
+ case ED_EOF: \
+ case ED_EXIT: \
+ return ED_NOERR; \
+ case ED_FATAL: \
+ return ret; \
+ default: \
+ printf ("?\n"); \
+ break; \
+ } \
+ if (ret != ED_NOERR) continue
+
+
+int
+ed_help (struct ed_context *context, const char *str, size_t len)
+{
+ struct ed_command *c;
+
+ printf ("help:\n");
+ for (c = context->cmds; c->ed_cmd; c++)
+ printf (" %c\t%s\n", c->ed_c, c->ed_help);
+ return ED_NOERR;
+}
+
+int
+ed_loop (struct ed_command *cmds)
+{
+ struct ed_context context = {0, 0, 0, NULL};
+ size_t len;
+ char buf[4*1024];
+ char *str;
+ char **p;
+ ed_ret ret;
+
+ if (cmds == NULL)
+ return EINVAL;
+
+ context.cmds = cmds;
+
+ while (1) {
+ ret = get_string (stdin, buf, sizeof(buf));
+ HANDLE_ERROR(ret);
+
+ str = buf;
+ p = &str;
+ len = sizeof(buf);
+ ret = parse_addr (&context, p, &len);
+ HANDLE_ERROR(ret);
+ ret = findexec_cmd (cmds, *p, len, &context);
+ HANDLE_ERROR(ret);
+ }
+}
+
+
+int
+main(int argc, char **argv)
+{
+ char *databasedir = NULL;
+ vldb_init(databasedir);
+
+ ed_loop (vled);
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/mkinstalldirs b/usr.sbin/afs/src/mkinstalldirs
new file mode 100644
index 00000000000..a25c2c09630
--- /dev/null
+++ b/usr.sbin/afs/src/mkinstalldirs
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.1 2000/09/11 14:40:30 art Exp $
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/usr.sbin/afs/src/rx/Makefile.in b/usr.sbin/afs/src/rx/Makefile.in
new file mode 100644
index 00000000000..a6474c4eaab
--- /dev/null
+++ b/usr.sbin/afs/src/rx/Makefile.in
@@ -0,0 +1,155 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:20 art Exp $
+#
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+RM = rm
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+sbindir = @sbindir@
+libdir = @libdir@
+includedir = @includedir@
+
+DEFS = @DEFS@ -DRXDEBUG
+CFLAGS = @CFLAGS@
+INCLUDES = -I$(srcdir) -I../include -I$(srcdir)/../include \
+ @KRB4_INC_FLAGS@ -I$(srcdir)/../lib/cmd
+
+LIB = librx.a
+include_HEADERS = rx.h rx_clock.h rx_event.h rx_globs.h rx_mach.h rx_misc.h \
+ rx_multi.h rx_null.h rx_pkt.h rx_queue.h rx_trace.h \
+ rx_user.h rxgencon.h
+
+PROGS = test_rx_clock rxdebug rxperf
+
+LIB_SOURCES = \
+ rx_clock.c \
+ rx_event.c \
+ rx_user.c \
+ rx.c \
+ rx_globs.c \
+ rx_null.c \
+ rx_misc.c \
+ rx_pkt.c \
+ rx_rdwr.c \
+ rx_trace.c \
+ rx_multi.c
+
+test_rx_clock_SOURCES = test_rx_clock.c
+rxdebug_SOURCES = rxdebug.c
+rxperf_SOURCES = rxperf.c
+
+SOURCES = \
+ $(LIB_SOURCES) \
+ $(test_rx_clock_SOURCES) \
+ $(rxdebug_SOURCES) \
+ $(rxperf_SOURCES)
+
+LIB_OBJECTS = \
+ rx_clock.o \
+ rx_event.o \
+ rx_user.o \
+ rx.o \
+ rx_globs.o \
+ rx_null.o \
+ rx_misc.o \
+ rx_pkt.o \
+ rx_rdwr.o \
+ rx_trace.o \
+ rx_multi.o
+
+test_rx_clock_OBJECTS = test_rx_clock.o
+rxdebug_OBJECTS = rxdebug.o
+rxperf_OBJECTS = rxperf.o
+
+OBJECTS = \
+ $(LIB_OBJECTS) \
+ $(test_rx_clock_OBJECTS) \
+ $(rxdebug_OBJECTS) \
+ $(rxperf_OBJECTS)
+
+MANPAGES = rxdebug.1
+
+all: $(LIB) $(PROGS)
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+ $(MKINSTALLDIRS) $(DESTDIR)$(includedir)/rx
+ $(MKINSTALLDIRS) $(DESTDIR)$(sbindir) $(DESTDIR)$(bindir)
+ $(INSTALL_PROGRAM) rxdebug $(DESTDIR)$(bindir)/rxdebug
+ $(INSTALL_PROGRAM) rxperf $(DESTDIR)$(sbindir)/rxperf
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+ for x in $(include_HEADERS); do \
+ $(INSTALL_DATA) $(srcdir)/$$x $(DESTDIR)$(includedir)/rx/$$x; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ $(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$$e ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$$x \
+ $(DESTDIR)$(mandir)/man$$e/$$f.$$e; \
+ done
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+ rm -f $(DESTDIR)$(bindir)/rxdebug
+ rm -f $(DESTDIR)$(sbindir)/rxperf
+ for x in $(include_HEADERS); do \
+ rm -f $(DESTDIR)$(includedir)/rx/$$x; \
+ done ; \
+ MANPAGES='$(MANPAGES)'; for x in $$MANPAGES; do \
+ n=`echo $$x | sed 's/\(.*\)\.[1-9a-zA-Z]*$$/\1/'`; \
+ e=`echo $$x | sed 's/.*\.\([1-9a-zA-Z]*\)$$/\1/'`; \
+ f=`echo $$n | sed '$(transform)'`; \
+ rm -rf $(DESTDIR)$(mandir)/$$f.$$e; \
+ done
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) $(INCLUDES) $(CFLAGS) $<
+
+clean:
+ rm -f $(LIB) $(PROGS) *.o *.a
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *~
+
+realclean: distclean
+ rm -f TAGS
+
+$(LIB): $(LIB_OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(LIB_OBJECTS)
+ -$(RANLIB) $@
+
+test_rx_clock: $(test_rx_clock_OBJECTS) $(LIB)
+ $(CC) -o $@ $(test_rx_clock_OBJECTS) -L. -lrx $(LIBS)
+
+rxdebug: $(rxdebug_OBJECTS) $(LIB)
+ $(CC) -o $@ $(rxdebug_OBJECTS) -L../lib/cmd -lcmd -L. -lrx $(LIBS) -L../lwp -llwp @PLWP_LIB_FLAGS@ -L../lib/roken -lroken @LIBS@
+
+rxperf: $(rxperf_OBJECTS) $(LIB)
+ $(CC) -o $@ $(rxperf_OBJECTS) -L../lib/cmd -lcmd -L. -lrx $(LIBS) -L../lwp -llwp @PLWP_LIB_FLAGS@ -L../lib/roken -lroken @LIBS@
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=rx/Makefile CONFIG_HEADERS= ./config.status
+
+.PHONY: all clean mostlyclean distclean realclean install uninstall
diff --git a/usr.sbin/afs/src/rx/rxdebug.1 b/usr.sbin/afs/src/rx/rxdebug.1
new file mode 100644
index 00000000000..f37225cbebc
--- /dev/null
+++ b/usr.sbin/afs/src/rx/rxdebug.1
@@ -0,0 +1,75 @@
+.\" Copyright (c) 2000 Kungliga Tekniska Högskolan
+.\" $Id: rxdebug.1,v 1.1 2000/09/11 14:41:23 art Exp $
+.Dd Aug 24, 2000
+.Dt SECTION
+.Nm rxdebug
+.Os Arla
+.Sh NAME
+.Nm rxdebug
+.Nd
+a tool to diagnose problems with rx.
+.Sh SYNOPSIS
+.Nm
+.Op Fl port Ar port
+.Op Fl nodally
+.Op Fl allconnection
+.Op Fl rxstats
+.Op Fl onlyserver
+.Op Fl onlyclient
+.Op Fl onlyport Ar port
+.Op Fl onlyhost Ar host
+.Op Fl onlyauth Ar authlevel
+.Op Fl version
+.Op Fl noconns
+.Fl servers Ar servers ...
+.Sh DESCRIPTION
+Supported options:
+.Bl -tag -width Ds
+.It Fl port Ar port
+what port should be used to talk the rx implemetation
+.It Fl nodally
+don't show dally connections.
+.It Fl allconnection
+show all connection.
+.It Fl rxstats
+show statistics about rx performance, loss of packets, etc
+.It Fl onlyserver
+show only server connections
+.It Fl onlyclient
+show only client connections
+.It Fl onlyport Ar port
+only display the connection that use
+.Ar port .
+.It Fl onlyhost Ar host
+only display the connection from
+.Ar host .
+.It Fl onlyauth Ar authlevel
+only display connection with auth level
+.Ar authlevel
+.It Fl version
+display version of the remote implementation.
+.Nm
+.It Fl noconns
+do not show any connection.
+.It servers ...
+list of the servers to talk to.
+.El
+.Sh DIAGNOSTICS
+.Nm
+is used to diagnose a rx-implementation, what version the afs-client
+are running, why rx missbehavies, or if there are performance problems.
+.Pp
+.Sh EXAMPLES
+.Bd -literal
+datan# rxdebug -servers localhost -port 4711 -status -noconn
+Trying 127.0.0.1 (port 4711):
+Free packets: 65, packet reclaims: 0, calls: 28, used FDs: 6
+not waiting for packets.
+0 calls waiting for a thread
+Done.
+data# rxdebug -servers localhost -port 4711 -version
+Trying 127.0.0.1 (port 4711):
+AFS version: arla-0.34.1
+.Ed
+.\".Sh SEE ALSO
+.\"XXX
diff --git a/usr.sbin/afs/src/rx/rxdebug.c b/usr.sbin/afs/src/rx/rxdebug.c
new file mode 100644
index 00000000000..1271de203d8
--- /dev/null
+++ b/usr.sbin/afs/src/rx/rxdebug.c
@@ -0,0 +1,670 @@
+/*
+****************************************************************************
+* Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
+* *
+* Permission to use, copy, modify, and distribute this software and its *
+* documentation for any purpose and without fee is hereby granted, *
+* provided that the above copyright notice appear in all copies and *
+* that both that copyright notice and this permission notice appear in *
+* supporting documentation, and that the name of IBM not be used in *
+* advertising or publicity pertaining to distribution of the software *
+* without specific, written prior permission. *
+* *
+* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
+* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
+* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
+* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
+* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
+****************************************************************************
+*/
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <cmd.h>
+
+#include <stdio.h>
+
+#include "rx_user.h"
+#include "rx_clock.h"
+#include "rx_queue.h"
+#include "rx.h"
+
+RCSID ("$Id: rxdebug.c,v 1.1 2000/09/11 14:41:23 art Exp $");
+
+#define TIMEOUT 20
+
+static short
+PortNumber(char *aport)
+{
+ return htons(atoi (aport));
+}
+
+static short
+PortName(char *aname)
+{
+ struct servent *ts = getservbyname(aname, NULL);
+ if (ts == NULL)
+ return -1;
+ return ts->s_port; /* returns it in network byte order */
+}
+
+static int
+MakeCall (int asocket, long ahost, short aport, char *adata,
+ long alen, char *aresult, long aresultLen)
+{
+ static long counter = 100;
+ long endTime;
+ struct rx_header theader;
+ char tbuffer[1500];
+ register long code;
+ struct timeval tv;
+ struct sockaddr_in taddr, faddr;
+ int faddrLen;
+ fd_set imask;
+ register char *tp;
+
+ endTime = time(0) + TIMEOUT; /* try for N seconds */
+ counter++;
+ tp = &tbuffer[sizeof(struct rx_header)];
+ taddr.sin_family = AF_INET;
+ taddr.sin_port = aport;
+ taddr.sin_addr.s_addr = ahost;
+ while(1) {
+ bzero(&theader, sizeof(theader));
+ theader.epoch = htonl(999);
+ theader.cid = 0;
+ theader.callNumber = htonl(counter);
+ theader.seq = 0;
+ theader.serial = 0;
+ theader.type = RX_PACKET_TYPE_DEBUG;
+ theader.flags = RX_CLIENT_INITIATED | RX_LAST_PACKET;
+ theader.serviceId = 0;
+
+ bcopy(&theader, tbuffer, sizeof(theader));
+ bcopy(adata, tp, alen);
+ code = sendto(asocket, tbuffer, alen+sizeof(struct rx_header), 0,
+ (struct sockaddr *)&taddr, sizeof(struct sockaddr_in));
+
+ /* see if there's a packet available */
+
+ FD_ZERO(&imask);
+ FD_SET(asocket,&imask);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ code = select(asocket+1, &imask, NULL, NULL, &tv);
+ if (code > 0) {
+ /* now receive a packet */
+ faddrLen = sizeof(struct sockaddr_in);
+ code = recvfrom(asocket, tbuffer, sizeof(tbuffer), 0,
+ (struct sockaddr *)&faddr, &faddrLen);
+
+ bcopy(tbuffer, &theader, sizeof(struct rx_header));
+ if (counter == ntohl(theader.callNumber)) break;
+ }
+
+ /* see if we've timed out */
+ if (endTime < time(0)) return -1;
+ }
+ code -= sizeof(struct rx_header);
+ if (code > aresultLen) code = aresultLen;
+ bcopy(tp, aresult, code);
+ return code;
+}
+
+static int
+GetVersion(int asocket, long ahost, short aport, void *adata, long alen,
+ char *aresult, long aresultLen)
+{
+ static long counter = 100;
+ long endTime;
+ struct rx_header theader;
+ char tbuffer[1500];
+ register long code;
+ struct timeval tv;
+ struct sockaddr_in taddr, faddr;
+ int faddrLen;
+ fd_set imask;
+ register char *tp;
+
+ endTime = time(0) + TIMEOUT; /* try for N seconds */
+ counter++;
+ tp = &tbuffer[sizeof(struct rx_header)];
+ taddr.sin_family = AF_INET;
+ taddr.sin_port = aport;
+ taddr.sin_addr.s_addr = ahost;
+ while(1) {
+ bzero(&theader, sizeof(theader));
+ theader.epoch = htonl(999);
+ theader.cid = 0;
+ theader.callNumber = htonl(counter);
+ theader.seq = 0;
+ theader.serial = 0;
+ theader.type = RX_PACKET_TYPE_VERSION;
+ theader.flags = RX_CLIENT_INITIATED | RX_LAST_PACKET;
+ theader.serviceId = 0;
+
+ bcopy(&theader, tbuffer, sizeof(theader));
+ bcopy(adata, tp, alen);
+
+ code = sendto(asocket, tbuffer, alen+sizeof(struct rx_header), 0,
+ (struct sockaddr *)&taddr, sizeof(struct sockaddr_in));
+
+ /* see if there's a packet available */
+ FD_ZERO(&imask);
+ FD_SET(asocket, &imask);
+
+/* should be 1 */
+
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+
+ code = select(32, &imask, 0, 0, &tv);
+ if (code > 0) {
+ /* now receive a packet */
+ faddrLen = sizeof(struct sockaddr_in);
+
+ code = recvfrom(asocket, tbuffer, sizeof(tbuffer), 0,
+ (struct sockaddr *)&faddr, &faddrLen);
+
+ bcopy(tbuffer, &theader, sizeof(struct rx_header));
+
+ if (counter == ntohl(theader.callNumber)) break;
+ }
+
+ /* see if we've timed out */
+ if (endTime < time(0)) return -1;
+ }
+ code -= sizeof(struct rx_header);
+ if (code > aresultLen) code = aresultLen;
+ bcopy(tp, aresult, code);
+ return code;
+}
+
+static int
+MapOldConn (char version, struct rx_debugConn *tconn)
+{
+ int i;
+ struct rx_debugConn_vL *vL = (struct rx_debugConn_vL *)tconn;
+#define MOVEvL(a) (tconn->a = vL->a)
+
+ if ((version <= RX_DEBUGI_VERSION_W_UNALIGNED_CONN) ||
+ (version > RX_DEBUGI_VERSION)) {
+ /* any old or unrecognized version... */
+ for (i=0;i<RX_MAXCALLS;i++) {
+ MOVEvL(callState[i]);
+ MOVEvL(callMode[i]);
+ MOVEvL(callFlags[i]);
+ MOVEvL(callOther[i]);
+ }
+ if (version == RX_DEBUGI_VERSION_W_SECSTATS) {
+ MOVEvL(secStats.type);
+ MOVEvL(secStats.level);
+ MOVEvL(secStats.flags);
+ MOVEvL(secStats.expires);
+ MOVEvL(secStats.packetsReceived);
+ MOVEvL(secStats.packetsSent);
+ MOVEvL(secStats.bytesReceived);
+ MOVEvL(secStats.bytesSent);
+ }
+ }
+ return 0;
+}
+
+static int
+MainCommand (struct cmd_syndesc *as, void *arock)
+{
+ register int i;
+ int s;
+ int j;
+ struct sockaddr_in taddr;
+ long host;
+ struct in_addr hostAddr;
+ short port;
+ struct hostent *th;
+ struct rx_debugIn tin;
+ int code;
+ int nodally;
+ int allconns;
+ int rxstats;
+ int onlyClient, onlyServer;
+ long onlyHost;
+ short onlyPort;
+ int onlyAuth;
+ int flag;
+ int dallyCounter;
+ int withSecStats;
+ int withAllConn;
+ int withRxStats;
+ int withWaiters;
+ struct rx_debugStats tstats;
+ char *portName, *hostName;
+ struct rx_debugConn tconn;
+ short noConns;
+
+ int version_flag;
+ char version[64];
+ char nada[64];
+ long length=64;
+
+ nodally = (as->parms[2].items ? 1 : 0);
+ allconns = (as->parms[3].items ? 1 : 0);
+ rxstats = (as->parms[4].items ? 1 : 0);
+ onlyServer = (as->parms[5].items ? 1 : 0);
+ onlyClient = (as->parms[6].items ? 1 : 0);
+ version_flag=(as->parms[10].items ? 1 : 0);
+ noConns = (as->parms[11].items ? 1 : 0);
+
+ if (as->parms[0].items)
+ hostName = as->parms[0].items->data;
+ else
+ hostName = (char *) 0;
+
+ if (as->parms[1].items)
+ portName = as->parms[1].items->data;
+ else
+ portName = (char *) 0;
+
+ if (as->parms[7].items) {
+ char *name = as->parms[7].items->data;
+ if ((onlyPort = PortNumber(name)) == -1)
+ onlyPort = PortName(name);
+ if (onlyPort == -1) {
+ printf("rxdebug: can't resolve port name %s\n", name);
+ exit(1);
+ }
+ } else onlyPort = -1;
+
+ if (as->parms[8].items) {
+ char *name = as->parms[8].items->data;
+ struct hostent *th;
+ th = gethostbyname(name);
+ if (!th) {
+ printf("rxdebug: host %s not found in host table\n", name);
+ exit(1);
+ }
+ bcopy(th->h_addr, &onlyHost, sizeof(long));
+ } else onlyHost = -1;
+
+ if (as->parms[9].items) {
+ char *name = as->parms[9].items->data;
+ if (strcmp (name, "clear") == 0) onlyAuth = 0;
+ else if (strcmp (name, "auth") == 0) onlyAuth = 1;
+ else if (strcmp (name, "crypt") == 0) onlyAuth = 2;
+ else if ((strcmp (name, "null") == 0) ||
+ (strcmp (name, "none") == 0) ||
+ (strncmp (name, "noauth", 6) == 0) ||
+ (strncmp (name, "unauth", 6) == 0)) onlyAuth = -1;
+ else {
+ fprintf (stderr, "Unknown authentication level: %s\n", name);
+ exit (1);
+ }
+ } else onlyAuth = 999;
+
+ /* lookup host */
+ if (hostName) {
+ th = gethostbyname(hostName);
+ if (!th) {
+ printf("rxdebug: host %s not found in host table\n", hostName);
+ exit(1);
+ }
+ bcopy(th->h_addr, &host, sizeof(long));
+ }
+ else host = htonl(0x7f000001); /* IP localhost */
+
+ if (!portName)
+ port = htons(7000); /* default is fileserver */
+ else {
+ if ((port = PortNumber(portName)) == -1)
+ port = PortName(portName);
+ if (port == -1) {
+ printf("rxdebug: can't resolve port name %s\n", portName);
+ exit(1);
+ }
+ }
+
+ dallyCounter = 0;
+
+ hostAddr.s_addr = host;
+ printf("Trying %s (port %d):\n", inet_ntoa(hostAddr), ntohs(port));
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ taddr.sin_family = AF_INET;
+ taddr.sin_port = 0;
+ taddr.sin_addr.s_addr = 0;
+ code = bind(s, (struct sockaddr *)&taddr, sizeof(struct sockaddr_in));
+ if (code) {
+ perror("bind");
+ exit(1);
+ }
+
+ if(version_flag)
+ {
+ nada[0] = '\0';
+
+ code = GetVersion(s, host, port, nada, length,
+ version, length);
+ if (code < 0)
+ {
+ printf("get version call failed with code %d, errno %d\n",
+ code,errno);
+ exit(1);
+ }
+ printf("AFS version: %s\n",version);fflush(stdout);
+
+ exit(0);
+
+ }
+
+
+ tin.type = htonl(RX_DEBUGI_GETSTATS);
+ tin.index = 0;
+ code = MakeCall(s, host, port, (char *) &tin, sizeof(tin),
+ (char *) &tstats, sizeof(tstats));
+ if (code < 0) {
+ printf("getstats call failed with code %d\n", code);
+ exit(1);
+ }
+
+ if ((tstats.version < RX_DEBUGI_VERSION_MINIMUM) ||
+ (tstats.version > RX_DEBUGI_VERSION))
+ tstats.version = RX_DEBUGI_VERSION_MINIMUM-1;
+ withSecStats = (tstats.version >= RX_DEBUGI_VERSION_W_SECSTATS);
+ withAllConn = (tstats.version >= RX_DEBUGI_VERSION_W_GETALLCONN);
+ withRxStats = (tstats.version >= RX_DEBUGI_VERSION_W_RXSTATS);
+ withWaiters = (tstats.version >= RX_DEBUGI_VERSION_W_WAITERS);
+
+ printf("Free packets: %ld, packet reclaims: %ld, calls: %ld, "
+ "used FDs: %d\n",
+ (long)ntohl(tstats.nFreePackets),
+ (long)ntohl(tstats.packetReclaims),
+ (long)ntohl(tstats.callsExecuted),
+ tstats.usedFDs);
+ if (!tstats.waitingForPackets) printf("not ");
+ printf("waiting for packets.\n");
+ if (withWaiters)
+ printf("%ld calls waiting for a thread\n",
+ (long)ntohl(tstats.nWaiting));
+
+ if (rxstats) {
+ if (!withRxStats) {
+ noRxStats:
+ withRxStats = 0;
+ fprintf (stderr, "WARNING: Server doens't support "
+ "retrieval of Rx statistics\n");
+ } else {
+ struct rx_stats rxstats;
+ int i;
+ long *lp;
+
+ bzero (&rxstats, sizeof(rxstats));
+ tin.type = htonl(RX_DEBUGI_RXSTATS);
+ tin.index = 0;
+ /* should gracefully handle the case where rx_stats grows */
+ code = MakeCall(s, host, port, (char *) &tin, sizeof(tin),
+ (char *) &rxstats, sizeof(rxstats));
+ if (code < 0) {
+ printf("rxstats call failed with code %d\n", code);
+ exit(1);
+ }
+ if (code != sizeof(rxstats)) {
+ if ((code == sizeof(tin)) &&
+ (ntohl(((struct rx_debugIn *)(&rxstats))->type) ==
+ RX_DEBUGI_BADTYPE)) goto noRxStats;
+ fprintf (stderr, "WARNING: returned Rx statistics of "
+ "unexpected size (got %d)\n",
+ code);
+ /* handle other versions?... */
+ }
+
+ /* Since its all longs convert to host order with a loop. */
+ lp = (long *)&rxstats;
+ for (i=0; i<sizeof(rxstats)/sizeof(int); i++,lp++)
+ *lp = ntohl(*lp);
+
+ rx_PrintTheseStats (stdout, &rxstats, sizeof(rxstats));
+ }
+ }
+
+ if (noConns)
+ return 0;
+
+ tin.type = htonl(RX_DEBUGI_GETCONN);
+ if (allconns) {
+ if (!withAllConn)
+ fprintf (stderr, "WARNING: Server doesn't support retrieval of "
+ "all connections,\n"
+ "getting only interesting instead.\n");
+ else tin.type = htonl(RX_DEBUGI_GETALLCONN);
+ }
+
+ if (onlyServer) printf ("Showing only server connections\n");
+ if (onlyClient) printf ("Showing only client connections\n");
+ if (onlyAuth != 999) {
+ static char *name[] =
+ {"unauthenticated", "rxkad_clear", "rxkad_auth", "rxkad_crypt"};
+ printf ("Showing only %s connections\n", name[onlyAuth+1]);
+ }
+ if (onlyHost != -1) {
+ hostAddr.s_addr = onlyHost;
+ printf ("Showing only connections from host %s\n",
+ inet_ntoa(hostAddr));
+ }
+ if (onlyPort != -1)
+ printf ("Showing only connections on port %u\n", ntohs(onlyPort));
+
+ for(i=0;;i++) {
+ tin.index = htonl(i);
+ bzero (&tconn, sizeof(tconn));
+ code = MakeCall(s, host, port, (char *)&tin, sizeof(tin),
+ (char *) &tconn, sizeof(tconn));
+ if (code < 0) {
+ printf("getconn call failed with code %d\n", code);
+ break;
+ }
+ MapOldConn (tstats.version, &tconn);
+ if (tconn.cid == htonl(0xffffffff)) {
+ printf("Done.\n");
+ break;
+ }
+
+ /* see if we're in nodally mode and all calls are dallying */
+ if (nodally) {
+ flag = 0;
+ for(j=0;j<RX_MAXCALLS;j++) {
+ if (tconn.callState[j] != RX_STATE_NOTINIT &&
+ tconn.callState[j] != RX_STATE_DALLY) {
+ flag = 1;
+ break;
+ }
+ }
+ if (flag == 0) {
+ /*
+ * this call looks too ordinary, bump skipped count and go
+ * around again
+ */
+ dallyCounter++;
+ continue;
+ }
+ }
+ if ((onlyHost != -1) && (onlyHost != tconn.host)) continue;
+ if ((onlyPort != -1) && (onlyPort != tconn.port)) continue;
+ if (onlyServer && (tconn.type != RX_SERVER_CONNECTION)) continue;
+ if (onlyClient && (tconn.type != RX_CLIENT_CONNECTION)) continue;
+ if (onlyAuth != 999) {
+ if (onlyAuth == -1) {
+ if (tconn.securityIndex != 0) continue;
+ } else {
+ if (tconn.securityIndex != 2) continue;
+ if (withSecStats && (tconn.secStats.type == 3) &&
+ (tconn.secStats.level != onlyAuth)) continue;
+ }
+ }
+
+ /* now display the connection */
+ hostAddr.s_addr = tconn.host;
+ printf("Connection from host %s, port %d, ",
+ inet_ntoa(hostAddr), ntohs(tconn.port));
+ if (tconn.epoch)
+ printf ("Cuid %lx/%lx", (unsigned long)ntohl(tconn.epoch),
+ (unsigned long)ntohl(tconn.cid));
+ else
+ printf ("cid %lx", (unsigned long)ntohl(tconn.cid));
+ if (tconn.error)
+ printf (", error %ld", (long)ntohl(tconn.error));
+ printf("\n serial %ld, ", (long)ntohl(tconn.serial));
+ printf(" maxPacketSize %ld, ", (long)ntohl(tconn.maxPacketSize));
+
+ if (tconn.flags) {
+ printf ("flags");
+ if (tconn.flags & RX_CONN_MAKECALL_WAITING)
+ printf(" MAKECALL_WAITING");
+ if (tconn.flags & RX_CONN_DESTROY_ME) printf(" DESTROYED");
+ if (tconn.flags & RX_CONN_USING_PACKET_CKSUM) printf(" pktCksum");
+ printf (", ");
+ }
+ printf("security index %d, ", tconn.securityIndex);
+ if (tconn.type == RX_CLIENT_CONNECTION) printf("client conn\n");
+ else printf("server conn\n");
+
+ if (withSecStats) {
+ switch ((int)tconn.secStats.type) {
+ case 0:
+ if (tconn.securityIndex == 2)
+ printf (" no GetStats procedure for security object\n");
+ break;
+ case 1:
+ printf (" rxnull level=%d, flags=%ld\n",
+ tconn.secStats.level, tconn.secStats.flags);
+ break;
+ case 2:
+ printf (" rxvab level=%d, flags=%ld\n",
+ tconn.secStats.level, tconn.secStats.flags);
+ break;
+ case 3: {
+ char *level;
+ char flags = ntohl(tconn.secStats.flags);
+ if (tconn.secStats.level == 0) level = "clear";
+ else if (tconn.secStats.level == 1) level = "auth";
+ else if (tconn.secStats.level == 2) level = "crypt";
+ else level = "unknown";
+ printf (" rxkad: level %s", level);
+ if (flags) printf (", flags");
+ if (flags & 1) printf (" unalloc");
+ if (flags & 2) printf (" authenticated");
+ if (flags & 4) printf (" expired");
+ if (flags & 8) printf (" pktCksum");
+ if (tconn.secStats.expires)
+ /* Apparently due to a bug in the RT compiler that
+ * prevents (u_long)0xffffffff => (double) from working,
+ * this code produces negative lifetimes when run on the
+ * RT. */
+ printf (", expires in %.1f hours",
+ ((u_long)ntohl(tconn.secStats.expires) -
+ time(0)) / 3600.0);
+ if (!(flags & 1)) {
+ printf ("\n Received %ld bytes in %ld packets\n",
+ (long)ntohl(tconn.secStats.bytesReceived),
+ (long)ntohl(tconn.secStats.packetsReceived));
+ printf (" Sent %ld bytes in %ld packets\n",
+ (long)ntohl(tconn.secStats.bytesSent),
+ (long)ntohl(tconn.secStats.packetsSent));
+ } else
+ printf ("\n");
+ break;
+ }
+
+ default: printf(" unknown\n");
+ }
+ }
+
+ for(j=0;j<RX_MAXCALLS;j++) {
+ printf(" call %d: # %ld, state ", j,
+ (long)ntohl(tconn.callNumber[j]));
+ if (tconn.callState[j]==RX_STATE_NOTINIT) {
+ printf("not initialized\n");
+ continue;
+ }
+ else if (tconn.callState[j]==RX_STATE_PRECALL)
+ printf("precall, ");
+ else if (tconn.callState[j] == RX_STATE_ACTIVE)
+ printf("active, ");
+ else if (tconn.callState[j] == RX_STATE_DALLY)
+ printf("dally, ");
+ printf("mode: ");
+ if (tconn.callMode[j]==RX_MODE_SENDING)
+ printf("sending");
+ else if (tconn.callMode[j]==RX_MODE_RECEIVING)
+ printf("receiving");
+ else if (tconn.callMode[j]==RX_MODE_ERROR)
+ printf("error");
+ else if (tconn.callMode[j] == RX_MODE_EOF)
+ printf("eof");
+ else printf("unknown");
+ if (tconn.callFlags[j]) {
+ printf(", flags:");
+ if (tconn.callFlags[j]&RX_CALL_READER_WAIT)
+ printf(" reader_wait");
+ if (tconn.callFlags[j]&RX_CALL_WAIT_WINDOW_ALLOC)
+ printf(" window_alloc");
+ if (tconn.callFlags[j]&RX_CALL_WAIT_WINDOW_SEND)
+ printf(" window_send");
+ if (tconn.callFlags[j]&RX_CALL_WAIT_PACKETS)
+ printf(" wait_packets");
+ if (tconn.callFlags[j]&RX_CALL_WAIT_PROC)
+ printf(" waiting_for_process");
+ if (tconn.callFlags[j]&RX_CALL_RECEIVE_DONE)
+ printf(" receive_done");
+ if (tconn.callFlags[j]&RX_CALL_CLEARED)
+ printf(" call_cleared");
+ }
+ if (tconn.callOther[j] & RX_OTHER_IN)
+ printf(", has_input_packets");
+ if (tconn.callOther[j] & RX_OTHER_OUT)
+ printf(", has_output_packets");
+ printf("\n");
+ }
+ }
+ if (nodally) printf("Skipped %d dallying connections.\n", dallyCounter);
+ return 0;
+}
+
+/* simple main program */
+
+int
+main(int argc, char **argv)
+{
+ struct cmd_syndesc *ts;
+
+ ts = cmd_CreateSyntax((char *) 0, MainCommand, 0, "probe RX server");
+ cmd_AddParm(ts, "-servers", CMD_SINGLE, CMD_REQUIRED, "server machine");
+ cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
+ cmd_AddParm(ts, "-nodally", CMD_FLAG, CMD_OPTIONAL,
+ "don't show dallying conns");
+ cmd_AddParm(ts, "-allconnections", CMD_FLAG, CMD_OPTIONAL,
+ "don't filter out uninteresting connections on server");
+ cmd_AddParm(ts, "-rxstats", CMD_FLAG, CMD_OPTIONAL, "show Rx statistics");
+ cmd_AddParm(ts, "-onlyserver", CMD_FLAG, CMD_OPTIONAL,
+ "only show server conns");
+ cmd_AddParm(ts, "-onlyclient", CMD_FLAG, CMD_OPTIONAL,
+ "only show client conns");
+ cmd_AddParm(ts, "-onlyport", CMD_SINGLE, CMD_OPTIONAL, "show only <port>");
+ cmd_AddParm(ts, "-onlyhost", CMD_SINGLE, CMD_OPTIONAL, "show only <host>");
+ cmd_AddParm(ts, "-onlyauth", CMD_SINGLE, CMD_OPTIONAL,
+ "show only <auth level>");
+
+ cmd_AddParm(ts,"-version",CMD_FLAG,CMD_OPTIONAL,"show AFS version id");
+ cmd_AddParm(ts,"-noconns",CMD_FLAG,CMD_OPTIONAL,"show no connections");
+
+ cmd_Dispatch(argc, argv);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/rx/rxperf.c b/usr.sbin/afs/src/rx/rxperf.c
new file mode 100644
index 00000000000..1a535662a8a
--- /dev/null
+++ b/usr.sbin/afs/src/rx/rxperf.c
@@ -0,0 +1,400 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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
+
+RCSID("$Id: rxperf.c,v 1.1 2000/09/11 14:41:23 art Exp $");
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <strings.h>
+#include <assert.h>
+#include <unistd.h>
+#include <cmd.h>
+
+#include <roken.h>
+#include <err.h>
+
+#include "rx.h"
+#include "rx_null.h"
+
+#define DEFAULT_PORT 4711
+#define DEFAULT_HOST "127.0.0.1"
+#define DEFAULT_BYTES 1000000
+#define RXPERF_BUFSIZE 1400
+
+enum { RX_PERF_VERSION = 0 };
+enum { RX_SERVER_ID = 147 };
+enum { RX_PERF_SEND = 0, RX_PERF_RECV = 1 };
+
+
+/*
+ *
+ */
+
+static void
+sigusr1 (int foo)
+{
+ exit (2); /* XXX profiler */
+}
+
+/*
+ *
+ */
+
+static struct timeval timer_start;
+static struct timeval timer_stop;
+static int timer_check = 0;
+
+static void
+start_timer (void)
+{
+ timer_check++;
+ gettimeofday (&timer_start, NULL);
+}
+
+/*
+ *
+ */
+
+static void
+end_and_print_timer (char *str)
+{
+ long long start_l, stop_l;
+
+ timer_check--;
+ assert (timer_check == 0);
+ gettimeofday(&timer_stop, NULL);
+ start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
+ stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
+ printf("%s:\t%8llu msec\n", str, (stop_l-start_l)/1000);
+}
+
+/*
+ *
+ */
+
+static u_long
+str2addr (const char *s)
+{
+ struct in_addr server;
+ struct hostent *h;
+
+ if (inet_aton (s, &server) == 1)
+ return server.s_addr;
+ h = gethostbyname (s);
+ if (h != NULL) {
+ memcpy (&server, h->h_addr_list[0], sizeof(server));
+ return server.s_addr;
+ }
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+static void
+get_sec(int serverp, struct rx_securityClass** sec, int *secureindex)
+{
+ if (serverp) {
+ *sec = rxnull_NewServerSecurityObject();
+ *secureindex = 1;
+ } else {
+ *sec = rxnull_NewClientSecurityObject();
+ *secureindex = 0;
+ }
+}
+
+/*
+ * process the "RPC" and return the results
+ */
+
+static int32_t
+rxperf_ExecuteRequest(struct rx_call *call)
+{
+ int32_t version;
+ int32_t command;
+ u_int32_t bytes;
+ char buf[RXPERF_BUFSIZE];
+ int size;
+
+ if (rx_Read (call, &version, 4) != 4) {
+ warn ("rx_Read failed to read version");
+ return -1;
+ }
+
+ if (htonl(RX_PERF_VERSION) != version) {
+ warnx ("client has wrong version");
+ return -1;
+ }
+
+ if (rx_Read (call, &command, 4) != 4) {
+ warnx ("rx_Read failed to read command");
+ return -1;
+ }
+ command = ntohl(command);
+
+ if (rx_Read (call, &bytes, 4) != 4) {
+ warnx ("rx_Read failed to read bytes");
+ return -1;
+ }
+ bytes = ntohl(bytes);
+
+ memset (buf, 0, sizeof(buf));
+
+ switch (command) {
+ case RX_PERF_SEND:
+ while (bytes > 0) {
+ size = sizeof(buf);
+ if (size > bytes)
+ size = bytes;
+ if (rx_Read (call, buf, size) != size)
+ errx (1, "rx_Read failed to read data");
+ bytes -= size;
+ }
+ {
+ int32_t data = htonl(4711); /* XXX */
+ if (rx_Write (call, &data, 4) != 4)
+ errx (1, "rx_Write failed when sending back result");
+ }
+ break;
+ case RX_PERF_RECV:
+ default:
+ warnx ("client sent a unsupported command: %d", command);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ *
+ */
+
+static void
+do_server (int port)
+{
+ struct rx_service *service;
+ struct rx_securityClass *secureobj;
+ int secureindex;
+ int ret;
+
+ ret = rx_Init (port);
+ if (ret)
+ errx (1, "rx_Init failed");
+
+ get_sec(1, &secureobj, &secureindex);
+
+ service = rx_NewService (0,
+ RX_SERVER_ID,
+ "rxperf",
+ &secureobj,
+ secureindex,
+ rxperf_ExecuteRequest);
+ if (service == NULL)
+ errx(1, "Cant create server");
+
+ rx_StartServer(1) ;
+ abort();
+}
+
+/*
+ *
+ */
+
+static void
+do_client (const char *server, int port, int32_t bytes)
+{
+ struct rx_connection *conn;
+ struct rx_call *call;
+ u_int32_t addr = str2addr(server);
+ struct rx_securityClass *secureobj;
+ int secureindex;
+ char buf[RXPERF_BUFSIZE];
+ int32_t data;
+ int size;
+ int ret;
+ char *stamp;
+
+ memset (buf, 0, sizeof(buf));
+
+ ret = rx_Init (0);
+ if (ret)
+ errx (1, "rx_Init failed");
+
+ get_sec(0, &secureobj, &secureindex);
+
+ conn = rx_NewConnection(addr,
+ port,
+ RX_SERVER_ID,
+ secureobj,
+ secureindex);
+ if (conn == NULL)
+ errx (1, "failed to contact %s", server);
+
+ call = rx_NewCall (conn);
+ if (call == NULL)
+ errx (1, "rx_NewCall failed");
+
+ data = htonl(RX_PERF_VERSION);
+ if (rx_Write (call, &data, 4) != 4)
+ errx (1, "rx_Write failed to send version");
+
+ data = htonl(RX_PERF_SEND);
+ if (rx_Write (call, &data, 4) != 4)
+ errx (1, "rx_Write failed to send command");
+
+ asprintf (&stamp, "send %d bytes", bytes);
+ start_timer();
+
+ data = htonl (bytes);
+ if (rx_Write (call, &data, 4) != 4)
+ errx (1, "rx_Write failed to send size");
+
+ while (bytes > 0) {
+ size = sizeof (buf);
+ if (size > bytes)
+ size = bytes;
+ if (rx_Write (call, buf, size) != size)
+ errx (1, "failed when %d bytes was left to send", bytes);
+ bytes -= size;
+ }
+ if (rx_Read (call, &bytes, 4) != 4)
+ errx (1, "failed to read result from server");
+ end_and_print_timer (stamp);
+ rx_EndCall (call, 0);
+}
+
+/*
+ * do argument processing and call networking functions
+ */
+
+static int
+rxperf_server (struct cmd_syndesc *as, void *arock)
+{
+ int port = DEFAULT_PORT;
+ char *portname;
+ char *ptr;
+
+ if (as->parms[0].items) {
+ portname = as->parms[1].items->data;
+ port = strtol (portname, &ptr, 0);
+ if (ptr && ptr != '\0')
+ errx (1, "can't resolve portname");
+ }
+
+ do_server (htons(port));
+
+ return 0;
+}
+
+/*
+ * do argument processing and call networking functions
+ */
+
+static int
+rxperf_client (struct cmd_syndesc *as, void *arock)
+{
+ char *host = DEFAULT_HOST;
+ int bytes = DEFAULT_BYTES;
+ int port = DEFAULT_PORT;
+ char *numbytes = NULL;
+ char *portname;
+ char *ptr;
+
+ if (as->parms[0].items)
+ host = as->parms[0].items->data;
+
+ if (as->parms[1].items) {
+ portname = as->parms[1].items->data;
+ port = strtol (portname, &ptr, 0);
+ if (ptr && ptr != '\0')
+ errx (1, "can't resolve portname");
+ }
+
+ if (as->parms[2].items) {
+ numbytes = as->parms[2].items->data;
+ bytes = strtol (numbytes, &ptr, 0);
+ if (ptr && *ptr != '\0')
+ errx (1, "can't resolve number of bytes to transfer");
+ }
+
+ do_client (host, htons(port), bytes);
+
+ return 0;
+}
+
+/*
+ * setup world and call cmd
+ */
+
+int
+main(int argc, char **argv)
+{
+ struct cmd_syndesc *ts;
+ PROCESS pid;
+
+ set_progname (argv[0]);
+
+ signal (SIGUSR1, sigusr1);
+
+ ts = cmd_CreateSyntax("server", rxperf_server, NULL, "server");
+ cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "udp port");
+
+ ts = cmd_CreateSyntax("client", rxperf_client, NULL, "client");
+ cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "server machine");
+ cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "udp port");
+ cmd_AddParm(ts, "-bytes", CMD_SINGLE, CMD_OPTIONAL, "number of bytes to transfer");
+
+ LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid);
+
+ cmd_Dispatch(argc, argv);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/rx/test_rx_clock.c b/usr.sbin/afs/src/rx/test_rx_clock.c
new file mode 100644
index 00000000000..c7f2b88e135
--- /dev/null
+++ b/usr.sbin/afs/src/rx/test_rx_clock.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1998 - 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <config.h>
+
+#include "rx_clock.h"
+
+RCSID("$Id: test_rx_clock.c,v 1.1 2000/09/11 14:41:23 art Exp $");
+
+int
+main(int argc, char **argv)
+{
+ struct clock clock_old = {0, 0};
+
+ clock_Init ();
+ for (;;) {
+ struct clock now;
+
+ clock_NewTime ();
+ clock_GetTime (&now);
+ if (now.sec < clock_old.sec ||
+ (now.sec == clock_old.sec && now.usec < clock_old.usec))
+ abort ();
+ printf ("%6ld.%6ld\r", now.sec, now.usec);
+ }
+ return 0;
+}
diff --git a/usr.sbin/afs/src/rxdef/Makefile.in b/usr.sbin/afs/src/rxdef/Makefile.in
new file mode 100644
index 00000000000..e018fc84d54
--- /dev/null
+++ b/usr.sbin/afs/src/rxdef/Makefile.in
@@ -0,0 +1,196 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:23 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+RM = rm
+YDR = ../ydr/ydr
+YDRFLAGS = -I$(srcdir)
+ETAGS = etags
+MAKEDEPEND = makedepend
+DEFINES =
+INCLUDES = -I../include \
+ -I$(srcdir)/../include \
+ -I$(srcdir)/..
+REALCFLAGS = $(INCLUDES) @KRB4_INC_FLAGS@ $(DEFINES) $(CFLAGS)
+XGFILES = $(srcdir)/vldb.xg \
+ $(srcdir)/fs.xg \
+ $(srcdir)/cb.xg \
+ $(srcdir)/pts.xg \
+ $(srcdir)/bos.xg \
+ $(srcdir)/volumeserver.xg
+HDRS = vldb.h cb.h fs.h pts.h # volumeserver.h bos.h ubik.h
+MOREHDRS = vldb.cs.h vldb.ss.h cb.cs.h cb.ss.h fs.cs.h fs.ss.h \
+ pts.cs.h pts.ss.h ubik.cs.h ubik.ss.h \
+ bos.cs.h pts.ss.h
+CFILES = vldb.ss.c vldb.cs.c vldb.ydr.c \
+ fs.ss.c fs.cs.c fs.ydr.c \
+ cb.ss.c cb.cs.c cb.ydr.c \
+ pts.ss.c pts.cs.c pts.ydr.c \
+ bos.ss.c bos.cs.c bos.ydr.c \
+ volumeserver.ss.c volumeserver.cs.c volumeserver.ydr.c \
+ ubik.ss.c ubik.cs.c ubik.ydr.c \
+ ka.ss.c ka.cs.c ka.ydr.c
+OBJS = $(CFILES:.c=.o)
+SRCS = $(CFILES) $(HDRS)
+
+FSSERVERLIB = librxfsserver.a
+VLSERVERLIB = librxvlserver.a
+VOLSERVERLIB = librxvolserver.a
+PTSERVERLIB = libptserver.a
+PTCLIENTLIB = libptclient.a
+BOSSERVERLIB = libbosserver.a
+BOSCLIENTLIB = libbosclient.a
+KACLIENTLIB = libkaclient.a
+KASERVERLIB = libkaserver.a
+CLIENTLIB = librxdefclient.a
+
+#vldb.ydr.o fs.ydr.o cb.ydr.o volumeserver.ydr.o
+CLIENTOBJS = vldb.cs.o fs.cs.o cb.ss.o volumeserver.cs.o \
+ pts.cs.o ubik.cs.o bos.cs.o
+FSSERVEROBJS = fs.ss.o cb.cs.o
+VLSERVEROBJS = vldb.ss.o vldb.ydr.o ubik.ss.o
+VOLSERVEROBJS = volumeserver.ss.o volumeserver.ydr.o
+PTSERVEROBJS = pts.ydr.o pts.ss.o
+PTCLIENTOBJS = pts.ydr.o pts.cs.o
+BOSSERVEROBJS = bos.ydr.o bos.ss.o
+BOSCLIENTOBJS = bos.ydr.o bos.cs.o
+KACLIENTOBJS = ka.ydr.o ka.cs.o
+KASERVEROBJS = ka.ydr.o ka.ss.o
+RESTSERVEROBJS = pts.ss.o ubik.ss.o
+
+LIBS = $(CLIENTLIB) $(FSSERVERLIB) $(VLSERVERLIB) $(VOLSERVERLIB) $(PTSERVERLIB) $(PTCLIENTLIB) $(BOSSERVERLIB) $(BOSCLIENTLIB) $(KACLIENTLIB) $(KASERVERLIB)
+
+.PHONY: all install depend tags clean
+
+all: $(LIBS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ for LIB in $(LIBS) ; do $(INSTALL_DATA) $$LIB $(DESTDIR)$(libdir)/$$LIB ; done
+ $(MKINSTALLDIRS) $(DESTDIR)$(includedir)
+ for INC in $(HDRS) $(MOREHDRS) ; do $(INSTALL_DATA) $$INC $(DESTDIR)$(includedir)/$$INC ; done
+
+
+uninstall:
+ for LIB in $(LIBS); do rm -f $(DESTDIR)$(libdir)/$$LIB ; done
+ for INC in $(HDRS) $(MOREHDRS); do rm -f $(DESTDIR)$(includedir)/$$INC ; done
+
+ydr: $(XGFILES)
+ ../ydr/ydr $<
+
+# $(SERVEROBJS) $(CLIENTOBJS): $(XGFILES) $(CFILES) $(HDRS)
+
+
+$(CLIENTLIB): $(CLIENTOBJS)
+ $(AR) cr $@ $(CLIENTOBJS)
+ $(RANLIB) $@
+
+$(FSSERVERLIB): $(FSSERVEROBJS)
+ $(AR) cr $@ $(FSSERVEROBJS)
+ $(RANLIB) $@
+
+$(VLSERVERLIB): $(VLSERVEROBJS)
+ $(AR) cr $@ $(VLSERVEROBJS)
+ $(RANLIB) $@
+
+$(VOLSERVERLIB): $(VOLSERVEROBJS)
+ $(AR) cr $@ $(VOLSERVEROBJS)
+ $(RANLIB) $@
+
+$(PTSERVERLIB): $(PTSERVEROBJS)
+ $(AR) cr $@ $(PTSERVEROBJS)
+ $(RANLIB) $@
+
+$(PTCLIENTLIB): $(PTCLIENTOBJS)
+ $(AR) cr $@ $(PTCLIENTOBJS)
+ $(RANLIB) $@
+
+$(BOSSERVERLIB): $(BOSSERVEROBJS)
+ $(AR) cr $@ $(BOSSERVEROBJS)
+ $(RANLIB) $@
+
+$(BOSCLIENTLIB): $(BOSCLIENTOBJS)
+ $(AR) cr $@ $(BOSCLIENTOBJS)
+ $(RANLIB) $@
+
+$(KACLIENTLIB): $(KACLIENTOBJS)
+ $(AR) cr $@ $(KACLIENTOBJS)
+ $(RANLIB) $@
+
+$(KASERVERLIB): $(KASERVEROBJS)
+ $(AR) cr $@ $(KASERVEROBJS)
+ $(RANLIB) $@
+
+#%.cs.c %.cs.h %.ss.c %.ss.h %.ydr.c %.h: %.xg
+# $(YDR) $(YDRFLAGS) $(srcdir)/$(<F)
+
+vldb.cs.c vldb.cs.h vldb.ss.c vldb.ss.h vldb.ydr.c vldb.h: vldb.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/vldb.xg
+
+fs.cs.c fs.cs.h fs.ss.c fs.ss.h fs.ydr.c fs.h: fs.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/fs.xg
+
+cb.cs.c cb.cs.h cb.ss.c cb.ss.h cb.ydr.c cb.h: cb.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/cb.xg
+
+pts.cs.c pts.cs.h pts.ss.c pts.ss.h pts.ydr.c pts.h: pts.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/pts.xg
+
+bos.cs.c bos.cs.h bos.ss.c bos.ss.h bos.ydr.c bos.h: bos.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/bos.xg
+
+ka.cs.c ka.cs.h ka.ss.c ka.ss.h ka.ydr.c ka.h: ka.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/ka.xg
+
+volumeserver.cs.c volumeserver.cs.h volumeserver.ss.c volumeserver.ss.h volumeserver.ydr.c volumeserver.h: volumeserver.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/volumeserver.xg
+
+ubik.cs.c ubik.cs.h ubik.ss.c ubik.ss.h ubik.ydr.c ubik.h: ubik.xg
+ $(YDR) $(YDRFLAGS) $(srcdir)/ubik.xg
+
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=rxdef/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(CFILES)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(OBJS) $(LIBS) ydr_tmp*.c *.cs.c *.cs.h *.ss.c *.ss.h *.ydr.c *.td.c *~ *.o core *.core vldb.h cb.h fs.h pts.h bos.h ka.h volumeserver.h ubik.h
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/rxdef/bos.xg b/usr.sbin/afs/src/rxdef/bos.xg
new file mode 100644
index 00000000000..6a979917e8d
--- /dev/null
+++ b/usr.sbin/afs/src/rxdef/bos.xg
@@ -0,0 +1,248 @@
+/* This is -*-c-*- */
+/* $Id: bos.xg,v 1.1 2000/09/11 14:41:24 art Exp $ */
+
+/*
+ * Interface to BOS server
+ */
+
+package BOZO_
+
+%#include <config.h>
+%#include <roken.h>
+%#include <fs_errors.h>
+
+error-function conv_to_arla_errno
+
+const BZNOTACTIVE = 39424;
+const BZNOENT = 39425;
+const BZBUSY = 39426;
+const BZEXISTS = 39427;
+const BZNOCREATE = 39428;
+const BZDOM = 39429;
+const BZACCESS = 39430;
+const BZSYNTAX = 39431;
+const BZIO = 39432;
+const BZNET = 39433;
+const BZBADTYPE = 39434;
+
+const BOZO_BSSIZE = 256;
+
+/*
+ *
+ */
+
+const BSTAT_SHUTDOWN = 0;
+const BSTAT_NORMAL = 1;
+const BSTAT_SHUTTINGDOWN = 2;
+const BSTAT_STARTINGUP = 3;
+
+const BOZO_PRUNEOLD = 1;
+const BOZO_PRUNEBAK = 2;
+const BOZO_PRUNECORE = 3;
+
+const BPROC_STARTED = 1;
+const BPROC_EXITED = 2;
+
+const BOZO_HASCORE = 1;
+const BOZO_ERRORSTOP = 2;
+const BOZO_BADDIRACCESS = 3;
+
+const BNODE_NEEDTIMEOUT = 0x01;
+const BNODE_ACTIVE = 0x02;
+const BNODE_WAIT = 0x04;
+const BNODE_DELETE = 0x08;
+const BNODE_ERRORSTOP = 0x10;
+
+const KTIME_HOUR = 0x01;
+const KTIME_MIN = 0x02;
+const KTIME_SEC = 0x04; /* XXX check me */
+const KTIME_DAY = 0x08;
+const KTIME_TIME = 0x07;
+const KTIME_NEVER = 0x10;
+const KTIME_NOW = 0x20;
+
+#if 0
+const GETSTATUS_FSRUN = "file server running";
+const GETSTATUS_RSRUNVOLDOWN = "file server running; volser down";
+const GETSTATUS_SALVAGE = "salvaging file system";
+const GETSTATUS_FSSTART = "starting file server";
+const GETSTATUS_FSDOWN = "file server shutting down";
+const GETSTATUS_SALVAGERDOWN = "salvager shutting down";
+const GETSTATUS_FSSTOP = "salvager shut down";
+#endif
+
+struct bozo_status {
+ long goal;
+ long fileGoal;
+ long porcStartTime;
+ long procStarts;
+ long lastAnyExit;
+ long lastErrorExit;
+ long errorCode;
+ long errorSignal;
+ long flags;
+ long spare[8];
+};
+
+struct bozo_netKTime {
+ long mask;
+ short hour;
+ short min;
+ short sec;
+ short day;
+};
+
+struct bozo_key {
+ char data[8];
+};
+
+struct bozo_keyInfo {
+ long mod_sec;
+ long mod_usec;
+ unsigned long keyCheckSum;
+ long spare2;
+};
+
+struct bozo_keyInfoFOOO {
+ long goal;
+ long fileGoal;
+ long procStartTime;
+ long procStarts;
+ long lastAnyExit;
+ long lastErrorExit;
+ long errorCode;
+ long errorSignal;
+ long flags;
+ long spare[8];
+};
+
+#if 0
+struct bnode_ops {
+ struct bnode *(*create)();
+ long (*timeout)();
+ long (*getstat)();
+ long (*setstat)();
+ long (*delete)();
+ long (*procexit)();
+ long (*getstring)();
+ long (*getparm)();
+ long (*restartp)();
+ long (*hascore)();
+};
+#endif
+
+
+CreateBnode (IN string type,
+ IN string instance,
+ IN string p1,
+ IN string p2,
+ IN string p3,
+ IN string p4,
+ IN string p5,
+ IN string p6) = 80;
+
+DeleteBnode (IN string instance) = 81;
+
+SetStatus (IN string instance) = 82;
+
+GetStatus (IN string instance,
+ OUT long *inStat,
+ OUT string statdescr<BOZO_BSSIZE>) = 83;
+
+
+EnumerateInstance (IN long instance,
+ OUT string iname) = 84;
+
+GetInstanceInfo ( IN string instance,
+ OUT string type<>,
+ OUT struct bozo_status *status) = 85;
+
+GetInstanceParm (IN string instance<>,
+ IN long num,
+ OUT string parm<>) = 86;
+
+AddSUser (IN string name) = 87;
+
+DeleteSUser (IN string name) = 88;
+
+ListSUsers (IN long an,
+ OUT string name<>) = 89;
+
+ListKeys (IN long an,
+ OUT long *kvno,
+ OUT struct bozo_key *key,
+ OUT struct bozo_keyInfo *keinfo) = 90;
+
+AddKey (IN long an,
+ IN struct bozo_key *key) = 91;
+
+DeleteKey (IN long an) = 92;
+
+SetCellName (IN string name) = 93;
+
+GetCellName (OUT string name<>) = 94;
+
+GetCellHost (IN long awhich,
+ OUT string name<>) = 95;
+
+AddCellHost (IN string name) = 96;
+
+DeleteCellHost (IN string name) = 97;
+
+SetTStatus (IN string instance,
+ IN long status) = 98;
+
+ShutdownAll () = 99;
+
+RestartAll () = 100;
+
+StartupAll () = 101;
+
+SetNoAuthFlag (IN long flag) = 102;
+
+ReBozo () = 103;
+
+Restart (IN string instance) = 104;
+
+Install (IN string path,
+ IN long size,
+ IN long flags,
+ IN long date) = 105;
+
+/* EndBOZO_Install ? XXX */
+
+UnInstall (IN string path) = 106;
+
+GetDates (IN string path,
+ OUT long *newtime,
+ OUT long *baktime,
+ OUT long *oldtime) = 107;
+
+
+Exec (IN string cmd) = 108;
+
+Prune (IN long flags) = 109;
+
+SetRestartTime (IN long type,
+ IN struct bozo_netKTime *restartTime) = 110;
+
+
+
+GetRestartTime (IN long type,
+ OUT struct bozo_netKTime *restartTime) = 111;
+
+#if 0
+GetLog 112
+/* the documentation about this call(s?) is/are very confusing/confused */
+#endif
+
+WaitAll () = 113;
+
+GetInstanceStrings (IN string instance,
+ OUT string errorname<>,
+ OUT string spare1<>,
+ OUT string spare2<>,
+ OUT string spare3<>) = 114;
+
+
+/* XXX */
diff --git a/usr.sbin/afs/src/rxdef/ka.xg b/usr.sbin/afs/src/rxdef/ka.xg
new file mode 100644
index 00000000000..85f121b72ca
--- /dev/null
+++ b/usr.sbin/afs/src/rxdef/ka.xg
@@ -0,0 +1,177 @@
+/* This is -*-c-*- */
+
+/*
+ * Interface to KAS
+ */
+
+const AUTHENTICATE_OLD = 1;
+const CHANGEPASSWORD = 2;
+const GETTICKET_OLD = 3;
+const SETPASSWORD = 4;
+const SETFIELDS = 5;
+const CREATEUSER = 6;
+const DELETEUSER = 7;
+const GETENTRY = 8;
+const LISTENTRY = 9;
+const GETSTATS = 10;
+const DEBUG = 11;
+const GETPASSWORD = 12;
+const GETRANDOMKEY = 13;
+const AUTHENTICATE = 21;
+const GETTICKET = 23;
+
+const MAXKAKVNO = 127;
+
+/* Flags (note 0 is illegal) */
+
+const KAFNORMAL = 0x1;
+/* For the two following the KAFNORMAL MUST not be set */
+const KAFREE = 0x2; /* on freelist */
+const KAOLDKEYS = 0x10; /* used to store old keys */
+/* misc flags */
+const KASPECIAL = 0x100; /* special authserver principal */
+const KAFASSOCROOT = 0x200; /* root of associate tree */
+const KAFASSOC = 0x300; /* associate entry */
+
+/* The following flags are used on KAA_SetFields() */
+const KAFADMIN = 0x004; /* administrator */
+const KAFNOTGS = 0x008; /* can't get or use TGT */
+const KAFNOSEAL = 0x020; /* can't be used as server */
+const KAFNOCPW = 0x040; /* can't change password */
+const KAFNEWASSOC = 0x080; /* can create associates */
+
+/* MISC stuff */
+
+const KAMAJORVERSION = 5;
+const KAMINORVERSION = 1;
+const NEVERDATE = 037777777777;
+const KADEBUGKCINFOSIZE = 25;
+
+#define Date u_int32_t
+
+/* Errors */
+
+const KADATABASEINCONSISTENT = 180480;
+const KAEXIST = 180481;
+const KAIO = 180482;
+const KACREATEFAIL = 180483;
+const KANOENT = 180484;
+const KAEMPTY = 180485;
+const KABADNAME = 180486;
+const KABADINDEX = 180487;
+const KANOAUTH = 180488;
+const KAANSWERTOOLONG = 180489;
+const KABADREQUEST = 180490;
+const KAOLDINTERFACE = 180491;
+const KABADARGUMENT = 180492;
+const KABADCMD = 180493;
+const KANOKEYS = 180494;
+const KAREADPW = 180495;
+const KABADKEY = 180496;
+const KAUBIKINIT = 180497;
+const KAUBIKCALL = 180498;
+const KABADPROTOCOL = 180499;
+const KANOCELLS = 180500;
+const KANOCELL = 180501;
+const KATOOMANYUBIKS = 180502;
+const KATOOMANYKEYS = 180503;
+const KABADTICKET = 180504;
+const KAUNKNOWNKEY = 180505;
+const KAKEYCACHEINVALID = 180506;
+const KABADSERVER = 180507;
+const KABADUSER = 180508;
+const KABADCPW = 180509;
+const KABADCREATE = 180510;
+const KANOTICKET = 180511;
+const KAASSOCUSER = 180512;
+const KANOTSPECIAL = 180513;
+const KACLOCKSKEW = 180514;
+const KANORECURSE = 180515;
+const KARXFAIL = 180516;
+const KANULLPASSWORD = 180517;
+const KAINTERNALERROR = 180518;
+const KAPWEXPIRED = 180519;
+const KAREUSED = 180520;
+const KATOOSOON = 180521;
+const KALOCKED = 180522;
+
+
+
+struct ka_CBS {
+ char Seq<>;
+};
+
+struct ka_BBS {
+ int32_t MaxSeqLen;
+ char Seq<>;
+};
+
+struct EncryptionKey {
+ char key[8];
+};
+
+#define MAXKANAMELEN 64
+
+typedef string kaname<MAXKANAMELEN>;
+
+struct kaident {
+ char name[MAXKANAMELEN];
+ char instance[MAXKANAMELEN];
+};
+
+struct kaentryinfo {
+ int32_t minor_version;
+ int32_t flags;
+ u_int32_t user_expiration;
+ Date modification_time;
+ kaident modification_user;
+ Date change_password_time;
+ long max_ticket_lifetime;
+ long key_version;
+ EncryptionKey key;
+ u_int32_t keyCheckSym;
+ int32_t reserved2;
+ int32_t reserved3;
+ int32_t reserved4;
+};
+
+
+package KAA_
+
+Authenticate (IN kaname name,
+ IN kaname instance,
+ IN Date start_time,
+ IN Date end_time,
+ INOUT ka_BBS *answer) = 21;
+
+ChangePassword (IN kaname name,
+ IN kaname instance,
+ IN ka_CBS arequest,
+ INOUT ka_BBS *oanswer) = 2;
+
+package KAM_
+
+SetPassword (IN kaname name,
+ IN kaname instance,
+ IN int32_t kvno,
+ IN EncryptionKey password) = 4;
+
+SetFields (IN kaname name,
+ IN kaname instance,
+ IN int32_t flags,
+ IN Date user_expiration,
+ IN int32_t max_ticket_lifetime,
+ IN int32_t maxAssociates,
+ IN int32_t spare1,
+ IN int32_t spare2) = 5;
+
+CreateUser (IN kaname name,
+ IN kaname instance,
+ IN EncryptionKey password) = 6;
+
+GetEntry (IN kaname name,
+ IN kaname instance,
+ IN long major_version,
+ OUT kaentryinfo *entry) = 8;
+
+
diff --git a/usr.sbin/afs/src/rxkad/Makefile.in b/usr.sbin/afs/src/rxkad/Makefile.in
new file mode 100644
index 00000000000..9c45402e6a3
--- /dev/null
+++ b/usr.sbin/afs/src/rxkad/Makefile.in
@@ -0,0 +1,96 @@
+#
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:25 art Exp $
+#
+
+# This should really be set from configure
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@ -O
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+libdir = @libdir@
+
+PICFLAGS = # @PICFLAGS@
+
+LIBPREFIX = lib
+#@LIBPREFIX@
+LIBNAME = $(LIBPREFIX)rxkad
+#LIBEXT = @LIBEXT@ Always build archive library!
+LIBEXT = a
+SHLIBEXT = @SHLIBEXT@
+LDSHARED = @LDSHARED@
+LIB = $(LIBNAME).$(LIBEXT)
+
+SOURCES = rxk_locl.c rxk_clnt.c rxk_serv.c rxk_crpt.c rxk_info.c osi_alloc.c compat.c
+
+OBJECTS = rxk_locl.o rxk_clnt.o rxk_serv.o rxk_crpt.o rxk_info.o osi_alloc.o compat.o
+
+all: $(LIB)
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(includedir)/rx
+ $(INSTALL_DATA) $(srcdir)/rxkad.h $(DESTDIR)$(includedir)/rx/rxkad.h
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+
+uninstall:
+ rm -f $(DESTDIR)$(includedir)/rx/rxkad.h
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+
+Wall:
+ make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
+
+.c.o:
+ $(CC) -c $(DEFS) -I../include -I$(srcdir)/../include -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) @KRB4_INC_FLAGS@ $<
+
+fc_test: rxk_crpt.c
+ $(CC) -DTEST -o $@ $(DEFS) -I../include -I$(srcdir)/.. -I$(srcdir)/../lwp -I$(srcdir)/../include $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) @KRB4_INC_FLAGS@ $(VPATH)/rxk_crpt.c
+
+
+check:
+
+clean:
+ rm -f $(LIB) *.o *.a fc_test
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile *.tab.c *~
+
+realclean: distclean
+ rm -f TAGS
+
+dist: $(DISTFILES)
+ for file in $(DISTFILES); do \
+ ln $$file ../`cat ../.fname`/lib \
+ || cp -p $$file ../`cat ../.fname`/lib; \
+ done
+
+$(LIBNAME).a: $(OBJECTS)
+ rm -f $@
+ $(AR) cr $@ $(OBJECTS)
+ -$(RANLIB) $@
+
+$(LIBNAME).$(SHLIBEXT): $(OBJECTS)
+ rm -f $@
+ $(LDSHARED) -o $@ $(OBJECTS)
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+$(OBJECTS): ../include/config.h
+
+.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean dist
diff --git a/usr.sbin/afs/src/tests/Makefile.in b/usr.sbin/afs/src/tests/Makefile.in
new file mode 100644
index 00000000000..8e9a4faba69
--- /dev/null
+++ b/usr.sbin/afs/src/tests/Makefile.in
@@ -0,0 +1,231 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:26 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+REALCFLAGS = -I../include -I$(srcdir)/../include @KRB4_INC_FLAGS@ $(CFLAGS) \
+ -I../rxdef -I$(srcdir)/../appl/lib
+CPPFLAGS = @CPPFLAGS@
+DEFS = @DEFS@
+LDFLAGS = @LDFLAGS@
+LIBS = -L../lib/roken -lroken @LIBS@
+KAFS_LIBS = @AFS_EXTRA_LIBS@ @KAFS_LIBS@
+KRB_LIBS = @KRB4_LIB_FLAGS@
+APPL_LIB = -L../appl/lib -larlalib -L../lib/ko -lko
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+
+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 ga-test create-remove \
+ symlink echo-n test-parallel1 test-parallel2 create-stat \
+ kill-softly kill-softer rm-rf apwd 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
+
+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 ga-test.o \
+ create-remove.o symlink.o echo-n.o test-parallel1.o \
+ test-parallel1.o \
+ create-stat.o kill-softly.o kill-softer.o rm-rf.o apwd.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
+
+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.o \
+ 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 ga-test.c \
+ create-remove.c symlink.c echo-n.c test-parallel1.c \
+ test-parallel2.c \ \
+ create-stat.c kill-softly.c kill-softer.c rm-rf.c apwd.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
+
+all: run-tests $(TEST_PROGRAMS)
+
+run-tests: run-tests.in
+ (cd ..; CONFIG_FILES=tests/run-tests CONFIG_HEADERS= $(SHELL) config.status)
+ @chmod +x run-tests
+
+write-ro-file: write-ro-file.o
+ $(CC) $(LDFLAGS) -o $@ write-ro-file.o $(LIBS)
+
+read-vs-mmap: read-vs-mmap.o
+ $(CC) $(LDFLAGS) -o $@ read-vs-mmap.o $(LIBS)
+
+read-vs-mmap2: read-vs-mmap2.o
+ $(CC) $(LDFLAGS) -o $@ read-vs-mmap2.o $(LIBS)
+
+mmap-vs-read: mmap-vs-read.o
+ $(CC) $(LDFLAGS) -o $@ mmap-vs-read.o $(LIBS)
+
+mmap-vs-read2: mmap-vs-read2.o
+ $(CC) $(LDFLAGS) -o $@ mmap-vs-read2.o $(LIBS)
+
+read-write: read-write.o
+ $(CC) $(LDFLAGS) -o $@ read-write.o $(LIBS)
+
+mmap-and-read: mmap-and-read.o
+ $(CC) $(LDFLAGS) -o $@ mmap-and-read.o $(LIBS)
+
+large-dir: large-dir.o
+ $(CC) $(LDFLAGS) -o $@ large-dir.o $(LIBS)
+
+large-dir2: large-dir2.o
+ $(CC) $(LDFLAGS) -o $@ large-dir2.o $(LIBS)
+
+large-dir3: large-dir3.o
+ $(CC) $(LDFLAGS) -o $@ large-dir3.o $(LIBS)
+
+ga-test: ga-test.o
+ $(CC) $(LDFLAGS) -o $@ ga-test.o $(LIBS)
+
+test-setgroups: test-setgroups.o
+ $(CC) $(LDFLAGS) -o $@ test-setgroups.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+test-setpag: test-setpag.o
+ $(CC) $(LDFLAGS) -o $@ test-setpag.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+hardlink1: hardlink1.o
+ $(CC) $(LDFLAGS) -o $@ hardlink1.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+hardlink2: hardlink2.o
+ $(CC) $(LDFLAGS) -o $@ hardlink2.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+mkdir2: mkdir2.o
+ $(CC) $(LDFLAGS) -o $@ mkdir2.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+create-files: create-files.o
+ $(CC) $(LDFLAGS) -o $@ create-files.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+create-symlinks: create-symlinks.o
+ $(CC) $(LDFLAGS) -o $@ create-symlinks.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+create-dirs: create-dirs.o
+ $(CC) $(LDFLAGS) -o $@ create-dirs.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+create-remove: create-remove.o
+ $(CC) $(LDFLAGS) -o $@ create-remove.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+
+dup2-and-unlog: dup2-and-unlog.o
+ $(CC) $(LDFLAGS) -o $@ dup2-and-unlog.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+readdir-vs-lstat: readdir-vs-lstat.o
+ $(CC) $(LDFLAGS) -o $@ readdir-vs-lstat.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+symlink: symlink.o
+ $(CC) $(LDFLAGS) -o $@ symlink.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+echo-n: echo-n.o
+ $(CC) $(LDFLAGS) -o $@ echo-n.o
+
+test-parallel1: test-parallel1.o
+ $(CC) $(LDFLAGS) -o $@ test-parallel1.o $(LIBS)
+
+test-parallel2: test-parallel2.o
+ $(CC) $(LDFLAGS) -o $@ test-parallel2.o $(LIBS)
+
+create-stat: create-stat.o
+ $(CC) $(LDFLAGS) -o $@ create-stat.o $(APPL_LIB) $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+kill-softly: kill-softly.o
+ $(CC) $(LDFLAGS) -o $@ kill-softly.o $(APPL_LIB) $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+kill-softer: kill-softer.o
+ $(CC) $(LDFLAGS) -o $@ kill-softer.o $(APPL_LIB) $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+rm-rf: rm-rf.o
+ $(CC) $(LDFLAGS) -o $@ rm-rf.o $(APPL_LIB) $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+apwd: apwd.o
+ $(CC) $(LDFLAGS) -o $@ apwd.o $(APPL_LIB) $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+exit-wo-close: exit-wo-close.o
+ $(CC) $(LDFLAGS) -o $@ exit-wo-close.o $(APPL_LIB) $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+strange-characters-c: strange-characters-c.o
+ $(CC) $(LDFLAGS) -o $@ strange-characters-c.o $(KRB_LIBS) $(LIBS)
+
+pine: pine.o
+ $(CC) $(LDFLAGS) -o $@ pine.o $(KRB_LIBS) $(LIBS)
+
+append-over-page: append-over-page.o
+ $(CC) $(LDFLAGS) -o $@ append-over-page.o $(KRB_LIBS) $(LIBS)
+
+write-ucc: write-ucc.o
+ $(CC) $(LDFLAGS) -o $@ write-ucc.o $(KRB_LIBS) $(LIBS)
+
+utime-dir: utime-dir.o
+ $(CC) $(LDFLAGS) -o $@ utime-dir.o $(KRB_LIBS) $(LIBS)
+
+mmap-shared-write: mmap-shared-write.o
+ $(CC) $(LDFLAGS) -o $@ mmap-shared-write.o $(KRB_LIBS) $(LIBS)
+
+rename5: rename5.o
+ $(CC) $(LDFLAGS) -o $@ rename5.o $(KRB_LIBS) $(LIBS)
+
+rename-under-feet: rename-under-feet.o
+ $(CC) $(LDFLAGS) -o $@ rename-under-feet.o $(KRB_LIBS) $(LIBS)
+
+write-closed: write-closed.o
+ $(CC) $(LDFLAGS) -o $@ write-closed.o $(KRB_LIBS) $(LIBS)
+
+write-closed2: write-closed2.o
+ $(CC) $(LDFLAGS) -o $@ write-closed2.o $(KAFS_LIBS) $(KRB_LIBS) $(LIBS)
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(DEFS) -I$(srcdir) -I. $(REALCFLAGS) $<
+
+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:
+
+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
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=tests/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+.PHONY: all install clean realclean distclean mostlyclean install uninstall check
diff --git a/usr.sbin/afs/src/tests/append-over-page.c b/usr.sbin/afs/src/tests/append-over-page.c
new file mode 100644
index 00000000000..9e8594a381a
--- /dev/null
+++ b/usr.sbin/afs/src/tests/append-over-page.c
@@ -0,0 +1,986 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <roken.h>
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+RCSID("$Id: append-over-page.c,v 1.1 2000/09/11 14:41:26 art Exp $");
+
+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";
+
+ set_progname (argv[0]);
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/append1 b/usr.sbin/afs/src/tests/append1
new file mode 100644
index 00000000000..c7dc373571b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/append1
@@ -0,0 +1,6 @@
+#!/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
diff --git a/usr.sbin/afs/src/tests/apwd.c b/usr.sbin/afs/src/tests/apwd.c
new file mode 100644
index 00000000000..59b93005be3
--- /dev/null
+++ b/usr.sbin/afs/src/tests/apwd.c
@@ -0,0 +1,471 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <getarg.h>
+
+#include <roken.h>
+
+RCSID("$Id: apwd.c,v 1.1 2000/09/11 14:41:26 art Exp $");
+
+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", sizeof(real_buf));
+ ret = 1;
+ }
+ if (func (buf, sizeof(buf)) == NULL) {
+ fprintf (verbose_fp, "%s(buf, %u) failed\n", func_name, 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",
+ 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 getargs args[] = {
+ {"verbose", 'v', arg_flag, &verbose_flag, "verbose", NULL},
+ {"help", 0, arg_flag, &help_flag, NULL, NULL},
+ {NULL, 0, arg_end, NULL, NULL, NULL}
+};
+
+static void
+usage (int exit_val)
+{
+ arg_printusage (args, NULL, "", ARG_GNUSTYLE);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret = 0;
+ int optind = 0;
+
+ set_progname (argv[0]);
+
+ verbose_flag = getenv ("VERBOSE") != NULL;
+
+ if (getarg (args, argc, argv, &optind, ARG_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;
+}
diff --git a/usr.sbin/afs/src/tests/boot-strap-arla b/usr.sbin/afs/src/tests/boot-strap-arla
new file mode 100644
index 00000000000..4310dc9dcf6
--- /dev/null
+++ b/usr.sbin/afs/src/tests/boot-strap-arla
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $Id: boot-strap-arla,v 1.1 2000/09/11 14:41:26 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/build-emacs b/usr.sbin/afs/src/tests/build-emacs
new file mode 100644
index 00000000000..94277bec767
--- /dev/null
+++ b/usr.sbin/afs/src/tests/build-emacs
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: build-emacs,v 1.1 2000/09/11 14:41:26 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/build-emacs-j b/usr.sbin/afs/src/tests/build-emacs-j
new file mode 100644
index 00000000000..6c59c2e0c98
--- /dev/null
+++ b/usr.sbin/afs/src/tests/build-emacs-j
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: build-emacs-j,v 1.1 2000/09/11 14:41:26 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/build-gdb b/usr.sbin/afs/src/tests/build-gdb
new file mode 100644
index 00000000000..e2439a8c405
--- /dev/null
+++ b/usr.sbin/afs/src/tests/build-gdb
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: build-gdb,v 1.1 2000/09/11 14:41:26 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/checkpwd b/usr.sbin/afs/src/tests/checkpwd
new file mode 100644
index 00000000000..865edc4169e
--- /dev/null
+++ b/usr.sbin/afs/src/tests/checkpwd
@@ -0,0 +1,3 @@
+#!/bin/sh
+# $Id: checkpwd,v 1.1 2000/09/11 14:41:27 art Exp $
+$objdir/apwd
diff --git a/usr.sbin/afs/src/tests/compare-inum-mp b/usr.sbin/afs/src/tests/compare-inum-mp
new file mode 100644
index 00000000000..f82ea65462b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/compare-inum-mp
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id: compare-inum-mp,v 1.1 2000/09/11 14:41:27 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/compare-inums b/usr.sbin/afs/src/tests/compare-inums
new file mode 100644
index 00000000000..e8b0a9690a2
--- /dev/null
+++ b/usr.sbin/afs/src/tests/compare-inums
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: compare-inums,v 1.1 2000/09/11 14:41:27 art Exp $
+$objdir/create-files 100 0 || exit 1
+$objdir/readdir-vs-lstat . || exit 1
diff --git a/usr.sbin/afs/src/tests/compare-with-local b/usr.sbin/afs/src/tests/compare-with-local
new file mode 100644
index 00000000000..cec819bb63f
--- /dev/null
+++ b/usr.sbin/afs/src/tests/compare-with-local
@@ -0,0 +1,77 @@
+#!/bin/sh
+# $Id: compare-with-local,v 1.1 2000/09/11 14:41:27 art Exp $
+#################################################################
+#
+# 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
diff --git a/usr.sbin/afs/src/tests/copy-and-diff-gnu-mirror b/usr.sbin/afs/src/tests/copy-and-diff-gnu-mirror
new file mode 100644
index 00000000000..3f83f2e385a
--- /dev/null
+++ b/usr.sbin/afs/src/tests/copy-and-diff-gnu-mirror
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: copy-and-diff-gnu-mirror,v 1.1 2000/09/11 14:41:27 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $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/'{}' \;
diff --git a/usr.sbin/afs/src/tests/creat1 b/usr.sbin/afs/src/tests/creat1
new file mode 100644
index 00000000000..9bdf2b50c6b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/creat1
@@ -0,0 +1,5 @@
+#!/bin/sh
+> foobar
+test -f foobar || exit 1
+test -s foobar && exit 1
+rm foobar || exit 1
diff --git a/usr.sbin/afs/src/tests/create-dirs.c b/usr.sbin/afs/src/tests/create-dirs.c
new file mode 100644
index 00000000000..4617cf4d6fa
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-dirs.c
@@ -0,0 +1,100 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: create-dirs.c,v 1.1 2000/09/11 14:41:27 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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);
+}
diff --git a/usr.sbin/afs/src/tests/create-files.c b/usr.sbin/afs/src/tests/create-files.c
new file mode 100644
index 00000000000..3350dd35be5
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-files.c
@@ -0,0 +1,123 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: create-files.c,v 1.1 2000/09/11 14:41:27 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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);
+}
diff --git a/usr.sbin/afs/src/tests/create-remove-dirs b/usr.sbin/afs/src/tests/create-remove-dirs
new file mode 100644
index 00000000000..94868b0ecbc
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-remove-dirs
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: create-remove-dirs,v 1.1 2000/09/11 14:41:27 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/create-remove dir 1000
diff --git a/usr.sbin/afs/src/tests/create-remove-files b/usr.sbin/afs/src/tests/create-remove-files
new file mode 100644
index 00000000000..37d12ffc40f
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-remove-files
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: create-remove-files,v 1.1 2000/09/11 14:41:27 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/create-remove file 1000
diff --git a/usr.sbin/afs/src/tests/create-remove.c b/usr.sbin/afs/src/tests/create-remove.c
new file mode 100644
index 00000000000..bea505d7421
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-remove.c
@@ -0,0 +1,142 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: create-remove.c,v 1.1 2000/09/11 14:41:27 art Exp $");
+#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);
+}
+
+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;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/create-stat.c b/usr.sbin/afs/src/tests/create-stat.c
new file mode 100644
index 00000000000..c51039c512e
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-stat.c
@@ -0,0 +1,174 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <atypes.h>
+
+#include <kafs.h>
+
+#include <fs.h>
+#include <arlalib.h>
+
+#include <err.h>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: create-stat.c,v 1.1 2000/09/11 14:41:27 art Exp $");
+#endif
+
+#ifdef KERBEROS
+
+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;
+ VenusFid fid;
+ char *filename;
+ ino_t afsfileid;
+
+ set_progname (argv[0]);
+
+ if (!k_hasafs())
+ errx (1, "!k_hasafs");
+
+ 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;
+}
+
+#else /* !KERBEROS */
+
+int
+main (int argc, char **argv)
+{
+ set_progname (argv[0]);
+
+ errx (1, "no kafs");
+}
+
+#endif
diff --git a/usr.sbin/afs/src/tests/create-symlinks.c b/usr.sbin/afs/src/tests/create-symlinks.c
new file mode 100644
index 00000000000..54e1f126bba
--- /dev/null
+++ b/usr.sbin/afs/src/tests/create-symlinks.c
@@ -0,0 +1,100 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: create-symlinks.c,v 1.1 2000/09/11 14:41:28 art Exp $");
+#endif
+
+static int
+creat_symlinks (int count)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ char num[17];
+
+ snprintf (num, sizeof(num), "%d", i);
+
+ ret = symlink ("kaka", num);
+ if (ret < 0)
+ err (1, "symlink %s", num);
+ }
+ 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;
+
+ set_progname (argv[0]);
+
+ 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_symlinks (count);
+}
diff --git a/usr.sbin/afs/src/tests/dd b/usr.sbin/afs/src/tests/dd
new file mode 100644
index 00000000000..501c65ef8ce
--- /dev/null
+++ b/usr.sbin/afs/src/tests/dd
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id: dd,v 1.1 2000/09/11 14:41:28 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/deep-tree b/usr.sbin/afs/src/tests/deep-tree
new file mode 100644
index 00000000000..a4b17af2962
--- /dev/null
+++ b/usr.sbin/afs/src/tests/deep-tree
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: deep-tree,v 1.1 2000/09/11 14:41:28 art Exp $
+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 5 6 7 8 9" )
+${objdir}/rm-rf foo
diff --git a/usr.sbin/afs/src/tests/deep-tree2 b/usr.sbin/afs/src/tests/deep-tree2
new file mode 100644
index 00000000000..2a8b65ec45c
--- /dev/null
+++ b/usr.sbin/afs/src/tests/deep-tree2
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $Id: deep-tree2,v 1.1 2000/09/11 14:41:28 art Exp $
+
+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
diff --git a/usr.sbin/afs/src/tests/dir-size-mismatch b/usr.sbin/afs/src/tests/dir-size-mismatch
new file mode 100644
index 00000000000..1696976f8b2
--- /dev/null
+++ b/usr.sbin/afs/src/tests/dir-size-mismatch
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $Id: dir-size-mismatch,v 1.1 2000/09/11 14:41:28 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/dir-tree b/usr.sbin/afs/src/tests/dir-tree
new file mode 100644
index 00000000000..5f020a17099
--- /dev/null
+++ b/usr.sbin/afs/src/tests/dir-tree
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $Id: dir-tree,v 1.1 2000/09/11 14:41:28 art Exp $
+
+#######################################################
+#
+# 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
diff --git a/usr.sbin/afs/src/tests/discon-create b/usr.sbin/afs/src/tests/discon-create
new file mode 100644
index 00000000000..7c57171debd
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-create
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: discon-create,v 1.1 2000/09/11 14:41:28 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} conn disconn
+> foobar
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/discon-echo b/usr.sbin/afs/src/tests/discon-echo
new file mode 100644
index 00000000000..13cbe7748c5
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-echo
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: discon-echo,v 1.1 2000/09/11 14:41:28 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} conn disconn
+echo hej > hej
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/discon-mkdir b/usr.sbin/afs/src/tests/discon-mkdir
new file mode 100644
index 00000000000..98052e4cecb
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-mkdir
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: discon-mkdir,v 1.1 2000/09/11 14:41:28 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} conn disconn
+mkdir dir
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/discon-mkdir2 b/usr.sbin/afs/src/tests/discon-mkdir2
new file mode 100644
index 00000000000..0d9c7e7e310
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-mkdir2
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: discon-mkdir2,v 1.1 2000/09/11 14:41:28 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} conn disconn
+mkdir dir || exit 1
+cd dir || exit 1
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/discon-tar1 b/usr.sbin/afs/src/tests/discon-tar1
new file mode 100644
index 00000000000..82def0cba4f
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-tar1
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $Id: discon-tar1,v 1.1 2000/09/11 14:41:28 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+FS=${FS:-${objdir}/../appl/fs/fs}
+TARBOLL=$AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.5a.tar.gz
+file $TARBOLL >&4 || exit 1
+${FS} conn disconn
+gzip -dc $TARBOLL | tar xvf - >&4 || exit 1
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/discon-tar2 b/usr.sbin/afs/src/tests/discon-tar2
new file mode 100644
index 00000000000..5c483594228
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-tar2
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $Id: discon-tar2,v 1.1 2000/09/11 14:41:29 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+FS=${FS:-${objdir}/../appl/fs/fs}
+TARBOLL=$AFSROOT/stacken.kth.se/ftp/pub/gnu/emacs/emacs-20.5a.tar.gz
+file $TARBOLL >&4 || exit 1
+mkdir one || exit 1
+(cd one && gzip -dc $TARBOLL | tar xvf - >&4 || exit 1)
+${FS} conn disconn
+mkdir two || exit 1
+(cd two && gzip -dc $TARBOLL | tar xvf - >&4 || exit 1)
+${FS} conn conn
+diff -r one two >/dev/null || exit 1
diff --git a/usr.sbin/afs/src/tests/discon-touch1 b/usr.sbin/afs/src/tests/discon-touch1
new file mode 100644
index 00000000000..fdcc007b8b7
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-touch1
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: discon-touch1,v 1.1 2000/09/11 14:41:29 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+> foobar
+${FS} conn disconn
+touch foobar
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/discon-touch2 b/usr.sbin/afs/src/tests/discon-touch2
new file mode 100644
index 00000000000..dc9bf7316c2
--- /dev/null
+++ b/usr.sbin/afs/src/tests/discon-touch2
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id: discon-touch2,v 1.1 2000/09/11 14:41:29 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+> foobar
+${FS} conn disconn
+touch foobar
+touch foobar
+${FS} conn conn
diff --git a/usr.sbin/afs/src/tests/dup2-and-unlog.c b/usr.sbin/afs/src/tests/dup2-and-unlog.c
new file mode 100644
index 00000000000..0151fe79ddb
--- /dev/null
+++ b/usr.sbin/afs/src/tests/dup2-and-unlog.c
@@ -0,0 +1,53 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <err.h>
+#include <roken.h>
+#include <atypes.h>
+#include <kafs.h>
+
+#ifdef KERBEROS
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+
+ set_progname (argv[0]);
+
+ if (!k_hasafs())
+ errx (1, "no afs");
+
+ 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");
+
+ k_unlog();
+
+ close (fd);
+ close (fd + 1);
+
+ exit (0);
+}
+
+#else /* !KERBEROS */
+
+int
+main (int argc, char **argv)
+{
+ set_progname (argv[0]);
+
+ errx (1, "no kafs");
+}
+
+#endif /* !KERBEROS */
diff --git a/usr.sbin/afs/src/tests/echo-n.c b/usr.sbin/afs/src/tests/echo-n.c
new file mode 100644
index 00000000000..377723cb8ad
--- /dev/null
+++ b/usr.sbin/afs/src/tests/echo-n.c
@@ -0,0 +1,20 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+RCSID("$Id: echo-n.c,v 1.1 2000/09/11 14:41:29 art Exp $");
+
+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;
+}
diff --git a/usr.sbin/afs/src/tests/exec b/usr.sbin/afs/src/tests/exec
new file mode 100644
index 00000000000..f6535c0531b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/exec
@@ -0,0 +1,9 @@
+#!/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
diff --git a/usr.sbin/afs/src/tests/exit-wo-close.c b/usr.sbin/afs/src/tests/exit-wo-close.c
new file mode 100644
index 00000000000..cb034f3d287
--- /dev/null
+++ b/usr.sbin/afs/src/tests/exit-wo-close.c
@@ -0,0 +1,134 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: exit-wo-close.c,v 1.1 2000/09/11 14:41:29 art Exp $");
+#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";
+
+ set_progname (argv[0]);
+
+ if (argc != 2 && argc != 1)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ return doit (file);
+}
diff --git a/usr.sbin/afs/src/tests/fcachesize-dir b/usr.sbin/afs/src/tests/fcachesize-dir
new file mode 100644
index 00000000000..ef41ccb7443
--- /dev/null
+++ b/usr.sbin/afs/src/tests/fcachesize-dir
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $Id: fcachesize-dir,v 1.1 2000/09/11 14:41:29 art Exp $
+
+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
diff --git a/usr.sbin/afs/src/tests/fcachesize-file-small b/usr.sbin/afs/src/tests/fcachesize-file-small
new file mode 100644
index 00000000000..fbdcde9bfdf
--- /dev/null
+++ b/usr.sbin/afs/src/tests/fcachesize-file-small
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $Id: fcachesize-file-small,v 1.1 2000/09/11 14:41:29 art Exp $
+
+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
diff --git a/usr.sbin/afs/src/tests/find-and-cat-netbsd b/usr.sbin/afs/src/tests/find-and-cat-netbsd
new file mode 100644
index 00000000000..581b1fa6ab7
--- /dev/null
+++ b/usr.sbin/afs/src/tests/find-and-cat-netbsd
@@ -0,0 +1,5 @@
+#!/bin/sh
+# $Id: find-and-cat-netbsd,v 1.1 2000/09/11 14:41:29 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/find-linux b/usr.sbin/afs/src/tests/find-linux
new file mode 100644
index 00000000000..6f26f203522
--- /dev/null
+++ b/usr.sbin/afs/src/tests/find-linux
@@ -0,0 +1,5 @@
+#!/bin/sh
+# $Id: find-linux,v 1.1 2000/09/11 14:41:29 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/fs-flush b/usr.sbin/afs/src/tests/fs-flush
new file mode 100644
index 00000000000..fef644beb15
--- /dev/null
+++ b/usr.sbin/afs/src/tests/fs-flush
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: fs-flush,v 1.1 2000/09/11 14:41:30 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+> foobar
+${FS} flush
+test -f foobar || exit 1 \ No newline at end of file
diff --git a/usr.sbin/afs/src/tests/fs-sa-la b/usr.sbin/afs/src/tests/fs-sa-la
new file mode 100644
index 00000000000..b8153496dba
--- /dev/null
+++ b/usr.sbin/afs/src/tests/fs-sa-la
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: fs-sa-la,v 1.1 2000/09/11 14:41:30 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . kalle-anka-nu rl 2>&4
+${FS} la >&4 2>&4
+exit 0
diff --git a/usr.sbin/afs/src/tests/ga-test.c b/usr.sbin/afs/src/tests/ga-test.c
new file mode 100644
index 00000000000..681b0d2c3e3
--- /dev/null
+++ b/usr.sbin/afs/src/tests/ga-test.c
@@ -0,0 +1,332 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 getarg works as expected
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <err.h>
+#include <roken.h>
+
+#include <getarg.h>
+
+RCSID("$Id: ga-test.c,v 1.1 2000/09/11 14:41:30 art Exp $");
+
+typedef struct {
+ int style;
+ int argc;
+ char *argv[10];
+ enum { GA_SUCCESS = 0, GA_FAILURE } retval ;
+} ga_tests;
+
+
+/* XXX TODO: arg_negative_flag, manualpage generation ? */
+
+/*
+ *
+ */
+
+static void
+test_simple_string (void)
+{
+ char *string;
+ int i, optind;
+ ga_tests tests[] = {
+ { ARG_GNUSTYLE, 2, { "string", "--string=foo", NULL } },
+ { ARG_GNUSTYLE, 3, { "string", "-s", "foo", NULL} },
+ { ARG_AFSSTYLE, 3, { "string", "-string", "foo", NULL} },
+ { ARG_AFSSTYLE, 2, { "string", "--flag"}, GA_FAILURE },
+ { ARG_AFSSTYLE, 2, { "string", "foo", NULL} }
+ };
+
+ struct getargs args[] = {
+ { "string", 's', arg_string, NULL,
+ "string test", "stringfoo", arg_mandatory},
+ { NULL, 0, arg_end, NULL, NULL }
+ }, *a = args;
+
+ a->value = &string;
+
+ for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ string = NULL;
+ optind = 0;
+
+ if (getarg (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)
+{
+ getarg_strings strings;
+
+ int i, optind;
+ ga_tests tests[] = {
+ { ARG_GNUSTYLE, 3, { "strings",
+ "--strings=foo", "--strings=bar", NULL } },
+ { ARG_GNUSTYLE, 5, { "strings", "-s", "foo", "-s", "bar", NULL} },
+ { ARG_AFSSTYLE, 4, { "strings", "-string", "foo", "bar", NULL} }
+#if 0
+ { ARG_AFSSTYLE, 3, { "strings", "foo", "bar", NULL} }
+#endif
+ };
+
+ struct getargs args[] = {
+ { "strings", 's', arg_strings, NULL,
+ "strings test", "stringsfoo", arg_optional},
+ { NULL, 0, arg_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 (getarg (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[] = {
+ { ARG_GNUSTYLE, 2, { "integer", "--integer=4711", NULL } },
+ { ARG_GNUSTYLE, 3, { "integer", "-i", "4711", NULL} },
+ { ARG_AFSSTYLE, 3, { "integer", "-integer", "4711", NULL} },
+ { ARG_AFSSTYLE, 2, { "integer", "4711", NULL} }
+ };
+
+ struct getargs args[] = {
+ { "integer", 'i', arg_integer, NULL,
+ "integer test", "integer", arg_mandatory},
+ { NULL, 0, arg_end, NULL, NULL }
+ }, *a = args;
+
+ a->value = &integer;
+
+ for (i = 0 ; i < sizeof(tests)/sizeof(*tests); i++) {
+ integer = 0;
+ optind = 0;
+
+ if (getarg (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[] = {
+ { ARG_GNUSTYLE, 2, { "flag", "--flag=yes", NULL }, GA_SUCCESS },
+ { ARG_GNUSTYLE, 2, { "flag", "-g", NULL}, GA_SUCCESS },
+ { ARG_AFSSTYLE, 2, { "flag", "--flag"}, GA_FAILURE },
+ { ARG_AFSSTYLE, 2, { "flag", "-flag", NULL}, GA_SUCCESS },
+#if 0
+ /* XXX */
+ { ARG_AFSSTYLE, 2, { "flag", "yes", NULL}, GA_SUCCESS },
+#endif
+ { ARG_GNUSTYLE, 2, { "flag", "--no-flag", NULL}, GA_SUCCESS }
+ };
+
+ struct getargs args[] = {
+ { "flag", 'g', arg_flag, NULL,
+ "flag", "flag bar", arg_optional},
+ { NULL, 0, arg_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 (getarg (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)
+{
+ set_progname (argv[0]);
+
+ test_simple_string();
+ test_simple_strings();
+ test_simple_integer();
+ test_simple_flag();
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/generic-build b/usr.sbin/afs/src/tests/generic-build
new file mode 100644
index 00000000000..4451f389143
--- /dev/null
+++ b/usr.sbin/afs/src/tests/generic-build
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $Id: generic-build,v 1.1 2000/09/11 14:41:30 art Exp $
+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
+mkdir $obj || exit 1
+cd $obj || exit 1
+../$b/configure >&4 || exit 1
+make $MAKEFLAGS || exit 1
diff --git a/usr.sbin/afs/src/tests/getdents-and-unlink1 b/usr.sbin/afs/src/tests/getdents-and-unlink1
new file mode 100644
index 00000000000..e2fb5769393
--- /dev/null
+++ b/usr.sbin/afs/src/tests/getdents-and-unlink1
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $Id: getdents-and-unlink1,v 1.1 2000/09/11 14:41:30 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/getdents-and-unlink2 b/usr.sbin/afs/src/tests/getdents-and-unlink2
new file mode 100644
index 00000000000..b3f5b873df9
--- /dev/null
+++ b/usr.sbin/afs/src/tests/getdents-and-unlink2
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $Id: getdents-and-unlink2,v 1.1 2000/09/11 14:41:30 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/getdents-and-unlink3 b/usr.sbin/afs/src/tests/getdents-and-unlink3
new file mode 100644
index 00000000000..9b0208f727a
--- /dev/null
+++ b/usr.sbin/afs/src/tests/getdents-and-unlink3
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $Id: getdents-and-unlink3,v 1.1 2000/09/11 14:41:30 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/hardlink1.c b/usr.sbin/afs/src/tests/hardlink1.c
new file mode 100644
index 00000000000..7ff6f0e630a
--- /dev/null
+++ b/usr.sbin/afs/src/tests/hardlink1.c
@@ -0,0 +1,154 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: hardlink1.c,v 1.1 2000/09/11 14:41:30 art Exp $");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd1, fd2;
+ int ret;
+ struct stat sb1, sb2;
+
+ set_progname (argv[0]);
+
+ 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");
+
+ if (unlink ("foo") < 0)
+ err (1, "unlink foo");
+
+ ret = fstat (fd2, &sb2);
+ if (ret < 0)
+ err (1, "fstat bar");
+
+ if (sb2.st_nlink != 1)
+ errx (1, "bar.st_nlink != 1");
+
+ if (unlink ("bar") < 0)
+ err (1, "unlink bar");
+
+ ret = fstat (fd2, &sb2);
+ if (ret < 0)
+ err (1, "fstat bar");
+
+ if (sb2.st_nlink != 0)
+ errx (1, "bar.st_nlink != 0");
+
+ ret = close (fd2);
+ if (ret < 0)
+ err (1, "close bar");
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/hardlink2.c b/usr.sbin/afs/src/tests/hardlink2.c
new file mode 100644
index 00000000000..d6accab2bec
--- /dev/null
+++ b/usr.sbin/afs/src/tests/hardlink2.c
@@ -0,0 +1,110 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: hardlink2.c,v 1.1 2000/09/11 14:41:30 art Exp $");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd1;
+ int ret;
+ struct stat sb1;
+
+ set_progname (argv[0]);
+
+ 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 = 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;
+}
diff --git a/usr.sbin/afs/src/tests/hello-world.in b/usr.sbin/afs/src/tests/hello-world.in
new file mode 100644
index 00000000000..fd7bb9522d9
--- /dev/null
+++ b/usr.sbin/afs/src/tests/hello-world.in
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id: hello-world.in,v 1.1 2000/09/11 14:41:30 art Exp $
+cat <<FOO > foo.c
+int main() { return 0; }
+FOO
+%CC% -o foo foo.c || exit 1
+./foo || exit 1
+rm -f foo foo.c
diff --git a/usr.sbin/afs/src/tests/kill-softer.c b/usr.sbin/afs/src/tests/kill-softer.c
new file mode 100644
index 00000000000..04ef9ffadc0
--- /dev/null
+++ b/usr.sbin/afs/src/tests/kill-softer.c
@@ -0,0 +1,198 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: kill-softer.c,v 1.1 2000/09/11 14:41:30 art Exp $");
+#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)
+{
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/kill-softly.c b/usr.sbin/afs/src/tests/kill-softly.c
new file mode 100644
index 00000000000..8d4c974ab43
--- /dev/null
+++ b/usr.sbin/afs/src/tests/kill-softly.c
@@ -0,0 +1,168 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: kill-softly.c,v 1.1 2000/09/11 14:41:30 art Exp $");
+#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)
+{
+ set_progname (argv[0]);
+
+ if (argc != 2)
+ errx (1, "usage: %s directory", argv[0]);
+ do_dir (argv[1]);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/kotest b/usr.sbin/afs/src/tests/kotest
new file mode 100644
index 00000000000..80bbf66ae1e
--- /dev/null
+++ b/usr.sbin/afs/src/tests/kotest
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: kotest,v 1.1 2000/09/11 14:41:31 art Exp $
+
+exec ${objdir}/../lib/ko/kotest
diff --git a/usr.sbin/afs/src/tests/large-dir-16384 b/usr.sbin/afs/src/tests/large-dir-16384
new file mode 100644
index 00000000000..1275df6d3c0
--- /dev/null
+++ b/usr.sbin/afs/src/tests/large-dir-16384
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: large-dir-16384,v 1.1 2000/09/11 14:41:31 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/large-dir large-dir-16384 16384
diff --git a/usr.sbin/afs/src/tests/large-dir-extra b/usr.sbin/afs/src/tests/large-dir-extra
new file mode 100644
index 00000000000..f6c20d76821
--- /dev/null
+++ b/usr.sbin/afs/src/tests/large-dir-extra
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: large-dir-extra,v 1.1 2000/09/11 14:41:31 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/large-dir.c b/usr.sbin/afs/src/tests/large-dir.c
new file mode 100644
index 00000000000..c2e474b5963
--- /dev/null
+++ b/usr.sbin/afs/src/tests/large-dir.c
@@ -0,0 +1,164 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: large-dir.c,v 1.1 2000/09/11 14:41:31 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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);
+}
diff --git a/usr.sbin/afs/src/tests/large-dir2.c b/usr.sbin/afs/src/tests/large-dir2.c
new file mode 100644
index 00000000000..c6435200534
--- /dev/null
+++ b/usr.sbin/afs/src/tests/large-dir2.c
@@ -0,0 +1,143 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: large-dir2.c,v 1.1 2000/09/11 14:41:31 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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);
+}
diff --git a/usr.sbin/afs/src/tests/large-dir3.c b/usr.sbin/afs/src/tests/large-dir3.c
new file mode 100644
index 00000000000..629d03c7e2e
--- /dev/null
+++ b/usr.sbin/afs/src/tests/large-dir3.c
@@ -0,0 +1,131 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: large-dir3.c,v 1.1 2000/09/11 14:41:31 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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);
+}
diff --git a/usr.sbin/afs/src/tests/ls-afs b/usr.sbin/afs/src/tests/ls-afs
new file mode 100644
index 00000000000..65281c3b213
--- /dev/null
+++ b/usr.sbin/afs/src/tests/ls-afs
@@ -0,0 +1,5 @@
+#!/bin/sh
+# $Id: ls-afs,v 1.1 2000/09/11 14:41:31 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+ls -l $AFSROOT >/dev/null
+true
diff --git a/usr.sbin/afs/src/tests/many-dirs b/usr.sbin/afs/src/tests/many-dirs
new file mode 100644
index 00000000000..e3852d14bc6
--- /dev/null
+++ b/usr.sbin/afs/src/tests/many-dirs
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: many-dirs,v 1.1 2000/09/11 14:41:31 art Exp $
+
+$objdir/create-dirs 1000
diff --git a/usr.sbin/afs/src/tests/many-fetchs b/usr.sbin/afs/src/tests/many-fetchs
new file mode 100644
index 00000000000..02bd402acea
--- /dev/null
+++ b/usr.sbin/afs/src/tests/many-fetchs
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $Id: many-fetchs,v 1.1 2000/09/11 14:41:31 art Exp $
+
+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
diff --git a/usr.sbin/afs/src/tests/many-files b/usr.sbin/afs/src/tests/many-files
new file mode 100644
index 00000000000..b756aee1268
--- /dev/null
+++ b/usr.sbin/afs/src/tests/many-files
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: many-files,v 1.1 2000/09/11 14:41:31 art Exp $
+
+$objdir/create-files 1000 0
diff --git a/usr.sbin/afs/src/tests/many-files-with-content b/usr.sbin/afs/src/tests/many-files-with-content
new file mode 100644
index 00000000000..22f5c912ce5
--- /dev/null
+++ b/usr.sbin/afs/src/tests/many-files-with-content
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: many-files-with-content,v 1.1 2000/09/11 14:41:31 art Exp $
+
+$objdir/create-files 1000 10
diff --git a/usr.sbin/afs/src/tests/many-stores b/usr.sbin/afs/src/tests/many-stores
new file mode 100644
index 00000000000..47e4b30d345
--- /dev/null
+++ b/usr.sbin/afs/src/tests/many-stores
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $Id: many-stores,v 1.1 2000/09/11 14:41:31 art Exp $
+
+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
diff --git a/usr.sbin/afs/src/tests/many-symlinks b/usr.sbin/afs/src/tests/many-symlinks
new file mode 100644
index 00000000000..83d5e983d1d
--- /dev/null
+++ b/usr.sbin/afs/src/tests/many-symlinks
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: many-symlinks,v 1.1 2000/09/11 14:41:32 art Exp $
+
+$objdir/create-symlinks 1000
diff --git a/usr.sbin/afs/src/tests/mkdir b/usr.sbin/afs/src/tests/mkdir
new file mode 100644
index 00000000000..4cb864d5b67
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mkdir
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $Id: mkdir,v 1.1 2000/09/11 14:41:32 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/mkdir-lnk b/usr.sbin/afs/src/tests/mkdir-lnk
new file mode 100644
index 00000000000..f2247a23575
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mkdir-lnk
@@ -0,0 +1,12 @@
+#!/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
diff --git a/usr.sbin/afs/src/tests/mkdir1 b/usr.sbin/afs/src/tests/mkdir1
new file mode 100644
index 00000000000..7b48950176c
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mkdir1
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: mkdir1,v 1.1 2000/09/11 14:41:32 art Exp $
+mkdir foobar || exit 1
+test -d foobar || exit 1
+test -d foobar/. || exit 1
+test -d foobar/.. || exit 1
+rmdir foobar || exit 1
diff --git a/usr.sbin/afs/src/tests/mkdir2.c b/usr.sbin/afs/src/tests/mkdir2.c
new file mode 100644
index 00000000000..a68f033b24b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mkdir2.c
@@ -0,0 +1,89 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: mkdir2.c,v 1.1 2000/09/11 14:41:32 art Exp $");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ struct stat dot_sb, sb;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/mkm-rmm b/usr.sbin/afs/src/tests/mkm-rmm
new file mode 100644
index 00000000000..fc702b6c69c
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mkm-rmm
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $Id: mkm-rmm,v 1.1 2000/09/11 14:41:32 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/mmap-and-read.c b/usr.sbin/afs/src/tests/mmap-and-read.c
new file mode 100644
index 00000000000..88d39f8fca7
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mmap-and-read.c
@@ -0,0 +1,152 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: mmap-and-read.c,v 1.1 2000/09/11 14:41:32 art Exp $");
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static char *
+generate_random_file (const char *filename,
+ unsigned npages,
+ unsigned pagesize)
+{
+ 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", 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(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;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", sz);
+ if (read (fd, buf, sz) != sz)
+ err (1, "read");
+ return buf;
+}
+
+int
+main (int argc, char **argv)
+{
+ const char *file = "foo";
+ const size_t sz = 4 * getpagesize();
+ char *buf;
+ char *malloc_buf;
+ int fd;
+ int ret;
+
+ set_progname (argv[0]);
+
+ srand (time(NULL));
+
+ buf = generate_random_file (file, 4, getpagesize());
+
+ 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 != 0;
+}
diff --git a/usr.sbin/afs/src/tests/mmap-shared-write.c b/usr.sbin/afs/src/tests/mmap-shared-write.c
new file mode 100644
index 00000000000..65bfc5902f1
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mmap-shared-write.c
@@ -0,0 +1,108 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#ifdef RCSID
+RCSID("$Id: mmap-shared-write.c,v 1.1 2000/09/11 14:41:32 art Exp $");
+#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";
+
+ set_progname(argv[0]);
+
+ if (argc != 1 && argc != 2)
+ usage ();
+
+ if (argc == 2)
+ filename = argv[1];
+
+ return doit (filename);
+}
diff --git a/usr.sbin/afs/src/tests/mmap-vs-read.c b/usr.sbin/afs/src/tests/mmap-vs-read.c
new file mode 100644
index 00000000000..96282ab5df6
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mmap-vs-read.c
@@ -0,0 +1,175 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: mmap-vs-read.c,v 1.1 2000/09/11 14:41:32 art Exp $");
+#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", 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;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", sz);
+ if (read (fd, buf, sz) != sz)
+ err (1, "read");
+ 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)
+{
+ 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)
+{
+ set_progname (argv[0]);
+
+ if (argc != 1)
+ debug = 1;
+
+ srand (time(NULL));
+
+ if (do_test (0))
+ return 1;
+ if (do_test (1))
+ return 2;
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/mmap-vs-read2.c b/usr.sbin/afs/src/tests/mmap-vs-read2.c
new file mode 100644
index 00000000000..cfffde2ef69
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mmap-vs-read2.c
@@ -0,0 +1,175 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: mmap-vs-read2.c,v 1.1 2000/09/11 14:41:32 art Exp $");
+#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", 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;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", sz);
+ if (read (fd, buf, sz) != sz)
+ err (1, "read");
+ 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)
+{
+ 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)
+{
+ set_progname (argv[0]);
+
+ if (argc != 1)
+ debug = 1;
+
+ srand (time(NULL));
+
+ if (do_test (0))
+ return 1;
+ if (do_test (1))
+ return 2;
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/mountpoint.in b/usr.sbin/afs/src/tests/mountpoint.in
new file mode 100644
index 00000000000..aba14848be3
--- /dev/null
+++ b/usr.sbin/afs/src/tests/mountpoint.in
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $Id: mountpoint.in,v 1.1 2000/09/11 14:41:33 art Exp $
+FS=${FS:-${objdir}/../appl/fs/fs}
+${FS} sa . system:anyuser all || exit 1
+${FS} mkm root root.afs || exit 1
+test -d root || exit 1
+${FS} rmm root || 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
diff --git a/usr.sbin/afs/src/tests/parallel1 b/usr.sbin/afs/src/tests/parallel1
new file mode 100644
index 00000000000..b98f8517c44
--- /dev/null
+++ b/usr.sbin/afs/src/tests/parallel1
@@ -0,0 +1,5 @@
+#!/bin/sh
+# $Id: parallel1,v 1.1 2000/09/11 14:41:33 art Exp $
+if test "X$FAST" != "X" ; then echo "Not running $0" ; exit 0 ; fi
+$objdir/test-parallel1 1>&4
+
diff --git a/usr.sbin/afs/src/tests/pine.c b/usr.sbin/afs/src/tests/pine.c
new file mode 100644
index 00000000000..bfb9b84ba72
--- /dev/null
+++ b/usr.sbin/afs/src/tests/pine.c
@@ -0,0 +1,108 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+RCSID("$Id: pine.c,v 1.1 2000/09/11 14:41:33 art Exp $");
+
+#define LOCK "mailbox-name.lock"
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ struct stat sb;
+ char unique[1024];
+ int retrycount = 0;
+
+ set_progname (argv[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;
+}
diff --git a/usr.sbin/afs/src/tests/read-vs-mmap.c b/usr.sbin/afs/src/tests/read-vs-mmap.c
new file mode 100644
index 00000000000..b1d2ac860ca
--- /dev/null
+++ b/usr.sbin/afs/src/tests/read-vs-mmap.c
@@ -0,0 +1,175 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: read-vs-mmap.c,v 1.1 2000/09/11 14:41:33 art Exp $");
+#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", 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;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", sz);
+ if (read (fd, buf, sz) != sz)
+ err (1, "read");
+ 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)
+{
+ 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)
+{
+ set_progname (argv[0]);
+
+ if (argc != 1)
+ debug = 1;
+
+ srand (time(NULL));
+
+ if (do_test (0))
+ return 1;
+ if (do_test (1))
+ return 2;
+
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/read-vs-mmap2.c b/usr.sbin/afs/src/tests/read-vs-mmap2.c
new file mode 100644
index 00000000000..d71e45066f9
--- /dev/null
+++ b/usr.sbin/afs/src/tests/read-vs-mmap2.c
@@ -0,0 +1,138 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: read-vs-mmap2.c,v 1.1 2000/09/11 14:41:33 art Exp $");
+#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", 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;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", sz);
+ if (read (fd, buf, sz) != sz)
+ err (1, "read");
+ 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;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/read-write.c b/usr.sbin/afs/src/tests/read-write.c
new file mode 100644
index 00000000000..ee1c7de7017
--- /dev/null
+++ b/usr.sbin/afs/src/tests/read-write.c
@@ -0,0 +1,150 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: read-write.c,v 1.1 2000/09/11 14:41:33 art Exp $");
+#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", 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", 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;
+
+ buf = malloc (sz);
+ if (buf == NULL)
+ err (1, "malloc %u", sz);
+ if (read(fd, buf, sz) != sz)
+ err (1, "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;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/readdir-vs-lstat.c b/usr.sbin/afs/src/tests/readdir-vs-lstat.c
new file mode 100644
index 00000000000..2d746fc7963
--- /dev/null
+++ b/usr.sbin/afs/src/tests/readdir-vs-lstat.c
@@ -0,0 +1,109 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: readdir-vs-lstat.c,v 1.1 2000/09/11 14:41:33 art Exp $");
+#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 = ".";
+
+ set_progname (argv[0]);
+
+ if (argc > 2)
+ usage (1);
+
+ if (argc > 1)
+ name = argv[1];
+
+ return verify_inodes (name);
+}
diff --git a/usr.sbin/afs/src/tests/readfile-wo-create b/usr.sbin/afs/src/tests/readfile-wo-create
new file mode 100644
index 00000000000..209fd344927
--- /dev/null
+++ b/usr.sbin/afs/src/tests/readfile-wo-create
@@ -0,0 +1,3 @@
+#!/bin/sh
+FOO=`cat $AFSROOT/stacken.kth.se/ftp/pub/arla/tests/used-by-arla-check`
+test "X"$FOO = "Xfoo" || exit 1
diff --git a/usr.sbin/afs/src/tests/rename-under-feet.c b/usr.sbin/afs/src/tests/rename-under-feet.c
new file mode 100644
index 00000000000..455dcfabdd9
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rename-under-feet.c
@@ -0,0 +1,166 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <roken.h>
+
+#include <err.h>
+
+RCSID("$Id: rename-under-feet.c,v 1.1 2000/09/11 14:41:33 art Exp $");
+
+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(getcwd (buf, sizeof(buf)) == NULL)
+ err (1, "getcwd");
+ 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;
+
+ set_progname (argv[0]);
+
+ 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 != 1)
+ err (1, "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)
+ return 0;
+ else
+ return 1;
+}
diff --git a/usr.sbin/afs/src/tests/rename1 b/usr.sbin/afs/src/tests/rename1
new file mode 100644
index 00000000000..f210d5ec2d1
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rename1
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: rename1,v 1.1 2000/09/11 14:41:33 art Exp $
+touch foo || exit 1
+mv foo bar || exit 1
+test -f foo && exit 1
+test -f bar || exit 1
+rm bar || exit 1
diff --git a/usr.sbin/afs/src/tests/rename2 b/usr.sbin/afs/src/tests/rename2
new file mode 100644
index 00000000000..ddddfeb9199
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rename2
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: rename2,v 1.1 2000/09/11 14:41:33 art Exp $
+touch foo bar || exit 1
+mv foo bar || exit 1
+test -f foo && exit 1
+test -f bar || exit 1
+rm bar || exit 1
diff --git a/usr.sbin/afs/src/tests/rename3 b/usr.sbin/afs/src/tests/rename3
new file mode 100644
index 00000000000..3233bad24c7
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rename3
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $Id: rename3,v 1.1 2000/09/11 14:41:33 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/rename4 b/usr.sbin/afs/src/tests/rename4
new file mode 100644
index 00000000000..370107b7d06
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rename4
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id: rename4,v 1.1 2000/09/11 14:41:34 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/rename5.c b/usr.sbin/afs/src/tests/rename5.c
new file mode 100644
index 00000000000..33300ef0371
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rename5.c
@@ -0,0 +1,114 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <roken.h>
+
+#include <err.h>
+
+RCSID("$Id: rename5.c,v 1.1 2000/09/11 14:41:34 art Exp $");
+
+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;
+
+ set_progname (argv[0]);
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/rm-rf.c b/usr.sbin/afs/src/tests/rm-rf.c
new file mode 100644
index 00000000000..6d1481073ca
--- /dev/null
+++ b/usr.sbin/afs/src/tests/rm-rf.c
@@ -0,0 +1,150 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <fs.h>
+#include <arlalib.h>
+#include <kafs.h>
+
+#include <err.h>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: rm-rf.c,v 1.1 2000/09/11 14:41:34 art Exp $");
+#endif
+
+static void
+kill_one (const char *filename);
+
+static void
+kill_dir (const char *dirname);
+
+static void
+do_dir (const char *dirname);
+
+#ifdef KERBEROS
+static int has_afs = 0;
+#endif
+
+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;
+
+#ifdef KERBEROS
+ if (has_afs) {
+ ret = fs_rmmount (dirname);
+ if (ret == 0)
+ return;
+ }
+#endif
+
+ 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)
+{
+ set_progname (argv[0]);
+
+#ifdef KERBEROS
+ has_afs = k_hasafs();
+#endif
+
+ if (argc < 2)
+ errx (1, "usage: %s directory [...]", argv[0]);
+ while (argc >= 2) {
+ do_dir (argv[1]);
+ argc--;
+ argv++;
+ }
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/run-tests.in b/usr.sbin/afs/src/tests/run-tests.in
new file mode 100644
index 00000000000..c5f1fc3dbd8
--- /dev/null
+++ b/usr.sbin/afs/src/tests/run-tests.in
@@ -0,0 +1,235 @@
+#!/bin/sh
+#
+# $Id: run-tests.in,v 1.1 2000/09/11 14:41:34 art Exp $
+#
+srcdir=@srcdir@
+objdir=`pwd`
+SHELL=/bin/sh
+VERSION=@VERSION@
+PACKAGE=@PACKAGE@
+host=@host@
+
+AFSROOT=${AFSROOT-/afs}
+export AFSROOT
+
+ARLA_TESTS="creat1 \
+ mkdir1 \
+ mkdir2 \
+ symlink \
+ hardlink1 \
+ hardlink2 \
+ touch1 \
+ write1 \
+ write2 \
+ append1 \
+ rename1 \
+ rename2 \
+ rename3 \
+ rename4 \
+ rename5 \
+ rename-under-feet \
+ mkdir-lnk \
+ mkm-rmm \
+ fs-sa-la \
+ dd \
+ exec \
+ ga-test \
+ kotest \
+ readfile-wo-create \
+ mountpoint \
+ strange-characters \
+ strange-characters-c \
+ strange-other-characters \
+ pine \
+ write-ro-file \
+ hello-world \
+ write-ucc \
+ utime-dir \
+ append-over-page \
+ mmap-shared-write \
+ read-vs-mmap \
+ read-vs-mmap2 \
+ mmap-vs-read \
+ mmap-vs-read2 \
+ read-write \
+ mmap-and-read \
+ checkpwd \
+ exit-wo-close \
+ dir-size-mismatch \
+ parallel1 \
+ getdents-and-unlink1 \
+ getdents-and-unlink2 \
+ getdents-and-unlink3 \
+ build-gdb \
+ large-dir-16384 \
+ large-dir-extra \
+ find-linux \
+ find-and-cat-netbsd \
+ test-gunzip-gnu-mirror \
+ build-emacs \
+ build-emacs-j \
+ untar-emacs \
+ copy-and-diff-gnu-mirror \
+ setpag \
+ create-remove-files \
+ create-remove-dirs \
+ fcachesize-dir \
+ fcachesize-file-small \
+ compare-inums \
+ compare-inum-mp"
+
+# visit-volumes \
+
+
+# discon-create \
+# discon-echo \
+# discon-touch1 \
+# discon-touch2 \
+# discon-mkdir \
+# discon-mkdir2 \
+# discon-tar1 \
+# discon-tar2 \
+
+# you need to be root to run this: setgroups
+
+MILKO_TESTS="mkdir \
+ many-dirs \
+ many-files \
+ many-symlinks \
+ many-files-with-content \
+ many-stores \
+ many-fetchs \
+ deep-tree \
+ deep-tree2 \
+ boot-strap-arla"
+
+TESTS="$ARLA_TESTS"
+TEST_MODE="arla"
+
+linebreak=":-------------------------------;"
+
+PARALLELL=
+FAST=
+PRINT_CACHESIZE=
+usage="Usage: $0 [-arla|-milko] [-all] [-fast] [-j] [-verbose] [-x] tests ..."
+while true
+do
+ case $1 in
+ -all) ALL=yes;;
+ -fast) FAST=yes;;
+ -j) PARALLELL="&";;
+ -verbose) VERBOSE=yes;;
+ -x) SHELLVERBOSE="-x";;
+ -p) PRINT_CACHESIZE="yes";;
+ -arla) TESTS="$ARLA_TESTS";TEST_MODE="arla";;
+ -milko) TESTS="$MILKO_TESTS";TEST_MODE="milko";;
+ -help|--help) echo $usage;
+ echo "arla tests available: $linebreak"; for a in "$ARLA_TESTS"; do echo $a ; done;
+ echo "milko tests available: $linebreak"; for a in "$MILKO_TESTS"; do echo $a ; done;
+ exit 0;;
+ -version|--version) echo "$0 $Id: run-tests.in,v 1.1 2000/09/11 14:41:34 art Exp $"; 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 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 "${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)."
+ 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
diff --git a/usr.sbin/afs/src/tests/setgroups b/usr.sbin/afs/src/tests/setgroups
new file mode 100644
index 00000000000..865724b7da7
--- /dev/null
+++ b/usr.sbin/afs/src/tests/setgroups
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: setgroups,v 1.1 2000/09/11 14:41:34 art Exp $
+
+$objdir/test-setgroups nobody 1>&4
diff --git a/usr.sbin/afs/src/tests/setpag b/usr.sbin/afs/src/tests/setpag
new file mode 100644
index 00000000000..88eb580bfe1
--- /dev/null
+++ b/usr.sbin/afs/src/tests/setpag
@@ -0,0 +1,4 @@
+#!/bin/sh
+# $Id: setpag,v 1.1 2000/09/11 14:41:34 art Exp $
+
+$objdir/test-setpag 1>&4
diff --git a/usr.sbin/afs/src/tests/shallow-tree b/usr.sbin/afs/src/tests/shallow-tree
new file mode 100644
index 00000000000..b4692032818
--- /dev/null
+++ b/usr.sbin/afs/src/tests/shallow-tree
@@ -0,0 +1,5 @@
+#!/bin/sh
+# $Id: shallow-tree,v 1.1 2000/09/11 14:41:34 art Exp $
+
+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
diff --git a/usr.sbin/afs/src/tests/strange-characters b/usr.sbin/afs/src/tests/strange-characters
new file mode 100644
index 00000000000..d339c6a9bf0
--- /dev/null
+++ b/usr.sbin/afs/src/tests/strange-characters
@@ -0,0 +1,7 @@
+#!/bin/sh
+# $Id: strange-characters,v 1.1 2000/09/11 14:41:34 art Exp $
+for i in å ä ö åäö; do
+ touch $i || exit 1
+ test -f $i || exit 1
+ rm $i || exit 1
+done
diff --git a/usr.sbin/afs/src/tests/strange-characters-c.c b/usr.sbin/afs/src/tests/strange-characters-c.c
new file mode 100644
index 00000000000..472e107901b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/strange-characters-c.c
@@ -0,0 +1,100 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: strange-characters-c.c,v 1.1 2000/09/11 14:41:34 art Exp $");
+#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 = "åäö";
+
+ set_progname (argv[0]);
+
+ if (argc != 1)
+ usage (1);
+
+ creat_file (file);
+ look_at_file (file);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/strange-other-characters b/usr.sbin/afs/src/tests/strange-other-characters
new file mode 100644
index 00000000000..28b9aa9e4eb
--- /dev/null
+++ b/usr.sbin/afs/src/tests/strange-other-characters
@@ -0,0 +1,5 @@
+#!/bin/sh
+# $Id: strange-other-characters,v 1.1 2000/09/11 14:41:34 art Exp $
+dir=$AFSROOT/stacken.kth.se/ftp/pub/arla/tests
+
+test -f $dir/åäö || exit 1
diff --git a/usr.sbin/afs/src/tests/symlink.c b/usr.sbin/afs/src/tests/symlink.c
new file mode 100644
index 00000000000..dccbf6232aa
--- /dev/null
+++ b/usr.sbin/afs/src/tests/symlink.c
@@ -0,0 +1,79 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: symlink.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+#endif
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ struct stat sb;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/test-gunzip-gnu-mirror b/usr.sbin/afs/src/tests/test-gunzip-gnu-mirror
new file mode 100644
index 00000000000..94c6df3b532
--- /dev/null
+++ b/usr.sbin/afs/src/tests/test-gunzip-gnu-mirror
@@ -0,0 +1,14 @@
+#!/bin/sh
+# $Id: test-gunzip-gnu-mirror,v 1.1 2000/09/11 14:41:35 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/test-parallel1.c b/usr.sbin/afs/src/tests/test-parallel1.c
new file mode 100644
index 00000000000..099a9a65ee6
--- /dev/null
+++ b/usr.sbin/afs/src/tests/test-parallel1.c
@@ -0,0 +1,108 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <roken.h>
+
+#include <atypes.h>
+#include <kafs.h>
+
+#ifdef RCSID
+RCSID("$Id: test-parallel1.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/test-parallel2.c b/usr.sbin/afs/src/tests/test-parallel2.c
new file mode 100644
index 00000000000..de580ae793d
--- /dev/null
+++ b/usr.sbin/afs/src/tests/test-parallel2.c
@@ -0,0 +1,190 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <roken.h>
+
+#include <atypes.h>
+#include <kafs.h>
+
+#ifdef RCSID
+RCSID("$Id: test-parallel2.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+#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;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/test-setgroups.c b/usr.sbin/afs/src/tests/test-setgroups.c
new file mode 100644
index 00000000000..1a21d07ff8f
--- /dev/null
+++ b/usr.sbin/afs/src/tests/test-setgroups.c
@@ -0,0 +1,151 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#include <atypes.h>
+#include <kafs.h>
+
+#ifdef RCSID
+RCSID("$Id: test-setgroups.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+#endif
+
+#ifdef KERBEROS
+
+#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;
+
+ set_progname (argv[0]);
+
+ if (argc != 2)
+ errx (1, "Usage: %s user", argv[0]);
+ user = argv[1];
+
+ if (!k_hasafs ())
+ errx (1, "No AFS?");
+
+ this_pwd = getpwuid (getuid ());
+ if (this_pwd == NULL)
+ errx (1, "Who are you?");
+ this_user = estrdup (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 k_setpag()\n");
+ ret = k_setpag ();
+ if (ret < 0)
+ err (1, "k_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;
+}
+
+#else /* !KERBEROS */
+
+int
+main (int argc, char **argv)
+{
+ set_progname (argv[0]);
+
+ errx (1, "no kafs");
+}
+
+#endif /* !KERBEROS */
diff --git a/usr.sbin/afs/src/tests/test-setpag.c b/usr.sbin/afs/src/tests/test-setpag.c
new file mode 100644
index 00000000000..3d0dea6c91a
--- /dev/null
+++ b/usr.sbin/afs/src/tests/test-setpag.c
@@ -0,0 +1,144 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#include <atypes.h>
+#include <kafs.h>
+
+#ifdef RCSID
+RCSID("$Id: test-setpag.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+#endif
+
+#ifdef KERBEROS
+
+#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;
+
+ set_progname (argv[0]);
+
+ if (argc != 1)
+ errx (1, "Usage: %s", argv[0]);
+
+ if (!k_hasafs ())
+ errx (1, "No AFS?");
+
+ 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 = k_setpag ();
+ if (ret < 0)
+ err (1, "k_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;
+ }
+}
+
+#else /* !KERBEROS */
+
+int
+main (int argc, char **argv)
+{
+ set_progname (argv[0]);
+
+ errx (1, "no kafs");
+}
+
+#endif /* !KERBEROS */
diff --git a/usr.sbin/afs/src/tests/touch1 b/usr.sbin/afs/src/tests/touch1
new file mode 100644
index 00000000000..61badc5dc6a
--- /dev/null
+++ b/usr.sbin/afs/src/tests/touch1
@@ -0,0 +1,4 @@
+#!/bin/sh
+touch foobar || exit 1
+test -f foobar || exit 1
+rm foobar || exit 1
diff --git a/usr.sbin/afs/src/tests/untar-emacs b/usr.sbin/afs/src/tests/untar-emacs
new file mode 100644
index 00000000000..78b4a569a0c
--- /dev/null
+++ b/usr.sbin/afs/src/tests/untar-emacs
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $Id: untar-emacs,v 1.1 2000/09/11 14:41:35 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/utime-dir.c b/usr.sbin/afs/src/tests/utime-dir.c
new file mode 100644
index 00000000000..6f44e30ba36
--- /dev/null
+++ b/usr.sbin/afs/src/tests/utime-dir.c
@@ -0,0 +1,86 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+RCSID("$Id: utime-dir.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+
+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";
+
+ set_progname (argv[0]);
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/visit-volumes b/usr.sbin/afs/src/tests/visit-volumes
new file mode 100644
index 00000000000..49cf953f9ec
--- /dev/null
+++ b/usr.sbin/afs/src/tests/visit-volumes
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $Id: visit-volumes,v 1.1 2000/09/11 14:41:35 art Exp $
+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
diff --git a/usr.sbin/afs/src/tests/write-closed.c b/usr.sbin/afs/src/tests/write-closed.c
new file mode 100644
index 00000000000..5aa765ee326
--- /dev/null
+++ b/usr.sbin/afs/src/tests/write-closed.c
@@ -0,0 +1,104 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <roken.h>
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+RCSID("$Id: write-closed.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+
+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";
+
+ set_progname (argv[0]);
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/write-closed2.c b/usr.sbin/afs/src/tests/write-closed2.c
new file mode 100644
index 00000000000..15356deec3f
--- /dev/null
+++ b/usr.sbin/afs/src/tests/write-closed2.c
@@ -0,0 +1,139 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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 <atypes.h>
+#include <kafs.h>
+
+#include <roken.h>
+
+#include <err.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+RCSID("$Id: write-closed2.c,v 1.1 2000/09/11 14:41:35 art Exp $");
+
+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 k_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";
+
+ set_progname (argv[0]);
+
+ if (!k_hasafs())
+ errx (1, "!k_hasafs");
+
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/write-ro-file.c b/usr.sbin/afs/src/tests/write-ro-file.c
new file mode 100644
index 00000000000..e3cb769a119
--- /dev/null
+++ b/usr.sbin/afs/src/tests/write-ro-file.c
@@ -0,0 +1,77 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+#ifdef RCSID
+RCSID("$Id: write-ro-file.c,v 1.1 2000/09/11 14:41:36 art Exp $");
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ int ret;
+
+ set_progname (argv[0]);
+
+ 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;
+}
diff --git a/usr.sbin/afs/src/tests/write-ucc.c b/usr.sbin/afs/src/tests/write-ucc.c
new file mode 100644
index 00000000000..3c207d81c2b
--- /dev/null
+++ b/usr.sbin/afs/src/tests/write-ucc.c
@@ -0,0 +1,110 @@
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. 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>
+#include <roken.h>
+
+RCSID("$Id: write-ucc.c,v 1.1 2000/09/11 14:41:36 art Exp $");
+
+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";
+
+ set_progname (argv[0]);
+ if (argc != 1 && argc != 2)
+ errx (1, "usage: %s [file]", argv[0]);
+ if (argc == 2)
+ file = argv[1];
+ doit (file);
+ return 0;
+}
diff --git a/usr.sbin/afs/src/tests/write1 b/usr.sbin/afs/src/tests/write1
new file mode 100644
index 00000000000..00d386d9b11
--- /dev/null
+++ b/usr.sbin/afs/src/tests/write1
@@ -0,0 +1,4 @@
+#!/bin/sh
+echo hej > foo || exit 1
+if test X`cat foo` != X"hej"; then exit 1; fi
+rm foo || exit 1
diff --git a/usr.sbin/afs/src/tests/write2 b/usr.sbin/afs/src/tests/write2
new file mode 100644
index 00000000000..8d15d9a7a95
--- /dev/null
+++ b/usr.sbin/afs/src/tests/write2
@@ -0,0 +1,6 @@
+#!/bin/sh
+echo hopp > foo || exit 1
+if test `cat foo` != "hopp"; then exit 1; fi
+echo hej > foo || exit 1
+if test `cat foo` != "hej"; then exit 1; fi
+rm foo || exit 1
diff --git a/usr.sbin/afs/src/util/Makefile.in b/usr.sbin/afs/src/util/Makefile.in
new file mode 100644
index 00000000000..b5192951b35
--- /dev/null
+++ b/usr.sbin/afs/src/util/Makefile.in
@@ -0,0 +1,123 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:36 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+MAKEDEPEND = makedepend
+ETAGS = etags
+LIBS = -L../lib/roken -lroken @LIBS@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+libdir = @libdir@
+
+# Profiler flags
+PROF =
+
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+REALCFLAGS = $(CFLAGS) $(DEFS) \
+ -I$(srcdir) -I../include -I$(srcdir)/../include $(PROF)
+
+PROGS = mmaptime_test util-tester heaptest
+LIB = libutil.a
+
+HEADERS = bool.h hash.h heap.h list.h log.h
+
+SRCS = \
+ $(mmaptime_test_SRCS) \
+ $(libutil_SRCS) \
+ $(util_tester_SRCS) \
+ $(heaptest_SRCS)
+
+mmaptime_test_PROG= mmaptime_test
+mmaptime_test_SRCS= mmaptime.c mmaptime_test.c
+mmaptime_test_OBJS= mmaptime.o mmaptime_test.o
+
+libutil_SRCS = hash.c list.c log.c \
+ mmaptime.c heap.c
+libutil_OBJS = hash.o list.o log.o \
+ mmaptime.o heap.o
+
+util_tester_PROG = util-tester
+
+util_tester_SRCS = util-tester.c
+
+util_tester_OBJS = util-tester.o
+
+heaptest_PROG = heaptest
+
+heaptest_SRCS = heaptest.c
+
+heaptest_OBJS = heaptest.o
+
+.PHONY: all install uninstall depend tags clean check
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(REALCFLAGS) $<
+
+all: $(PROGS) $(LIB)
+
+$(mmaptime_test_PROG): $(mmaptime_test_OBJS)
+ $(CC) -o $@ $(mmaptime_test_OBJS) $(LIBS) $(PROF)
+
+libutil_LIB: $(libutil_OBJS)
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+ $(INSTALL_DATA) $(LIB) $(DESTDIR)$(libdir)/$(LIB)
+ for i in $(HEADERS); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir)/$$i; \
+ done
+
+uninstall:
+ rm -f $(DESTDIR)$(libdir)/$(LIB)
+ for i in $(HEADERS); do \
+ rm -f $(DESTDIR)$(includedir)/$$i; \
+ done
+
+libutil.a: $(libutil_OBJS)
+ $(AR) cr $@ $(libutil_OBJS)
+ $(RANLIB) $@
+
+$(util_tester_PROG): libutil.a $(util_tester_OBJS)
+ $(CC) -o $@ $(util_tester_OBJS) -L. -lutil $(LIBS) $(PROF)
+
+$(heaptest_PROG): libutil.a $(heaptest_OBJS)
+ $(CC) -o $@ $(heaptest_OBJS) -L. -lutil $(LIBS) $(PROF)
+
+check: all
+ ./$(heaptest_PROG) 100
+ ./$(util_tester_PROG) >/dev/null
+
+depend: $(SRCS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=util/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+tags: TAGS
+
+TAGS: $(SRCS)
+ $(ETAGS) -t $(SRCS)
+
+clean:
+ rm -f $(OBJS) $(PROGS) libutil.a *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile
+
+realclean: distclean
+ rm -f TAGS
diff --git a/usr.sbin/afs/src/util/log_log.3 b/usr.sbin/afs/src/util/log_log.3
new file mode 100644
index 00000000000..0d5287d8f9d
--- /dev/null
+++ b/usr.sbin/afs/src/util/log_log.3
@@ -0,0 +1,148 @@
+.\" Copyright (c) 2000 Kungliga Tekniska Högskolan
+.\" $Id: log_log.3,v 1.1 2000/09/11 14:41:39 art Exp $
+.Dd August 24, 2000
+.Dt LOG_LOG
+.Os UTIL
+.Sh NAME
+.Nm log_log ,
+.Nm log_vlog ,
+.Nm log_open ,
+.Nm log_close ,
+.Nm log_unit_init ,
+.Nm log_unit_free ,
+.Nm log_set_mask ,
+.Nm log_get_mask ,
+.Nm log_mask2str ,
+.Nm log_set_mask_str
+.Nd provides unified logging
+.Sh SYNOPSIS
+.Fd #include <parse_units.h>
+.Fd #include <log.h>
+.Fo "void log_log"
+.Fa "Log_unit *unit"
+.Fa "unsigned level"
+.Fa "const char *fmt"
+.Fa ...
+.Fc
+.Fo "void log_vlog"
+.Fa "Log_unit *unit"
+.Fa "unsigned level"
+.Fa "const char *fmt"
+.Fa "va_list args"
+.Fc
+.Fo "Log_method *log_open"
+.Fa "char *progname"
+.Fa "char *fname"
+.Fc
+.Fo "void log_close"
+.Fa "Log_method *method"
+.Fc
+.Fo "Log_unit *log_unit_init"
+.Fa "Log_method *method"
+.Fa "const char *name"
+.Fa "struct units *lognames"
+.Fa "unsigned long default_mask"
+.Fc
+.Fo "void log_unit_free"
+.Fa "Log_method *method"
+.Fa "Log_unit *unit"
+.Fc
+.Fo "void log_set_mask"
+.Fa "Log_unit *unit"
+.Fa "unsigned long mask"
+.Fc
+.Fo "unsigned log_get_mask"
+.Fa "Log_unit *unit"
+.Fc
+.Fo "void log_mask2str"
+.Fa "Log_method *method"
+.Fa "Log_unit *unit"
+.Fa "char *buf"
+.Fa "size_t sz"
+.Fc
+.Fo "void log_set_mask_str"
+.Fa "Log_method *method"
+.Fa "Log_unit *default_unit"
+.Fa "const char *str"
+.Fc
+.Sh DESCRIPTION
+.Nm log_log
+will let you have a unified logging system throu-out your whole project.
+No more strange errnos like
+.Er EINVAL
+returned from libraries since they can print to stderr (not knowing
+what fd will be connected to fd number 2).
+.Pp
+.Fn log_open
+will open a Log_method that all Log_units will log though, Log_method
+controls to what device the log is sent. Logging devices, passed in
+fname, are syslog, /dev/stderr, or a file.
+.Pp
+.Fn log_close
+closeses the Log_method and assosiated Log_units.
+.Pp
+.Fn log_unit_init
+will return a logging unit, that is used by a subsystem.
+.Pp
+.Fn log_unit_free
+will free a logging unit allocated by
+.Fn log_unit_init .
+.Pp
+.Fn log_set_mask
+set the logging mask for a logging unit.
+.Pp
+.Fn log_get_mask
+get the logging mask for a logging unit.
+.Pp
+.Fn log_mask2str
+convert the longing mask for `unit' (or all if this is NULL), to a
+string that can be printed. The string can be parsed by
+.Fn log_set_mask_str .
+.Pp
+.Fn log_set_mask_str
+will set the mask for `default_unit' (or all if this is NULL).
+.Sh EXAMPLE
+.Bd -literal
+#include <parse_units.h>
+#include <log.h>
+#include <err.h>
+
+enum { A_WARNING = 1, A_DEBUG = 2 };
+
+struct units u_units[] = {
+ { "debug", A_DEBUG },
+ { "warning", A_WARNING },
+ { NULL, 0 }
+};
+
+int
+main (int argc, char **argv)
+{
+ Log_method *m;
+ Log_unit *u;
+ char buf[1024];
+
+ m = log_open ("log-tester", "/dev/stderr");
+ if (m == NULL)
+ errx (1, "log_open");
+
+ u = log_unit_init (m, "test-foo", u_units, A_WARNING);
+ if (u == NULL)
+ errx (1, "log_unit_init");
+
+ log_log (u, A_WARNING, "this should show");
+ log_log (u, A_DEBUG, "this should NOT show");
+
+ log_mask2str (m, NULL, buf, sizeof(buf));
+ printf ("logmask: %s\\n", buf);
+
+ log_close (m);
+
+ return 0;
+}
+.Ed
+.Sh BUGS
+Should maybe include a log_logx version.
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr syslogd 8
diff --git a/usr.sbin/afs/src/ydr/Makefile.in b/usr.sbin/afs/src/ydr/Makefile.in
new file mode 100644
index 00000000000..bc1ef1731e4
--- /dev/null
+++ b/usr.sbin/afs/src/ydr/Makefile.in
@@ -0,0 +1,99 @@
+# $Id: Makefile.in,v 1.1 2000/09/11 14:41:40 art Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+YACC = @YACC@
+LEX = @LEX@
+YFLAGS = -d
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+ETAGS = etags
+MAKEDEPEND = makedepend
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+
+DEFS = @DEFS@ -DCPP="\"@CPP@\""
+
+SHELL = /bin/sh
+
+CFLAGS = @CFLAGS@
+REALCFLAGS = -I$(srcdir) \
+ -I$(srcdir)/../util \
+ -I../include \
+ -I$(srcdir)/../include \
+ -I. \
+ $(CFLAGS) $(DEFS)
+ydr_SRCS = parse.y lex.l main.c symbol.c types.c output.c
+ydr_OBJS = parse.o lex.o main.o symbol.o types.o output.o
+HDRS = sym.h types.h output.h lex.h parse.h
+bin_PROGRAMS = ydr
+
+SRCS = $(ydr_SRCS)
+OBJS = $(ydr_OBJS)
+
+all: $(bin_PROGRAMS)
+
+.PHONY: all install uninstall depend tags clean
+
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(REALCFLAGS) $<
+
+.l.c:
+ $(LEX) $(LFLAGS) -t $< >$@
+
+install: all
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ for x in $(bin_PROGRAMS); do \
+ f=`echo $$x | sed '$(transform)'`; \
+ $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/$$f; \
+ done
+
+uninstall:
+ for x in $(bin_PROGRAMS); do \
+ f=`echo $$x | sed '$(transform)'`; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+ydr: $(ydr_OBJS) ../util/libutil.a
+ $(CC) $(LDFLAGS) -o $@ $(ydr_OBJS) ../util/libutil.a -L../lib/roken -lroken $(LIBS)
+
+parse.c: parse.h
+parse.h: parse.y
+ $(YACC) $(YFLAGS) $(srcdir)/parse.y
+ mv -f y.tab.h parse.h
+ mv -f y.tab.c parse.c
+
+lex.c: lex.l
+ $(LEX) $(srcdir)/lex.l
+ mv -f lex.yy.c lex.c
+
+lex.o: parse.h
+
+Makefile: Makefile.in ../config.status
+ cd ..; CONFIG_FILES=ydr/Makefile CONFIG_HEADERS= $(SHELL) config.status
+
+depend: $(SRCS) $(HDRS)
+ $(MAKEDEPEND) -- $(REALCFLAGS) -- $^
+
+tags: TAGS
+
+TAGS: $(SRCS) $(HDRS)
+ $(ETAGS) -t $(SRCS) $(HDRS)
+
+clean :
+ rm -f $(OBJS) $(bin_PROGRAMS) lex.c parse.c parse.h *~ *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status
+
+realclean: distclean
+ rm -f TAGS