├── .github
└── workflows
│ ├── build.yml
│ ├── docker-deploy.yml
│ └── macos-pkg.yml
├── .gitignore
├── .gitmodules
├── COPYRIGHT
├── Dockerfile
├── EXCLUDE
├── Makefile.in
├── OS_X
├── License.rtf
├── ReadMe.rtf
├── Welcome.rtf
├── background.tiff
└── distribution.xml
├── README.md
├── SPEC
├── VERSION
├── aclocal.m4
├── applefile.c
├── applefile.h
├── argcargv.c
├── argcargv.h
├── base64.c
├── base64.h
├── bootstrap.sh
├── ca.sh
├── cksum.c
├── cksum.h
├── code.c
├── code.h
├── command.c
├── command.h
├── config.guess
├── config.h.in
├── config.sub
├── configure.ac
├── connect.c
├── connect.h
├── contrib
├── fsspy.c
└── specialist
├── daemon.c
├── docker-compose.yml
├── docker
├── entrypoint
└── etc
│ ├── rsyslog.d
│ ├── imux.conf
│ └── stdout.conf
│ └── rsyslogd.conf
├── fsdiff.c
├── hardlink.c
├── install-sh
├── ktcheck.c
├── lapply.c
├── largefile.h
├── lcksum.c
├── lcreate.c
├── lfdiff.c
├── list.c
├── list.h
├── llist.c
├── llist.h
├── lmerge.c
├── lmerge.h
├── logname.c
├── logname.h
├── lsize.c
├── lsort.c
├── man
├── applefile.5
├── fsdiff.1
├── ktcheck.1
├── lapply.1
├── lcksum.1
├── lcreate.1
├── lfdiff.1
├── lmerge.1
├── lsort.1
├── radmind.8
├── rash.1
├── repo.1
└── twhich.1
├── mkdirs.c
├── mkdirs.h
├── mkprefix.c
├── mkprefix.h
├── openssl_compat.c
├── openssl_compat.h
├── pathcmp.c
├── pathcmp.h
├── progress.c
├── progress.h
├── ra.sh
├── radstat.c
├── radstat.h
├── repo.c
├── report.c
├── report.h
├── retr.c
├── rmdirs.c
├── rmdirs.h
├── root.c
├── root.h
├── stor.c
├── t2pkg.c
├── tls.c
├── tls.h
├── transcript.c
├── transcript.h
├── twhich.c
├── update.c
├── update.h
├── version.c
├── wildcard.c
└── wildcard.h
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on:
3 | push:
4 | branches: [ master ]
5 | pull_request:
6 | branches: [ master ]
7 | jobs:
8 | build:
9 | strategy:
10 | matrix:
11 | os: [ ubuntu-18.04, ubuntu-20.04, macos-10.15, macos-11 ]
12 | name: ${{ matrix.os }} radmind
13 | runs-on: ${{ matrix.os }}
14 |
15 | steps:
16 | - name: Checkout sources
17 | uses: actions/checkout@v2
18 | - name: Configure
19 | run: |
20 | if [ "$RUNNER_OS" == "macOS" ]; then
21 | brew install openssl
22 | sudo ln -s /usr/local/opt/openssl /usr/local/openssl
23 | fi
24 | sh bootstrap.sh
25 | ./configure
26 | - name: Build
27 | run: |
28 | make
29 | - name: Install
30 | run: |
31 | sudo make install
32 | - name: Test
33 | run: |
34 | fsdiff -c sha1 -K /dev/null .
35 |
36 |
--------------------------------------------------------------------------------
/.github/workflows/docker-deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy docker
2 | on:
3 | workflow_dispatch
4 | env:
5 | REGISTRY: ghcr.io
6 | IMAGE_NAME: ${{ github.repository }}
7 | jobs:
8 | build-and-push-image:
9 | runs-on: ubuntu-latest
10 | permissions:
11 | contents: read
12 | packages: write
13 | steps:
14 | - name: Check Out Repo
15 | uses: actions/checkout@v2
16 | - name: Extract metadata (tags, labels) for Docker
17 | id: meta
18 | uses: docker/metadata-action@v3
19 | with:
20 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
21 | - name: Login
22 | uses: docker/login-action@v1
23 | with:
24 | registry: ${{ env.REGISTRY }}
25 | username: ${{ github.actor }}
26 | password: ${{ secrets.GITHUB_TOKEN }}
27 | - name: Set up QEMU
28 | uses: docker/setup-qemu-action@v1
29 | - name: Set up Docker Buildx
30 | id: buildx
31 | uses: docker/setup-buildx-action@v1
32 | - name: Cache docker layers
33 | uses: actions/cache@v2
34 | with:
35 | path: /tmp/.buildx-cache
36 | key: ${{ runner.os }}-buildx-${{ github.sha }}
37 | restore-keys: |
38 | ${{ runner.os }}-buildx-
39 | - name: Build and push
40 | id: docker_build
41 | uses: docker/build-push-action@v2
42 | with:
43 | context: .
44 | builder: ${{ steps.buildx.outputs.name }}
45 | platforms: linux/amd64,linux/arm64
46 | push: true
47 | tags: 1.14.1a
48 | labels: ${{ steps.meta.outputs.labels }}
49 | cache-from: type=local,src=/tmp/.buildx-cache
50 | cache-to: type=local,dest=/tmp/.buildx-cache
51 | - name: Image digest
52 | run: echo ${{ steps.docker_build.outputs.digest }}
53 |
--------------------------------------------------------------------------------
/.github/workflows/macos-pkg.yml:
--------------------------------------------------------------------------------
1 | name: Build Pkg
2 | on:
3 | workflow_dispatch
4 | jobs:
5 | build-pkg:
6 | strategy:
7 | matrix:
8 | os: [ macos-10.15 ]
9 | name: ${{ matrix.os }} radmind
10 | runs-on: ${{ matrix.os }}
11 | steps:
12 | - name: Checkout sources
13 | uses: actions/checkout@v2
14 | - name: Configure
15 | run: |
16 | if [ "$RUNNER_OS" == "macOS" ]; then
17 | brew install openssl
18 | sudo ln -s /usr/local/opt/openssl /usr/local/openssl
19 | fi
20 | sh bootstrap.sh
21 | ./configure
22 | - name: make package
23 | run: |
24 | make package
25 | - name: Upload to GitHub Release
26 | uses: svenstaro/upload-release-action@v2
27 | with:
28 | repo_token: ${{ secrets.GITHUB_TOKEN }}
29 | file: "../RadmindTools-*.pkg"
30 | file_glob: true
31 | tag: ${{ github.ref }}
32 | overwrite: true
33 | asset_name: RadmindTools.pkg
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Autoconf Generated Files #
2 | ############################
3 | autom4te.cache
4 | configure
5 |
6 | # Configure Generated Files #
7 | #############################
8 | Makefile
9 | config.h
10 | config.log
11 | config.status
12 |
13 | # Compiled Files #
14 | ##################
15 | *.o
16 | fsdiff
17 | ktcheck
18 | lapply
19 | lcksum
20 | lcreate
21 | lfdiff
22 | lmerge
23 | lsort
24 | radmind
25 | repo
26 | twhich
27 |
28 | # macOS garbage #
29 | #################
30 | .DS_Store
31 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "libsnet"]
2 | path = libsnet
3 | url = git://libsnet.git.sourceforge.net/gitroot/libsnet/libsnet
4 |
--------------------------------------------------------------------------------
/COPYRIGHT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2003 Regents of The University of Michigan.
2 | All Rights Reserved.
3 |
4 | Permission to use, copy, modify, and distribute this software and
5 | its documentation for any purpose and without fee is hereby granted,
6 | provided that the above copyright notice appears in all copies and
7 | that both that copyright notice and this permission notice appear
8 | in supporting documentation, and that the name of The University
9 | of Michigan not be used in advertising or publicity pertaining to
10 | distribution of the software without specific, written prior
11 | permission. This software is supplied as is without expressed or
12 | implied warranties of any kind.
13 |
14 | Research Systems Unix Group
15 | The University of Michigan
16 | c/o Wesley Craig
17 | 4251 Plymouth Road B1F2, #2600
18 | Ann Arbor, MI 48105-2785
19 | radmind@umich.edu
20 | http://rsug.itd.umich.edu/software/radmind/
21 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:latest AS builder
2 |
3 | RUN apt-get update && \
4 | apt-get install -q -y \
5 | autoconf \
6 | git \
7 | gcc \
8 | libssl-dev \
9 | make \
10 | wget
11 |
12 | COPY . /radmind/
13 | COPY ./.git /radmind/.git/
14 | COPY ./.gitmodules /radmind/
15 |
16 | RUN cd radmind && \
17 | if [ -e radmind ]; then rm -r radmind; fi && \
18 | sh bootstrap.sh && \
19 | wget -O config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub' && \
20 | wget -O config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess' && \
21 | cp config.guess libsnet && \
22 | cp config.sub libsnet && \
23 | autoconf && \
24 | cd libsnet && \
25 | autoconf && \
26 | cd .. && \
27 | ./configure && \
28 | make && \
29 | make install && \
30 | mkdir -p /var/radmind/{cert,client,postapply,preapply}
31 |
32 | # Build rsyslog so we can grab omstdout.so
33 |
34 | RUN wget https://www.rsyslog.com/files/download/rsyslog/rsyslog-8.2112.0.tar.gz && \
35 | tar xzf rsyslog-8.2112.0.tar.gz && \
36 | cd rsyslog-8.2112.0 && \
37 | ln -snf /usr/share/zoneinfo/Europe/London /etc/localtime && echo Europe/London > /etc/timezone && \
38 | apt install -q -y \
39 | libcurl4-gnutls-dev \
40 | libestr-dev \
41 | libfastjson-dev \
42 | libgcrypt-dev \
43 | pkg-config \
44 | uuid-dev \
45 | zlib1g-dev && \
46 | ./configure --prefix=/usr --enable-omstdout && \
47 | make && \
48 | make install
49 |
50 | FROM ubuntu:latest
51 |
52 | RUN apt-get update && \
53 | apt-get install -y \
54 | libssl-dev
55 |
56 | # Add rsyslog (because radmind doesn't log to stdout but rsyslog can w/ omstdout)
57 |
58 | COPY ./docker/etc /etc/
59 | COPY --from=builder /usr/lib/rsyslog/omstdout.so /usr/local/lib/omstdout.so
60 | RUN apt-get install -y rsyslog && \
61 | mv /usr/local/lib/omstdout.so /lib/*-linux-gnu/rsyslog/ && \
62 | rm /etc/rsyslog.d/50-default.conf
63 |
64 |
65 | # Copy radmind
66 |
67 | COPY --from=builder /usr/local/ /usr/local/
68 | COPY docker/entrypoint /usr/local/bin/entrypoint
69 |
70 | ENTRYPOINT ["/usr/local/bin/entrypoint"]
71 |
--------------------------------------------------------------------------------
/EXCLUDE:
--------------------------------------------------------------------------------
1 | EXCLUDE
2 | .git
3 | CVS
4 | Makefile
5 | autom4te.cache
6 | config.log
7 | config.status
8 |
--------------------------------------------------------------------------------
/OS_X/License.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;}
4 | {\info
5 | {\title Copyright (c) 2003 Regents of The University of Michigan}
6 | {\author Patrick McNeal}
7 | {\*\company University of Michigan}}\margl359\margr359\vieww9000\viewh8400\viewkind0
8 | \deftab720
9 | \pard\pardeftab720\ql\qnatural
10 |
11 | \f0\b\fs24 \cf0 Copyright (c) 2003, 2007 Regents of The University of Michigan\
12 | All Rights Reserved
13 | \f1\b0 \
14 | \
15 | 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 appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of The University of Michigan not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. This software is supplied as is without expressed or implied warranties of any kind.\
16 | \
17 | Research Systems Unix Group\
18 | The University of Michigan\
19 | c/o Wesley Craig\
20 | 4251 Plymouth Road B1F2, #2600\
21 | Ann Arbor, MI 48105-2785\
22 | radmind@umich.edu\
23 | http://radmind.org}
--------------------------------------------------------------------------------
/OS_X/ReadMe.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;}
4 | \vieww8640\viewh9000\viewkind0
5 | \pard\ql\qnatural
6 |
7 | \f0\b\fs24 \cf0 About radmind
8 | \f1\b0 \
9 | Radmind is a set of tools that can be used to maintain systems and act as a tripwire for security purposes.\
10 | \
11 |
12 | \f0\b Change Log
13 | \f1\b0 \
14 | To see what has been changed in the version see the release notes on the Radmind SourceForge site https://sourceforge.net/projects/radmind/ .\
15 | \
16 |
17 | \f0\b Requirements\
18 |
19 | \f1\b0 This package require a Macintosh running Mac OS X 10.3 or later. To run radmind on prior versions of Mac OS X, you must download and build the source code.\
20 | \
21 |
22 | \f0\b Installing Radmind
23 | \f1\b0 \
24 | This package installs software into standard file locations. If you have moved /usr/local/bin, /usr/local/sbin, /usr/local/man or /private/var we recommend that you install from the source code rather than using this installer.\
25 | \
26 | You will need administrator privileges to install radmind. This installer installs all components of the radmind tools. To install the server startup item, you will need to run the Radmind Assistant, choose Run Setup Steps from the Session menu, and choose "I'm new, and I'd like to set up a radmind server" in the window.\
27 | \
28 |
29 | \f0\b Known Issues
30 | \f1\b0 \
31 | On OpenDarwin based systems, the message "hfs_bwrite: called with lock bit set" is logged when you are doing a high volume of writes to a volume.\
32 | \
33 |
34 | \f0\b Reporting Bugs\
35 |
36 | \f1\b0 Before submitting a bug report, check the Radmind bug tracker at https://sourceforge.net/tracker/?group_id=141444&atid=749492 to see if it has already been reported. If not, you can submit a detailed report. Include the version of the tools, the version of the OS, the version of the Radmind Assistant, any error messages or crashlogs created by the tools, and a list of the steps it takes to cause the bug.\
37 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
38 | \cf0 \
39 | \pard\ql\qnatural
40 |
41 | \f0\b \cf0 For more information\
42 |
43 | \f1\b0 For help using any of the radmind tools, see their man page. There is also an active archived mailing list. For more details, see the radmind website's Contact page: http://radmind.org/contact.html\
44 | \
45 | Visit the radmind web site at http://radmind.org\
46 | \
47 | Copyright (c) 2003, 2007 Regents of The University of Michigan\
48 | All Rights Reserved}
--------------------------------------------------------------------------------
/OS_X/Welcome.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\mac\ansicpg10000\cocoartf102
2 | {\fonttbl\f0\fswiss\fcharset77 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;}
4 | \vieww9000\viewh9000\viewkind0
5 | \pard\qc
6 |
7 | \f0\fs36 \cf0 Welcome to the Radmind tool installer. You will be guided through the necessary steps.
8 | \fs24 \
9 | }
--------------------------------------------------------------------------------
/OS_X/background.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Radmind/radmind/e30841e7de583e5c5412673ede5099399a4b501a/OS_X/background.tiff
--------------------------------------------------------------------------------
/OS_X/distribution.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 | RadmindTools.pkg
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Radmind
2 | =======
3 |
4 | Radmind is a suite of Unix command-line tools and a server designed to remotely administer the file systems of multiple Unix machines.
5 |
6 | Copyright (c) 2003 Regents of The University of Michigan.
7 | All Rights Reserved. See COPYRIGHT.
8 |
9 | ## Contents
10 |
11 | * [Quick Installation Instructions](#quick-installation-instructions)
12 | * [Detailed Installation Instructions](#detailed-installation-instructions)
13 | * [Configuring for Ubuntu 18.04](#configuring-for-ubuntu-1804)
14 | * [Configuring for CentOS 7](#configuring-for-centos-7)
15 | * [Configuring for FreeBSD 11](#configuring-for-freebsd-11)
16 | * [Configuring for RedHat 9](#configuring-for-redhat-9)
17 | * [Configuring for macOS](#configuring-for-macOS)
18 | * [Getting the Source](#getting-the-source)
19 | * [Configuring and Building](#configuring-and-building)
20 | * [Building an OS X Installer Package](#building-an-os-x-installer-package)
21 | * [Known Issues](#known-issues)
22 | * [More Information](#more-informatino)
23 | * [References](#references)
24 |
25 | ## Quick Installation Instructions
26 |
27 | From within the source directory:
28 |
29 | ```
30 | ./configure
31 | make
32 | make install
33 | ```
34 |
35 | ## Detailed Installation Instructions
36 |
37 | ### Configuring for Ubuntu 18.04
38 |
39 | These are the commands I had to run to get radmind to build using Vagrant and [generic/ubuntu1804](https://app.vagrantup.com/generic/boxes/ubuntu1804).
40 |
41 | ```
42 | sudo apt-get -y update
43 | sudo apt-get -y install gcc
44 | sudo apt-get -y install libssl-dev
45 | sudo apt-get -y install make
46 | sudo apt-get -y install autoconf
47 |
48 | ```
49 |
50 | ### Configuring for CentOS 7
51 |
52 | These are the commands I had to run to get radmind to build using Vagrant and [generic/centos7](https://app.vagrantup.com/generic/boxes/centos7).
53 |
54 | ```
55 | sudo yum -y update
56 | sudo yum -y install git
57 | sudo yum -y install openssl-devel.x86_64
58 | ```
59 |
60 | ### Configuring for FreeBSD 11
61 |
62 | These are the commands I had to run to get radmind to build using Vagrant and [generic/freebsd11](https://app.vagrantup.com/generic/boxes/freebsd11).
63 |
64 | ```
65 | sudo pkg update
66 | sudo pkg install -y git
67 | sudo pkg install -y autoconf
68 | ```
69 |
70 | ### Configuring for RedHat 9
71 |
72 | To properly build Radmind on RedHat 9 with SSL support, you have to specify the location of your Kerberos files:
73 |
74 | ```
75 | export CPPFLAGS=-I/usr/kerberos/include
76 | ```
77 |
78 | ### Configuring for macOS
79 |
80 | Last tested on 10.14 (using homebrew)
81 |
82 | - Install [Xcode](https://developer.apple.com/xcode/).
83 | - Install [brew](https://brew.sh).
84 |
85 | Run these commands as an admin user.
86 |
87 | ```
88 | brew install autoconf
89 | brew install openssl
90 | sudo ln -s /usr/local/opt/openssl /usr/local/openssl
91 | ```
92 |
93 | Last tested on 10.14 (using fink)
94 |
95 | - Install [Xcode](https://developer.apple.com/xcode/).
96 | - Install [fink](https://finkproject.org).
97 |
98 | Run these commands as an admin user.
99 |
100 | ```
101 | fink install autoconf
102 | fink install openssl
103 | ```
104 |
105 | ### Configuring for Raspbian Stretch (Debian 9)
106 |
107 | ```
108 | sudo apt-get -y update
109 | sudo apt-get -y install git
110 | sudo apt-get -y install autoconf
111 | sudo apt-get -y install libssl-dev
112 | ```
113 |
114 | ### Getting the Source
115 |
116 | You can either download the source from the [Radmind project homepage](http://radmind.org/) and uncompress it into a directory of your choice, or else you can use git to build the most recent development source of the project.
117 |
118 | Building Radmind from the git repository is a good way to ensure you've got the most up-to-date version of everything. You can also help contribute by filing bug reports on the [Radmind GitHub page](https://github.com/Radmind/radmind).
119 |
120 | First clone the repository locally:
121 |
122 | ```
123 | git clone https://github.com/Radmind/radmind.git radmind
124 | ```
125 |
126 | Then move into the directory and check out the required submodules [1]:
127 |
128 | ```
129 | cd radmind
130 | sh bootstrap.sh
131 | ```
132 |
133 | ### Configuring and Building
134 | If configure files are to be rebuilt (because we installed it), issue the following commands
135 | ```
136 | autoconf
137 | cd libsnet
138 | autoconf
139 | cd ..
140 | ```
141 |
142 | Now that everything is set up, we have to actually do the configuration and installation. Configure the build:
143 |
144 | ```
145 | ./configure
146 | ```
147 |
148 | Note that the configure scripts take several options. To see them all, do `./configure --help`.
149 |
150 | Now we're ready to actually build everything together:
151 |
152 | ```
153 | make
154 | make install
155 | ```
156 |
157 | ## Building an OS X Installer Package
158 |
159 | The Radmind Makefile contains a target called `package`, which will construct a Mac OS X installer package suitable for distribution. To make the package, log in as an administrator, enter the Radmind source directory, and follow the steps below:
160 |
161 | ```
162 | ./configure
163 | make package
164 | ```
165 |
166 | During the build process, you will be prompted for your password.
167 |
168 | PackageMaker currently does not work with `make`, so at the end of the build process you will see "make: *** [package] Error 2" even though that package was created successfully.
169 |
170 | After the source has been built and the package created, you will be left with a package called 'RadmindTools.pkg' in the parent directory of the Radmind source. This file may be double-clicked in the Finder to launch the Installer.
171 |
172 | This target will fail if it is used on a system other than Mac OS X.
173 |
174 | ## Known Issues
175 |
176 | * On OpenDarwin based systems, the message "hfs_bwrite: called with lock bit set" is logged when you are doing a high volume of writes to a volume.
177 | * `lcksum`'s progress output currently does not provide steady feedback increments.
178 |
179 | ## More Information
180 |
181 | If you have any problems with this source, you may want to check [the issue tracker](../../issues) to see if any problems have reports. You can also contact the Radmind development team by e-mailing [mlib-its-mac-github-radmind@lists.utah.edu](mailto:mlib-its-mac-github-radmind@lists.utah.edu)
182 |
183 | An archived e-mail discussion list has also been set up. See the website for details on how to join.
184 |
185 | In June of 2015, management of this project was transferred from the University of Michigan to the University of Utah. The University of Utah decided to migrate the project from the rapidly-deteriorating SourceForge hosting site over to GitHub. We felt that this would help keep the project alive and make it easier to maintain. Note that the University of Utah, while longtime users of Radmind, are no longer contributing to the upkeep of the project except to merge pull requests, make sure it builds, and keep this readme updated. If you feel you would be a better steward for Radmind's future, contact us.
186 |
187 | The transfer of issues/bugs and their comments was automated using the [gosf2github](https://github.com/cmungall/gosf2github) script. Because no username map was readily available, all of the issues and comments were automatically assigned to the member of the University of Utah's team who managed the migration, [@pdarragh](https://github.com/pdarragh).
188 |
189 | ## References
190 |
191 | [1]: Current submodules:
192 | * [libsnet](http://sourceforge.net/projects/libsnet), a networking library with TLS support
193 |
--------------------------------------------------------------------------------
/SPEC:
--------------------------------------------------------------------------------
1 | Copyright (c) 2003 Regents of The University of Michigan.
2 | All Rights Reserved. See COPYRIGHT.
3 |
4 | Response codes of x0x are for general commands, e.g. QUIT, NOOP. x3x
5 | are for STAT, x4x are for RETR, x5x for STOR.
6 |
7 | BANNER
8 |
9 | QUIT causes the server to close the connection.
10 |
11 | C: QUIT "\r\n"
12 | S: 201 QUIT OK, closing connection "\r\n"
13 |
14 | NOOP does nothing, but should generate a valid response.
15 |
16 | C: NOOP "\r\n"
17 | S: 202 NOOP OK "\r\n"
18 |
19 | All of STAT, RETR, and STOR take similar arguments.
20 |
21 | ::= "COMMAND" |
22 | "COMMAND" |
23 | "TRANSCRIPT" |
24 | "SPECIAL" |
25 | "FILE"
26 |
27 | ::= encoded ascii blah blah blah
28 |
29 | STAT does not allow a "FILE" .
30 |
31 | C: STAT "\r\n"
32 | S: 230 Returning STAT information "\r\n"
33 | S: f "\r\n"
34 |
35 | RETR
36 |
37 | C: RETR "\r\n"
38 | S: 240 Retrieving file "\r\n"
39 | S: "\r\n"
40 | S:
41 | S: ".\r\n"
42 |
43 | STOR
44 |
45 | C: STOR "\r\n"
46 | S: 350 Storing file "\r\n"
47 | C: "\r\n"
48 | C:
49 | C: ".\r\n"
50 | S: 250 File stored "\r\n"
51 |
52 | AUTH works per rfc2222 SASL.
53 |
54 | COMPress
55 |
56 | C: COMP [optional-data] "\r\n"
57 | S: 320 Ready to start "\r\n"
58 | S: 220 compression [optional-string] enabled "\r\n"
59 |
60 | REPOrt an event on the client
61 |
62 | C: REPO "\r\n"
63 | S: 215 Report successful "\r\n"
64 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | internal
2 |
--------------------------------------------------------------------------------
/aclocal.m4:
--------------------------------------------------------------------------------
1 | AC_DEFUN([CHECK_SNET],
2 | [
3 | AC_MSG_CHECKING(for snet)
4 | snetdir="libsnet"
5 | AC_ARG_WITH(snet,
6 | AC_HELP_STRING([--with-snet=DIR], [path to snet]),
7 | snetdir="$withval")
8 | if test -f "$snetdir/snet.h"; then
9 | found_snet="yes";
10 | CPPFLAGS="$CPPFLAGS -I$snetdir";
11 | fi
12 | if test x_$found_snet != x_yes; then
13 | AC_MSG_ERROR(cannot find snet libraries)
14 | else
15 | LIBS="$LIBS -lsnet";
16 | LDFLAGS="$LDFLAGS -L$snetdir";
17 | fi
18 | AC_MSG_RESULT(yes)
19 | ])
20 |
21 | AC_DEFUN([CHECK_SSL],
22 | [
23 | AC_MSG_CHECKING(for ssl)
24 | ssldirs="/usr/local/openssl /usr/lib/openssl /usr/openssl \
25 | /usr/local/ssl /usr/lib/ssl /usr/ssl \
26 | /usr/pkg /usr/local /usr /sw /opt/sw"
27 | AC_ARG_WITH(ssl,
28 | AC_HELP_STRING([--with-ssl=DIR], [path to ssl]),
29 | ssldirs="$withval")
30 | for dir in $ssldirs; do
31 | ssldir="$dir"
32 | if test -f "$dir/include/openssl/ssl.h"; then
33 | found_ssl="yes";
34 | CPPFLAGS="$CPPFLAGS -I$ssldir/include";
35 | break;
36 | fi
37 | if test -f "$dir/include/ssl.h"; then
38 | found_ssl="yes";
39 | CPPFLAGS="$CPPFLAGS -I$ssldir/include";
40 | break
41 | fi
42 | done
43 | if test x_$found_ssl != x_yes; then
44 | AC_MSG_ERROR(cannot find ssl libraries)
45 | else
46 | AC_DEFINE(HAVE_LIBSSL)
47 | LIBS="$LIBS -lssl -lcrypto";
48 | LDFLAGS="$LDFLAGS -L$ssldir/lib";
49 | fi
50 | AC_MSG_RESULT(yes)
51 | ])
52 |
53 | AC_DEFUN([CHECK_ZLIB],
54 | [
55 | AC_MSG_CHECKING(for zlib)
56 | zlibdirs="/usr /usr/local /sw /opt/sw"
57 | withval=""
58 | AC_ARG_WITH(zlib,
59 | [AC_HELP_STRING([--with-zlib=DIR], [path to zlib])],
60 | [])
61 | if test x_$withval != x_no; then
62 | if test x_$withval != x_yes -a \! -z "$withval"; then
63 | zlibdirs="$withval"
64 | fi
65 | for dir in $zlibdirs; do
66 | zlibdir="$dir"
67 | if test -f "$dir/include/zlib.h"; then
68 | found_zlib="yes";
69 | break;
70 | fi
71 | done
72 | if test x_$found_zlib = x_yes; then
73 | if test "$dir" != "/usr"; then
74 | CPPFLAGS="$CPPFLAGS -I$zlibdir/include";
75 | LDFLAGS="$LDFLAGS -L$zlibdir/lib";
76 | ac_configure_args="$ac_configure_args --with-zlib=$dir";
77 | fi
78 | LIBS="$LIBS -lz";
79 | AC_DEFINE(HAVE_ZLIB)
80 | AC_MSG_RESULT(yes)
81 | else
82 | AC_MSG_RESULT(no)
83 | fi
84 | else
85 | ac_configure_args="$ac_configure_args --with-zlib=no";
86 | AC_MSG_RESULT(no)
87 | fi
88 | ])
89 |
90 | AC_DEFUN([SET_NO_SASL],
91 | [
92 | ac_configure_args="$ac_configure_args --with-sasl=no";
93 | AC_MSG_RESULT(Disabled SASL)
94 | ])
95 |
96 | AC_DEFUN([CHECK_UNIVERSAL_BINARIES],
97 | [
98 | AC_ARG_ENABLE(universal_binaries,
99 | AC_HELP_STRING([--enable-universal-binaries], [build universal binaries (default=no)]),
100 | ,[enable_universal_binaries=no])
101 | if test "${enable_universal_binaries}" = "yes"; then
102 | case "${host_os}" in
103 | darwin8*)
104 | macosx_sdk="MacOSX10.4u.sdk"
105 | arches="-arch i386 -arch ppc"
106 | ;;
107 |
108 | darwin9*|darwin10*|darwin11*)
109 | dep_target="-mmacosx-version-min=10.4"
110 | macosx_sdk="MacOSX10.5.sdk"
111 | arches="-arch i386 -arch x86_64 -arch ppc -arch ppc64"
112 | LDFLAGS="$LDFLAGS -L/Developer/SDKs/$macosx_sdk/usr/lib"
113 | ;;
114 |
115 | *)
116 | AC_MSG_ERROR([Building universal binaries on ${host_os} is not supported])
117 | ;;
118 | esac
119 |
120 | echo ===========================================================
121 | echo Setting up universal binaries for ${host_os}
122 | echo ===========================================================
123 | OPTOPTS="$OPTOPTS -isysroot /Developer/SDKs/$macosx_sdk $dep_target $arches"
124 | fi
125 | ])
126 |
127 | AC_DEFUN([MACOSX_MUTE_DEPRECATION_WARNINGS],
128 | [
129 | dnl Lion deprecates a system-provided OpenSSL. Build output
130 | dnl is cluttered with useless deprecation warnings.
131 |
132 | AS_IF([test x"$CC" = x"gcc"], [
133 | case "${host_os}" in
134 | darwin11*)
135 | AC_MSG_NOTICE([muting deprecation warnings from compiler])
136 | OPTOPTS="$OPTOPTS -Wno-deprecated-declarations"
137 | ;;
138 |
139 | *)
140 | ;;
141 | esac
142 | ])
143 | ])
144 |
--------------------------------------------------------------------------------
/applefile.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 | #include "applefile.h"
8 | #include
9 | #include
10 |
11 | #ifdef __APPLE__
12 | #include
13 |
14 | struct attrlist getalist = {
15 | ATTR_BIT_MAP_COUNT,
16 | 0,
17 | ATTR_CMN_FNDRINFO,
18 | 0,
19 | 0,
20 | ATTR_FILE_RSRCLENGTH,
21 | 0,
22 | };
23 |
24 | struct attrlist getdiralist = {
25 | ATTR_BIT_MAP_COUNT,
26 | 0,
27 | ATTR_CMN_FNDRINFO,
28 | 0,
29 | 0,
30 | 0,
31 | 0,
32 | };
33 |
34 | struct attrlist setalist = {
35 | ATTR_BIT_MAP_COUNT,
36 | 0,
37 | ATTR_CMN_FNDRINFO,
38 | 0,
39 | 0,
40 | 0,
41 | 0,
42 | };
43 | #endif /* __APPLE__ */
44 |
45 | struct as_header as_header = {
46 | AS_MAGIC,
47 | AS_VERSION,
48 | {
49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 | },
52 | AS_NENTRIES,
53 | };
54 |
55 | extern struct as_header as_header;
56 |
57 | /* endian handlers for x86 Macs */
58 | void
59 | as_entry_netswap( struct as_entry *e )
60 | {
61 | #ifdef __BIG_ENDIAN__
62 | return;
63 | #else /* __BIG_ENDIAN__ */
64 | e->ae_id = htonl( e->ae_id );
65 | e->ae_offset = htonl( e->ae_offset );
66 | e->ae_length = htonl( e->ae_length );
67 | #endif /* __BIG_ENDIAN__ */
68 | }
69 |
70 | void
71 | as_entry_hostswap( struct as_entry *e )
72 | {
73 | #ifdef __BIG_ENDIAN__
74 | return;
75 | #else /* __BIG_ENDIAN__ */
76 | e->ae_id = ntohl( e->ae_id );
77 | e->ae_offset = ntohl( e->ae_offset );
78 | e->ae_length = ntohl( e->ae_length );
79 | #endif /* __BIG_ENDIAN__ */
80 | }
81 |
--------------------------------------------------------------------------------
/applefile.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | /*
7 | * applesingle format:
8 | * header:
9 | * -magic number (4 bytes)
10 | * -version number (4 bytes)
11 | * -filler (16 bytes)
12 | * -number of entries (2 bytes)
13 | * -x number of entries, with this format:
14 | * id (4 bytes)
15 | * offset (4 bytes)
16 | * length (4 bytes)
17 | * data:
18 | * -finder info
19 | * -rsrc fork
20 | * -data fork
21 | */
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | #define AS_HEADERLEN 26
28 |
29 | #ifdef __BIG_ENDIAN__
30 |
31 | #define AS_MAGIC 0x00051600
32 | #define AS_VERSION 0x00020000
33 | #define AS_NENTRIES 0x0003
34 |
35 | #else /* __BIG_ENDIAN__ */
36 |
37 | #define AS_MAGIC 0x00160500
38 | #define AS_VERSION 0x00000200
39 | #define AS_NENTRIES 0x0300
40 |
41 | #endif /* __BIG_ENDIAN__ */
42 |
43 | #define ASEID_DFORK 1
44 | #define ASEID_RFORK 2
45 | #define ASEID_FINFO 9
46 |
47 | #define AS_FIE 0 /* for array of ae_entry structs */
48 | #define AS_RFE 1
49 | #define AS_DFE 2
50 |
51 | #define FINFOLEN 32
52 |
53 | #define FI_CREATOR_OFFSET 4
54 |
55 | /* applesingle entry */
56 | struct as_entry {
57 | uint32_t ae_id;
58 | uint32_t ae_offset;
59 | uint32_t ae_length;
60 | };
61 |
62 | /* applesingle header */
63 | struct as_header {
64 | uint32_t ah_magic;
65 | uint32_t ah_version;
66 | uint8_t ah_filler[ 16 ];
67 | uint16_t ah_num_entries;
68 | };
69 |
70 | #if defined(__APPLE__) && defined(__LP64__) && defined(__GNUC__)
71 | #pragma pack(push)
72 | #pragma pack(4)
73 | #endif /* __APPLE__ && __LP64__ && __GNUC__ */
74 | struct attr_info {
75 | uint32_t ai_size;
76 | uint8_t ai_data[ FINFOLEN ];
77 | off_t ai_rsrc_len;
78 | };
79 | #if defined(__APPLE__) && defined(__LP64__) && defined(__GNUC__)
80 | #pragma pack(pop)
81 | #endif /* __APPLE__ && __LP64__ && __GNUC__ */
82 |
83 | struct applefileinfo {
84 | struct attr_info ai; // finder info
85 | struct as_entry as_ents[ 3 ]; // Apple Single entries
86 | // For Finder info, rcrs and data forks
87 | off_t as_size; // Total apple single file size
88 | };
89 |
90 | void as_entry_netswap( struct as_entry *e );
91 | void as_entry_hostswap( struct as_entry *e );
92 | off_t ckapplefile( char *applefile, int afd );
93 |
--------------------------------------------------------------------------------
/argcargv.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | /*
7 | * Return parsed argc/argv from the net.
8 | */
9 |
10 | #include "config.h"
11 |
12 | #include
13 |
14 | #include "argcargv.h"
15 |
16 | #define ACV_ARGC 10
17 | #define ACV_WHITE 0
18 | #define ACV_WORD 1
19 | static ACAV *acavg = NULL;
20 |
21 | ACAV*
22 | acav_alloc( void )
23 | {
24 | ACAV *acav;
25 |
26 | if ( ( acav = (ACAV*)malloc( sizeof( ACAV ) ) ) == NULL ) {
27 | return( NULL );
28 | }
29 | if ( ( acav->acv_argv =
30 | (char **)malloc( sizeof(char *) * ( ACV_ARGC ) ) ) == NULL ) {
31 | free( acav );
32 | return( NULL );
33 | }
34 | acav->acv_argc = ACV_ARGC;
35 |
36 | return( acav );
37 | }
38 |
39 | /*
40 | * acav->acv_argv = **argv[] if passed an ACAV
41 | */
42 |
43 | int
44 | acav_parse( ACAV *acav, char *line, char **argv[] )
45 | {
46 | int ac;
47 | int state;
48 |
49 | if ( acav == NULL ) {
50 | if ( acavg == NULL ) {
51 | if (( acavg = acav_alloc()) == NULL ) {
52 | return( -1 );
53 | }
54 | }
55 | acav = acavg;
56 | }
57 |
58 | ac = 0;
59 | state = ACV_WHITE;
60 |
61 | for ( ; *line != '\0'; line++ ) {
62 | switch ( *line ) {
63 | case ' ' :
64 | case '\t' :
65 | case '\n' :
66 | if ( state == ACV_WORD ) {
67 | *line = '\0';
68 | state = ACV_WHITE;
69 | }
70 | break;
71 | default :
72 | if ( state == ACV_WHITE ) {
73 | acav->acv_argv[ ac++ ] = line;
74 | if ( ac >= acav->acv_argc ) {
75 | /* realloc */
76 | if (( acav->acv_argv = (char **)realloc( acav->acv_argv,
77 | sizeof( char * ) * ( acav->acv_argc + ACV_ARGC )))
78 | == NULL ) {
79 | return( -1 );
80 | }
81 | acav->acv_argc += ACV_ARGC;
82 | }
83 | state = ACV_WORD;
84 | }
85 | }
86 | }
87 |
88 | acav->acv_argv[ ac ] = NULL;
89 | *argv = acav->acv_argv;
90 | return( ac );
91 | }
92 |
93 | int
94 | acav_free( ACAV *acav )
95 | {
96 | free( acav->acv_argv );
97 | free( acav );
98 |
99 | return( 0 );
100 | }
101 |
--------------------------------------------------------------------------------
/argcargv.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #define argcargv(X, Y) (acav_parse( NULL, X, Y ))
7 |
8 | typedef struct {
9 | int acv_argc;
10 | char **acv_argv;
11 | } ACAV;
12 | ACAV* acav_alloc( void );
13 | int acav_parse( ACAV *acav, char *, char *** );
14 | int acav_free( ACAV *acav );
15 |
--------------------------------------------------------------------------------
/base64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #define SZ_BASE64_E( x ) (((x)+2)/3*4+1)
7 | #define SZ_BASE64_D( x ) (((x)*3)/4)
8 |
9 | void base64_e( unsigned char *, int, char * );
10 | void base64_d( char *, int, unsigned char * );
11 |
--------------------------------------------------------------------------------
/bootstrap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Prepare a checked-out source tree for build
4 | #
5 | # Make sure git and autoconf are in PATH
6 |
7 | # If necessary, populate libsnet/
8 | if [ -f "./.gitmodules" -a ! -f "./libsnet/.git" ]
9 | then
10 | git submodule init
11 | git submodule update
12 | fi
13 |
14 | (cd libsnet && autoconf)
15 |
16 | autoconf
17 |
18 | exit 0
19 |
--------------------------------------------------------------------------------
/ca.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Certificate Authority shell script (cash)
4 | # Basic client side functions include:
5 | #
6 | # trip
7 | # update
8 | # create
9 | # auto
10 | # force
11 | #
12 |
13 | EDITOR=${EDITOR:-vi}
14 | MAILDOMAIN="_RADMIND_MAIL_DOMAIN"
15 | VERSION=_RADMIND_VERSION
16 | RADMINDDIR=/var/radmind
17 | #CADIR=${RADMINDDIR}/ca
18 | CERTDIR=${RADMINDDIR}/cert
19 | SPECIALDIR=${RADMINDDIR}/special
20 | CLIENTCERTDIR=/private/var/radmind/cert
21 | CADIR=./CA
22 | OPENSSLCNF=openssl2.cnf
23 |
24 | PATH=/usr/local/bin:/usr/bin:/bin; export PATH
25 |
26 | MKTEMP="_RADMIND_MKTEMP"
27 | TEMPFILES=FALSE
28 | TMPDIR="/tmp/.ca.$$"
29 | if [ -f "${MKTEMP}" ]; then
30 | TMPDIR=`${MKTEMP} -qd /tmp/.ca.$$.XXXXXX`
31 | if [ $? -ne 0 ]; then
32 | echo "mktemp failed"
33 | exit 1
34 | fi
35 | fi
36 |
37 | makecert() {
38 | if [ -z $1 ]; then
39 | echo -n "Enter new certificate common name: "
40 | read CN
41 | if [ -z ${CN} ]; then
42 | echo "Invalid common name"
43 | cleanup
44 | exit 1
45 | fi
46 | else
47 | CN=$1
48 | fi
49 | CERT=`grep /CN=${CN}/ index.txt | grep ^V | cut -f4`
50 | if [ ! -z ${CERT} ]; then
51 | echo Using existing certificate ${CERT}.pem
52 | return 0
53 | fi
54 | openssl req -new -keyout keys/${CN}.key -out csrs/${CN}.csr -days 360 -config openssl2.cnf -nodes <&2
84 | exit 1
85 | }
86 |
87 | cleanup() {
88 | if [ "$TEMPFILES" = FALSE ]; then
89 | rm -fr "${TMPDIR}"
90 | fi
91 | }
92 |
93 | while getopts V opt; do
94 | case $opt in
95 | V) echo ${VERSION}
96 | exit 0
97 | ;;
98 |
99 | *) usage
100 | ;;
101 | esac
102 | done
103 | shift `expr $OPTIND - 1`
104 |
105 | if [ $# -ne 1 ]; then
106 | usage
107 | fi
108 |
109 | if [ ! -d ${TMPDIR} ]; then
110 | mkdir -m 700 ${TMPDIR}
111 | if [ $? -ne 0 ]; then
112 | echo "Cannot create temporary directory $TMPDIR"
113 | exit 1
114 | fi
115 | fi
116 |
117 | # Trap meaningful signals
118 | trap cleanup HUP INT PIPE QUIT TERM TRAP XCPU XFSZ
119 | echo $1
120 |
121 | case "$1" in
122 | init)
123 | # Setup Certificate Authority
124 | if [ -d ${CADIR} ]; then
125 | echo ${CADIR} already exists
126 | Yn "Remove existing certificate authority?"
127 | if [ $? -eq 0 ]; then
128 | cleanup
129 | exit 1
130 | fi
131 | rm -rf ${CADIR}
132 | if [ $? -ne 0 ]; then
133 | echo "Cannot remove old certificate authority"
134 | cleanup
135 | exit 1
136 | fi
137 | fi
138 |
139 | mkdir -p ${CADIR}
140 | if [ $? -ne 0 ]; then
141 | echo "Cannot create ${CADIR}"
142 | cleanup
143 | exit 1
144 | fi
145 | cd ${CADIR}
146 | if [ $? -ne 0 ]; then
147 | echo "Cannot cd to ${CADIR}"
148 | cleanup
149 | exit 1
150 | fi
151 | mkdir certs private keys csrs
152 | if [ $? -ne 0 ]; then
153 | echo "Cannot create directories"
154 | cleanup
155 | exit 1
156 | fi
157 | echo "01" > serial
158 | touch index.txt
159 | wget http://radmind.org/files/openssl2.cnf
160 | if [ $? -ne 0 ]; then
161 | echo "Cannot get default ${OPENSSLCNF}"
162 | cleanup
163 | exit 1
164 | fi
165 | openssl req -config ${OPENSSLCNF} -x509 -newkey rsa -days 1825 -keyout private/ca-key.pem -out certs/ca-cert.pem -outform PEM
166 | makecert `hostname`
167 |
168 | ;;
169 |
170 | create)
171 | if [ ! -d ${CADIR} ]; then
172 | echo "No certificate authority"
173 | cleanup
174 | exit 1
175 | fi
176 | cd ${CADIR}
177 |
178 | makecert
179 |
180 | cat certs/${CERT}.pem keys/${CN}.key > ${CERTDIR}/${CN}.pem
181 | if [ $? -ne 0 ]; then
182 | echo Unable to create ${CERTDIR}/${CN}.pem
183 | cleanup
184 | exit 1
185 | fi
186 | if [ ! -d ${SPECIALDIR}/${CN}/${CLIENTCERTDIR} ]; then
187 | mkdir -p ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}
188 | if [ $? -ne 0 ]; then
189 | echo Unable to create ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}
190 | cleanup
191 | exit 1
192 | fi
193 | fi
194 | if [ -a ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}/cert.pem ]; then
195 | rm -f ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}/cert.pem
196 | echo Unable to remove old ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}/cert.pem
197 | cleanup
198 | exit 1
199 | fi
200 |
201 | ln -s ${CERTDIR}/${CN}.pem ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}/cert.pem
202 | if [ $? -ne 0 ]; then
203 | echo Unable to link ${CERTDIR}/${CN}.pem to ${SPECIALDIR}/${CN}/${CLIENTCERTDIR}/cert.pem
204 | cleanup
205 | exit 1
206 | fi
207 | ;;
208 |
209 | *)
210 | usage
211 | ;;
212 |
213 | esac
214 |
215 | cleanup
216 | exit 0
217 |
--------------------------------------------------------------------------------
/cksum.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #ifdef __APPLE__
12 | #include
13 | #endif /* __APPLE__ */
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 |
23 | #include "openssl_compat.h" // Compatibility shims for OpenSSL < 1.1.0
24 | #include "applefile.h"
25 | #include "cksum.h"
26 | #include "base64.h"
27 |
28 | /*
29 | * do_cksum calculates the checksum for PATH and returns it base64 encoded
30 | * in cksum_b64 which must be of size SZ_BASE64_E( EVP_MAX_MD_SIZE ).
31 | *
32 | * return values:
33 | * < 0 system error: errno set, no message given
34 | * >= 0 number of bytes check summed
35 | */
36 |
37 | off_t
38 | do_fcksum( int fd, char *cksum_b64 )
39 | {
40 | unsigned int md_len;
41 | ssize_t rr;
42 | off_t size = 0;
43 | unsigned char buf[ 8192 ];
44 | extern EVP_MD *md;
45 | EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
46 | unsigned char md_value[ SZ_BASE64_D( SZ_BASE64_E( EVP_MAX_MD_SIZE ) ) ];
47 |
48 | EVP_DigestInit( mdctx, md );
49 |
50 | while (( rr = read( fd, buf, sizeof( buf ))) > 0 ) {
51 | size += rr;
52 | EVP_DigestUpdate( mdctx, buf, (unsigned int)rr );
53 | }
54 | if ( rr < 0 ) {
55 | EVP_MD_CTX_free(mdctx);
56 | return( -1 );
57 | }
58 |
59 | EVP_DigestFinal( mdctx, md_value, &md_len );
60 | base64_e( md_value, md_len, cksum_b64 );
61 | EVP_MD_CTX_free( mdctx );
62 |
63 | return( size );
64 | }
65 |
66 | off_t
67 | do_cksum( char *path, char *cksum_b64 )
68 | {
69 | int fd;
70 | off_t size = 0;
71 |
72 | if (( fd = open( path, O_RDONLY, 0 )) < 0 ) {
73 | return( -1 );
74 | }
75 |
76 | size = do_fcksum( fd, cksum_b64 );
77 |
78 | if ( close( fd ) != 0 ) {
79 | return( -1 );
80 | }
81 |
82 | return( size );
83 | }
84 |
85 | #ifdef __APPLE__
86 |
87 | /*
88 | * do_acksum calculates the checksum for the encoded apple single file of PATH
89 | * and returns it base64 encoded in cksum_b64 which must be of size
90 | * SZ_BASE64_E( EVP_MAX_MD_SIZE ).
91 | *
92 | * return values:
93 | * >= 0 number of bytes check summed
94 | * < 0 system error: errno set, no message given
95 | *
96 | * do_acksum should only be called on native HFS+ system.
97 | */
98 |
99 | off_t
100 | do_acksum( char *path, char *cksum_b64, struct applefileinfo *afinfo )
101 | {
102 | int dfd, rfd, rc;
103 | char buf[ 8192 ], rsrc_path[ MAXPATHLEN ];
104 | off_t size = 0;
105 | extern struct as_header as_header;
106 | struct as_entry as_entries_endian[ 3 ];
107 | unsigned int md_len;
108 | extern EVP_MD *md;
109 | EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
110 | unsigned char md_value[ SZ_BASE64_D( SZ_BASE64_E( EVP_MAX_MD_SIZE ) ) ];
111 |
112 | EVP_DigestInit( mdctx, md );
113 |
114 | /* checksum applesingle header */
115 | EVP_DigestUpdate( mdctx, (char *)&as_header, AS_HEADERLEN );
116 | size += (size_t)AS_HEADERLEN;
117 |
118 | /* endian handling, sum big-endian header entries */
119 | memcpy( &as_entries_endian, &afinfo->as_ents,
120 | ( 3 * sizeof( struct as_entry )));
121 | as_entry_netswap( &as_entries_endian[ AS_FIE ] );
122 | as_entry_netswap( &as_entries_endian[ AS_RFE ] );
123 | as_entry_netswap( &as_entries_endian[ AS_DFE ] );
124 |
125 | /* checksum header entries */
126 | EVP_DigestUpdate( mdctx, (char *)&as_entries_endian,
127 | (unsigned int)( 3 * sizeof( struct as_entry )));
128 | size += sizeof( 3 * sizeof( struct as_entry ));
129 |
130 | /* checksum finder info data */
131 | EVP_DigestUpdate( mdctx, afinfo->ai.ai_data, FINFOLEN );
132 | size += FINFOLEN;
133 |
134 | /* checksum rsrc fork data */
135 | if ( afinfo->as_ents[ AS_RFE ].ae_length > 0 ) {
136 | if ( snprintf( rsrc_path, MAXPATHLEN, "%s%s",
137 | path, _PATH_RSRCFORKSPEC ) >= MAXPATHLEN ) {
138 | errno = ENAMETOOLONG;
139 | EVP_MD_CTX_free(mdctx);
140 | return( -1 );
141 | }
142 |
143 | if (( rfd = open( rsrc_path, O_RDONLY )) < 0 ) {
144 | EVP_MD_CTX_free(mdctx);
145 | return( -1 );
146 | }
147 | while (( rc = read( rfd, buf, sizeof( buf ))) > 0 ) {
148 | EVP_DigestUpdate( mdctx, buf, (unsigned int)rc );
149 | size += (size_t)rc;
150 | }
151 | if ( close( rfd ) < 0 ) {
152 | EVP_MD_CTX_free(mdctx);
153 | return( -1 );
154 | }
155 | if ( rc < 0 ) {
156 | EVP_MD_CTX_free(mdctx);
157 | return( -1 );
158 | }
159 | }
160 |
161 | if (( dfd = open( path, O_RDONLY, 0 )) < 0 ) {
162 | EVP_MD_CTX_free( mdctx );
163 | return( -1 );
164 | }
165 | /* checksum data fork */
166 | while (( rc = read( dfd, buf, sizeof( buf ))) > 0 ) {
167 | EVP_DigestUpdate( mdctx, buf, (unsigned int)rc );
168 | size += (size_t)rc;
169 | }
170 | if ( rc < 0 ) {
171 | EVP_MD_CTX_free( mdctx );
172 | return( -1 );
173 | }
174 | if ( close( dfd ) < 0 ) {
175 | EVP_MD_CTX_free( mdctx );
176 | return( -1 );
177 | }
178 |
179 | EVP_DigestFinal( mdctx, md_value, &md_len );
180 | base64_e( ( unsigned char* ) md_value, md_len, cksum_b64 );
181 | EVP_MD_CTX_free( mdctx );
182 |
183 | return( size );
184 | }
185 | #else /* __APPLE__ */
186 |
187 | /*
188 | * stub fuction for non-hfs+ machines.
189 | *
190 | * return values:
191 | * -1 system error: non hfs+ system
192 | */
193 |
194 | off_t
195 | do_acksum( char *path, char *cksum_b64, struct applefileinfo *afino )
196 | {
197 | errno = EOPNOTSUPP;
198 | return( -1 );
199 | }
200 | #endif /* __APPLE__ */
201 |
--------------------------------------------------------------------------------
/cksum.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | off_t do_fcksum( int fd, char *cksum_b64 );
7 | off_t do_cksum( char *path, char *cksum_b64 );
8 | off_t do_acksum( char *path, char *cksum_b64, struct applefileinfo *afinfo );
9 |
--------------------------------------------------------------------------------
/code.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "code.h"
15 |
16 | /*
17 | * Escape certain characters. This code must match decode() *and*
18 | * argcargv().
19 | */
20 | char *
21 | encode( char *line )
22 | {
23 | /* static */
24 | static char buf[ 2 * MAXPATHLEN ];
25 | char *temp;
26 |
27 | if ( strlen( line ) > MAXPATHLEN ) {
28 | return( NULL );
29 | }
30 |
31 | temp = buf;
32 | for ( ; *line != '\0'; line++, temp++ ) {
33 | switch ( *line ) {
34 | case ' ' :
35 | *temp = '\\';
36 | temp++;
37 | *temp = 'b';
38 | break;
39 | case '\t' :
40 | *temp = '\\';
41 | temp++;
42 | *temp = 't';
43 | break;
44 | case '\n':
45 | *temp = '\\';
46 | temp++;
47 | *temp = 'n';
48 | break;
49 | case '\r':
50 | *temp = '\\';
51 | temp++;
52 | *temp = 'r';
53 | break;
54 | case '\\':
55 | *temp = '\\';
56 | temp++;
57 | *temp = '\\';
58 | break;
59 | default :
60 | *temp = *line;
61 | break;
62 | }
63 | }
64 |
65 | *temp = '\0';
66 | return( buf );
67 | }
68 |
69 | char *
70 | decode( char *line )
71 | {
72 | /* static */
73 | static char buf[ MAXPATHLEN ];
74 | char *temp, *end;
75 |
76 | if ( strlen( line ) > ( 2 * MAXPATHLEN )) {
77 | return( NULL );
78 | }
79 |
80 | end = buf + MAXPATHLEN;
81 | temp = buf;
82 |
83 | for ( ; *line != '\0'; line++, temp++ ) {
84 | /* Check for buffer overflow - must have space for '\0' */
85 | if ( temp >= end ) {
86 | return( NULL );
87 | }
88 | switch( *line ) {
89 | case '\\':
90 | line++;
91 | switch( *line ) {
92 | case 'n':
93 | *temp = '\n';
94 | break;
95 | case 't':
96 | *temp = '\t';
97 | break;
98 | case 'b':
99 | *temp = ' ';
100 | break;
101 | case 'r':
102 | *temp = '\r';
103 | break;
104 | case '\\':
105 | *temp = '\\';
106 | break;
107 | default:
108 | break;
109 | }
110 | break;
111 | default:
112 | *temp = *line;
113 | break;
114 | }
115 | }
116 |
117 | *temp = '\0';
118 | return( buf );
119 | }
120 |
--------------------------------------------------------------------------------
/code.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | char *encode( char * );
7 | char *decode( char * );
8 |
--------------------------------------------------------------------------------
/command.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int cmdloop( int, struct sockaddr_in * );
7 | int command_k( char *, int );
8 | char **special_t( char *, char * );
9 | int keyword( int, char*[] );
10 | extern char *path_radmind;
11 |
12 | struct command {
13 | char *c_name;
14 | int (*c_func)( SNET *, int, char *[] );
15 | };
16 |
17 | #define RADMIND_STAT_FMT "%s %s %o %d %d %" PRItimet "d %" PRIofft "d %s\r\n"
18 |
--------------------------------------------------------------------------------
/config.h.in:
--------------------------------------------------------------------------------
1 | /* Size of off_T */
2 | #undef SIZEOF_OFF_T
3 |
4 | /* Version number of package */
5 | #undef VERSION
6 |
7 | /* Define to make fseeko etc. visible, on some hosts. */
8 | #undef _LARGEFILE_SOURCE
9 |
10 | /* Define for large files, on AIX-style hosts. */
11 | #undef _LARGE_FILES
12 |
13 | /* Number of bits in a file offset, on hosts where this is settable.
14 | case in
15 | # HP-UX 10.20 and later
16 | hpux10.2-90-9* | hpux11-9* | hpux2-90-9*)
17 | ac_cv_sys_file_offset_bits=64 ;;
18 | esac */
19 | #undef _FILE_OFFSET_BITS
20 |
21 | #undef HAVE_LIBSSL
22 | #undef HAVE_X509_VERIFY_PARAM
23 | #undef HAVE_ZEROCONF
24 |
25 | #undef HAVE_LIBPAM
26 | #undef HAVE_PAM_PAM_APPL_H
27 | #undef HAVE_SECURITY_PAM_APPL_H
28 |
29 | #undef HAVE_DNSSD
30 | #undef HAVE_LCHOWN
31 | #undef HAVE_LCHMOD
32 | #undef HAVE_ZLIB
33 |
34 | #undef HAVE_WAIT4
35 | #undef HAVE_STRTOLL
36 |
37 | #undef MAJOR_IN_SYSMACROS
38 | #undef MAJOR_IN_MKDEV
39 |
40 | #ifndef MIN
41 | #define MIN(a,b) ((a)<(b)?(a):(b))
42 | #endif /* MIN */
43 |
44 | #ifndef MAX
45 | #define MAX(a,b) ((a)>(b)?(a):(b))
46 | #endif /* MAX */
47 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 |
2 | # Process this file with autoconf to produce a configure script.
3 | AC_INIT(radmind, VERSION, radmind@umich.edu)
4 | AC_CONFIG_HEADER(config.h)
5 | AC_PREREQ(2.52)
6 | AC_COPYRIGHT([Copyright (c) 2003 Regents of The University of Michigan. All Rights Reserved.])
7 | AC_CONFIG_SRCDIR([applefile.c])
8 |
9 | # Set up variables
10 | AC_ARG_VAR(diffpath, [path to diff utility])
11 | AC_ARG_VAR(echopath, [path to echo utility])
12 |
13 | AC_ARG_WITH(server, AC_HELP_STRING([--with-server=SERVER], [default radmind server]), server="$withval", server="radmind" )
14 | AC_SUBST(server)
15 |
16 | AC_ARG_WITH(authlevel, AC_HELP_STRING([--with-authlevel=AUTHLEVEL], [default TLS authorization level]), authlevel="$withval", authlevel="0" )
17 | AC_SUBST(authlevel)
18 |
19 | AC_ARG_WITH(radminddir, AC_HELP_STRING([--with-radminddir=DIR], [default radmind server storage]), radminddir="$withval", radminddir="/var/radmind" )
20 | AC_SUBST(radminddir)
21 |
22 | AC_ARG_WITH(maxconnections, AC_HELP_STRING([--with-max-connections=MAX], [maximum number of simultaneous connections]), maxconnections="$withval", maxconnections=0 )
23 | AC_SUBST(maxconnections)
24 |
25 | AC_ARG_WITH(maildomain, AC_HELP_STRING([--with-maildomain=DOMAIN], [default radmind mail domain]), maildomain="$withval", maildomain="" )
26 | AC_SUBST(maildomain)
27 |
28 | build_date=`date "+%B %d, %Y"`
29 | AC_SUBST(build_date)
30 |
31 | #AC_ARG_WITH(certdir, AC_HELP_STRING([--cert=DIR], [default certificate location]), certdir="$withval", certdir="/var/radmind/cert" )
32 | #AC_SUBST(certdir)
33 |
34 | AC_CANONICAL_SYSTEM
35 |
36 | # Checks for programs.
37 | AC_PROG_AWK
38 | AC_PROG_CC
39 | AC_PROG_INSTALL
40 | AC_PATH_PROG(diffpath, diff)
41 | AC_PATH_PROG(echopath, echo)
42 | AC_PATH_PROG(mktemppath, mktemp)
43 | AC_SYS_LARGEFILE
44 |
45 | # Check sizes
46 | AC_CHECK_SIZEOF(off_t)
47 | AC_CHECK_SIZEOF(time_t)
48 |
49 | # check early to make any required changes to environment for following tests.
50 | CHECK_UNIVERSAL_BINARIES
51 |
52 | # mute Mac OS X's helpful notices that using dylib OpenSSL
53 | MACOSX_MUTE_DEPRECATION_WARNINGS
54 |
55 | # Checks for header files
56 |
57 | # glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits
58 | # deprecation warning which causes compilation failure later with -Werror.
59 | # So use -Werror here as well to force proper sys/sysmacros.h detection.
60 | SAVED_CFLAGS="$CFLAGS"
61 | CFLAGS="$HOST_CFLAGS -Werror"
62 | AC_HEADER_MAJOR
63 | CFLAGS="$SAVED_CFLAGS"
64 |
65 |
66 | # Checks for libraries.
67 | AC_CHECK_LIB(c, inet_aton, libc_inet_aton=yes)
68 | if test x$libc_inet_aton != xyes; then
69 | AC_CHECK_LIB(resolv, inet_aton)
70 | fi
71 | if test x$host_vendor = xapply; then
72 | AC_CHECK_LIB(c, lchown, [AC_DEFINE(HAVE_LCHOWN)], [])
73 | AC_CHECK_LIB(c, lchmod, [AC_DEFINE(HAVE_LCHMOD)], [])
74 | fi
75 | AC_CHECK_LIB(nsl, gethostbyaddr)
76 | AC_CHECK_LIB([socket], [socket])
77 | AC_CHECK_LIB([ssl], [SSL_accept], , [CHECK_SSL])
78 | AC_CHECK_HEADER([openssl/ssl.h], [], [AC_MSG_ERROR([header file
79 | is required for this software. You may be running RedHat 9. If so, see the FAQ or the README for further instructions.])])
80 | AC_CHECK_LIB([crypto], [SSLeay_version], , [CHECK_SSL])
81 | AC_CHECK_LIB([crypto], [X509_VERIFY_PARAM_set_flags], [AC_DEFINE(HAVE_X509_VERIFY_PARAM)], [])
82 |
83 | # PAM
84 | AC_ARG_WITH([pam], AC_HELP_STRING([--with-pam=PATH], [Pluggable Authentication Module support (default: /usr)]), [], with_pam=/usr)
85 | if test x_"$with_pam" != x_no; then
86 | CPPFLAGS="${CPPFLAGS} -I$with_pam/include"
87 | LDFLAGS="${LDFLAGS} -L$with_pam/lib"
88 | AC_CHECK_LIB([pam], [pam_start],
89 | [
90 | AC_CHECK_HEADERS(pam/pam_appl.h, , [AC_CHECK_HEADERS(security/pam_appl.h)])
91 | AC_DEFINE(HAVE_LIBPAM)
92 | LIBS="$LIBS -lpam";
93 | ]
94 | )
95 | fi
96 | AC_CHECK_HEADER([dns_sd.h], [AC_DEFINE(HAVE_DNSSD)], [], [])
97 | AC_CHECK_LIB(dns_sd, DNSServiceRegister)
98 |
99 | CHECK_ZLIB
100 |
101 | # HPUX lacks wait4 and strtoll
102 | AC_CHECK_FUNCS(wait4 strtoll)
103 |
104 | # Miscellaneous:
105 | if test x_"$OPTOPTS" = x_; then
106 | if test x_$GCC = x_yes; then
107 | OPTOPTS="$OPTOPTS -Wall -Wmissing-prototypes"
108 | fi
109 | if test x_$build_vendor = x_hp; then
110 | OPTOPTS="$OPTOPTS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
111 | fi
112 | fi
113 | AC_SUBST(OPTOPTS)
114 |
115 | SET_NO_SASL
116 | AC_CONFIG_SUBDIRS(libsnet)
117 | AC_CONFIG_FILES(Makefile)
118 | AC_OUTPUT
119 |
--------------------------------------------------------------------------------
/connect.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2007 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 |
25 | #ifdef HAVE_ZLIB
26 | #include
27 | #endif /* HAVE_ZLIB */
28 |
29 | #include
30 |
31 | #include "applefile.h"
32 | #include "cksum.h"
33 | #include "connect.h"
34 | #include "argcargv.h"
35 |
36 | #define RADMIND_IANA_PORT 6222
37 | #define RADMIND_LEGACY_PORT 6662
38 |
39 | extern void (*logger)( char * );
40 | extern int verbose;
41 | struct timeval timeout = { 60, 0 };
42 | extern int errno;
43 | extern SSL_CTX *ctx;
44 |
45 |
46 | #ifdef HAVE_ZLIB
47 | int zlib_level = 0;
48 | #endif
49 |
50 | void
51 | v_logger( char *line )
52 | {
53 | printf( "<<< %s\n", line );
54 | return;
55 | }
56 |
57 | static SNET *
58 | connectsn2( struct sockaddr_in *sin )
59 | {
60 | int s;
61 | int one = 1;
62 | int connectsn2_errno = 0;
63 | SNET *sn = NULL;
64 | struct protoent *proto;
65 |
66 | if (( s = socket( PF_INET, SOCK_STREAM, 0 )) < 0 ) {
67 | perror( "socket" );
68 | exit( 2 );
69 | }
70 |
71 | if (( proto = getprotobyname( "tcp" )) == NULL ) {
72 | perror( "getprotobyname" );
73 | exit( 2 );
74 | }
75 | if ( setsockopt( s, proto->p_proto, TCP_NODELAY, &one,
76 | sizeof( one )) != 0 ) {
77 | perror( "snet_setopt" );
78 | exit( 2 );
79 | }
80 |
81 | if ( verbose ) printf( "trying %s:%u... ", inet_ntoa( sin->sin_addr ),
82 | ntohs( sin->sin_port ));
83 | if ( connect( s, (struct sockaddr *)sin,
84 | sizeof( struct sockaddr_in )) != 0 ) {
85 | connectsn2_errno = errno;
86 | if ( verbose ) printf( "failed: %s\n", strerror( errno ));
87 | (void)close( s );
88 | errno = connectsn2_errno;
89 | return( NULL );
90 | }
91 | if ( verbose ) printf( "success!\n" );
92 | if (( sn = snet_attach( s, 1024 * 1024 )) == NULL ) {
93 | perror( "snet_attach" );
94 | exit( 2 );
95 | }
96 |
97 | return( sn );
98 | }
99 |
100 | SNET *
101 | connectsn( char *host, unsigned short port )
102 | {
103 | int i;
104 | struct hostent *he;
105 | struct sockaddr_in sin;
106 | struct servent *se = NULL;
107 | SNET *sn = NULL;
108 |
109 | memset( &sin, 0, sizeof( struct sockaddr_in ));
110 | sin.sin_family = AF_INET;
111 |
112 | #ifdef notdef
113 | /*
114 | * this code should be enabled only to deal with bugs in
115 | * the gethostbyname() routine
116 | */
117 | if (( sin.sin_addr.s_addr = inet_addr( host )) != -1 ) {
118 | return( connectsn2( &sin ));
119 | }
120 | #endif // notdef
121 |
122 | if (( he = gethostbyname( host )) == NULL ) {
123 | fprintf( stderr, "%s: Unknown host\n", host );
124 | return( NULL );
125 | }
126 |
127 | if ( port == 0 ) {
128 | /* maybe radmind's in /etc/services. if not, use default. */
129 | se = getservbyname( "radmind", "tcp" );
130 | }
131 |
132 | for ( i = 0; he->h_addr_list[ i ] != NULL; i++ ) {
133 | memcpy( &sin.sin_addr.s_addr, he->h_addr_list[ i ],
134 | (unsigned int)he->h_length );
135 | if ( se != NULL ) {
136 | /* getservbyname returns port numbers in network byte order */
137 | sin.sin_port = se->s_port;
138 | } else if (( sin.sin_port = port ) == 0 ) {
139 | sin.sin_port = htons( RADMIND_IANA_PORT );
140 | }
141 |
142 | /*
143 | * radmind's original port was 6662, but got
144 | * registered as 6222 with IANA, and will show
145 | * up in future /etc/services as 6222. during
146 | * the transition, fall back to trying the
147 | * legacy port if the new port connection fails.
148 | */
149 | if (( sn = connectsn2( &sin )) == NULL && port == 0 ) {
150 | /* try connecting to old non-IANA registered port */
151 | sin.sin_port = htons( RADMIND_LEGACY_PORT );
152 | sn = connectsn2( &sin );
153 | }
154 | if ( sn != NULL ) {
155 | return( sn );
156 | }
157 | }
158 | fprintf( stderr, "connection to %s failed: %s\n",
159 | inet_ntoa( sin.sin_addr ), strerror( errno ));
160 | fprintf( stderr, "%s: connection failed\n", host );
161 | return( NULL );
162 | }
163 |
164 | int
165 | closesn( SNET *sn )
166 | {
167 | char *line;
168 | struct timeval tv;
169 |
170 | /* Close network connection */
171 | if ( snet_writef( sn, "QUIT\r\n" ) < 0 ) {
172 | fprintf( stderr, "QUIT failed: %s\n", strerror( errno ));
173 | exit( 2 );
174 | }
175 | tv = timeout;
176 | if (( line = snet_getline_multi( sn, logger, &tv )) == NULL ) {
177 | fprintf( stderr, "close failed: %s\n", strerror( errno ));
178 | exit( 2 );
179 | }
180 | if ( *line != '2' ) {
181 | perror( line );
182 | return( -1 );
183 | }
184 | if ( snet_close( sn ) != 0 ) {
185 | fprintf( stderr, "snet_close failed: %s\n", strerror( errno ));
186 | exit( 2 );
187 | }
188 | return( 0 );
189 | }
190 |
191 | char **
192 | get_capabilities( SNET *sn )
193 | {
194 | char *line;
195 | char temp[ MAXPATHLEN ];
196 | char **capa = NULL;
197 | int i, ac;
198 | char **av;
199 | struct timeval tv;
200 |
201 | while( 1 ) {
202 | tv = timeout;
203 | if (( line = snet_getline( sn, &tv )) == NULL ) {
204 | fprintf( stderr, "connection failed\n" );
205 | return( NULL );
206 | }
207 | if ( *line != '2' ) {
208 | fprintf( stderr, "%s\n", line );
209 | return( NULL );
210 | }
211 | if ( verbose ) printf( "<<< %s\n", line );
212 | strcpy( temp, line+4 );
213 | if (( ac = argcargv( temp, &av )) != 0 ) {
214 | if ( strncasecmp( "CAPAbilities", av[0], MIN( 12, strlen( av[0] ))) == 0 ) {
215 | capa = malloc( sizeof(char *)*ac );
216 | for ( i = 0; i+1 < ac; i++ ) {
217 | capa[i] = strdup( av[i+1] );
218 | }
219 | capa[i] = NULL;
220 | }
221 | }
222 | switch( line[3] ) {
223 | case ' ':
224 | if( !capa ) {
225 | capa = malloc( sizeof( char * ));
226 | *capa = NULL;
227 | }
228 | return ( capa );
229 | case '-':
230 | break;
231 | default:
232 | fprintf ( stderr, "%s\n", line );
233 | return ( NULL );
234 | }
235 | }
236 | }
237 |
238 | #ifdef HAVE_ZLIB
239 | int
240 | negotiate_compression( SNET *sn, char **capa )
241 | {
242 | char *name = NULL;
243 | char *line;
244 | int type = 0;
245 | int level = 0;
246 | struct timeval tv;
247 |
248 | /* Place compression algorithms in descending order of desirability */
249 | if ( zlib_level ) {
250 | /* walk through capabilities looking for "ZLIB" */
251 | if ( check_capability( "ZLIB", capa ) == 1 ) {
252 | name = "ZLIB";
253 | type = SNET_ZLIB;
254 | level = zlib_level;
255 | }
256 |
257 | if ( level == 0 ) {
258 | fprintf( stderr, "compression capability mismatch, "
259 | "compression disabled\n" );
260 | return( 0 );
261 | }
262 | }
263 |
264 | if ( verbose ) printf( ">>> COMP %s %d\n", name, level );
265 | snet_writef( sn, "COMP %s %d\r\n", name, level );
266 |
267 | tv = timeout;
268 | if (( line = snet_getline( sn, &tv )) == NULL ) {
269 | perror( "snet_getline" );
270 | return( -1 );
271 | }
272 | if( verbose ) printf( "<<< %s\n", line );
273 | if ( *line != '3' ) {
274 | fprintf( stderr, "%s\n", line );
275 | return( -1 );
276 | }
277 |
278 | if ( snet_setcompression( sn, type, level ) < 0 ) {
279 | perror( "snet_setcompression" );
280 | return( -1 );
281 | }
282 |
283 | tv = timeout;
284 | if (( line = snet_getline( sn, &tv )) == NULL ) {
285 | perror( "snet_getline" );
286 | return( -1 );
287 | }
288 | if( verbose ) printf( "<<< %s\n", line );
289 | if ( *line != '2' ) {
290 | fprintf( stderr, "%s\n", line );
291 | return( -1 );
292 | }
293 |
294 | return( 0 );
295 | }
296 |
297 | int
298 | print_stats( SNET *sn )
299 | {
300 | z_stream in_stream, out_stream;
301 |
302 | if ( snet_flags( sn ) & SNET_ZLIB ) {
303 | in_stream = snet_zistream( sn );
304 | out_stream = snet_zostream( sn );
305 |
306 | #define RATIO(a,b) (((double)(a))/((double)(b)))
307 | if ( verbose ) {
308 | printf( "zlib stats +++ In: %lu:%lu (%.3f:1) "
309 | "+++ Out: %lu:%lu (%.3f:1)\n",
310 | in_stream.total_out, in_stream.total_in,
311 | RATIO( in_stream.total_out, in_stream.total_in ),
312 | out_stream.total_in, out_stream.total_out,
313 | RATIO( out_stream.total_in, out_stream.total_out ));
314 | } else {
315 | syslog( LOG_INFO, "zlib stats +++ In: %lu:%lu (%.3f:1) "
316 | "+++ Out: %lu:%lu (%.3f:1)\n",
317 | in_stream.total_out, in_stream.total_in,
318 | RATIO( in_stream.total_out, in_stream.total_in ),
319 | out_stream.total_in, out_stream.total_out,
320 | RATIO( out_stream.total_in, out_stream.total_out ));
321 | }
322 | }
323 | return( 0 );
324 | }
325 | #endif /* HAVE_ZLIB */
326 |
327 | /*
328 | * check_capabilities: check to see if type is a listed capability
329 | *
330 | * return codes:
331 | * 0: type not in capability list
332 | * 1: type in capability list
333 | */
334 | int
335 | check_capability( char *type, char **capa )
336 | {
337 | char **p;
338 |
339 | /* walk through capabilities looking for "REPO" */
340 | for ( p = capa; *p; p++ ) {
341 | if ( !strncasecmp( type, *p, MIN( 4, strlen( *p )))) {
342 | return( 1 );
343 | }
344 | }
345 | return( 0 );
346 | }
347 |
--------------------------------------------------------------------------------
/connect.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | SNET * connectsn( char *host, unsigned short port );
7 | int closesn( SNET *sn );
8 | char **get_capabilities( SNET * );
9 | #ifdef HAVE_ZLIB
10 | int negotiate_compression( SNET *, char ** );
11 | int print_stats( SNET * );
12 | extern int zlib_level;
13 | #endif /* HAVE_ZLIB */
14 |
15 | int retr( SNET *sn, char *pathdesc, char *path, char *temppath,
16 | mode_t tempmode, off_t transize, char *trancksum );
17 | int retr_applefile( SNET *sn, char *pathdesc, char *path, char *temppath,
18 | mode_t tempmode, off_t transize, char *trancksum );
19 |
20 | int n_stor_file( SNET *sn, char *pathdesc, char *path );
21 | int stor_file( SNET *sn, char *pathdesc, char *path, off_t transize,
22 | char *trancksum );
23 | int n_stor_applefile( SNET *sn, char *pathdesc, char *path );
24 | int stor_applefile( SNET *sn, char *pathdesc, char *path, off_t transize,
25 | char *trancksum, struct applefileinfo *afinfo );
26 | int stor_response( SNET *sn, int *respcount, struct timeval * );
27 | void v_logger( char *string);
28 | int check_capability( char *type, char **capa );
29 |
--------------------------------------------------------------------------------
/contrib/fsspy.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 The Regents of The University of Michigan
3 | * All Rights Reserved.
4 | *
5 | * Permission to use, copy, modify, and distribute this software and
6 | * its documentation for any purpose and without fee is hereby granted,
7 | * provided that the above copyright notice appears in all copies and
8 | * that both that copyright notice and this permission notice appear
9 | * in supporting documentation, and that the name of The University
10 | * of Michigan not be the software without specific, written prior
11 | * permission. This software is supplied as is without expressed or
12 | * implied warranties of any kind.
13 | *
14 | * Written by Andrew Mortensen, Dec. 2008.
15 | */
16 |
17 | /*
18 | * To compile:
19 | gcc -g -framework CoreFoundation -framework CoreServices \
20 | -o fsspy fsspy.c
21 | *
22 | */
23 |
24 | #include
25 | #include
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | extern int errno;
36 |
37 | struct event {
38 | char *e_path;
39 | unsigned long long e_id;
40 | unsigned long e_flags;
41 | struct event *e_next;
42 | };
43 |
44 | struct event *event_head = NULL;
45 |
46 | int debug = 0;
47 | int case_sensitive = 1;
48 | int delayed_print = 0;
49 | int all_paths = 0;
50 | char *prefix = NULL;
51 |
52 | int
53 | ischild( char *child, char *parent )
54 | {
55 | int rc, len;
56 |
57 | if ( parent == NULL ) {
58 | return( 1 );
59 | }
60 |
61 | if (( len = strlen( parent )) > strlen( child )) {
62 | return( 0 );
63 | }
64 | if ( len == 1 && *parent == '/' ) {
65 | return(( *child == '/' ));
66 | }
67 |
68 | if ( case_sensitive ) {
69 | rc = strncmp( parent, child, len );
70 | } else {
71 | rc = strncasecmp( parent, child, len );
72 | }
73 | if ( rc == 0 && ( child[ len ] == '/' || child[ len ] == '\0' )) {
74 | return( 1 );
75 | }
76 |
77 | return( 0 );
78 | }
79 |
80 | struct event *
81 | event_new( char *path, unsigned long long id, unsigned long flags )
82 | {
83 | struct event *new;
84 | int len;
85 |
86 | if (( new = (struct event *)malloc( sizeof( struct event ))) == NULL ) {
87 | return( NULL );
88 | }
89 |
90 | /* user may have specified a prefix for the path. */
91 | len = strlen( path ) + 1;
92 | if ( prefix != NULL ) {
93 | len += strlen( prefix );
94 | }
95 | if (( new->e_path = (char *)malloc( len )) == NULL ) {
96 | free( new );
97 | return( NULL );
98 | }
99 | if ( prefix != NULL ) {
100 | strcpy( new->e_path, prefix );
101 | strcat( new->e_path, path );
102 | } else {
103 | strcpy( new->e_path, path );
104 | }
105 |
106 | /* the fsevents API returns paths with a trailing slash. chop it. */
107 | len = strlen( new->e_path );
108 | if ( new->e_path[ len - 1 ] == '/' ) {
109 | new->e_path[ len - 1 ] = '\0';
110 | }
111 |
112 | new->e_id = id;
113 | new->e_flags = flags;
114 | new->e_next = NULL;
115 |
116 | return( new );
117 | }
118 |
119 | void
120 | event_insert( struct event **head, struct event *new )
121 | {
122 | struct event **cur;
123 | struct event *tmp;
124 | int rc;
125 |
126 | /* must use while loop here since we're traversing and (maybe) deleting. */
127 | cur = head;
128 |
129 | while ( *cur != NULL ) {
130 | if ( !all_paths && ischild( new->e_path, (*cur)->e_path )) {
131 | /* drop new node. we've already got the parent in the list. */
132 | free( new->e_path );
133 | free( new );
134 | return;
135 | } else if ( !all_paths && ischild((*cur)->e_path, new->e_path )) {
136 | /* the new node is the cur parent. drop cur. */
137 | tmp = *cur;
138 | *cur = (*cur)->e_next;
139 | free( tmp->e_path );
140 | free( tmp );
141 | /* the deletion takes care of the increment. */
142 | } else {
143 | if ( case_sensitive ) {
144 | rc = strcmp( new->e_path, (*cur)->e_path );
145 | } else {
146 | rc = strcasecmp( new->e_path, (*cur)->e_path );
147 | }
148 |
149 | if ( rc == 0 ) {
150 | /* new is already in the list. drop it. */
151 | free( new->e_path );
152 | free( new );
153 | return;
154 | } else if ( rc < 0 ) {
155 | break;
156 | } else {
157 | cur = &(*cur)->e_next;
158 | }
159 | }
160 | }
161 |
162 | new->e_next = *cur;
163 | *cur = new;
164 | }
165 |
166 | void
167 | event_print( struct event **head )
168 | {
169 | struct event *cur, *tmp;
170 |
171 | for ( cur = *head; cur != NULL; cur = tmp ) {
172 | printf( "%s\n", cur->e_path );
173 |
174 | tmp = cur->e_next;
175 |
176 | free( cur->e_path );
177 | free( cur );
178 | }
179 |
180 | *head = NULL;
181 | }
182 |
183 | void
184 | fsevent_callback( ConstFSEventStreamRef ref, void *info,
185 | size_t nevents, void *eventpaths,
186 | const FSEventStreamEventFlags eflags[],
187 | const FSEventStreamEventId eids[] )
188 | {
189 | struct event *new;
190 | char **paths = eventpaths;
191 | int i;
192 | time_t now;
193 |
194 | #define FSEVENTID "ID"
195 | #define FSEVENTFLAGS "Flags"
196 | #define FSEVENTPATH "Path"
197 |
198 | if ( debug && nevents > 0 ) {
199 | printf( "# %-8s %-10s %s\n", FSEVENTID, FSEVENTFLAGS, FSEVENTPATH );
200 | }
201 |
202 | for ( i = 0; i < nevents; i++ ) {
203 | if (( new = event_new( paths[ i ], eids[ i ],
204 | eflags[ i ] )) == NULL ) {
205 | perror( "event_new: malloc" );
206 | exit( 2 );
207 | }
208 | event_insert( &event_head, new );
209 |
210 | if ( debug ) {
211 | printf( "%-10llu %-10lu %s\n", eids[ i ], ( unsigned long )eflags[ i ], paths[ i ] );
212 | }
213 | }
214 |
215 | if ( nevents > 0 && !delayed_print ) {
216 | event_print( &event_head );
217 | }
218 | }
219 |
220 | /* called when the user-specified run time ends */
221 | void
222 | timer_callback( CFRunLoopRef runloop, void *info )
223 | {
224 | FSEventStreamRef fsstream = (FSEventStreamRef)info;
225 |
226 | /* block until all events are cleared. */
227 | FSEventStreamFlushSync( fsstream );
228 |
229 | CFRunLoopStop( CFRunLoopGetCurrent());
230 | }
231 |
232 | int
233 | main( int ac, char *av[] )
234 | {
235 | CFStringRef *paths = NULL;
236 | CFArrayRef watchpaths = NULL;
237 | FSEventStreamRef fsstream = NULL;
238 | CFAbsoluteTime latency = 2.0;
239 | CFRunLoopTimerRef timer;
240 | SInt32 runloop_rc;
241 | int watchtime = 0;
242 | int c;
243 | int i;
244 | int err = 0;
245 |
246 | extern int optind;
247 | extern char *optarg;
248 |
249 | while (( c = getopt( ac, av, "adIl:p:t:w" )) != -1 ) {
250 | switch ( c ) {
251 | case 'a': /* print all paths regardless of overlap. */
252 | all_paths = 1;
253 | break;
254 |
255 | case 'd': /* debug */
256 | debug = 1;
257 | break;
258 |
259 | case 'I': /* case-insensitive path comparisons */
260 | case_sensitive = 0;
261 | break;
262 |
263 | case 'l': /* latency */
264 | errno = 0;
265 | latency = strtod( optarg, NULL );
266 | if ( errno ) {
267 | fprintf( stderr, "strtod %s: %s\n", optarg, strerror( errno ));
268 | exit( 1 );
269 | }
270 | if ( latency < 0.0 ) {
271 | fprintf( stderr, "latency cannot be negative\n" );
272 | exit( 1 );
273 | }
274 | break;
275 |
276 | case 'p': /* prefix for path output. */
277 | if (( prefix = strdup( optarg )) == NULL ) {
278 | perror( "strdup" );
279 | exit( 2 );
280 | }
281 | break;
282 |
283 | case 't': /* time in seconds to watch given paths */
284 | errno = 0;
285 | watchtime = strtoul( optarg, NULL, 10 );
286 | if ( errno ) {
287 | fprintf( stderr, "strtoul %s: %s\n", optarg, strerror( errno ));
288 | exit( 1 );
289 | }
290 | break;
291 |
292 | case 'w': /* print paths after watchtime elapses. */
293 | delayed_print = 1;
294 | break;
295 |
296 | default:
297 | err++;
298 | break;
299 | }
300 | }
301 |
302 | if ( delayed_print && !watchtime ) {
303 | err++;
304 | }
305 |
306 | if ( err || ( ac - optind ) < 1 ) {
307 | fprintf( stderr, "usage: %s [ -adI ] [ -l delay_in_seconds ] "
308 | "[ -p path_prefix ] [ -t run_time_in_seconds [ -w ]] "
309 | "path1 [path2 path3 ... pathN]\n", av[ 0 ] );
310 | exit( 1 );
311 | }
312 |
313 | if (( paths = ( CFStringRef * )malloc(( ac - 1 ) * sizeof( CFStringRef )))
314 | == NULL ) {
315 | perror( "malloc" );
316 | exit( 2 );
317 | }
318 | for ( i = 1; i < ac; i++ ) {
319 | paths[ i - 1 ] = CFStringCreateWithCString( kCFAllocatorDefault,
320 | av[ i ], kCFStringEncodingUTF8 );
321 | if ( paths[ i - 1 ] == NULL ) {
322 | fprintf( stderr, "%s: failed to create CFStringRef\n", av[ i ] );
323 | exit( 2 );
324 | }
325 | }
326 | watchpaths = CFArrayCreate( kCFAllocatorDefault,
327 | ( const void ** )paths,
328 | ac - 1,
329 | &kCFTypeArrayCallBacks );
330 | if ( watchpaths == NULL ) {
331 | fprintf( stderr, "CFArrayCreate failed\n" );
332 | exit( 2 );
333 | }
334 |
335 | for ( i = 0; i < ( ac - 1 ); i++ ) {
336 | CFRelease( paths[ i ] );
337 | }
338 | free( paths );
339 |
340 | fsstream = FSEventStreamCreate( kCFAllocatorDefault, &fsevent_callback,
341 | NULL, watchpaths,
342 | kFSEventStreamEventIdSinceNow,
343 | latency, kFSEventStreamCreateFlagNone );
344 | if ( fsstream == NULL ) {
345 | fprintf( stderr, "FSEventStreamCreate failed\n" );
346 | exit( 2 );
347 | }
348 |
349 | /* line buffering to make sure we get the output */
350 | setlinebuf( stdout );
351 |
352 | FSEventStreamScheduleWithRunLoop( fsstream,
353 | CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
354 | if ( !FSEventStreamStart( fsstream )) {
355 | fprintf( stderr, "FSEventStreamStart failed\n" );
356 | exit( 2 );
357 | }
358 |
359 | if ( watchtime ) {
360 | CFRunLoopTimerContext context = { 0, fsstream, NULL, NULL, NULL };
361 | timer = CFRunLoopTimerCreate( kCFAllocatorDefault,
362 | watchtime + CFAbsoluteTimeGetCurrent(),
363 | 0, 0, 0,
364 | (CFRunLoopTimerCallBack)timer_callback,
365 | &context );
366 | if ( timer == NULL ) {
367 | fprintf( stderr, "CFRunLoopTimerCreate failed\n" );
368 | exit( 2 );
369 | }
370 | CFRunLoopAddTimer( CFRunLoopGetCurrent(),
371 | timer, kCFRunLoopDefaultMode );
372 | }
373 |
374 | CFRunLoopRun();
375 |
376 | if ( delayed_print ) {
377 | event_print( &event_head );
378 | }
379 |
380 | FSEventStreamStop( fsstream );
381 | FSEventStreamInvalidate( fsstream );
382 | FSEventStreamRelease( fsstream );
383 |
384 | if ( prefix != NULL ) {
385 | free( prefix );
386 | }
387 |
388 | return( 0 );
389 | }
390 |
--------------------------------------------------------------------------------
/contrib/specialist:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | # specialist: assist creation of special files.
4 |
5 | PATH=/bin:/usr/bin:/usr/local/bin; export PATH
6 |
7 | SCRIPT=`basename "$0"`
8 | INPUT_FORMAT=${INPUT_FORMAT:=path}
9 |
10 | usage() {
11 | echo "usage: ${SCRIPT} [ -T ]" 1>&2
12 | exit 1
13 | }
14 |
15 | die() {
16 | msg=$*
17 |
18 | echo "${msg}" 1>&2
19 | exit 2
20 | }
21 |
22 | # create a special transcript line for the given path.
23 | specialize() {
24 | local path="$1"
25 |
26 | [ -n "${path}" -a -f "${path}" ] || die "Invalid path: ${path}"
27 |
28 | fsdiff -1 -c sha1 "${path}"
29 | return $?
30 | }
31 |
32 | specialize_transcript() {
33 | local path=""
34 | status=0
35 |
36 | while read type path remainder; do
37 | if [ x"${type}" != x"f" ]; then
38 | continue
39 | fi
40 |
41 | specialize "${path}"
42 | done
43 | }
44 |
45 | specialize_paths() {
46 | local path=""
47 | status=0
48 |
49 | while read path; do
50 | specialize "${path}"
51 | if [ $? -ne 0 ]; then
52 | status=1
53 | fi
54 | done
55 |
56 | return "${status}"
57 | }
58 |
59 | while getopts T opt; do
60 | case $opt in
61 | T)
62 | INPUT_FORMAT="transcript"
63 | ;;
64 |
65 | *)
66 | usage
67 | ;;
68 |
69 | esac
70 | done
71 | shift $((OPTIND - 1))
72 |
73 | if [ x"${INPUT_FORMAT}" = x"transcript" ]; then
74 | specialize_transcript
75 | else
76 | specialize_paths
77 | fi
78 |
79 | exit $?
80 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | app:
4 | image: "ghcr.io/magnusviri/radmind:master"
5 | build:
6 | context: ./
7 | ports:
8 | - "6222:6222"
9 | volumes:
10 | - ./radmind:/var/radmind
11 |
--------------------------------------------------------------------------------
/docker/entrypoint:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eu
3 |
4 | if [ ! -e "/var/radmind/cert" ]; then
5 | mkdir -p /var/radmind/cert
6 | fi
7 | if [ ! -e "/var/radmind/client" ]; then
8 | mkdir /var/radmind/client
9 | fi
10 | if [ ! -e "/var/radmind/postapply" ]; then
11 | mkdir /var/radmind/postapply
12 | fi
13 | if [ ! -e "/var/radmind/preapply" ]; then
14 | mkdir /var/radmind/preapply
15 | fi
16 | if [ ! -e "/var/radmind/config" ]; then
17 | echo "* test.K" >> /var/radmind/config
18 | if [ ! -e "/var/radmind/command" ]; then
19 | mkdir /var/radmind/command
20 | fi
21 | if [ ! -e "/var/radmind/command/test.K" ]; then
22 | echo "# hi from radmind" > /var/radmind/command/test.K
23 | fi
24 | fi
25 |
26 | # Run radmind in the background because it doesn't log to stdout.
27 |
28 | /usr/local/sbin/radmind
29 |
30 | # Run rsyslog in foreground
31 |
32 | pidfile="/var/run/rsyslogd.pid"
33 | rm -f "${pidfile}"
34 | exec rsyslogd -n -f /etc/rsyslogd.conf -i "${pidfile}"
35 |
--------------------------------------------------------------------------------
/docker/etc/rsyslog.d/imux.conf:
--------------------------------------------------------------------------------
1 | # http://www.rsyslog.com/doc/
2 |
3 | # Input modules
4 | module(load="imuxsock")
5 | input(type="imuxsock" Socket="/var/run/rsyslog/dev/log" CreatePath="on")
6 |
--------------------------------------------------------------------------------
/docker/etc/rsyslog.d/stdout.conf:
--------------------------------------------------------------------------------
1 | # http://www.rsyslog.com/doc/
2 |
3 | # Output modes
4 | $ModLoad omstdout.so # provide messages to stdout
5 |
6 | # Actions
7 | *.* :omstdout: # send everything to stdout
8 |
--------------------------------------------------------------------------------
/docker/etc/rsyslogd.conf:
--------------------------------------------------------------------------------
1 | #
2 | # http://www.rsyslog.com/doc/
3 | #
4 |
5 | # Include all config files in /etc/rsyslog.d/
6 | #
7 | $IncludeConfig /etc/rsyslog.d/*.conf
8 |
--------------------------------------------------------------------------------
/hardlink.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "applefile.h"
15 | #include "transcript.h"
16 |
17 | struct devlist {
18 | struct devlist *d_next;
19 | dev_t d_dev;
20 | struct inolist *d_ilist;
21 | };
22 |
23 | struct inolist {
24 | struct inolist *i_next;
25 | ino_t i_ino;
26 | char *i_name;
27 | int i_flag;
28 | };
29 |
30 |
31 | static struct devlist *dev_head = NULL;
32 |
33 | static char *i_insert( struct devlist *dev_head,
34 | struct pathinfo *pinfo );
35 | static struct devlist *d_insert( struct devlist **dev_head,
36 | struct pathinfo *pinfo );
37 | void hardlink_free( void );
38 |
39 | char *
40 | hardlink( struct pathinfo *pinfo )
41 | {
42 | struct devlist *device;
43 |
44 | device = d_insert( &dev_head, pinfo );
45 |
46 | return( i_insert( device, pinfo ));
47 | }
48 |
49 | static struct devlist *
50 | d_insert( struct devlist **dev_head, struct pathinfo *pinfo )
51 | {
52 | struct devlist *new, **cur;
53 |
54 | for ( cur = dev_head; *cur != NULL; cur = &(*cur)->d_next ) {
55 | if ( pinfo->pi_stat.st_dev <= (*cur)->d_dev ) {
56 | break;
57 | }
58 | }
59 |
60 | if (( (*cur) != NULL ) && ( pinfo->pi_stat.st_dev == (*cur)->d_dev )) {
61 | return( *cur );
62 | }
63 |
64 | if (( new = ( struct devlist * ) malloc( sizeof( struct devlist )))
65 | == NULL ) {
66 | perror( "d_insert malloc" );
67 | exit( 2 );
68 | }
69 |
70 | new->d_dev = pinfo->pi_stat.st_dev;
71 | new->d_ilist = NULL;
72 | new->d_next = *cur;
73 | *cur = new;
74 |
75 | return( *cur );
76 | }
77 |
78 | static char *
79 | i_insert( struct devlist *dev_head, struct pathinfo *pinfo )
80 | {
81 | struct inolist *new, **cur;
82 |
83 | for ( cur = &dev_head->d_ilist; *cur != NULL; cur = &(*cur)->i_next ) {
84 | if ( pinfo->pi_stat.st_ino <= (*cur)->i_ino ) {
85 | break;
86 | }
87 | }
88 |
89 | if (( (*cur) != NULL ) && ( pinfo->pi_stat.st_ino == (*cur)->i_ino )) {
90 | return( (*cur)->i_name );
91 | }
92 |
93 | if (( new = ( struct inolist * ) malloc( sizeof( struct inolist )))
94 | == NULL ) {
95 | perror( "i_insert malloc" );
96 | exit( 2 );
97 | }
98 |
99 | if (( new->i_name = ( char * ) malloc( strlen( pinfo->pi_name ) + 1 ))
100 | == NULL ) {
101 | perror( "i_insert malloc" );
102 | exit( 2 );
103 | }
104 |
105 | strcpy( new->i_name, pinfo->pi_name );
106 | new->i_ino = pinfo->pi_stat.st_ino;
107 | new->i_flag = 0;
108 |
109 | new->i_next = *cur;
110 | *cur = new;
111 |
112 | return( NULL );
113 |
114 | }
115 |
116 | void
117 | hardlink_free( )
118 | {
119 | struct devlist *dev_next;
120 | struct inolist *ino_head, *ino_next;
121 |
122 | while ( dev_head != NULL ) {
123 | dev_next = dev_head->d_next;
124 | ino_head = dev_head->d_ilist;
125 | while ( ino_head != NULL ) {
126 | ino_next = ino_head->i_next;
127 | free( ino_head->i_name);
128 | free( ino_head );
129 | ino_head = ino_next;
130 | }
131 | free( dev_head );
132 | dev_head = dev_next;
133 | }
134 | }
135 |
136 | int
137 | hardlink_changed( struct pathinfo *pinfo, int set )
138 | {
139 | struct devlist *dcur;
140 | struct inolist *icur;
141 |
142 | for ( dcur = dev_head; dcur != NULL; dcur = dcur->d_next ) {
143 | if ( pinfo->pi_stat.st_dev <= dcur->d_dev ) {
144 | break;
145 | }
146 | }
147 |
148 | if (( dcur == NULL ) || ( pinfo->pi_stat.st_dev != dcur->d_dev )) {
149 | fprintf( stderr, "hardlink_changed: %s: dev not found\n",
150 | pinfo->pi_name );
151 | exit( 2 );
152 | }
153 |
154 | for ( icur = dcur->d_ilist; icur != NULL; icur = icur->i_next ) {
155 | if ( pinfo->pi_stat.st_ino <= icur->i_ino ) {
156 | break;
157 | }
158 | }
159 |
160 | if (( icur == NULL ) || ( pinfo->pi_stat.st_ino != icur->i_ino )) {
161 | fprintf( stderr, "hardlink_changed: %s: ino not found\n",
162 | pinfo->pi_name );
163 | exit( 2 );
164 | }
165 |
166 | if ( set ) {
167 | icur->i_flag = 1;
168 | }
169 |
170 | return( icur->i_flag );
171 | }
172 |
--------------------------------------------------------------------------------
/install-sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # install - install a program, script, or datafile
4 | # This comes from X11R5 (mit/util/scripts/install.sh).
5 | #
6 | # Copyright 1991 by the Massachusetts Institute of Technology
7 | #
8 | # Permission to use, copy, modify, distribute, and sell this software and its
9 | # documentation for any purpose is hereby granted without fee, provided that
10 | # the above copyright notice appear in all copies and that both that
11 | # copyright notice and this permission notice appear in supporting
12 | # documentation, and that the name of M.I.T. not be used in advertising or
13 | # publicity pertaining to distribution of the software without specific,
14 | # written prior permission. M.I.T. makes no representations about the
15 | # suitability of this software for any purpose. It is provided "as is"
16 | # without express or implied warranty.
17 | #
18 | # Calling this script install-sh is preferred over install.sh, to prevent
19 | # `make' implicit rules from creating a file called install from it
20 | # when there is no Makefile.
21 | #
22 | # This script is compatible with the BSD install script, but was written
23 | # from scratch. It can only install one file at a time, a restriction
24 | # shared with many OS's install programs.
25 |
26 |
27 | # set DOITPROG to echo to test this script
28 |
29 | # Don't use :- since 4.3BSD and earlier shells don't like it.
30 | doit="${DOITPROG-}"
31 |
32 |
33 | # put in absolute paths if you don't have them in your path; or use env. vars.
34 |
35 | mvprog="${MVPROG-mv}"
36 | cpprog="${CPPROG-cp}"
37 | chmodprog="${CHMODPROG-chmod}"
38 | chownprog="${CHOWNPROG-chown}"
39 | chgrpprog="${CHGRPPROG-chgrp}"
40 | stripprog="${STRIPPROG-strip}"
41 | rmprog="${RMPROG-rm}"
42 | mkdirprog="${MKDIRPROG-mkdir}"
43 |
44 | transformbasename=""
45 | transform_arg=""
46 | instcmd="$mvprog"
47 | chmodcmd="$chmodprog 0755"
48 | chowncmd=""
49 | chgrpcmd=""
50 | stripcmd=""
51 | rmcmd="$rmprog -f"
52 | mvcmd="$mvprog"
53 | src=""
54 | dst=""
55 | dir_arg=""
56 |
57 | while [ x"$1" != x ]; do
58 | case $1 in
59 | -c) instcmd="$cpprog"
60 | shift
61 | continue;;
62 |
63 | -d) dir_arg=true
64 | shift
65 | continue;;
66 |
67 | -m) chmodcmd="$chmodprog $2"
68 | shift
69 | shift
70 | continue;;
71 |
72 | -o) chowncmd="$chownprog $2"
73 | shift
74 | shift
75 | continue;;
76 |
77 | -g) chgrpcmd="$chgrpprog $2"
78 | shift
79 | shift
80 | continue;;
81 |
82 | -s) stripcmd="$stripprog"
83 | shift
84 | continue;;
85 |
86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'`
87 | shift
88 | continue;;
89 |
90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
91 | shift
92 | continue;;
93 |
94 | *) if [ x"$src" = x ]
95 | then
96 | src=$1
97 | else
98 | # this colon is to work around a 386BSD /bin/sh bug
99 | :
100 | dst=$1
101 | fi
102 | shift
103 | continue;;
104 | esac
105 | done
106 |
107 | if [ x"$src" = x ]
108 | then
109 | echo "install: no input file specified"
110 | exit 1
111 | else
112 | :
113 | fi
114 |
115 | if [ x"$dir_arg" != x ]; then
116 | dst=$src
117 | src=""
118 |
119 | if [ -d $dst ]; then
120 | instcmd=:
121 | chmodcmd=""
122 | else
123 | instcmd=$mkdirprog
124 | fi
125 | else
126 |
127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
128 | # might cause directories to be created, which would be especially bad
129 | # if $src (and thus $dsttmp) contains '*'.
130 |
131 | if [ -f $src -o -d $src ]
132 | then
133 | :
134 | else
135 | echo "install: $src does not exist"
136 | exit 1
137 | fi
138 |
139 | if [ x"$dst" = x ]
140 | then
141 | echo "install: no destination specified"
142 | exit 1
143 | else
144 | :
145 | fi
146 |
147 | # If destination is a directory, append the input filename; if your system
148 | # does not like double slashes in filenames, you may need to add some logic
149 |
150 | if [ -d $dst ]
151 | then
152 | dst="$dst"/`basename $src`
153 | else
154 | :
155 | fi
156 | fi
157 |
158 | ## this sed command emulates the dirname command
159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
160 |
161 | # Make sure that the destination directory exists.
162 | # this part is taken from Noah Friedman's mkinstalldirs script
163 |
164 | # Skip lots of stat calls in the usual case.
165 | if [ ! -d "$dstdir" ]; then
166 | defaultIFS='
167 | '
168 | IFS="${IFS-${defaultIFS}}"
169 |
170 | oIFS="${IFS}"
171 | # Some sh's can't handle IFS=/ for some reason.
172 | IFS='%'
173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
174 | IFS="${oIFS}"
175 |
176 | pathcomp=''
177 |
178 | while [ $# -ne 0 ] ; do
179 | pathcomp="${pathcomp}${1}"
180 | shift
181 |
182 | if [ ! -d "${pathcomp}" ] ;
183 | then
184 | $mkdirprog "${pathcomp}"
185 | else
186 | :
187 | fi
188 |
189 | pathcomp="${pathcomp}/"
190 | done
191 | fi
192 |
193 | if [ x"$dir_arg" != x ]
194 | then
195 | $doit $instcmd $dst &&
196 |
197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
201 | else
202 |
203 | # If we're going to rename the final executable, determine the name now.
204 |
205 | if [ x"$transformarg" = x ]
206 | then
207 | dstfile=`basename $dst`
208 | else
209 | dstfile=`basename $dst $transformbasename |
210 | sed $transformarg`$transformbasename
211 | fi
212 |
213 | # don't allow the sed command to completely eliminate the filename
214 |
215 | if [ x"$dstfile" = x ]
216 | then
217 | dstfile=`basename $dst`
218 | else
219 | :
220 | fi
221 |
222 | # Make a temp file name in the proper directory.
223 |
224 | dsttmp=$dstdir/#inst.$$#
225 |
226 | # Move or copy the file name to the temp name
227 |
228 | $doit $instcmd $src $dsttmp &&
229 |
230 | trap "rm -f ${dsttmp}" 0 &&
231 |
232 | # and set any options; do chmod last to preserve setuid bits
233 |
234 | # If any of these fail, we abort the whole thing. If we want to
235 | # ignore errors from any of these, just make sure not to ignore
236 | # errors from the above "$doit $instcmd $src $dsttmp" command.
237 |
238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
242 |
243 | # Now rename the file to the real destination.
244 |
245 | $doit $rmcmd -f $dstdir/$dstfile &&
246 | $doit $mvcmd $dsttmp $dstdir/$dstfile
247 |
248 | fi &&
249 |
250 |
251 | exit 0
252 |
--------------------------------------------------------------------------------
/largefile.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #ifndef SIZEOF_OFF_T
7 | #error "sizeof off_t unknown."
8 | #endif
9 |
10 | #if SIZEOF_OFF_T == 8
11 | #ifdef HAVE_STRTOLL
12 | #define strtoofft(x,y,z) (strtoll((x),(y),(z)))
13 | #else
14 | #define strtoofft(x,y,z) (strtol((x),(y),(z)))
15 | #endif
16 | #define PRIofft "ll"
17 | #else /* a bit of an assumption, here */
18 | #define strtoofft(x,y,z) (strtol((x),(y),(z)))
19 | #define PRIofft "l"
20 | #endif
21 |
22 | #if SIZEOF_TIME_T == 8
23 | #ifdef HAVE_STRTOLL
24 | #define strtotimet(x,y,z) (strtoll((x),(y),(z)))
25 | #else /* !HAVE_STRTOLL */
26 | #define strtotimet(x,y,z) (strtol((x),(y),(z)))
27 | #endif /* HAVE_STRTOLL */
28 | #define PRItimet "ll"
29 | #else /* SIZEOF_TIME_T != 8 */
30 | #define strtotimet(x,y,z) (strtol((x),(y),(z)))
31 | #define PRItimet "l"
32 | #endif /* SIZEOF_TIME_T */
33 |
--------------------------------------------------------------------------------
/list.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include "list.h"
15 | #include "pathcmp.h"
16 |
17 | struct node * _list_create_node( char *path );
18 |
19 | struct node *
20 | _list_create_node( char *path )
21 | {
22 | struct node *new_node;
23 |
24 | if ( strlen( path ) >= MAXPATHLEN ) {
25 | errno = ENAMETOOLONG;
26 | return( NULL );
27 | }
28 |
29 | if (( new_node = (struct node *) malloc( sizeof( struct node ))) == NULL ) {
30 | return( NULL );
31 | }
32 | memset( new_node, 0, sizeof( struct node ));
33 | sprintf( new_node->n_path, "%s", path );
34 |
35 | return( new_node );
36 | }
37 |
38 | struct list *
39 | list_new( void )
40 | {
41 | struct list *list;
42 |
43 | if (( list = malloc( sizeof( struct list ))) == NULL ) {
44 | return( NULL );
45 | }
46 |
47 | memset( list, 0, sizeof( struct list ));
48 | return( list );
49 | }
50 |
51 | void
52 | list_clear( struct list *list )
53 | {
54 | /* Remove items from tail of list */
55 | while ( list->l_tail != NULL ) {
56 | list_remove_tail( list );
57 | }
58 | }
59 |
60 | void
61 | list_free( struct list *list )
62 | {
63 | list_clear( list );
64 | free( list );
65 | }
66 |
67 | void
68 | list_print( struct list *list )
69 | {
70 | struct node *cur;
71 | u_int i;
72 |
73 | printf( "count: %d\n", list->l_count );
74 | for ( cur = list->l_head, i = 1; cur != NULL; cur = cur->n_next, i++ ) {
75 | printf( "%d: %s ( prev %s next %s )\n", i, cur->n_path,
76 | cur->n_prev ? cur->n_prev->n_path : "NULL",
77 | cur->n_next ? cur->n_next->n_path : "NULL" );
78 | }
79 | printf( "\n" );
80 | }
81 |
82 | int
83 | list_insert_case( struct list *list, char *path, int case_sensitive )
84 | {
85 | struct node *new_node, *cur;
86 |
87 | for ( cur = list->l_head; cur != NULL; cur = cur->n_next ) {
88 | if ( pathcasecmp( cur->n_path, path, case_sensitive ) > 0 ) {
89 | break;
90 | }
91 | }
92 |
93 | /* Insert at tail or into empty list */
94 | if ( cur == NULL ) {
95 | return( list_insert_tail( list, path ));
96 | }
97 |
98 | /* Insert at head */
99 | if ( cur->n_prev == NULL ) {
100 | return( list_insert_head( list, path ));
101 | }
102 |
103 | /* Insert in middle */
104 | if (( new_node = _list_create_node( path )) == NULL ) {
105 | return( -1 );
106 | }
107 | new_node->n_next = cur;
108 | cur->n_prev->n_next = new_node;
109 | new_node->n_prev = cur->n_prev;
110 | cur->n_prev = new_node;
111 |
112 | list->l_count++;
113 | return( 0 );
114 | }
115 |
116 | int
117 | list_insert( struct list *list, char *path )
118 | {
119 | return( list_insert_case( list, path, 1 ));
120 | }
121 |
122 | int
123 | list_insert_head( struct list *list, char *path )
124 | {
125 | struct node *new_node;
126 |
127 | if (( new_node = _list_create_node( path )) == NULL ) {
128 | return( -1 );
129 | }
130 |
131 | if ( list->l_head == NULL ) {
132 | list->l_tail = new_node;
133 | } else {
134 | list->l_head->n_prev = new_node;
135 | new_node->n_next = list->l_head;
136 | }
137 | list->l_head = new_node;
138 |
139 | list->l_count++;
140 | return( 0 );
141 | }
142 |
143 | int
144 | list_insert_tail( struct list *list, char *path )
145 | {
146 | struct node *new_node;
147 |
148 | if (( new_node = _list_create_node( path )) == NULL ) {
149 | return( -1 );
150 | }
151 |
152 | if ( list->l_tail == NULL ) {
153 | list->l_head = new_node;
154 | } else {
155 | list->l_tail->n_next = new_node;
156 | new_node->n_prev = list->l_tail;
157 | }
158 | list->l_tail = new_node;
159 |
160 | list->l_count++;
161 | return( 0 );
162 | }
163 |
164 | int
165 | list_remove( struct list *list, char *path )
166 | {
167 | int count = 0;
168 | struct node *cur;
169 |
170 | for ( cur = list->l_head; cur != NULL; cur = cur->n_next ) {
171 | if ( pathcmp( cur->n_path, path ) == 0 ) {
172 |
173 | if ( list->l_head == cur ) {
174 | list_remove_head( list );
175 | count++;
176 |
177 | } else if ( list->l_tail == cur ) {
178 | list_remove_tail( list );
179 | count++;
180 |
181 | } else {
182 | /* Remove item */
183 | cur->n_prev->n_next = cur->n_next;
184 | cur->n_next->n_prev = cur->n_prev;
185 | free( cur );
186 | list->l_count--;
187 | count++;
188 | }
189 | }
190 | }
191 |
192 | return( count );
193 | }
194 |
195 | void
196 | list_remove_tail( struct list *list )
197 | {
198 | struct node *node;
199 |
200 | if (( node = list_pop_tail( list )) != NULL ) {
201 | free( node );
202 | }
203 | }
204 |
205 | struct node *
206 | list_pop_tail( struct list * list )
207 | {
208 | struct node *node;
209 |
210 | if ( list->l_tail == NULL ) {
211 | return( NULL );
212 | }
213 | node = list->l_tail;
214 | if ( list->l_count == 1 ) {
215 | list->l_tail = NULL;
216 | list->l_head = NULL;
217 | } else {
218 | list->l_tail = list->l_tail->n_prev;
219 | list->l_tail->n_next = NULL;
220 | }
221 | list->l_count--;
222 | return( node );
223 | }
224 |
225 | void
226 | list_remove_head( struct list *list )
227 | {
228 | struct node *node;
229 |
230 | if (( node = list_pop_head( list )) != NULL ) {
231 | free( node );
232 | }
233 | }
234 |
235 | struct node *
236 | list_pop_head( struct list *list )
237 | {
238 | struct node *node;
239 |
240 | if ( list->l_head == NULL ) {
241 | return( NULL );
242 | }
243 | node = list->l_head;
244 | if ( list->l_count == 1 ) {
245 | list->l_tail = NULL;
246 | list->l_head = NULL;
247 | }
248 | if ( list->l_head != NULL ) {
249 | list->l_head = list->l_head->n_next;
250 | list->l_head->n_prev = NULL;
251 | }
252 | list->l_count--;
253 | return( node );
254 | }
255 |
256 | int
257 | list_check( struct list *list, char *path )
258 | {
259 | struct node *cur;
260 |
261 | for ( cur = list->l_head; cur != NULL; cur = cur->n_next ) {
262 | if ( pathcmp( cur->n_path, path ) == 0 ) {
263 | return( 1 );
264 | }
265 | }
266 |
267 | return( 0 );
268 | }
269 |
--------------------------------------------------------------------------------
/list.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | struct list
7 | {
8 | int l_count;
9 | struct node *l_head;
10 | struct node *l_tail;
11 | };
12 |
13 | struct node
14 | {
15 | char n_path[ MAXPATHLEN ];
16 | struct node *n_next;
17 | struct node *n_prev;
18 | };
19 |
20 | #define list_size( list ) ((list) ? (list)->l_count : 0 )
21 |
22 | struct list * list_new( void );
23 | void list_clear( struct list *list );
24 | void list_free( struct list *list );
25 | void list_print( struct list *list );
26 | int list_insert( struct list *list, char *path );
27 | int list_insert_case( struct list *list, char *path,
28 | int case_sensitive );
29 | int list_insert_head( struct list *list, char *path );
30 | int list_insert_tail( struct list *list, char *path );
31 | int list_remove( struct list *list, char *path );
32 | void list_remove_head( struct list *list );
33 | void list_remove_tail( struct list *list );
34 | struct node * list_pop_head( struct list *list );
35 | struct node * list_pop_tail( struct list *list );
36 | int list_check( struct list *list, char *path );
37 | int list_check_case( struct list *list, char *path );
38 |
--------------------------------------------------------------------------------
/llist.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "applefile.h"
14 | #include "transcript.h"
15 | #include "llist.h"
16 |
17 | /* Allocate a new list node */
18 | struct llist *
19 | ll_allocate( char *name )
20 | {
21 | struct llist *new;
22 |
23 | /* allocate space for next item in list */
24 | if (( new = (struct llist *)malloc( sizeof( struct llist ))) == NULL ) {
25 | perror( "malloc" );
26 | exit( 2 );
27 | }
28 |
29 | /* copy info into new item */
30 | strcpy( new->ll_name, name );
31 | new->ll_next = NULL;
32 |
33 | return new;
34 | }
35 |
36 | /* Free the whole list */
37 | void
38 | ll_free( struct llist *head )
39 | {
40 | struct llist *next;
41 |
42 | for ( ; head != NULL; head = next ) {
43 | next = head->ll_next;
44 | free( head );
45 | }
46 | }
47 |
48 | void
49 | ll_insert( struct llist **headp, struct llist *new )
50 | {
51 | struct llist **current;
52 |
53 | /* find where in the list to put the new entry */
54 | for ( current = headp; *current != NULL; current = &(*current)->ll_next) {
55 | if ( strcmp( new->ll_name, (*current)->ll_name ) <= 0 ) {
56 | break;
57 | }
58 | }
59 |
60 | new->ll_next = *current;
61 | *current = new;
62 | return;
63 | }
64 |
65 | /* Insert a new node into the list */
66 | void
67 | ll_insert_case( struct llist **headp, struct llist *new )
68 | {
69 | struct llist **current;
70 |
71 | /* find where in the list to put the new entry */
72 | for ( current = headp; *current != NULL; current = &(*current)->ll_next) {
73 | if ( strcasecmp( new->ll_name, (*current)->ll_name ) <= 0 ) {
74 | break;
75 | }
76 | }
77 |
78 | new->ll_next = *current;
79 | *current = new;
80 | return;
81 | }
82 |
--------------------------------------------------------------------------------
/llist.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | struct llist {
7 | char ll_name[ MAXPATHLEN ];
8 | struct llist *ll_next;
9 | };
10 |
11 | struct llist * ll_allocate( char * );
12 | void ll_free( struct llist * );
13 | void ll_insert( struct llist **, struct llist * );
14 | void ll_insert_case( struct llist **, struct llist * );
15 |
--------------------------------------------------------------------------------
/lmerge.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | struct tran
7 | {
8 | int num;
9 | int eof;
10 | int tac;
11 | int remove;
12 | int linenum;
13 | char *path;
14 | char *name;
15 | char *line;
16 | char tline[ 2 * MAXPATHLEN ];
17 | char prepath[ MAXPATHLEN ];
18 | char filepath[ MAXPATHLEN ];
19 | char **targv;
20 | FILE *fs;
21 | ACAV *acav;
22 | struct node *next;
23 | };
24 | int getnextline( struct tran *tran );
25 |
--------------------------------------------------------------------------------
/logname.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "logname.h"
12 |
13 | struct syslogname _sysloglevel[] = {
14 | { "emerg", LOG_EMERG },
15 | { "alert", LOG_ALERT },
16 | { "crit", LOG_CRIT },
17 | { "err", LOG_ERR },
18 | { "warning", LOG_WARNING },
19 | { "notice", LOG_NOTICE },
20 | { "info", LOG_INFO },
21 | { "debug", LOG_DEBUG },
22 | { 0, 0 },
23 | };
24 |
25 | struct syslogname _syslogfacility[] = {
26 | #ifdef LOG_KERN
27 | { "kern", LOG_KERN },
28 | #endif // LOG_KERN
29 | { "user", LOG_USER },
30 | { "mail", LOG_MAIL },
31 | { "daemon", LOG_DAEMON },
32 | { "auth", LOG_AUTH },
33 | { "syslog", LOG_SYSLOG },
34 | { "lpr", LOG_LPR },
35 | { "news", LOG_NEWS },
36 | { "uucp", LOG_UUCP },
37 | { "cron", LOG_CRON },
38 | #ifdef LOG_FTP
39 | { "ftp", LOG_FTP },
40 | #endif // LOG_FTP
41 | #ifdef LOG_AUTHPRIV
42 | { "authpriv", LOG_AUTHPRIV },
43 | #endif // LOG_AUTHPRIV
44 | { "local0", LOG_LOCAL0 },
45 | { "local1", LOG_LOCAL1 },
46 | { "local2", LOG_LOCAL2 },
47 | { "local3", LOG_LOCAL3 },
48 | { "local4", LOG_LOCAL4 },
49 | { "local5", LOG_LOCAL5 },
50 | { "local6", LOG_LOCAL6 },
51 | { "local7", LOG_LOCAL7 },
52 | { 0, 0 },
53 | };
54 |
55 | int
56 | syslogname( char *name, struct syslogname *sln )
57 | {
58 | for ( ; sln->sl_name != 0; sln++ ) {
59 | if ( strcasecmp( sln->sl_name, name ) == 0 ) {
60 | return( sln->sl_value );
61 | }
62 | }
63 | return( -1 );
64 | }
65 |
--------------------------------------------------------------------------------
/logname.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 | struct syslogname {
6 | char *sl_name;
7 | int sl_value;
8 | };
9 |
10 | extern struct syslogname _syslogfacility[], _sysloglevel[];
11 | int syslogname( char *, struct syslogname * );
12 |
13 | #define syslogfacility(x) syslogname((x),_syslogfacility)
14 | #define sysloglevel(x) syslogname((x),_sysloglevel)
15 |
--------------------------------------------------------------------------------
/lsize.c:
--------------------------------------------------------------------------------
1 | #include "config.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "argcargv.h"
13 | #include "list.h"
14 |
15 | #define K_CLIENT 0
16 | #define K_SERVER 1
17 |
18 | extern int errno;
19 |
20 | off_t lsize( char *tpath );
21 | off_t kfile_size( char *kfile, int location );
22 |
23 | static struct list *kfile_list;
24 | static char kdir[ MAXPATHLEN ];
25 |
26 | off_t
27 | lsize( char *tpath )
28 | {
29 | FILE *tfp = NULL;
30 | unsigned long long totalsize = 0, cursize = 0;
31 | char **tav = NULL;
32 | char line[ MAXPATHLEN * 2 ];
33 | int tac, linenum = 1;
34 |
35 | if (( tfp = fopen( tpath, "r" )) == NULL ) {
36 | fprintf( stderr, "fopen %s: %s\n", tpath, strerror( errno ));
37 | exit( 2 );
38 | }
39 |
40 | while ( fgets( line, MAXPATHLEN * 2, tfp ) != NULL ) {
41 | linenum++;
42 | if (( tac = argcargv( line, &tav )) != 8 ) {
43 | continue;
44 | }
45 |
46 | if ( *tav[ 0 ] != 'a' && *tav[ 0 ] != 'f' ) {
47 | continue;
48 | }
49 |
50 | /* XXX - use strtoofft */
51 | cursize = strtoull( tav[ 6 ], NULL, 10 );
52 | if ( errno == ERANGE || errno == EINVAL ) {
53 | fprintf( stderr, "line %d: strtoull %s: %s\n",
54 | linenum, tav[ 6 ], strerror( errno ));
55 | exit( 2 );
56 | }
57 |
58 | totalsize += cursize;
59 | }
60 |
61 | ( void )fclose( tfp );
62 |
63 | return( totalsize );
64 | }
65 |
66 | off_t
67 | kfile_size( char *kfile, int location )
68 | {
69 | FILE *fp;
70 | off_t cursize = 0, total = 0;
71 | int length, ac, linenum = 0;
72 | char line[ MAXPATHLEN ];
73 | char fullpath[ MAXPATHLEN ];
74 | char *subpath;
75 | char **av;
76 |
77 | if (( fp = fopen( kfile, "r" )) == NULL ) {
78 | perror( kfile );
79 | return( -1 );
80 | }
81 |
82 | while ( fgets( line, sizeof( line ), fp ) != NULL ) {
83 | linenum++;
84 | length = strlen( line );
85 | if ( line[ length - 1 ] != '\n' ) {
86 | fprintf( stderr, "command: line %d: line too long\n", linenum );
87 | return( -1 );
88 | }
89 |
90 | /* skips blank lines and comments */
91 | if ((( ac = argcargv( line, &av )) == 0 ) || ( *av[ 0 ] == '#' )) {
92 | continue;
93 | }
94 |
95 | if ( ac != 2 ) {
96 | fprintf( stderr, "command: line %d: expected 2 arguments, got %d\n",
97 | linenum, ac );
98 | return( -1 );
99 | }
100 |
101 | switch( location ) {
102 | case K_CLIENT:
103 | if ( snprintf( fullpath, MAXPATHLEN, "%s%s", kdir,
104 | av[ 1 ] ) >= MAXPATHLEN ) {
105 | fprintf( stderr, "command: line %d: path too long\n",
106 | linenum );
107 | fprintf( stderr, "command: line %d: %s%s\n",
108 | linenum, kdir, av[ 1 ] );
109 | return( -1 );
110 | }
111 | break;
112 |
113 | case K_SERVER:
114 | if ( *av[ 0 ] == 'k' ) {
115 | subpath = "command";
116 | } else {
117 | subpath = "transcript";
118 | }
119 | if ( snprintf( fullpath, MAXPATHLEN, "%s/%s/%s", _RADMIND_PATH,
120 | subpath, av[ 1 ] ) >= MAXPATHLEN ) {
121 | fprintf( stderr, "command: line %d: path too long\n",
122 | linenum );
123 | fprintf( stderr, "command: line %d: %s%s\n",
124 | linenum, kdir, av[ 1 ] );
125 | return( -1 );
126 | }
127 | break;
128 |
129 | default:
130 | fprintf( stderr, "unknown location\n" );
131 | return( -1 );
132 | }
133 |
134 | switch( *av[ 0 ] ) {
135 | case 'k': /* command file */
136 | if ( list_check( kfile_list, fullpath )) {
137 | fprintf( stderr,
138 | "%s: line %d: command file loop: %s already included\n",
139 | kfile, linenum, av[ 1 ] );
140 | return( -1 );
141 | }
142 | if ( list_insert( kfile_list, fullpath ) != 0 ) {
143 | perror( "list_insert" );
144 | return( -1 );
145 | }
146 |
147 | if (( cursize = kfile_size( fullpath, location )) < 0 ) {
148 | return( -1 );
149 | }
150 | total += cursize;
151 | break;
152 |
153 | case 'n': /* negative */
154 | /* XXX - include sizes from negative? */
155 | continue;
156 |
157 | case 'p': /* positive */
158 | total += lsize( fullpath );
159 | break;
160 |
161 | case 's': /* special */
162 | /* XXX - provide -h option to indicate client? */
163 | continue;
164 |
165 | default:
166 | fprintf( stderr, "command: line %d: '%s' invalid\n",
167 | linenum, av[ 0 ] );
168 | return( -1 );
169 | }
170 | }
171 |
172 | if ( fclose( fp ) != 0 ) {
173 | perror( kfile );
174 | return( -1 );
175 | }
176 |
177 | return( total );
178 | }
179 |
180 | int
181 | main( int ac, char *av[] )
182 | {
183 | char *path = NULL, *ext = NULL, *p;
184 | double totalsize = 0;
185 | int c, factor = 1024, err = 0, kfile = 0;
186 | extern int optind;
187 |
188 | while (( c = getopt( ac, av, "bgkm" )) != EOF ) {
189 | switch ( c ) {
190 | case 'b': /* bytes */
191 | factor = 1;
192 | break;
193 |
194 | case 'g': /* gigabytes */
195 | factor = ( 1024 * 1024 * 1024 );
196 | break;
197 |
198 | case 'k': /* kilobytes (default) */
199 | factor = 1024;
200 | break;
201 |
202 | case 'm': /* megabytes */
203 | factor = ( 1024 * 1024 );
204 | break;
205 |
206 | case '?':
207 | err++;
208 | }
209 | }
210 |
211 | path = av[ optind ];
212 |
213 | if ( err || ( ac - optind ) != 1 ) {
214 | fprintf( stderr, "Usage: %s [ -bgkmt ] { commandfile "
215 | "| transcript }\n", av[ 0 ] );
216 | exit( 1 );
217 | }
218 |
219 | if (( ext = strrchr( path, '.' )) != NULL ) {
220 | if ( strcmp( ++ext, "K" ) == 0 ) {
221 | kfile = 1;
222 | if ( strlen( path ) >= MAXPATHLEN ) {
223 | fprintf( stderr, "%s: path too long\n", path );
224 | exit( 2 );
225 | }
226 | strcpy( kdir, path );
227 |
228 | if (( p = strrchr( kdir, '/' )) == NULL ) {
229 | /* use working directory */
230 | strcpy( kdir, "./" );
231 | } else {
232 | p++;
233 | *p = (char)'\0';
234 | }
235 | if (( kfile_list = list_new()) == NULL ) {
236 | perror( "list_new" );
237 | exit( 2 );
238 | }
239 | if ( list_insert( kfile_list, path ) != 0 ) {
240 | perror( "list_insert" );
241 | exit( 2 );
242 | }
243 | }
244 | /* otherwise assume it's a transcript */
245 | }
246 |
247 | if ( kfile ) {
248 | if (( totalsize = ( double )kfile_size( path, K_SERVER )) < 0 ) {
249 | exit( 2 );
250 | }
251 | } else {
252 | totalsize = ( double )lsize( path );
253 | }
254 |
255 | totalsize /= ( double )factor;
256 |
257 | printf( "%.2f\n", totalsize );
258 |
259 | return( 0 );
260 | }
261 |
--------------------------------------------------------------------------------
/lsort.c:
--------------------------------------------------------------------------------
1 | #include "config.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "argcargv.h"
13 | #include "code.h"
14 | #include "pathcmp.h"
15 |
16 | int linecount;
17 | FILE *outtran;
18 |
19 | struct save_line {
20 | struct save_line *next;
21 | char *key;
22 | char *data;
23 | } *lines;
24 |
25 | void save_it( char *buffer, char *pathname );
26 | static int lsort_cmp( const void *a1, const void *b1 );
27 | void sort_them( void );
28 | void print_them( void );
29 | void process( char * arg );
30 |
31 | int case_sensitive = 1;
32 |
33 | void
34 | save_it( char *buffer, char *pathname )
35 | {
36 | struct save_line *sp;
37 |
38 | sp = malloc( sizeof( *sp ) + strlen( buffer ) + strlen( pathname ) + 4 );
39 | sp->key = (char*)( sp + 1 );
40 | strcpy( sp->key, pathname );
41 | sp->data = ( sp->key + strlen( sp->key ) + 1 );
42 | strcpy( sp->data, buffer );
43 | sp->next = lines;
44 | lines = sp;
45 | linecount++;
46 | }
47 |
48 | static int
49 | lsort_cmp( const void *a1, const void *b1 )
50 | {
51 | const struct save_line **a, **b;
52 |
53 | a = (const struct save_line**)a1;
54 | b = (const struct save_line**)b1;
55 |
56 | return( pathcasecmp((*a)->key, (*b)->key, case_sensitive ));
57 | }
58 |
59 | void
60 | sort_them( void )
61 | {
62 | struct save_line **x, *sp, **y;
63 |
64 | x = (struct save_line**) malloc( sizeof( *x ) * linecount );
65 | y = x;
66 |
67 | for ( sp = lines; sp; sp = sp->next ) {
68 | *y++ = sp;
69 | }
70 |
71 | qsort( x, linecount, sizeof *x, lsort_cmp );
72 |
73 | sp = 0;
74 | while ( y-- != x ) {
75 | (*y)->next = sp;
76 | sp = (*y);
77 | }
78 |
79 | lines = sp;
80 | }
81 |
82 | void
83 | print_them( void )
84 | {
85 | struct save_line *sp;
86 | for ( sp = lines; sp; sp = sp->next ) {
87 | fputs( sp->data, outtran );
88 | if ( ferror( outtran )) {
89 | perror( "fputs" );
90 | exit( 2 );
91 | }
92 | }
93 | }
94 |
95 | void
96 | process( char *arg )
97 | {
98 | FILE *f;
99 | ACAV *acav;
100 | char buffer[4096];
101 | char *fn;
102 | int lineno, argc;
103 | char **argv;
104 | char *line = NULL;
105 |
106 | if ( strcmp( arg, "-" )) {
107 | fn = arg;
108 | f = fopen( arg, "r" );
109 | } else {
110 | fn = "(stdin)";
111 | f = stdin;
112 | }
113 | if ( !f ) {
114 | perror( arg );
115 | exit( 2 );
116 | }
117 |
118 | acav = acav_alloc();
119 |
120 | lineno = 0;
121 | while ( fgets( buffer, sizeof buffer, f )) {
122 | lineno++;
123 |
124 | if (( line = strdup( buffer )) == NULL ) {
125 | perror( "strdup" );
126 | exit( 1 );
127 | }
128 |
129 | argc = acav_parse( acav, buffer, &argv );
130 |
131 | /* Skip blank lines */
132 | if ( argc == 0 ) {
133 | continue;
134 | }
135 |
136 | /* XXX - Drop comments - how would you sort them? */
137 | if ( *argv[ 0 ] == '#' ) {
138 | continue;
139 | }
140 |
141 | /* Get argument offset */
142 | if (( *argv[ 0 ] == '+' ) || ( *argv[ 0 ] == '-' )) {
143 | argv++;
144 | argc--;
145 | }
146 |
147 | if ( argc < 2 ) {
148 | fprintf( stderr, "%s: line %d: not enough fields\n", fn, lineno );
149 | exit( 1 );
150 | }
151 | save_it( line, decode( argv[ 1 ] ));
152 | }
153 |
154 | if ( f == stdin ) {
155 | clearerr( f );
156 | } else {
157 | fclose( f );
158 | }
159 |
160 | free( line );
161 | acav_free( acav );
162 | }
163 |
164 | int
165 | main( int argc, char **argv )
166 | {
167 | char c;
168 | int i, err = 0;
169 | extern char *version;
170 |
171 | outtran = stdout;
172 |
173 | while (( c = getopt( argc, argv, "Io:V" )) != EOF ) {
174 | switch( c ) {
175 | case 'I':
176 | case_sensitive = 0;
177 | break;
178 |
179 | case 'o':
180 | if (( outtran = fopen( optarg, "w" )) == NULL ) {
181 | perror( optarg );
182 | exit( 1 );
183 | }
184 | break;
185 |
186 | case 'V':
187 | printf( "%s\n", version );
188 | exit( 0 );
189 |
190 | default:
191 | err++;
192 | break;
193 | }
194 | }
195 |
196 | if ( err ) {
197 | fprintf( stderr, "Usage: %s [ -IV ] ", argv[ 0 ] );
198 | fprintf( stderr, "[ -o file ] [ files... ]\n" );
199 | exit( 1 );
200 | }
201 |
202 | if ( argc - optind == 0 ) {
203 | /* Only stdin */
204 | process( "-" );
205 | } else {
206 | /* Process all args */
207 | for ( i = optind; i < argc; i++ ) {
208 | if ( strcmp( argv[ i ], "-" ) == 0 ) {
209 | process( "-" );
210 | } else {
211 | process( argv[ i ] );
212 | }
213 | }
214 | }
215 |
216 | sort_them();
217 | print_them();
218 |
219 | exit( 0 );
220 | }
221 |
--------------------------------------------------------------------------------
/man/applefile.5:
--------------------------------------------------------------------------------
1 | .TH applefile "5" "_RADMIND_BUILD_DATE" "RSUG" "Headers, Environments, and Macros"
2 | .SH NAME
3 | .B applefile
4 | \- Radmind AppleSingle file
5 | .sp
6 | .SH DESCRIPTION
7 | To provide support for Mac OS X, radmind is aware of the Mac OS metadata used
8 | on HFS+-formatted drives. When
9 | .B lcreate
10 | uploads a file denoted in the transcript as an
11 | .B applefile
12 | (type 'a'), it encodes the file and the file's metadata to the server as an
13 | AppleSingle file. The AppleSingle file is an archive containing a file's
14 | relevant metadata and data in a single file stream. The radmind AppleSingle
15 | file has the following format:
16 | .sp
17 | 1) The AppleSingle header, consisting of a
18 | 4-byte magic number, 4-byte version number, 16-byte filler, 2-byte number
19 | denoting the number of entries in the archive, and 3 header entries, each
20 | describing the items in the archive and containing a 4-byte entry id, 4-byte
21 | offset, and 4-byte length;
22 | .sp
23 | 2) The file's Finder information (32 bytes),
24 | which stores
25 | the file's Type and Creator codes, as well its position in the Finder window;
26 | .sp
27 | 3) The file's Resource Fork, which contains things like images, sounds, and
28 | other data not easily or appropriately stored in the Data Fork;
29 | .sp
30 | 4) The file's
31 | Data Fork, the portion visible from the Finder, and the only part which is
32 | considered valid by flat file systems.
33 | .sp
34 | The radmind tool
35 | .B lapply
36 | similarly decodes the applefile from the server and restores it to the client
37 | Mac OS X machine running on an HFS+-formatted drive.
38 | .sp
39 | .SH MORE INFO
40 | The Apple Computer's AppleSingle RFC is available at
41 | .B http://www.faqs.org/rfcs/rfc1740.html.
42 | .sp
43 | .SH SEE ALSO
44 | .BR ktcheck (1),
45 | .BR lapply (1),
46 | .BR lcreate (1),
47 | .BR lcksum (1),
48 | .BR lfdiff (1),
49 | .BR lmerge (1),
50 | .BR lsort (1),
51 | .BR radmind (8),
52 | .BR twhich (1).
53 |
--------------------------------------------------------------------------------
/man/fsdiff.1:
--------------------------------------------------------------------------------
1 | .TH fsdiff "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B fsdiff
4 | \- compare filesystem to transcripts
5 | .SH SYNOPSIS
6 | .B fsdiff
7 | {
8 | .B -C
9 | |
10 | .B -A
11 | |
12 | .B -1
13 | } [
14 | .BI -IVWt
15 | ] [
16 | .BI \-K\ command
17 | ] [
18 | .BI \-c\ checksum
19 | ] [
20 | .BI \-o\ file
21 | [
22 | .BI -%
23 | ] ]
24 | .I path
25 | .sp
26 | .SH DESCRIPTION
27 | .B fsdiff
28 | reads a command file (the default name is
29 | .B command.K)
30 | to get a list of transcripts. If the command file is empty, the
31 | transcript list is considered to be the null transcript. Included command files
32 | are read depth first. The first
33 | transcript listed has the lowest precedence, the
34 | next higher, and the last has the highest.
35 | If any special files are
36 | listed, the
37 | .B special.T
38 | transcript will have the absolute highest precedence.
39 | .sp
40 | .B fsdiff
41 | walks the filesystem starting at
42 | .I path
43 | and compares the filesystem to the transcripts. Trailing '/'s on
44 | .I path
45 | are clipped.
46 | .sp
47 | If a transcript is
48 | .B positive,
49 | .B fsdiff
50 | checks all attributes of each file system object
51 | ( i.e. file, directory, link, etc ).
52 | If the -c option is given, checksums are also compared.
53 | If a transcript is
54 | .B negative,
55 | .B fsdiff
56 | checks only some of the attributes of the file system objects ( see
57 | TRANSCRIPTS section below ).
58 | There is only one
59 | .B special
60 | transcript,
61 | .B special.T,
62 | and it contains references to files that are host specific, eg.
63 | /etc/hostname.hme0.
64 | .sp
65 | Any discrepancies are printed on the standard output or, with the -o option,
66 | to a file. The default is to print the differences as edits to the
67 | transcript to make it match the filesystem. If the edit direction
68 | chosen is -T or -A, the differences are printed as edits to the file system
69 | to make it match the transcript. A "+" at the beginning of a line
70 | indicates a file must be downloaded. A "-" indicates the given object (
71 | file, directory, link etc ) must be removed.
72 | .sp
73 | .SH TRANSCRIPTS
74 | A transcript contains a list of filesystem objects, eg. directories,
75 | files, symbolic links etc. Transcripts have the following format:
76 | .sp
77 | .br
78 | type path [type specific information]
79 | .br
80 | .sp
81 | Type is a single letter: h, l, d, c, b, p, s, D, f, a. Path is the encoded
82 | path, where space is "\\b", tab is "\\t", newline is "\\n", carriage return
83 | is "\\r", and
84 | \\ is "\\\\". The type specific information varies.
85 | .sp
86 | .br
87 | l path target
88 | .br
89 | h path target
90 | .br
91 | .sp
92 | Type 'l' is a symbolic link and 'h' is a hard link. Target is encoded like
93 | path. If a symbolic link is listed in a negative transcript, the target
94 | is not checked.
95 | .sp
96 | .br
97 | d path mode uid gid [ finder-information ]
98 | .br
99 | D path mode uid gid
100 | .br
101 | s path mode uid gid
102 | .br
103 | p path mode uid gid
104 | .br
105 | .sp
106 | Type 'd' is a directory, 'D' is a door, 's' is a socket and 'p' is
107 | a named pipe. Mode is a 4 digit octal representation of the
108 | permissions. ( see
109 | .BR chmod(1).
110 | ) uid and gid are the user and group ids in decimal format.
111 | finder-information is used only on Mac OS X machines running on an
112 | HFS+ formatted drive to store directory finder information. If a
113 | directory is listed in a
114 | .B negative
115 | transcript, mode, uid, gid and, if listed, finder-information will
116 | be checked, but the directory itself will not be read.
117 | .sp
118 | .br
119 | b path mode uid gid major minor
120 | .br
121 | c path mode uid gid major minor
122 | .br
123 | .sp
124 | Type 'b' is a block special file, 'c' is a character special file.
125 | Major and minor are the major and minor device numbers in decimal.
126 | If a character special file is listed in a
127 | .B negative
128 | transcript, only major and minor device number will be checked.
129 | .sp
130 | .br
131 | f path mode uid gid mtime size checksum
132 | .br
133 | a path mode uid gid mtime size checksum
134 | .br
135 | .sp
136 | Type 'f' is a regular file. Mtime is a decimal number of seconds since 1970 GMT.
137 | Size is the size of the file in bytes. Checksum is the base64 encoded
138 | checksum if enabled, otherwise it is "-". If a file is listed in a
139 | .B negative
140 | transcript, only mode, uid and gid will be checked.
141 | .sp
142 | Type 'a' is an
143 | .B applefile,
144 | relevant only on Mac OS X machines running on an HFS+ formatted drive.
145 | An applefile
146 | has Mac OS metadata, and is stored on the server as an AppleSingle file
147 | (see applefile(5)).
148 | Everything that applies to
149 | a regular file applies to an applefile, as well.
150 | .sp
151 | Transcripts are sorted alphabetically, depth first, and case
152 | sensitively. This means subdirectories have precedence over files
153 | in the same directory: lexically, "/" has highest precedence. So
154 | the file:
155 | .sp
156 | /etc/passwd
157 | .sp
158 | comes before:
159 | .sp
160 | /etc.old
161 | .sp
162 | even though "." normally comes before "/", and:
163 | .sp
164 | /Library
165 | .sp
166 | would come before:
167 | .sp
168 | /dev
169 | .sp
170 | as capitalized characters are higher in precedence than
171 | lowercase ones. Both of the previous two directories would come
172 | before:
173 | .sp
174 | /etc.old
175 | .SH COMMAND FILES
176 | Command files have the following format:
177 | .br
178 | .sp
179 | type path
180 | .sp
181 | .br
182 | Type is 'k' for command file, 'p' for positive, 'n' for negative, 's'
183 | for special and 'x' for an exclude pattern. The
184 | argument path is either a command file name, transcript name,
185 | or in the case of type special, a full pathname.
186 | .br
187 | .br
188 | .sp
189 | # example command file
190 | .br
191 | k linux-base.K
192 | .br
193 | p test/denser-10.T
194 | .br
195 | p simta-032.T
196 | .br
197 | n simta-neg.T
198 | .br
199 | s /etc/fstab
200 | .br
201 | x /etc/tsm*.pid
202 | .sp
203 | Lines beginning with "#" are comments, and are skipped. A comment must
204 | be on a line by itself. Blank lines are also skipped. Exclude lines are
205 | wildcard patterns (see radmind(8) DESCRIPTION) of paths that will
206 | be ignored completely, that is, fsdiff will not care if an object matching
207 | an exclude line is present or absent, and will not print out anything
208 | relating to it. Exclude patterns apply to objects on the filesystem and
209 | paths in transcripts. Only special files are unaffected by excludes. For
210 | help determining which files you are excluding, use the -W flag.
211 | .sp
212 | If there is no command file, the transcript used is the null transcript.
213 | This means
214 | .B fsdiff
215 | will print out a difference line for every object in the
216 | filesystem, eg. a filesystem snapshot.
217 | .sp
218 | Positive and negative transcripts and special files can be removed from a command file by using minus lines. These lines effectively remove all previously referenced lines that match both the type and path of the minus line. Minus lines begin with a '-', followed by some amount of whitespace.
219 | .sp
220 | Minus lines only apply to transcripts and special files that have already been read from a command file. If a subsequent line or included command file lists the same transcript or special file, it will be once again included.
221 | .sp
222 | For example, if you wanted to remove the special file /etc/fstab from the previous example, you could use this command file:
223 | .br
224 | .br
225 | .sp
226 | # example command file
227 | .br
228 | k linux-base.K
229 | .br
230 | p test/denser-10.T
231 | .br
232 | p simta-032.T
233 | .br
234 | n simta-neg.T
235 | .br
236 | s /etc/fstab
237 | .br
238 | - s /etc/fstab
239 | .sp
240 | The minus line in this example would match the special file /etc/fstab, causing it to be effectively removed from the command file.
241 | .SH EXAMPLES
242 | In this example, fsdiff is used to generate a line for the negative
243 | transcript for /tmp.
244 | .sp
245 | .RS
246 | .nf
247 | example% fsdiff -1 /tmp
248 | d /tmp 1777 0 3
249 | example%
250 | .fi
251 | .RE
252 | .sp
253 | A more complete negative transcript might look like this:
254 | .sp
255 | .RS
256 | .nf
257 | example% vi negative.T
258 | f /etc/passwd 0444 0 3 993477914 482 -
259 | d /proc 0555 0 0
260 | d /tmp 1777 0 3
261 | f /var/adm/lastlog 0444 0 1 993662219 976304 -
262 | f /var/adm/messages 0644 0 0 993661335 94910 -
263 | f /var/adm/sulog 0600 0 0 993662246 422 -
264 | f /var/adm/utmpx 0644 0 2 993662219 2604 -
265 | f /var/adm/wtmpx 0644 4 4 993662219 111600 -
266 | f /var/cron/log 0600 0 0 993627000 2694 -
267 | d /xfn 0555 0 0
268 | .fi
269 | .RE
270 | .sp
271 | .SH OPTIONS
272 | .TP 19
273 | .B \-%
274 | percentage done progress output. Requires -o option.
275 | .TP 19
276 | .B no option
277 | fsdiff defaults to -A. Future releases will require an option explicitly.
278 | .TP 19
279 | .B \-1
280 | prints out a single transcript line for the given file. This option can be
281 | used to build
282 | .B negative
283 | transcripts.
284 | .TP 19
285 | .B \-A
286 | produces an applicable transcript.
287 | .TP 19
288 | .B \-C
289 | produces a creatable transcript.
290 | .TP 19
291 | .BI \-c\ checksum
292 | enables checksuming.
293 | .TP 19
294 | .BI \-I
295 | be case insensitive when compairing paths.
296 | .TP 19
297 | .BI \-K\ command
298 | specifies a command
299 | file name, by default
300 | .B _RADMIND_COMMANDFILE
301 | .TP 19
302 | .BI \-o\ file
303 | specifies an output file, default is the standard output.
304 | .TP 19
305 | .B \-V
306 | displays the version number of
307 | .BR fsdiff ,
308 | a list of supported checksumming algorithms in descending
309 | order of preference and then exits.
310 | .TP 19
311 | .B \-W
312 | prints a warning to the standard error when encountering an object
313 | matching an exclude pattern.
314 | .sp
315 | .TP 19
316 | .B \-t
317 | ignores files where only the timestamp has changed.
318 | .SH FILES
319 | .TP 19
320 | .B _RADMIND_COMMANDFILE
321 | name of the default command file.
322 | .TP 19
323 | .B special.T
324 | name of the special transcript.
325 | .sp
326 | .SH EXIT STATUS
327 | The following exit values are returned:
328 | .TP 5
329 | 0
330 | No errors.
331 | .TP 5
332 | >1
333 | An error occurred.
334 | .sp
335 | .SH SEE ALSO
336 | .BR ktcheck (1),
337 | .BR lapply (1),
338 | .BR lcksum (1),
339 | .BR lcreate (1),
340 | .BR lfdiff (1),
341 | .BR lmerge (1),
342 | .BR lsort (1),
343 | .BR twhich (1),
344 | .BR applefile (5),
345 | .BR radmind (8).
346 |
--------------------------------------------------------------------------------
/man/ktcheck.1:
--------------------------------------------------------------------------------
1 | .TH ktcheck "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B ktcheck
4 | \- verify and download command file and transcripts
5 | .SH SYNOPSIS
6 | .B ktcheck
7 | .RB [ \-CIinrV ]
8 | [
9 | .RB \-q\ |\ \-v
10 | ] [
11 | .BI \-D\ path
12 | ] [
13 | .BI \-e\ event
14 | ] [
15 | .BI \-c\ checksum
16 | ] [
17 | .BI \-K\ command-file
18 | ] [
19 | .BI \-h\ host
20 | ] [
21 | .BI \-p\ port
22 | ] [
23 | .BI \-P\ ca-pem-directory
24 | ] [
25 | .BI \-w\ auth-level
26 | ] [
27 | .BI \-x\ ca-pem-file
28 | ] [
29 | .BI \-y\ cert-pem-file
30 | ] [
31 | .BI \-z\ private-key-file
32 | ] [
33 | .BI \-Z\ compression-level
34 | ]
35 | .SH DESCRIPTION
36 | .B ktcheck
37 | verifies a client's command file with the radmind server
38 | .IR host .
39 | The command file is downloaded from
40 | .I host
41 | if it is missing or has the wrong size. With the -c option, checksums are
42 | also used to verify files.
43 |
44 | Reading the command file line-by-line,
45 | .B ktcheck
46 | verifies each command file and transcript listed, downloading it from
47 | .I host
48 | if it is missing or out of date.
49 | .B ktcheck
50 | ignors blank lines and comments ( lines starting with '#' ).
51 | Included command files are read are verified using the same method.
52 |
53 | Each special file listed in the command file is converted into a
54 | transcript line in special.T with information provided by
55 | .IR host .
56 | See
57 | .BR radmind (8)
58 | for details of the STAT command.
59 |
60 | If checksuming is turned on, the special transcript is verified using
61 | the checksum and file size. If either are wrong, the special transcript
62 | is updated.
63 | If checksuming is
64 | turned off, the special transcript is always updated.
65 |
66 | Files updated by
67 | .B ktcheck
68 | must be regular files and the user must have access to modify them.
69 |
70 | When run with the \-n option,
71 | .B ktcheck
72 | verifies but never downloads the command files or transcripts. A temporary
73 | special.T is created for verification and is removed on exit.
74 | .SH OPTIONS
75 | .TP 19
76 | .BI \-C
77 | clean
78 | .BR _RADMIND_DIR/client .
79 | .TP 19
80 | .BI \-c\ checksum
81 | enables checksuming.
82 | .TP 19
83 | .BI \-D\ path
84 | specifies the radmind working directory, by default
85 | .BR _RADMIND_PATH .
86 | .TP 19
87 | .BI \-e\ event
88 | the event type to report. This is limited to a single word, containing no
89 | white space. By default this is "ktcheck".
90 | .TP 19
91 | .BI \-I
92 | case-insensitive special.T, case-insensitive clean-up.
93 | .TP 19
94 | .BI \-i
95 | force output line buffering.
96 | .TP 19
97 | .BI \-h\ host
98 | specifies the radmind server, by default
99 | .BR _RADMIND_HOST .
100 | .TP 19
101 | .BI \-K\ command
102 | specifies a command file, by default
103 | .BR _RADMIND_COMMANDFILE .
104 | .TP 19
105 | .B \-n
106 | no files modified.
107 | .TP 19
108 | .BI \-p\ port
109 | specifies a port, by default
110 | .B 6222.
111 | .TP 19
112 | .BI \-P\ ca-pem-directory
113 | specifies a directory that contains certificates to be used when verifying the
114 | server. Certificates must be in PEM format and the directory must have been
115 | processed with the openssl c_rehash utility.
116 | .TP 19
117 | .B \-q
118 | suppress all messages.
119 | .TP 19
120 | .B \-r
121 | use random seed file $RANDFILE if that environment variable is set,
122 | $HOME/.rnd otherwise. See
123 | .BR RAND_load_file (3o).
124 | .TP 19
125 | .B \-V
126 | displays the version of
127 | .BR ktcheck ,
128 | a list of supported checksumming algorithms in descending
129 | order of preference and then exits.
130 | .TP 19
131 | .B \-v
132 | displays communication with the radmind server.
133 | .TP 19
134 | .BI \-w\ auth-level
135 | TLS authorization level, by default _RADMIND_AUTHLEVEL.
136 | 0 = no TLS, 1 = server verification, 2 = server and client verification.
137 | .TP 19
138 | .BI \-x\ ca-pem-file
139 | Certificate authority's public certificate, by default _RADMIND_TLS_CA.
140 | The default is not used when -P is specified.
141 | .TP 19
142 | .BI \-y\ cert-pem-file
143 | Client's public certificate, by default _RADMIND_TLS_CERT.
144 | .TP 19
145 | .BI \-z\ private-key-file
146 | Client's private key, by default _RADMIND_TLS_CERT.
147 | .TP 19
148 | .BI \-Z\ compression-level
149 | Compress all outbound data. compression-level can be between 0 and 9:
150 | 1 gives best speed, 9 gives best compression, 0 gives no compression at
151 | all (the input data is simply copied a block at a time).
152 | .SH FILES
153 | .TP 19
154 | .B _RADMIND_COMMANDFILE
155 | name of the default command file.
156 | .TP 19
157 | .B special.T
158 | name of the special transcript.
159 | .SH EXIT STATUS
160 | The following exit values are returned:
161 | .TP 5
162 | 0
163 | No differences were found.
164 | .TP 5
165 | 1
166 | Differences were found.
167 | .TP 5
168 | >1
169 | An error occurred.
170 | .SH SEE ALSO
171 | .BR fsdiff (1),
172 | .BR lapply (1),
173 | .BR lcksum (1),
174 | .BR lcreate (1),
175 | .BR lfdiff (1),
176 | .BR lmerge (1),
177 | .BR lsort (1),
178 | .BR twhich (1),
179 | .BR radmind (8),
180 | .BR RAND_load_file (3o).
181 |
--------------------------------------------------------------------------------
/man/lapply.1:
--------------------------------------------------------------------------------
1 | .TH lapply "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B lapply
4 | \- modify file system to match apply-able-transcript
5 | .SH SYNOPSIS
6 | .B lapply
7 | .RB [ \-CFiInrV ]
8 | [
9 | .RB \-%\ |\ \-q\ |\ \-v
10 | ] [
11 | .BI \-c\ checksum
12 | ] [
13 | .BI \-e\ event
14 | ] [
15 | .BI \-h\ host
16 | ] [
17 | .BI \-p\ port
18 | ] [
19 | .BI \-P\ ca-pem-directory
20 | ] [
21 | .BI \-u\ umask
22 | ] [
23 | .BI \-w\ auth-level
24 | ] [
25 | .BI \-x\ ca-pem-file
26 | ] [
27 | .BI \-y\ cert-pem-file
28 | ] [
29 | .BI \-z\ private-key-file
30 | ] [
31 | .BI \-Z\ compression-level
32 | ] {
33 | .I apply-able-transcript
34 | }
35 | .SH DESCRIPTION
36 | lapply reads an apply-able transcript line-by-line, modifying the file
37 | system to match the transcript. Transcript lines are applied in order
38 | unless they are directories marked for deletion. In such cases,
39 | subsequent transcript lines are first applied until the file system object
40 | listed is outside of the directory. If another directory marked for
41 | deletion is encountered, the process is started recursively.
42 | .sp
43 | lapply downloads missing files indicated by a "+" from the radmind server
44 | .I host.
45 | .I file
46 | is applied to the system with the attributes as described in
47 | the transcript line. File system objects marked with a "-" are removed.
48 | Other transcript lines indicate that a file system
49 | object must be modified or created if missing. lapply is not able to create
50 | doors or sockets.
51 | .sp
52 | File system objects listed in the transcript and present in the
53 | file system as a different type are automatically removed.
54 | .sp
55 | By default,
56 | .B lapply
57 | will exit with an error if an object's full path is not present on the file
58 | system. When run with the -C option,
59 | .B lapply
60 | will attempt to create any intermediate directories that are missing.
61 | Intermediated directories inherit the owner, group and permissions of its
62 | parent directory.
63 | .sp
64 | The radmind tools are unaware of user defined file flags, some of which
65 | may prevent lapply from successfully completing. Using the -F option,
66 | .B lapply
67 | will remove all user defined flags.
68 | .sp
69 | If
70 | .I apply-able-transcript
71 | is not given,
72 | .B lapply
73 | will use the standard input for reading.
74 | .sp
75 | .B lapply
76 | is also capable of decoding
77 | .B applefiles
78 | stored on the server by
79 | .B lcreate(1),
80 | restoring the files' Mac OS HFS+ metadata to the client machine. (Mac OS X,
81 | HFS+-formatted drives only.)
82 | .SH OPTIONS
83 | .TP 19
84 | .BI \-%
85 | percentage done progress output.
86 | .TP 19
87 | .BI \-c\ checksum
88 | enables checksuming.
89 | .TP 19
90 | .BI \-C
91 | create missing intermediate directories.
92 | .TP 19
93 | .BI \-e\ event
94 | the event type to report. This is limited to a single word, containing no
95 | white space. By default this is "lapply".
96 | .TP 19
97 | .BI \-h\ host
98 | specifies the radmind server, by default
99 | .BR _RADMIND_HOST .
100 | .TP 19
101 | .BI \-i
102 | force output linebuffering.
103 | .TP 19
104 | .BI \-I
105 | be case insensitive when comparing paths.
106 | .TP 19
107 | .B \-F
108 | remove all user defined flags for a file if they exist.
109 | .TP 19
110 | .B \-n
111 | no network connection will be made, causing only file system removals and
112 | updates to be applied. auth-level is implicitly set to 0.
113 | .TP 19
114 | .BI \-p\ port
115 | specifies the port of the radmind server, by default
116 | .BR 6222 .
117 | .TP 19
118 | .BI \-P\ ca-pem-directory
119 | specifies a directory that contains certificates to be used when verifying the server. Certificates must be in PEM format and the directory must have been
120 | processed with the openssl c_rehash utility.
121 | .TP 19
122 | .B \-q
123 | suppress all messages.
124 | .TP 19
125 | .B \-r
126 | use random seed file $RANDFILE if that environment variable is set,
127 | $HOME/.rnd otherwise. See
128 | .BR RAND_load_file (3o).
129 | .TP
130 | .BI \-u\ umask
131 | specifies the umask for temporary files, by default 0077
132 | .TP 19
133 | .B \-V
134 | displays the version number of
135 | .B lapply
136 | and exits.
137 | .TP 19
138 | .B \-v
139 | displays communication with the radmind server.
140 | .TP 19
141 | .BI \-w\ auth-level
142 | TLS authorization level, by default _RADMIND_AUTHLEVEL.
143 | 0 = no TLS, 1 = server verification, 2 = server and client verification.
144 | .TP 19
145 | .BI \-x\ ca-pem-file
146 | Certificate authority's public certificate, by default _RADMIND_TLS_CA.
147 | The default is not used when -P is specified.
148 | .TP 19
149 | .BI \-y\ cert-pem-file
150 | Client's public certificate, by default _RADMIND_TLS_CERT.
151 | .TP 19
152 | .BI \-z\ private-key-file
153 | Client's private key, by default _RADMIND_TLS_CERT.
154 | .TP 19
155 | .BI \-Z\ compression-level
156 | Compress all outbound data. compression-level can be between 0 and 9:
157 | 1 gives best speed, 9 gives best compression, 0 gives no compression at
158 | all (the input data is simply copied a block at a time).
159 | .SH EXIT STATUS
160 | The following exit values are returned:
161 | .TP 5
162 | 0
163 | Transcript was applied.
164 | .TP 5
165 | 1
166 | An error occurred, system was modified.
167 | .TP 5
168 | 2
169 | An error occurred, system was not modified.
170 | .SH SEE ALSO
171 | .BR fsdiff (1),
172 | .BR ktcheck (1),
173 | .BR lcksum (1),
174 | .BR lcreate (1),
175 | .BR lfdiff (1),
176 | .BR lmerge (1),
177 | .BR lsort (1),
178 | .BR twhich (1),
179 | .BR applefile (5),
180 | .BR radmind (8),
181 | .BR chflags (2),
182 | .BR RAND_load_file (3o).
183 |
--------------------------------------------------------------------------------
/man/lcksum.1:
--------------------------------------------------------------------------------
1 | .TH lcksum "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B lcksum
4 | \- verifies a transcript's checksums and file sizes
5 | .SH SYNOPSIS
6 | .B lcksum
7 | .RB [ \-%AiIqV ]
8 | [
9 | .BI \-D\ path
10 | ] [
11 | .BI \-n
12 | [
13 | .BI \-a
14 | ]] [
15 | .BI \-P\ prefix
16 | ]
17 | .BI \-c\ checksum
18 | .I transcript
19 | .I ...
20 | .sp
21 | .SH DESCRIPTION
22 | .B lcksum
23 | verifies and updates the checksums and file sizes of the
24 | transcript
25 | .I transcript
26 | line-by-line. If more than one transcript is passed to
27 | .B lcksum,
28 | all transcripts will be verified and updated.
29 | .B lcksum
30 | compares the checksum and
31 | file size listed in
32 | .I transcript
33 | to that
34 | of the file in the file system. Files must be located in
35 | file directory associated with
36 | .IR transcript .
37 | With the \-n option
38 | .B lcksum
39 | verifies but does not modify
40 | .IR transcript .
41 |
42 | If there is a difference in either the checksum or file size, the
43 | transcript line is updated using the checksum, file size and
44 | modification time of the actual file.
45 |
46 | In update mode,
47 | .B lcksum
48 | may modify the file sizes and/or checksums in
49 | .IR transcript ,
50 | so the user must have write access to
51 | .IR transcript .
52 | If an error occurs during an update of
53 | .IR transcript ,
54 | lcksum removes the temporary copy of
55 | .IR transcript
56 | that it created and exits with a status of 2.
57 |
58 | .B lcksum
59 | also verifies that
60 | .I transcript
61 | is sorted in depth first order.
62 |
63 | With the \-P option,
64 | .B lcksum
65 | will only verify transcript lines with paths starting with
66 | .IR prefix .
67 | .sp
68 | .SH OPTIONS
69 | .TP 19
70 | .B \-%
71 | progress output.
72 | .TP 19
73 | .B \-a
74 | continue checking on error. Requires -n option.
75 | .TP 19
76 | .B \-A
77 | verify AppleSingle headers.
78 | .TP 19
79 | .BI \-c\ checksum
80 | enables checksuming.
81 | .TP 19
82 | .BI \-D\ path
83 | specifies the radmind working directory, by default _RADMIND_PATH
84 | .TP 19
85 | .B \-i
86 | force line buffering.
87 | .TP 19
88 | .BI \-I
89 | be case insensitive when compairing paths.
90 | .TP 19
91 | .B \-n
92 | verify but do not modify
93 | .IR transcript .
94 | .TP 19
95 | .BI \-P\ prefix
96 | only verify transcript lines that begin with
97 | .IR prefix .
98 | .TP 19
99 | .B \-q
100 | suppress all messages.
101 | .TP 19
102 | .B \-V
103 | displays the version of
104 | .BR lcksum
105 | and a list of supported checksumming algorithms in descending
106 | order of preference and then exits.
107 | .sp
108 | .SH EXIT STATUS
109 | The following exit values are returned:
110 | .TP 5
111 | 0
112 | Transcript was verified.
113 | .TP 5
114 | 1
115 | Differences were found.
116 | .TP 5
117 | >1
118 | An error occurred.
119 | .sp
120 | .SH SEE ALSO
121 | .BR fsdiff (1),
122 | .BR ktcheck (1),
123 | .BR lapply (1),
124 | .BR lcreate (1),
125 | .BR lfdiff (1),
126 | .BR lmerge (1),
127 | .BR lsort (1),
128 | .BR twhich (1),
129 | .BR radmind (8).
130 |
--------------------------------------------------------------------------------
/man/lcreate.1:
--------------------------------------------------------------------------------
1 | .TH lcreate "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B lcreate
4 | \- upload transcripts and their corresponding files
5 | .SH SYNOPSIS
6 | .B lcreate
7 | .RB [ \-FilnNrTV ]
8 | [
9 | .RB \-%\ |\ \-q\ |\ \-v
10 | ] [
11 | .BI \-c\ checksum
12 | ] [
13 | .BI \-h\ host
14 | ] [
15 | .BI \-p\ port
16 | ] [
17 | .BI \-P\ ca-pem-directory
18 | ] [
19 | .BI \-t\ stored-name
20 | ] [
21 | .BI \-U\ user
22 | ] [
23 | .BI \-w\ auth-level
24 | ] [
25 | .BI \-x\ ca-pem-file
26 | ] [
27 | .BI \-y\ cert-pem-file
28 | ] [
29 | .BI \-z\ private-key-file
30 | ] [
31 | .BI \-Z\ compression-level
32 | ]
33 | .I create-able-transcript
34 | .SH DESCRIPTION
35 | .B lcreate
36 | reads and uploads a transcript and all corresponding files to the
37 | radmind server.
38 | .sp
39 | .B lcreate
40 | verifies the size listed in the transcript with the actual size of the file
41 | and stops on any differences.
42 | If the -F option is given,
43 | .B lcreate
44 | will store the file on the server and give a warning.
45 | .sp
46 | If the -n option is given, no files or transcripts are uploaded. Instead,
47 | .B lcreate
48 | uses
49 | .BR access (2)
50 | to verify that all files in the transcript exist in the
51 | filesystem, are readable by the user and have the same size as listed in the
52 | transcript. If used with the -c option, rather than calling
53 | .BR access (2),
54 | checksums are caluclated to
55 | verify file contents and user access.
56 | .sp
57 | If the -N option is
58 | given, indicating the transcript specified for upload is negative,
59 | .B lcreate
60 | will upload all corresponding files as zero length.
61 | .sp
62 | If the -T option is
63 | given,
64 | .B lcreate
65 | will upload the transcript only. No corresponding files will be
66 | uploaded. The transcript's stored name is, by default, the last part (
67 | after the slash ) of the given path, or as specified by the name given
68 | with the -t option.
69 | .B lcreate
70 | will print ( to the standard output ) the entire protocol exchange with the
71 | radmind server when the -v option is given.
72 | .sp
73 | By default,
74 | .B lcreate
75 | displays the percentage of bytes processed in a format that can be passed directly to iHook.
76 | .sp
77 | .B lcreate
78 | stores a Macintosh HFS+ file's data and corresponding metadata in a single
79 | .B applefile(5)
80 | on the server. With the -N option, applefiles are stored with a zero length
81 | resource fork, zero length data fork and a creator type of RDMD.
82 | Systems running Mac OS X on UFS-formatted drives do not need
83 | this special support.
84 | .SH OPTIONS
85 | .TP 19
86 | .BI \-%
87 | percentage done progress output.
88 | .TP 19
89 | .BI \-c\ checksum
90 | enables checksuming.
91 | .TP 19
92 | .BI \-F
93 | ignore file size differences.
94 | .TP 19
95 | .BI \-h\ hostname
96 | specifies the radmind server, by default
97 | .BR _RADMIND_HOST .
98 | .TP 19
99 | .BI \-i
100 | force output linebuffering.
101 | .TP 19
102 | .B \-l
103 | Turn on user authentication. Requires a TLS.
104 | .TP 19
105 | .B \-N
106 | uploads a
107 | .B negative
108 | transcript then uploads all corresponding files as zero length.
109 | .TP 19
110 | .B \-n
111 | Don't upload any files or transcripts. Verify all
112 | files in the transcript exist in the filesystem and have the size listed
113 | in the transcript.
114 | .TP 19
115 | .BI \-p\ port
116 | specifies a port, by default
117 | .BR 6222 .
118 | .TP 19
119 | .BI \-P\ ca-pem-directory
120 | specifies a directory that contains certificates to be used when verifying the server. Certificates must be in PEM format and the directory must have been
121 | processed with the openssl c_rehash utility.
122 | .TP 19
123 | .B \-q
124 | suppress all messages.
125 | .TP 19
126 | .B \-r
127 | use random seed file $RANDFILE if that environment variable is set,
128 | $HOME/.rnd otherwise. See
129 | .BR RAND_load_file (3o).
130 | .TP 19
131 | .B \-T
132 | uploads the transcript only, and
133 | .B not
134 | the corresponding files.
135 | .TP 19
136 | .BI \-t\ stored-name
137 | specifies the name under which the transcript will be stored when saved
138 | on the server.
139 | .TP 19
140 | .BI \-U\ user
141 | Specifes the user for user authentication. By default, the login name
142 | returned by
143 | .B getlogin()
144 | will be used.
145 | .TP 19
146 | .B \-V
147 | displays the version of
148 | .BR lcreate ,
149 | a list of supported checksumming algorithms in descending
150 | order of preference and then exits.
151 | .TP 19
152 | .B \-v
153 | increase the verbosity. -v produces one line for each file stored on the
154 | server. -vv displays all communication with the radmind server.
155 | .TP 19
156 | .BI \-w\ auth-level
157 | TLS authorization level, by default _RADMIND_AUTHLEVEL.
158 | 0 = no TLS, 1 = server verification, 2 = server and client verification.
159 | .TP 19
160 | .BI \-x\ ca-pem-file
161 | Certificate authority's public certificate, by default _RADMIND_TLS_CA.
162 | The default is not used when -P is specified.
163 | .TP 19
164 | .BI \-y\ cert-pem-file
165 | Client's public certificate, by default _RADMIND_TLS_CERT.
166 | .TP 19
167 | .BI \-z\ private-key-file
168 | Client's private key, by default _RADMIND_TLS_CERT.
169 | .TP 19
170 | .BI \-Z\ compression-level
171 | Compress all outbound data. compression-level can be between 0 and 9:
172 | 1 gives best speed, 9 gives best compression, 0 gives no compression at
173 | all (the input data is simply copied a block at a time).
174 | .SH SEE ALSO
175 | .BR fsdiff (1),
176 | .BR ktcheck (1),
177 | .BR lapply (1),
178 | .BR lcksum (1),
179 | .BR lfdiff (1),
180 | .BR lmerge (1),
181 | .BR lsort (1),
182 | .BR twhich (1),
183 | .BR applefile (5),
184 | .BR radmind (8),
185 | .BR RAND_load_file (3o).
186 |
--------------------------------------------------------------------------------
/man/lfdiff.1:
--------------------------------------------------------------------------------
1 | .TH lfdiff "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B lfdiff
4 | \- compare local files with copies on radmind server
5 | .SH SYNOPSIS
6 | .B lfdiff
7 | [
8 | .B \-IrvV
9 | ] [
10 | .BI \-T\ transcript
11 | |
12 | .B \-S
13 | ] [
14 | .BI \-h\ host
15 | ] [
16 | .BI \-p\ port
17 | ] [
18 | .BI \-P\ ca-pem-directory
19 | ] [
20 | .BI \-u\ umask
21 | ] [
22 | .BI \-w\ auth-level
23 | ] [
24 | .BI \-x\ ca-pem-file
25 | ] [
26 | .BI \-y\ cert-pem-file
27 | ] [
28 | .BI \-z\ private-key-file
29 | ] [
30 | .BI \-Z\ compression-level
31 | ] [
32 | .I supported\ diff\ options
33 | ] [
34 | .B \-X
35 | .I unsupported\ diff\ options
36 | ]
37 | .I file
38 | .SH DESCRIPTION
39 | .B lfdiff
40 | retrieves
41 | .IR file ,
42 | given as an unencoded path,
43 | from the radmind server
44 | .I host
45 | and writes it to
46 | /tmp.
47 | .I file
48 | is then compared to the local copy of
49 | .I file
50 | using
51 | .BR diff (1).
52 | The server copy and the local copy of
53 | .I file
54 | are passed to
55 | .BR diff (1)
56 | as file1
57 | and file2 arguments respectively.
58 | .I file
59 | is removed from /tmp on exit.
60 | .B lfdiff
61 | supports all single letter
62 | .BR diff (1)
63 | options not duplicated in
64 | .BR lfdiff .
65 | All other
66 | .BR diff (1)
67 | options are given using the \-X option.
68 | .SH OPTIONS
69 | .TP 19
70 | .B \-I
71 | compare paths case-insensitively
72 | .TP 19
73 | .BI \-h\ host
74 | specifies the radmind server, by default
75 | .BR _RADMIND_HOST .
76 | .TP 19
77 | .BI \-p\ port
78 | specifies the port of the radmind server, by default
79 | .BR 6222 .
80 | .TP 19
81 | .BI \-P\ ca-pem-directory
82 | specifies a directory that contains certificates to be used when verifying the server. Certificates must be in PEM format and the directory must have been
83 | processed with the openssl c_rehash utility.
84 | .TP 19
85 | .B \-r
86 | use random seed file $RANDFILE if that environment variable is set,
87 | $HOME/.rnd otherwise. See
88 | .BR RAND_load_file (3o).
89 | .TP 19
90 | .B \-S
91 | .I file
92 | is a special file.
93 | .TP 19
94 | .BI \-T\ transcript
95 | transcript that
96 | .I file
97 | is listed in.
98 | .TP
99 | .BI \-u\ umask
100 | specifies the umask for temporary files, by default 0077
101 | .TP 19
102 | .B \-V
103 | displays the version of
104 | .B lfdiff
105 | and exits.
106 | .TP 19
107 | .BI \-v
108 | display communication with the radmind server.
109 | .TP 19
110 | .BI \-X\ unsupported\ diff\ options
111 | passes options directly to
112 | .BR diff (1).
113 | .TP 19
114 | .BI \-w\ auth-level
115 | TLS authorization level, by default _RADMIND_AUTHLEVEL.
116 | 0 = no TLS, 1 = server verification, 2 = server and client verification.
117 | .TP 19
118 | .BI \-x\ ca-pem-file
119 | Certificate authority's public certificate, by default _RADMIND_TLS_CA.
120 | .TP 19
121 | .BI \-y\ cert-pem-file
122 | Client's public certificate, by default _RADMIND_TLS_CERT.
123 | The default is not used when -P is specified.
124 | .TP 19
125 | .BI \-z\ private-key-file
126 | Client's private key, by default _RADMIND_TLS_CERT.
127 | .TP 19
128 | .BI \-Z\ compression-level
129 | Compress all outbound data. compression-level can be between 0 and 9:
130 | 1 gives best speed, 9 gives best compression, 0 gives no compression at
131 | all (the input data is simply copied a block at a time).
132 | .SH EXIT STATUS
133 | The following exit values are returned:
134 | .TP 5
135 | 0
136 | No differences were found.
137 | .TP 5
138 | 1
139 | Differences were found.
140 | .TP 5
141 | >1
142 | An error occurred.
143 | .SH SEE ALSO
144 | .BR diff (1),
145 | .BR fsdiff (1),
146 | .BR ktcheck (1),
147 | .BR lapply (1),
148 | .BR lcksum (1),
149 | .BR lcreate (1),
150 | .BR lmerge (1),
151 | .BR lsort (1),
152 | .BR twhich (1),
153 | .BR radmind (8),
154 | .BR RAND_load_file (3o).
155 |
--------------------------------------------------------------------------------
/man/lmerge.1:
--------------------------------------------------------------------------------
1 | .TH lmerge "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B lmerge
4 | \- lmerge combines multiple transcripts into one.
5 | .SH SYNOPSIS
6 | .B lmerge
7 | .RB [ \-CIiVvT ]
8 | [
9 | .BI \-D\ path
10 | ] [
11 | .BI \-u\ umask
12 | ]
13 | .IR transcript ...
14 | .I dest
15 | .br
16 | .B lmerge
17 | .B \-f
18 | .RB [ \-IiVv ]
19 | [
20 | .BI \-D\ path
21 | ] [
22 | .BI \-u\ umask
23 | ]
24 | .I transcript1 transcript2
25 | .br
26 | .B lmerge
27 | .B \-n
28 | .RB [ \-IiVvT ]
29 | [
30 | .BI \-D\ path
31 | ] [
32 | .BI \-u\ umask
33 | ]
34 | .I transcript1 transcript2 dest
35 | .br
36 | .sp
37 | .SH DESCRIPTION
38 | .B lmerge
39 | walks through each transcript in precedence order ( highest precedence
40 | transcript listed first ) to create the apply-able transcript
41 | .IR dest .
42 | If multiple transcripts list the same file system object, the transcript
43 | line from the highest precedence transcript is written to
44 | .IR dest .
45 |
46 | Blank lines and comments ( lines starting with # ) are not written to
47 | .IR dest .
48 |
49 | With the \-f option
50 | .B lmerge
51 | does not create a new transcript and merges the first transcript into the
52 | second transcript. The second transcript must be writable by the user.
53 | Only two transcripts are allowed.
54 |
55 | If the highest precedence listing of a file system object is preceded with a
56 | \'-', the transcript line will not be written to
57 | .IR dest .
58 |
59 | Files listed in
60 | .I dest
61 | are linked from their original location to a file directory created by
62 | .BR lmerge .
63 | This directory is relative to the location of
64 | .IR dest .
65 | Since files are linked, all transcripts ( including
66 | .I dest
67 | ) and files must be located on the same volume.
68 |
69 | The \-C options runs
70 | .B lmerge
71 | in copy mode. Files listed in
72 | .I dest
73 | are copied from their original locations and are not linked.
74 |
75 | Using the \-f option,
76 | .B lmerge
77 | links all files from the lowest precedence
78 | transcript. If the transcript line for a file is preceded with a "-"
79 | it is also removed from the file directory associated with the lowest precedence
80 | transcript.
81 |
82 | The \-n option indicates that the highest precedence transcript has no
83 | associated file directory. All files listed in the highest precedence
84 | transcript must be in the file directory associated with the lowest precedence
85 | transcript. A transcript line in the highest precedence transcript written to
86 | .IR dest ,
87 | but files are linked from the lowest precedence transcript. Only two
88 | transcripts can be merged with the \-n option.
89 | .SH OPTIONS
90 | .TP 19
91 | .B \-C
92 | enable copy mode.
93 | .TP 19
94 | .B \-f
95 | merge
96 | .B transcript1
97 | into
98 | .IR transcript2 .
99 | .TP 19
100 | .BI \-D\ path
101 | specifies the radmind working directory, by default _RADMIND_PATH
102 | .TP 19
103 | .BI \-I
104 | path comparisons are case-insensitive.
105 | .TP 19
106 | .B \-n
107 | merge two transcripts linking all files from the lowest precedence
108 | transcript.
109 | .TP 19
110 | .B \-T
111 | merge transcripts only. Do not perform file system linking.
112 | May not be used with the \-f option.
113 | .TP 19
114 | .BI \-u\ umask
115 | use
116 | .I umask
117 | as the file mode creation mask, default is users umask.
118 | .TP 19
119 | .B \-V
120 | displays the version of
121 | .B lmerge
122 | and exits.
123 | .TP 19
124 | .B \-v
125 | displays merge information to the standard output.
126 | .sp
127 | .SH EXIT STATUS
128 | The following exit values are returned:
129 | .TP 5
130 | 0
131 | Merge successful.
132 | .TP 5
133 | >1
134 | An error occurred.
135 | .sp
136 | .SH SEE ALSO
137 | .BR fsdiff (1),
138 | .BR ktcheck (1),
139 | .BR lapply (1),
140 | .BR lcksum (1),
141 | .BR lcreate (1),
142 | .BR lfdiff (1),
143 | .BR lsort (1),
144 | .BR twhich (1),
145 | .BR radmind (8).
146 |
--------------------------------------------------------------------------------
/man/lsort.1:
--------------------------------------------------------------------------------
1 | .TH lsort "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B lsort
4 | \- sort transcripts
5 | .SH SYNOPSIS
6 | .B lsort
7 | [
8 | .RI \-IV
9 | ] [
10 | .BI \-o\ file
11 | ] [
12 | .I transcript ...
13 | ]
14 | .SH DESCRIPTION
15 | .B lsort
16 | sorts each
17 | .I transcript
18 | together and prints the results to the standard output.
19 | If
20 | .I transcript
21 | is not given,
22 | .B lsort
23 | will use the standard input for reading.
24 | .SH OPTIONS
25 | .TP 19
26 | .BI \-I
27 | be case insensitive when sorting transcripts.
28 | .TP 19
29 | .BI \-o\ file
30 | specifies an output file, default is the standard output.
31 | .TP 19
32 | .B \-V
33 | displays the version number of
34 | .BR lsort
35 | and exits.
36 | .SH EXIT STATUS
37 | The following exit values are returned:
38 | .TP 5
39 | 0
40 | No errors.
41 | .TP 5
42 | >0
43 | An error occurred.
44 | .SH SEE ALSO
45 | .BR fsdiff (1),
46 | .BR ktcheck (1),
47 | .BR lapply (1),
48 | .BR lcksum (1),
49 | .BR lcreate (1),
50 | .BR lfdiff (1),
51 | .BR lmerge (1),
52 | .BR lsort (1),
53 | .BR radmind (8).
54 |
--------------------------------------------------------------------------------
/man/rash.1:
--------------------------------------------------------------------------------
1 | .TH rash "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B rash
4 | \- Radmind Assistant
5 | .SH SYNOPSIS
6 | .B ra.sh
7 | [
8 | .B -cIltV
9 | ] [
10 | .B -%
11 | |
12 | .B -q
13 | ] [
14 | .BR \-C\ "generate"
15 | |
16 | .BI \-C\ checksum
17 | ] [
18 | .B \-D
19 | .I workingdir
20 | ] [
21 | .B \-h
22 | .I server
23 | ] [
24 | .B \-p
25 | .I port
26 | ] [
27 | .B \-r
28 | .I path
29 | ] [
30 | .B \-U
31 | .I user
32 | ] [
33 | .B \-w
34 | .I authlevel
35 | ] {
36 | .B trip
37 | |
38 | .B update
39 | |
40 | .B create
41 | |
42 | .B auto
43 | |
44 | .B force
45 | |
46 | .B checkout
47 | |
48 | .B checkin
49 | }
50 | .sp
51 | .SH DESCRIPTION
52 | .B rash
53 | is a command line application for running the Radmind
54 | tool set. It can be used to run the entire radmind process including
55 | updating a client, running a tripwire and creating loadsets. On
56 | machines with multiple administrators,
57 | .B rash
58 | can be used to limit
59 | conflicts from multiple administrators simultaneously using the tool.
60 |
61 | .B rash
62 | is run with a required option telling it what process to run:
63 | update, auto, force, create, trip, checkout or checkin.
64 |
65 | A machine can be updated by using either the update, auto or force
66 | option. update will prompt the user at each step in the process. auto
67 | will update the machine without any input, looping when possible to
68 | handle temporary problems such as networking issues or a busy server.
69 | auto is suitable to be run as an automated process. force updates
70 | a machine without looping or prompting for input and is handy for quick,
71 | manual updates.
72 |
73 | create is used to store a loadset on the radmind server in an
74 | interactive fashion. Before creating a transcript,
75 | .B rash
76 | first checks to
77 | see if the command file and transcripts are correct and prompts the user
78 | to update them if needed. The user can also edit the transcript before
79 | it is stored on the server.
80 |
81 | trip is used to run a tripwire on the system. If the command file and
82 | transcripts are correct, a full tripwire is run with checksums. Any
83 | differences are printed to the screen in a format suitable for e-mailed
84 | machine reporting.
85 |
86 | checkout is used to prevent other users from concurrently running
87 | .BR rash .
88 | It is helpful when an administrator is installing new software or
89 | configuring a client and does not want their work removed. Only the
90 | user who checked out a machine can run
91 | .B rash
92 | unless a new checkout is
93 | forced from an interactive
94 | .B rash
95 | session. An e-mail is sent to the
96 | previous users when a checkout is overridden. As trip does not modify
97 | the system, it can be run at any time, regardless of who has checked out
98 | the machine. checkin is used to release a machine. Only the user who
99 | checked out a machine may check it back in.
100 |
101 | checkin and checkout both use $USER to determine who is performing
102 | the command. $USER can be overridden using the -U option.
103 |
104 | The -c option can be used to turn on checksums for fsdiff. The only
105 | supported checksum is SHA1.
106 |
107 | .B rash
108 | supports running arbitrary scripts before and after lapply.
109 | Preapply scripts located in PREAPPLY are run before lapply, and
110 | postapply scripts located in POSTAPPLY are run after. The first
111 | argument passed to each script is the full path to apply-able
112 | transcript.
113 | .SH OPTIONS
114 | .TP 19
115 | .B \-%
116 | Tell
117 | .BR fsdiff (1)
118 | ,
119 | .BR lapply (1)
120 | , and
121 | .BR lcreate (1)
122 | to use percentage done progress output.
123 | .TP 19
124 | .B \-c
125 | use sha1 checksums.
126 | .TP 19
127 | .BR \-C\ "generate"
128 | Print a sha1 checksum of the difference transcript of applied changes. For use with
129 | .IR auto ,
130 | .IR force
131 | or
132 | .IR update .
133 | .TP 19
134 | .BI \-C\ checksum
135 | In
136 | .I auto
137 | mode, exit with an error if the checksum of the difference transcript to be applied does not match
138 | .IR checksum .
139 | In
140 | .I update
141 | or
142 | .I force
143 | mode, warn if the two do not match.
144 | .TP 19
145 | .BI \-D\ workingdir
146 | change to
147 | .I workingdir
148 | before running. Default is "/".
149 | .TP 19
150 | .BI \-h\ hostname
151 | specifies the radmind server, by default
152 | .BR _RADMIND_HOST .
153 | .TP 19
154 | .B \-I
155 | Tell
156 | .BR fsdiff (1)
157 | ,
158 | .BR ktcheck (1)
159 | , and
160 | .BR lapply (1)
161 | to use case-insensitive matching.
162 | .TP 19
163 | .B \-l
164 | Prompt for remote user name. The -U option disables this prompt.
165 | .TP 19
166 | .BI \-p\ port
167 | Specifies the port to connect to the server on, by default 6222.
168 | .TP 19
169 | .B \-q
170 | Tell
171 | .BR lapply (1)
172 | and
173 | .BR lcreate (1)
174 | to operate quietly.
175 | .TP 19
176 | .BI \-r\ path
177 | specifies root path from which fsdiff will start its scan of the
178 | filesystem
179 | .TP 19
180 | .B \-t
181 | use tempfiles
182 | .TP 19
183 | .BI \-U\ user
184 | specifies the user. By default, $USER
185 | will be used.
186 | .TP 19
187 | .B \-V
188 | displays the version of
189 | .B rash
190 | and exits.
191 | .TP 19
192 | .BI \-w\ auth-level
193 | TLS authorization level, by default _RADMIND_AUTHLEVEL.
194 | 0 = no TLS, 1 = server verification, 2 = server and client verification.
195 | .SH EXIT STATUS
196 | The following exit values are returned:
197 | .TP 5
198 | 0
199 | successful.
200 | .TP 5
201 | >1
202 | An error occurred.
203 | .sp
204 | .SH SEE ALSO
205 | .BR fsdiff (1),
206 | .BR ktcheck (1),
207 | .BR lapply (1),
208 | .BR lcksum (1),
209 | .BR lcreate (1),
210 | .BR lfdiff (1),
211 | .BR lmerge (1),
212 | .BR lsort (1),
213 | .BR twhich (1),
214 | .BR radmind (8).
215 |
--------------------------------------------------------------------------------
/man/repo.1:
--------------------------------------------------------------------------------
1 | .TH repo "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B repo
4 | \- report events to a radmind server
5 | .SH SYNOPSIS
6 | .B repo
7 | .BI \-e\ event
8 | [
9 | .RI \-Vv
10 | ] [
11 | .BI \-h\ host
12 | ] [
13 | .BI \-p\ port
14 | ] [
15 | .BI \-w\ auth-level
16 | ] [
17 | .BI \-x\ ca-pem-file
18 | ] [
19 | .BI \-y\ cert-pem-file
20 | ] [
21 | .BI \-z\ private-key-file
22 | ] [
23 | .BI \-Z\ compression-level
24 | ] [
25 | .I message ...
26 | ]
27 | .SH DESCRIPTION
28 | .B repo
29 | reports status messages to the radmind server. The administrator defines
30 | the
31 | .I event
32 | type with the -e option. The
33 | .I message
34 | is read from the command line or from standard input. The
35 | .I event
36 | and the
37 | .I message
38 | are logged by the server if
39 | .B repo
40 | succeeds.
41 | .SH OPTIONS
42 | .TP 19
43 | .BI \-e\ event
44 | the event type to report. This is limited to a single word, containing no
45 | white space.
46 | .TP 19
47 | .BI \-h\ host
48 | specifies the radmind server, by default
49 | .BR _RADMIND_HOST .
50 | .TP 19
51 | .BI \-p\ port
52 | specifies a port, by default
53 | .B 6222 .
54 | .TP 19
55 | .BI \-P\ ca-pem-directory
56 | specifies a directory that contains certificates to be used when verifying the server. Certificates must be in PEM format and the directory must have been
57 | processed with the openssl c_rehash utility.
58 | .TP 19
59 | .B \-V
60 | displays the version of
61 | .BR repo ,
62 | and exits.
63 | .TP 19
64 | .B \-v
65 | displays communication with the radmind server.
66 | .TP 19
67 | .BI \-w\ auth-level
68 | TLS authorization level, by default _RADMIND_AUTHLEVEL.
69 | 0 = no TLS, 1 = server verification, 2 = server and client verification.
70 | .TP 19
71 | .BI \-x\ ca-pem-file
72 | Certificate authority's public certificate, by default _RADMIND_TLS_CA.
73 | The default is not used when -P is specified.
74 | .TP 19
75 | .BI \-y\ cert-pem-file
76 | Client's public certificate, by default _RADMIND_TLS_CERT.
77 | .TP 19
78 | .BI \-z\ private-key-file
79 | Client's private key, by default _RADMIND_TLS_CERT.
80 | .TP 19
81 | .BI \-Z\ compression-level
82 | Compress all outbound data. compression-level can be between 0 and 9:
83 | 1 gives best speed, 9 gives best compression, 0 gives no compression at
84 | all (the input data is simply copied a block at a time).
85 | .SH EXIT STATUS
86 | The following exit values are returned:
87 | .TP 5
88 | 0
89 | No errors.
90 | .TP 5
91 | >0
92 | An error occurred.
93 | .SH SEE ALSO
94 | .BR radmind (8).
95 |
--------------------------------------------------------------------------------
/man/twhich.1:
--------------------------------------------------------------------------------
1 | .TH twhich "1" "_RADMIND_BUILD_DATE" "RSUG" "User Commands"
2 | .SH NAME
3 | .B twhich
4 | \- locates a file listing in transcripts
5 | .SH SYNOPSIS
6 | .B twhich
7 | [
8 | .RI \-aIrV
9 | ] [
10 | .BI \-K\ command
11 | ]
12 | .I file
13 | .br
14 | .B twhich
15 | .B \-s
16 | .BI \-K\ command
17 | [
18 | .RI \-aIV
19 | ]
20 | .I file
21 | .sp
22 | .SH DESCRIPTION
23 | .B twhich
24 | searches each transcript listed in the command file ( the default name is
25 | .B command.K )
26 | for
27 | .IR file .
28 | Transcripts are searched in precedence order.
29 | The first
30 | transcript listed in the command file has the lowest precedence, the
31 | next higher, and the last has the highest. If any special files are
32 | listed, the
33 | .B special.T
34 | transcript will have the absolute highest precedence.
35 | .I file
36 | must be the full decoded path (See
37 | .BR fsdiff (1)),
38 | as listed in the transcript.
39 |
40 | If
41 | .I file
42 | is found,
43 | .B twhich
44 | prints a message to the standard output indicating the transcript, line
45 | number and matching line, and then exits. With the -a option,
46 | .B twhich
47 | will continue to search all transcripts listed in the command file for
48 | .IR file .
49 | With the -r option,
50 | .B twhich
51 | will search for each path component, progressively building to
52 | .IR file ,
53 | behaving as above when matches are found. If a path element in
54 | .I file
55 | is missing, twhich will print "not found" and continue looking for
56 | the next element.
57 |
58 | The -s option is used to run
59 | .B twhich
60 | on a radmind server. When run on a server, the command file to search
61 | must be given with the -K option. All listed transcripts
62 | must be in the respective radmind server transcript directory.
63 |
64 | .sp
65 | .SH OPTIONS
66 | .TP 19
67 | .B \-a
68 | list all transcripts that contain
69 | .IR file .
70 | .TP 19
71 | .BI \-I
72 | be case insensitive when comparing paths.
73 | .TP 19
74 | .BI \-K\ command
75 | specifies a command
76 | file, by default
77 | .BR _RADMIND_COMMANDFILE
78 | .TP 19
79 | .B \-s
80 | indicates that
81 | .B twhich
82 | is running on a radmind server.
83 | .TP 19
84 | .B \-r
85 | searches for each path element in
86 | .IR file .
87 | .TP 19
88 | .B \-V
89 | displays the version number of
90 | .BR twhich
91 | and exits.
92 | .sp
93 | .SH FILES
94 | .TP 19
95 | .B _RADMIND_COMMANDFILE
96 | name of the default command file.
97 | .TP 19
98 | .B special.T
99 | name of the special transcript.
100 | .SH EXIT STATUS
101 | The following exit values are returned:
102 | .TP 5
103 | 0
104 | File was found.
105 | .TP 5
106 | 1
107 | File was not found.
108 | .TP 5
109 | >1
110 | An error occurred.
111 | .sp
112 | .SH SEE ALSO
113 | .BR fsdiff (1),
114 | .BR ktcheck (1),
115 | .BR lapply (1),
116 | .BR lcksum (1),
117 | .BR lcreate (1),
118 | .BR lfdiff (1),
119 | .BR lmerge (1),
120 | .BR lsort (1),
121 | .BR radmind (8).
122 |
--------------------------------------------------------------------------------
/mkdirs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "mkdirs.h"
14 |
15 | /*
16 | * The right most element of the path is assumed to be a file.
17 | */
18 | int
19 | mkdirs( char *path )
20 | {
21 | char *p, *q = NULL;
22 | int saved_errno;
23 |
24 | saved_errno = errno;
25 |
26 | /* try making longest path first, working backward */
27 | for (;;) {
28 | if (( p = strrchr( path, '/' )) == NULL ) {
29 | errno = EINVAL;
30 | return( -1 );
31 | }
32 | *p = '\0';
33 | if ( q != NULL ) {
34 | *q = '/';
35 | }
36 |
37 | if ( mkdir( path, 0777 ) == 0 ) {
38 | break;
39 | }
40 | if ( errno == EEXIST ) {
41 | break;
42 | } else if ( errno != ENOENT ) {
43 | return( -1 );
44 | }
45 | q = p;
46 | }
47 |
48 | *p = '/';
49 |
50 | if ( q != NULL ) {
51 | p++;
52 | for ( p = strchr( p, '/' ); p != NULL; p = strchr( p, '/' )) {
53 | *p = '\0';
54 | if ( mkdir( path, 0777 ) < 0 ) {
55 | if ( errno != EEXIST ) {
56 | return( -1 );
57 | }
58 | }
59 | *p++ = '/';
60 | }
61 | }
62 |
63 | errno = saved_errno;
64 |
65 | return( 0 );
66 | }
67 |
--------------------------------------------------------------------------------
/mkdirs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int mkdirs( char *path );
7 |
--------------------------------------------------------------------------------
/mkprefix.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include "mkprefix.h"
17 |
18 | int extern quiet;
19 | int extern showprogress;
20 |
21 | /* mkprefix attempts to create intermediate directories of path.
22 | * Intermediate directories are created with the permission of the
23 | * mode and UID of the last pre-existing parent directory.
24 | */
25 |
26 | int
27 | mkprefix( char *path )
28 | {
29 | char *p, parent_path[ MAXPATHLEN * 2 ];
30 | int saved_errno, parent_stats = 0;
31 | uid_t e_uid;
32 | struct stat st, parent_st;
33 | mode_t mode = 0777;
34 |
35 | e_uid = geteuid();
36 |
37 | /* Move past any leading /'s */
38 | for ( p = path; *p == '/'; p++ )
39 | ;
40 |
41 | /* Attempt to create each intermediate directory of path */
42 | for ( p = strchr( p, '/' ); p != NULL; p = strchr( p, '/' )) {
43 | *p = '\0';
44 | if ( mkdir( path, mode ) < 0 ) {
45 | /* Only error if path exists and it's not a directory */
46 | saved_errno = errno;
47 | if ( stat( path, &st ) != 0 ) {
48 | errno = saved_errno;
49 | return( -1 );
50 | }
51 | if ( !S_ISDIR( st.st_mode )) {
52 | errno = EEXIST;
53 | return( -1 );
54 | }
55 | errno = 0;
56 | *p++ = '/';
57 | continue;
58 | }
59 |
60 | /* Get stats from parent of first missing directory */
61 | if ( !parent_stats ) {
62 | if ( snprintf( parent_path, MAXPATHLEN, "%s/..", path)
63 | > MAXPATHLEN ) {
64 | fprintf( stderr, "%s/..: path too long\n", path );
65 | *p++ = '/';
66 | return( -1 );
67 | }
68 | if ( stat( parent_path, &parent_st ) != 0 ) {
69 | return( -1 );
70 | }
71 | parent_stats = 1;
72 | }
73 |
74 | /* Set mode to that of last preexisting parent */
75 | if ( mode != parent_st.st_mode ) {
76 | if ( chmod( path, parent_st.st_mode ) != 0 ) {
77 | return( -1 );
78 | }
79 | }
80 |
81 | /* Set uid to that of last preexisting parent */
82 | if ( e_uid != parent_st.st_uid ) {
83 | if ( chown( path, parent_st.st_uid, parent_st.st_gid ) != 0 ) {
84 | return( -1 );
85 | }
86 | }
87 |
88 | if ( !quiet && !showprogress ) {
89 | printf( "%s: created missing prefix\n", path );
90 | }
91 |
92 | *p++ = '/';
93 | }
94 | return( 0 );
95 | }
96 |
--------------------------------------------------------------------------------
/mkprefix.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int mkprefix( char *path );
7 |
--------------------------------------------------------------------------------
/openssl_compat.c:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenSSL Compatibility Shims for pre-1.1.0
3 | *
4 | */
5 |
6 | #include "openssl_compat.h"
7 | #if OPENSSL_VERSION_NUMBER < 0x10100000L
8 |
9 | static void *OPENSSL_zalloc(size_t num)
10 | {
11 | void *ret = OPENSSL_malloc(num);
12 |
13 | if (ret != NULL)
14 | memset(ret, 0, num);
15 | return ret;
16 | }
17 |
18 | EVP_MD_CTX *EVP_MD_CTX_new(void)
19 | {
20 | return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
21 | }
22 |
23 | void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
24 | {
25 | EVP_MD_CTX_cleanup(ctx);
26 | OPENSSL_free(ctx);
27 | }
28 |
29 | #endif // OLD OPENSSL <1.1.0
30 |
--------------------------------------------------------------------------------
/openssl_compat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * OpenSSL Compatibility Shims for pre-1.1.0
3 | *
4 | */
5 |
6 | #include
7 |
8 | #if OPENSSL_VERSION_NUMBER < 0x10100000L
9 | #include
10 | #include
11 |
12 | EVP_MD_CTX *EVP_MD_CTX_new(void);
13 | void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
14 |
15 | #endif // OLD OPENSSL <1.1.0
16 |
--------------------------------------------------------------------------------
/pathcmp.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #ifdef __APPLE__
9 | #define USE_ASCII 1
10 | #endif /* __APPLE__ */
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "pathcmp.h"
18 | #include "code.h"
19 |
20 | int
21 | pathcasecmp( const char *p1, const char *p2,
22 | int case_sensitive )
23 | {
24 | int rc;
25 |
26 | do {
27 | if ( case_sensitive ) {
28 | rc = ( (unsigned char)*p1 - (unsigned char)*p2 );
29 | } else {
30 | rc = ( tolower( *p1 ) - tolower( *p2 ));
31 | }
32 |
33 | if ( rc != 0 ) {
34 | if (( *p2 != '\0' ) && ( *p1 == '/' )) {
35 | return( -1 );
36 | } else if (( *p1 != '\0' ) && ( *p2 == '/' )) {
37 | return( 1 );
38 | } else {
39 | return( rc );
40 | }
41 | }
42 | p2++;
43 | } while ( *p1++ != '\0' );
44 |
45 | return( 0 );
46 | }
47 |
48 | /* Just like strcmp(), but pays attention to the meaning of '/'. */
49 | int
50 | pathcmp( const char *p1, const char *p2 )
51 | {
52 | return( pathcasecmp( p1, p2, 1 ));
53 | }
54 |
55 | int
56 | ischildcase( const char *child, const char *parent, int
57 | case_sensitive )
58 | {
59 | int rc;
60 | size_t parentlen;
61 |
62 |
63 | if ( parent == NULL ) {
64 | return( 1 );
65 | }
66 |
67 | parentlen = strlen( parent );
68 |
69 | if ( parentlen > strlen( child )) {
70 | return( 0 );
71 | }
72 | if (( 1 == parentlen ) && ( '/' == *parent )) {
73 | return( '/' == *child );
74 | }
75 |
76 | if ( case_sensitive ) {
77 | rc = strncmp( parent, child, parentlen );
78 | } else {
79 | rc = strncasecmp( parent, child, parentlen );
80 | }
81 | if (( rc == 0 ) && (( '/' == child[ parentlen ] ) ||
82 | ( '\0' == child[ parentlen ] ))) {
83 | return( 1 );
84 | }
85 | return( 0 );
86 | }
87 |
88 | int
89 | ischild( const char *child, const char *parent )
90 | {
91 | return( ischildcase( child, parent, 1 ));
92 | }
93 |
--------------------------------------------------------------------------------
/pathcmp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int pathcasecmp( const char *, const char *,
7 | int case_sensitive );
8 | int pathcmp( const char *, const char * );
9 | int ischildcase( const char *, const char *,
10 | int case_sensitive );
11 | int ischild( const char *, const char * );
12 |
--------------------------------------------------------------------------------
/progress.c:
--------------------------------------------------------------------------------
1 | #include "config.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "argcargv.h"
11 | #include "code.h"
12 | #include "largefile.h"
13 | #include "progress.h"
14 |
15 | int progress = -1;
16 | int showprogress = 0;
17 | off_t lsize = 0, total = 0;
18 |
19 | void
20 | linecheck( char *line, int ac, int linenum )
21 | {
22 | if ( ac < 8 ) {
23 | if ( line[ strlen( line ) - 1 ] == '\n' ) {
24 | line[ strlen( line ) - 1 ] = '\0';
25 | }
26 | fprintf( stderr, "%s: line %d: invalid transcript line\n",
27 | line, linenum );
28 | exit( 2 );
29 | }
30 | }
31 |
32 | off_t
33 | loadsetsize( FILE *tran )
34 | {
35 | char tline[ LINE_MAX ], line[ LINE_MAX ];
36 | char **targv;
37 | int tac, linenum = 0;
38 | off_t size = 0;
39 |
40 | while ( fgets( tline, LINE_MAX, tran ) != NULL ) {
41 | linenum++;
42 | strcpy( line, tline );
43 | if (( tac = argcargv( tline, &targv )) == 0 ) {
44 | continue;
45 | }
46 |
47 | switch ( *targv[ 0 ] ) {
48 | case 'a':
49 | case 'f':
50 | break;
51 |
52 | default:
53 | continue;
54 | }
55 |
56 | linecheck( line, tac, linenum );
57 | size += strtoofft( targv[ 6 ], NULL, 10 );
58 | }
59 |
60 | rewind( tran );
61 |
62 | return( size );
63 | }
64 |
65 | off_t
66 | applyloadsetsize( FILE *tran )
67 | {
68 | char tline[ LINE_MAX ], line[ LINE_MAX ];
69 | char **targv;
70 | int tac, linenum = 0;
71 | off_t size = 0;
72 |
73 | while ( fgets( tline, LINE_MAX, tran ) != NULL ) {
74 | linenum++;
75 | strcpy( line, tline );
76 | /* skip empty lines and transcript marker lines */
77 | if (( tac = argcargv( tline, &targv )) <= 1 ) {
78 | continue;
79 | }
80 |
81 | switch ( *targv[ 0 ] ) {
82 | case '+':
83 | switch ( *targv[ 1 ] ) {
84 | case 'a':
85 | case 'f':
86 | linecheck( line, tac, linenum );
87 | size += strtoofft( targv[ 7 ], NULL, 10 );
88 |
89 | default:
90 | break;
91 | }
92 |
93 | default:
94 | break;
95 | }
96 |
97 | size += PROGRESSUNIT;
98 | }
99 |
100 | rewind( tran );
101 |
102 | return( size );
103 | }
104 |
105 | off_t
106 | lcksum_loadsetsize( FILE *tran, char *prefix )
107 | {
108 | char tline[ LINE_MAX ], line[ LINE_MAX ];
109 | char *d_path = NULL;
110 | char **targv;
111 | int tac, linenum = 0;
112 | off_t size = 0;
113 |
114 | while ( fgets( tline, LINE_MAX, tran ) != NULL ) {
115 | linenum++;
116 | strcpy( line, tline );
117 | if (( tac = argcargv( tline, &targv )) <= 1 ) {
118 | continue;
119 | }
120 |
121 | if ( prefix != NULL ) {
122 | if (( d_path = decode( targv[ 1 ] )) == NULL ) {
123 | fprintf( stderr, "%d: path too long\n", linenum );
124 | exit( 2 );
125 | }
126 | if ( strncmp( d_path, prefix, strlen( prefix )) != 0 ) {
127 | continue;
128 | }
129 | }
130 |
131 | switch ( *targv[ 0 ] ) {
132 | case 'a':
133 | case 'f':
134 | linecheck( line, tac, linenum );
135 | size += strtoofft( targv[ 6 ], NULL, 10 );
136 |
137 | default:
138 | size += PROGRESSUNIT;
139 | break;
140 | }
141 | }
142 |
143 | rewind( tran );
144 | return( size );
145 | }
146 |
147 | void
148 | progressupdate( ssize_t bytes, char *path )
149 | {
150 | int last = progress;
151 |
152 | if ( bytes < 0 ) {
153 | return;
154 | }
155 |
156 | total += bytes;
157 |
158 | progress = ( int )((( float )total / ( float )lsize ) * 100 );
159 | if ( progress > last ) {
160 | printf( "%%%.2d %s\n", progress, path );
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/progress.h:
--------------------------------------------------------------------------------
1 | #define PROGRESSUNIT 1024
2 |
3 | void linecheck( char *line, int ac, int linenum );
4 | off_t loadsetsize( FILE *tran );
5 | off_t applyloadsetsize( FILE *tran );
6 | off_t lcksum_loadsetsize( FILE *tran, char *prefix );
7 | void progressupdate( ssize_t bytes, char *path );
8 |
--------------------------------------------------------------------------------
/radstat.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #ifdef __APPLE__
12 | #include
13 | #include
14 | #endif /* __APPLE__ */
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "applefile.h"
22 | #include "radstat.h"
23 |
24 | /* Return values:
25 | * < 0 system error - errno set
26 | * 0 okay
27 | * 1 error - unknown file type, errno not set
28 | */
29 |
30 | int
31 | radstat( char *path, struct stat *st, char *type, struct applefileinfo *afinfo )
32 | {
33 | #ifdef __APPLE__
34 | static char null_buf[ FINFOLEN ] = { 0 };
35 | extern struct attrlist getalist;
36 | extern struct attrlist getdiralist;
37 | #endif /* __APPLE__ */
38 |
39 | if ( lstat( path, st ) != 0 ) {
40 | if (( errno == ENOTDIR ) || ( errno == ENOENT )) {
41 | memset( st, 0, sizeof( struct stat ));
42 | *type = 'X';
43 | }
44 | return( -1 );
45 | }
46 |
47 | switch( st->st_mode & S_IFMT ) {
48 | case S_IFREG:
49 | #ifdef __APPLE__
50 | /* Check to see if it's an HFS+ file */
51 | if ( afinfo != NULL ) {
52 | if (( getattrlist( path, &getalist, &afinfo->ai,
53 | sizeof( struct attr_info ), FSOPT_NOFOLLOW ) == 0 )) {
54 | if (( afinfo->ai.ai_rsrc_len > 0 ) ||
55 | ( memcmp( afinfo->ai.ai_data, null_buf, FINFOLEN ) != 0 )) {
56 | *type = 'a';
57 | break;
58 | }
59 | }
60 | }
61 | #endif /* __APPLE__ */
62 | *type = 'f';
63 | break;
64 |
65 | case S_IFDIR:
66 | #ifdef __APPLE__
67 | /* Get any finder info */
68 | if ( afinfo != NULL ) {
69 | getattrlist( path, &getdiralist, &afinfo->ai,
70 | sizeof( struct attr_info ), FSOPT_NOFOLLOW );
71 | }
72 | #endif /* __APPLE__ */
73 | *type = 'd';
74 | break;
75 |
76 | case S_IFLNK:
77 | *type = 'l';
78 | break;
79 |
80 | case S_IFCHR:
81 | *type = 'c';
82 | break;
83 |
84 | case S_IFBLK:
85 | *type = 'b';
86 | break;
87 |
88 | #ifdef sun
89 | case S_IFDOOR:
90 | *type = 'D';
91 | break;
92 | #endif /* sun */
93 |
94 | case S_IFIFO:
95 | *type = 'p';
96 | break;
97 |
98 | case S_IFSOCK:
99 | *type = 's';
100 | break;
101 |
102 | default:
103 | return ( 1 );
104 | }
105 |
106 | #ifdef __APPLE__
107 | /* Calculate full size of applefile */
108 | if ( *type == 'a' ) {
109 |
110 | /* Finder Info */
111 | afinfo->as_ents[AS_FIE].ae_id = ASEID_FINFO;
112 | afinfo->as_ents[AS_FIE].ae_offset = AS_HEADERLEN +
113 | ( 3 * sizeof( struct as_entry )); /* 62 */
114 | afinfo->as_ents[AS_FIE].ae_length = FINFOLEN;
115 |
116 | /* Resource Fork */
117 | afinfo->as_ents[AS_RFE].ae_id = ASEID_RFORK;
118 | afinfo->as_ents[AS_RFE].ae_offset = /* 94 */
119 | ( afinfo->as_ents[ AS_FIE ].ae_offset
120 | + afinfo->as_ents[ AS_FIE ].ae_length );
121 | afinfo->as_ents[ AS_RFE ].ae_length = afinfo->ai.ai_rsrc_len;
122 |
123 | /* Data Fork */
124 | afinfo->as_ents[AS_DFE].ae_id = ASEID_DFORK;
125 | afinfo->as_ents[ AS_DFE ].ae_offset =
126 | ( afinfo->as_ents[ AS_RFE ].ae_offset
127 | + afinfo->as_ents[ AS_RFE ].ae_length );
128 | afinfo->as_ents[ AS_DFE ].ae_length = (u_int32_t)st->st_size;
129 |
130 | afinfo->as_size = afinfo->as_ents[ AS_DFE ].ae_offset
131 | + afinfo->as_ents[ AS_DFE ].ae_length;
132 |
133 | /* Set st->st_size to size of encoded apple single file */
134 | st->st_size = afinfo->as_size;
135 | }
136 | #endif /* __APPLE__ */
137 |
138 | return( 0 );
139 | }
140 |
--------------------------------------------------------------------------------
/radstat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int radstat( char *path, struct stat *st, char *fstype,
7 | struct applefileinfo *afinfo );
8 |
--------------------------------------------------------------------------------
/repo.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006, 2007 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #include
25 |
26 | #ifdef HAVE_ZLIB
27 | #include
28 | #endif /* HAVE_ZLIB */
29 |
30 | #include
31 |
32 | #include "code.h"
33 | #include "applefile.h"
34 | #include "connect.h"
35 | #include "report.h"
36 | #include "tls.h"
37 |
38 | int verbose = 0;
39 | void (*logger)( char * ) = NULL;
40 | extern struct timeval timeout;
41 | extern char *version;
42 | extern char *caFile, *caDir, *cert, *privatekey;
43 | SSL_CTX *ctx;
44 |
45 | int
46 | main( int argc, char *argv[] )
47 | {
48 | SNET *sn;
49 | int c, i = 0, err = 0, len;
50 | int authlevel = _RADMIND_AUTHLEVEL;
51 | int use_randfile = 0;
52 | extern int optind;
53 | unsigned short port = 0;
54 | char *host = _RADMIND_HOST;
55 | char *event = NULL;
56 | char repodata[ MAXPATHLEN * 2 ];
57 | char **capa = NULL; /* server capabilities */
58 |
59 | while (( c = getopt( argc, argv, "e:h:p:P:vVw:x:y:Z:z:" )) != EOF ) {
60 | switch ( c ) {
61 | case 'e': /* event to report */
62 | event = optarg;
63 | break;
64 |
65 | case 'h':
66 | host = optarg;
67 | break;
68 |
69 | case 'p':
70 | /* connect.c handles things if atoi returns 0 */
71 | port = htons( atoi( optarg ));
72 | break;
73 |
74 | case 'P':
75 | caDir = optarg;
76 | break;
77 |
78 | case 'v':
79 | verbose = 1;
80 | logger = v_logger;
81 | break;
82 |
83 | case 'V':
84 | printf( "%s\n", version );
85 | exit( 0 );
86 |
87 | case 'w':
88 | authlevel = atoi( optarg );
89 | if (( authlevel < 0 ) || ( authlevel > 2 )) {
90 | fprintf( stderr, "%s: invalid authorization level\n",
91 | optarg );
92 | exit( 2 );
93 | }
94 | break;
95 |
96 | case 'x':
97 | caFile = optarg;
98 | break;
99 |
100 | case 'y':
101 | cert = optarg;
102 | break;
103 |
104 | case 'z':
105 | privatekey = optarg;
106 | break;
107 |
108 | case 'Z':
109 | #ifdef HAVE_ZLIB
110 | zlib_level = atoi( optarg );
111 | if (( zlib_level < 0 ) || ( zlib_level > 9 )) {
112 | fprintf( stderr, "Invalid compression level\n" );
113 | exit( 1 );
114 | }
115 | break;
116 | #else /* HAVE_ZLIB */
117 | fprintf( stderr, "Zlib not supported.\n" );
118 | exit( 1 );
119 | #endif /* HAVE_ZLIB */
120 |
121 | default:
122 | err++;
123 | break;
124 | }
125 | }
126 |
127 | /* repo is useless without an event defined */
128 | if ( event == NULL ) {
129 | err++;
130 | }
131 |
132 | if ( err || (( argc - optind ) < 0 )) {
133 | fprintf( stderr, "usage: %s -e event [ -Vv ] ", argv[ 0 ] );
134 | fprintf( stderr, "[ -h host ] [ -p port ] [ -P ca-pem-directory ] " );
135 | fprintf( stderr, "[ -w auth-level ] [ -x ca-pem-file ] " );
136 | fprintf( stderr, "[ -y cert-pem-file ] [ -z key-pem-file ] " );
137 | fprintf( stderr, "[ -Z compression-level ] [ message ... ]\n" );
138 | exit( 1 );
139 | }
140 |
141 | if ( argc == optind ) { /* read message from stdin */
142 | if ( fgets( repodata, sizeof( repodata ), stdin ) == NULL ) {
143 | perror( "fgets" );
144 | exit( 2 );
145 | }
146 |
147 | len = strlen( repodata );
148 | if ( repodata[ len - 1 ] != '\n' ) {
149 | fprintf( stderr, "report too long\n" );
150 | exit( 2 );
151 | }
152 | repodata[ len - 1 ] = '\0';
153 | } else {
154 | if ( strlen( argv[ optind ] ) >= sizeof( repodata )) {
155 | fprintf( stderr, "%s: too long\n", argv[ optind ] );
156 | exit( 2 );
157 | }
158 | strcpy( repodata, argv[ optind ] );
159 |
160 | /* Skip first token in message */
161 | i = 1;
162 | for ( i += optind; i < argc; i++ ) {
163 | if (( strlen( repodata ) + strlen( argv[ i ] ) + 2 )
164 | >= sizeof( repodata )) {
165 | fprintf( stderr, "%s %s: too long\n", repodata, argv[ i ] );
166 | exit( 2 );
167 | }
168 | strcat( repodata, " " );
169 | strcat( repodata, argv[ i ] );
170 | }
171 | }
172 |
173 | if (( sn = connectsn( host, port )) == NULL ) {
174 | exit( 2 );
175 | }
176 | if (( capa = get_capabilities( sn )) == NULL ) {
177 | exit( 2 );
178 | }
179 |
180 | if ( authlevel != 0 ) {
181 | if ( tls_client_setup( use_randfile, authlevel, caFile, caDir, cert,
182 | privatekey ) != 0 ) {
183 | exit( 2 );
184 | }
185 | if ( tls_client_start( sn, host, authlevel ) != 0 ) {
186 | exit( 2 );
187 | }
188 | }
189 |
190 | #ifdef HAVE_ZLIB
191 | /* Enable compression */
192 | if ( zlib_level > 0 ) {
193 | if ( negotiate_compression( sn, capa ) != 0 ) {
194 | fprintf( stderr, "%s: server does not support reporting\n", host );
195 | exit( 2 );
196 | }
197 | }
198 | #endif /* HAVE_ZLIB */
199 |
200 | /* Check to see if server supports reporting */
201 | if ( check_capability( "REPO", capa ) == 0 ) {
202 | fprintf( stderr, "%s: server does not support reporting\n", host );
203 | exit( 2 );
204 | }
205 |
206 | if ( report_event( sn, event, repodata ) != 0 ) {
207 | exit( 2 );
208 | }
209 |
210 | if (( closesn( sn )) != 0 ) {
211 | fprintf( stderr, "closesn failed.\n" );
212 | exit( 2 );
213 | }
214 |
215 | return( 0 );
216 | }
217 |
--------------------------------------------------------------------------------
/report.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006, 2007 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #ifdef HAVE_ZLIB
24 | #include
25 | #endif /* HAVE_ZLIB */
26 |
27 | #include
28 |
29 | #include "code.h"
30 | #include "report.h"
31 |
32 | extern int verbose;
33 | extern void (*logger)( char * );
34 | extern struct timeval timeout;
35 |
36 | /*
37 | * report_event: report an arbitrary event to the server
38 | *
39 | * return codes:
40 | * 0: event reported
41 | * 1: report failed
42 | */
43 | int
44 | report_event( SNET *sn, char *event, char *repodata )
45 | {
46 | struct timeval tv;
47 | char *line;
48 | char *e_repodata;
49 | int i, len;
50 |
51 | /* sanity check the event */
52 | if ( event == NULL ) {
53 | fprintf( stderr, "report_event: event must be non-NULL\n" );
54 | return( 1 );
55 | }
56 | if (( len = strlen( event )) == 0 ) {
57 | fprintf( stderr, "report_event: invalid zero-length event\n" );
58 | return( 1 );
59 | } else {
60 | for ( i = 0; i < len; i++ ) {
61 | if ( isspace(( int )event[ i ] )) {
62 | fprintf( stderr, "report_event: event must not "
63 | "contain whitespace\n" );
64 | return( 1 );
65 | }
66 | }
67 | }
68 |
69 | if (( e_repodata = encode( repodata )) == NULL ) {
70 | fprintf( stderr, "report_event: encode: buffer too small\n" );
71 | return( 1 );
72 | }
73 |
74 | if ( snet_writef( sn, "REPO %s %s\r\n", event, e_repodata ) < 0 ) {
75 | perror( "snet_writef" );
76 | return( 1 );
77 | }
78 | if ( verbose ) printf( ">>> REPO %s %s\n", event, e_repodata );
79 |
80 | tv = timeout;
81 | if (( line = snet_getline_multi( sn, logger, &tv )) == NULL ) {
82 | perror( "snet_getline_multi" );
83 | return( 1 );
84 | }
85 | if ( *line != '2' ) {
86 | fprintf( stderr, "%s\n", line );
87 | return( 1 );
88 | }
89 |
90 | return( 0 );
91 | }
92 |
93 | /*
94 | * report_error_and_exit: report an error and exit with the give value
95 | */
96 | void
97 | report_error_and_exit( SNET *sn, char *event, char *repodata, int rc )
98 | {
99 | ( void )report_event( sn, event, repodata );
100 |
101 | exit( rc );
102 | }
103 |
--------------------------------------------------------------------------------
/report.h:
--------------------------------------------------------------------------------
1 | int report_event( SNET *sn, char *event, char *repodata );
2 | void report_error_and_exit( SNET *sn, char *event, char *repodata, int rc );
3 |
--------------------------------------------------------------------------------
/rmdirs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "rmdirs.h"
18 |
19 | int
20 | rmdirs( char *path )
21 | {
22 | int i, len, unlinkedfiles;
23 | char temp[ MAXPATHLEN ];
24 | DIR *dir;
25 | struct dirent *dirent;
26 | struct stat st;
27 |
28 | if (( dir = opendir( path )) == NULL ) {
29 | return( -1 );
30 | }
31 |
32 | /* readdir() on HFS+ is broken:
33 | * http://docs.info.apple.com/article.html?artnum=107884
34 | *
35 | * "The unspecified behavior is what readdir() should return after the
36 | * directory has been modified. Many file systems have been implemented
37 | * such that subsequent readdir() calls will return the next directory
38 | * entry. The implementation of the HFS file system cannot guarantee
39 | * that all enclosed files or directories will be removed using the
40 | * above method."
41 | */
42 |
43 | do {
44 | unlinkedfiles = 0;
45 |
46 | while (( dirent = readdir( dir )) != NULL ) {
47 |
48 | /* don't include . and .. */
49 | if (( strcmp( dirent->d_name, "." ) == 0 ) ||
50 | ( strcmp( dirent->d_name, ".." ) == 0 )) {
51 | continue;
52 | }
53 |
54 | len = strlen( path );
55 |
56 | /* absolute pathname. add 2 for / and NULL termination. */
57 | if (( len + strlen( dirent->d_name ) + 2 ) > MAXPATHLEN ) {
58 | fprintf( stderr, "Absolute pathname too long\n" );
59 | goto error;
60 | }
61 |
62 | if ( path[ len - 1 ] == '/' ) {
63 | if ( snprintf( temp, MAXPATHLEN, "%s%s", path, dirent->d_name )
64 | >= MAXPATHLEN ) {
65 | fprintf( stderr, "%s%s: path too long\n", path,
66 | dirent->d_name );
67 | goto error;
68 | }
69 | } else {
70 | if ( snprintf( temp, MAXPATHLEN, "%s/%s", path, dirent->d_name )
71 | >= MAXPATHLEN ) {
72 | fprintf( stderr, "%s/%s: path too long\n", path,
73 | dirent->d_name );
74 | goto error;
75 | }
76 | }
77 |
78 | if ( lstat( temp, &st ) != 0 ) {
79 | /* XXX - how to return path that gave error? */
80 | fprintf( stderr, "%s: %s\n", temp, strerror( errno ));
81 | goto error;
82 | }
83 | if ( S_ISDIR( st.st_mode )) {
84 | if ( rmdirs( temp ) != 0 ) {
85 | fprintf( stderr, "%s: %s\n", temp, strerror( errno ));
86 | goto error;
87 | }
88 | } else {
89 | if ( unlink( temp ) != 0 ) {
90 | fprintf( stderr, "%s: %s\n", temp, strerror( errno ));
91 | goto error;
92 | }
93 | unlinkedfiles = 1;
94 | }
95 | if ( unlinkedfiles ) {
96 | rewinddir( dir );
97 | }
98 | }
99 | } while ( unlinkedfiles );
100 |
101 | if ( closedir( dir ) != 0 ) {
102 | return( -1 );
103 | }
104 | if ( rmdir( path ) != 0 ) {
105 | return( -1 );
106 | }
107 |
108 | return ( 0 );
109 |
110 | error:
111 | i = errno;
112 | if ( closedir( dir ) != 0 ) {
113 | errno = i;
114 | }
115 | return( -1 );
116 | }
117 |
--------------------------------------------------------------------------------
/rmdirs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int rmdirs( char *path );
7 |
--------------------------------------------------------------------------------
/root.c:
--------------------------------------------------------------------------------
1 | #include "config.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "root.h"
10 |
11 | int
12 | get_root( char *radmind_path, char *path, char *file_root, char *tran_root, char *tran_name )
13 | {
14 | char real_path[ PATH_MAX ];
15 | char test_path[ MAXPATHLEN ];
16 | char radmind_real_path[ PATH_MAX ];
17 | char *p;
18 |
19 | if ( realpath( radmind_path, radmind_real_path ) == NULL ) {
20 | perror( radmind_real_path );
21 | return( -1 );
22 | }
23 | if ( realpath( path, real_path ) == NULL ) {
24 | perror( real_path );
25 | return( -1 );
26 | }
27 |
28 | /* Get transcript name */
29 | if (( p = strrchr( real_path, '/' )) == real_path ) {
30 | fprintf( stderr, "%s: invalid transcript location\n", real_path );
31 | return( -1 );
32 | }
33 | *p++ = '\0';
34 | if ( strlen( p ) >= MAXPATHLEN ) {
35 | fprintf( stderr, "%s: path too long\n", p );
36 | return( -1 );
37 | }
38 | strcpy( tran_name, p );
39 |
40 | if ( snprintf( test_path, MAXPATHLEN, "%s/tmp/transcript",
41 | radmind_real_path ) >= MAXPATHLEN ) {
42 | fprintf( stderr, "%s/tmp/transcirpt: path too long\n",
43 | radmind_real_path );
44 | return( -1 );
45 | }
46 |
47 | if ( strstr( real_path, test_path ) != NULL ) {
48 | if ( snprintf( file_root, MAXPATHLEN, "%s/tmp/file%s",
49 | radmind_real_path, &real_path[ strlen( test_path ) ])
50 | >= MAXPATHLEN ) {
51 | fprintf( stderr, "%s/tmp/file%s: path too long\n",
52 | radmind_real_path, &real_path[ strlen( test_path )] );
53 | return( -1 );
54 | }
55 | if ( snprintf( tran_root, MAXPATHLEN, "%s/tmp/transcript%s",
56 | radmind_real_path, &real_path[ strlen( test_path ) ])
57 | >= MAXPATHLEN ) {
58 | fprintf( stderr, "%s/tmp/transcript%s: path too long\n",
59 | radmind_real_path, &real_path[ strlen( test_path )] );
60 | return( -1 );
61 | }
62 | } else {
63 | if ( snprintf( test_path, MAXPATHLEN, "%s/transcript",
64 | radmind_real_path ) >= MAXPATHLEN ) {
65 | fprintf( stderr, "%s/transcript: path too long\n",
66 | radmind_real_path );
67 | return( -1 );
68 | }
69 |
70 | if ( strstr( real_path, test_path ) != NULL ) {
71 | if ( snprintf( file_root, MAXPATHLEN, "%s/file%s",
72 | radmind_real_path, &real_path[ strlen( test_path ) ])
73 | >= MAXPATHLEN ) {
74 | fprintf( stderr, "%s/file%s: path too long\n",
75 | radmind_real_path, &real_path[ strlen( test_path ) ]);
76 | return( -1 );
77 | }
78 | if ( snprintf( tran_root, MAXPATHLEN, "%s/transcript%s",
79 | radmind_real_path, &real_path[ strlen( test_path ) ])
80 | >= MAXPATHLEN ) {
81 | fprintf( stderr, "%s/transcript%s: path too long\n",
82 | radmind_real_path, &real_path[ strlen( test_path )] );
83 | return( -1 );
84 | }
85 | } else {
86 | if ( snprintf( file_root, MAXPATHLEN, "%s/../file",
87 | real_path ) >= MAXPATHLEN ) {
88 | fprintf( stderr, "%s/../file: path too long\n",
89 | real_path);
90 | return( -1);
91 | }
92 | snprintf( tran_root, MAXPATHLEN, "%s", real_path );
93 | }
94 | }
95 |
96 | return( 0 );
97 | }
98 |
--------------------------------------------------------------------------------
/root.h:
--------------------------------------------------------------------------------
1 | int get_root( char *radmind_path, char *path, char *file_root, char *tran_root, char *tran_name );
2 |
--------------------------------------------------------------------------------
/tls.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int tls_server_setup( int use_randfile, int authlevel, char *caFile, char *caDir, char *crlFile, char *crlDir, char *cert, char *privatekey );
7 | int tls_client_setup( int use_randfile, int authlevel, char *caFile, char *caDir, char *cert, char *privatekey );
8 | int tls_client_start( SNET *sn, char *host, int authlevel );
9 |
--------------------------------------------------------------------------------
/transcript.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include
7 |
8 | #define T_NULL 0
9 | #define T_POSITIVE 1
10 | #define T_NEGATIVE 2
11 | #define T_SPECIAL 3
12 |
13 | #define T_RELATIVE 0
14 | #define T_ABSOLUTE 1
15 |
16 | #define T_MOVE_TRAN 1
17 | #define T_MOVE_FS 2
18 | #define T_MOVE_BOTH 3
19 |
20 | #define T_MODE 0x0FFF
21 |
22 | #define APPLICABLE 0
23 | #define CREATABLE 1
24 |
25 | #define PR_TRAN_ONLY 1
26 | #define PR_FS_ONLY 2
27 | #define PR_DOWNLOAD 3
28 | #define PR_STATUS 4
29 | #define PR_STATUS_NEG 5
30 | #define PR_STATUS_MINUS 6
31 |
32 | #define K_CLIENT 0
33 | #define K_SERVER 1
34 |
35 | extern int edit_path;
36 | extern int skip;
37 | extern int cksum;
38 | extern int fs_minus;
39 | extern FILE *outtran;
40 | extern char *path_prefix;
41 |
42 |
43 | #define T_SKIP_POSITIVE (1 << 1)
44 | #define T_SKIP_NEGATIVE (1 << 2)
45 | #define T_SKIP_SPECIAL (1 << 3)
46 | #define T_SKIP_EXCLUDES (1 << 4)
47 | #define T_SKIP_ALL (T_SKIP_POSITIVE | T_SKIP_NEGATIVE | \
48 | T_SKIP_SPECIAL | T_SKIP_EXCLUDES)
49 |
50 | struct pathinfo {
51 | char pi_type;
52 | int pi_minus;
53 | char pi_name[ MAXPATHLEN ];
54 | char pi_link[ MAXPATHLEN ];
55 | struct stat pi_stat;
56 | char pi_cksum_b64[ MAXPATHLEN ];
57 | struct applefileinfo pi_afinfo;
58 | };
59 |
60 | struct transcript {
61 | struct transcript *t_next;
62 | struct transcript *t_prev;
63 | struct pathinfo t_pinfo;
64 | int t_type;
65 | int t_num;
66 | char t_fullname[ MAXPATHLEN ];
67 | char t_shortname[ MAXPATHLEN ];
68 | char t_kfile[ MAXPATHLEN ];
69 | int t_linenum;
70 | int t_eof;
71 | FILE *t_in;
72 | };
73 |
74 | int transcript( char *, struct stat *, char *, struct applefileinfo *, int );
75 | void transcript_init( char *kfile, int location );
76 | struct transcript *transcript_select( void );
77 | void transcript_parse( struct transcript * );
78 | void transcript_free( void );
79 | void t_new( int, char *, char *, char * );
80 | int t_exclude( char *path );
81 | void t_print( struct pathinfo *, struct transcript *, int );
82 | char *hardlink( struct pathinfo * );
83 | int hardlink_changed( struct pathinfo *, int );
84 | void hardlink_free( void );
85 |
--------------------------------------------------------------------------------
/twhich.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include
15 |
16 | #include "applefile.h"
17 | #include "transcript.h"
18 | #include "code.h"
19 | #include "pathcmp.h"
20 | #include "list.h"
21 | #include "wildcard.h"
22 |
23 | const EVP_MD *md;
24 |
25 | int case_sensitive = 1;
26 | int tran_format = -1;
27 |
28 | /*
29 | * exit codes:
30 | * 0 File found
31 | * 1 File not found.
32 | * >1 An error occurred.
33 | */
34 |
35 | static int
36 | twhich( char *pattern, int displayall )
37 | {
38 | struct node *node;
39 | struct transcript *tran;
40 | extern struct transcript *tran_head;
41 | extern struct list *exclude_list;
42 | int cmp = 0, match = 0;
43 |
44 | /* check exclude list */
45 | if ( exclude_list->l_count > 0 ) {
46 | for ( node = list_pop_head( exclude_list ); node != NULL;
47 | node = list_pop_head( exclude_list )) {
48 | if ( wildcard( node->n_path, pattern, case_sensitive )) {
49 | printf( "# Exclude\n" );
50 | printf( "# exclude pattern: %s\n", node->n_path );
51 | if ( !displayall ) {
52 | goto done;
53 | }
54 | }
55 | free( node );
56 | }
57 | }
58 |
59 | for ( tran = tran_head; tran->t_next != NULL; tran = tran->t_next ) {
60 |
61 | /* Skip NULL/empty transcripts */
62 | if ( tran->t_eof ) {
63 | continue;
64 | }
65 |
66 | while (( cmp = pathcasecmp( tran->t_pinfo.pi_name,
67 | pattern, case_sensitive )) < 0 ) {
68 | transcript_parse( tran );
69 | if ( tran->t_eof ) {
70 | break;
71 | }
72 | }
73 | if ( tran->t_eof ) {
74 | continue;
75 | }
76 |
77 | if ( cmp > 0 ) {
78 | continue;
79 | }
80 |
81 | if ( cmp == 0 ) {
82 | match++;
83 | switch( tran->t_type ) {
84 | case T_POSITIVE:
85 | printf( "# Positive\n" );
86 | break;
87 |
88 | case T_NEGATIVE:
89 | printf( "# Negative\n" );
90 | break;
91 |
92 | case T_SPECIAL:
93 | printf( "# Special\n" );
94 | break;
95 |
96 | default:
97 | fprintf( stderr, "unknown transcript type\n" );
98 | exit( 2 );
99 | }
100 | printf( "# %s:\n", tran->t_kfile );
101 |
102 | if ( tran->t_pinfo.pi_minus ) {
103 | printf( "%s:\n", tran->t_shortname );
104 | t_print( NULL, tran, PR_STATUS_MINUS );
105 | } else {
106 | t_print( NULL, tran, PR_TRAN_ONLY );
107 | }
108 |
109 | if ( !displayall ) {
110 | goto done;
111 | }
112 | }
113 | }
114 |
115 | done:
116 | if ( match ) {
117 | return( 0 );
118 | } else {
119 | return( 1 );
120 | }
121 | }
122 |
123 | int
124 | main( int argc, char **argv )
125 | {
126 | int c, err = 0, defaultkfile = 1, rc = 0, len;
127 | int server = 0, displayall = 0, recursive = 0;
128 | extern char *version;
129 | char *kfile = _RADMIND_COMMANDFILE;
130 | char *pattern, *p;
131 |
132 | while (( c = getopt( argc, argv, "aIK:rsV" )) != EOF ) {
133 | switch( c ) {
134 | case 'a':
135 | displayall = 1;
136 | break;
137 |
138 | case 'K':
139 | defaultkfile = 0;
140 | kfile = optarg;
141 | break;
142 |
143 | case 'I':
144 | case_sensitive = 0;
145 | break;
146 |
147 | case 'r': /* recursively twhich all path elements */
148 | recursive = 1;
149 | break;
150 |
151 | case 's':
152 | server = 1;
153 | break;
154 |
155 | case 'V':
156 | printf( "%s\n", version );
157 | exit( 0 );
158 |
159 | default:
160 | err++;
161 | break;
162 | }
163 | }
164 |
165 | if (( argc - optind ) != 1 ) {
166 | err++;
167 | }
168 |
169 | pattern = argv[ argc - 1 ];
170 | len = strlen( pattern );
171 |
172 | if ( server && defaultkfile ) {
173 | err++;
174 | }
175 |
176 | if ( err ) {
177 | fprintf( stderr, "Usage: %s [ -aIrV ] [ -K command file ] file\n",
178 | argv[ 0 ] );
179 | fprintf( stderr, "Usage: %s -s -K command [ -aIrV ] file\n",
180 | argv[ 0 ] );
181 | exit( 2 );
182 | }
183 |
184 | /* clip trailing slash */
185 | if ( len > 1 && pattern[ len - 1 ] == '/' ) {
186 | pattern[ len - 1 ] = '\0';
187 | len--;
188 | }
189 |
190 | /* Determine if called with relative or absolute pathing. Path is relative
191 | * if it's just '.' or starts with './'. File names that start with a '.'
192 | * are absolute.
193 | */
194 | if ( pattern[ 0 ] == '.' ) {
195 | if ( len == 1 ) {
196 | tran_format = T_RELATIVE;
197 | } else if ( pattern[ 1 ] == '/' ) {
198 | tran_format = T_RELATIVE;
199 | }
200 | } else {
201 | tran_format = T_ABSOLUTE;
202 | }
203 |
204 | /* initialize the transcripts */
205 | edit_path = APPLICABLE;
206 | if ( server ) {
207 | transcript_init( kfile, K_SERVER );
208 | } else {
209 | transcript_init( kfile, K_CLIENT );
210 | }
211 | outtran = stdout;
212 |
213 | if ( recursive ) {
214 | for ( p = pattern; *p == '/'; p++ )
215 | ;
216 | for ( p = strchr( p, '/' ); p != NULL; p = strchr( p, '/' )) {
217 | *p = '\0';
218 | if ( twhich( pattern, displayall ) != 0 ) {
219 | printf( "# %s: not found\n", pattern );
220 | }
221 |
222 | *p++ = '/';
223 | }
224 | }
225 | rc = twhich( pattern, displayall );
226 |
227 | exit( rc );
228 | }
229 |
--------------------------------------------------------------------------------
/update.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #ifdef MAJOR_IN_SYSMACROS
13 | #include
14 | #endif
15 | #ifdef MAJOR_IN_MKDEV
16 | #include
17 | #endif
18 |
19 | #ifdef __APPLE__
20 | #include
21 | #endif /* __APPLE__ */
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "applefile.h"
30 | #include "base64.h"
31 | #include "update.h"
32 | #include "code.h"
33 | #include "radstat.h"
34 | #include "largefile.h"
35 | #include "transcript.h"
36 | #include "progress.h"
37 | #include "mkdirs.h"
38 | #include "mkprefix.h"
39 |
40 | extern int quiet;
41 | extern int linenum;
42 | extern int showprogress;
43 | extern int create_prefix;
44 |
45 | /*
46 | * lchmod is only available on Mac OS X 10.5
47 | * right now. we use weak linking to avoid
48 | * two different builds for 10.4 and 10.5.
49 | */
50 | #ifdef HAVE_LCHMOD
51 | extern int lchmod( const char *, mode_t ) __attribute__(( weak ));
52 | #endif /* HAVE_LCHMOD */
53 |
54 | int
55 | update( char *path, char *displaypath, int present, int newfile,
56 | struct stat *st, int tac, char **targv, struct applefileinfo *afinfo )
57 | {
58 | int timeupdated = 0;
59 | mode_t mode;
60 | struct utimbuf times;
61 | uid_t uid;
62 | gid_t gid;
63 | dev_t dev;
64 | char type;
65 | char *d_target;
66 | #ifdef __APPLE__
67 | unsigned char fi_data[ SZ_BASE64_D( SZ_BASE64_E( FINFOLEN ) ) ];
68 | extern struct attrlist setalist;
69 | static char null_buf[ SZ_BASE64_D( SZ_BASE64_E( FINFOLEN ) ) ] = { 0 };
70 | #endif /* __APPLE__ */
71 |
72 | switch ( *targv[ 0 ] ) {
73 | case 'a':
74 | case 'f':
75 | if ( tac != 8 ) {
76 | fprintf( stderr, "%d: incorrect number of arguments\n", linenum );
77 | return( 1 );
78 | }
79 |
80 | mode = strtol( targv[ 2 ], (char **)NULL, 8 );
81 |
82 | times.modtime = strtotimet( targv[ 5 ], NULL, 10 );
83 | if ( times.modtime != st->st_mtime ) {
84 | times.actime = st->st_atime;
85 | if ( utime( path, × ) != 0 ) {
86 | perror( path );
87 | return( 1 );
88 | }
89 | timeupdated = 1;
90 | }
91 | break;
92 |
93 | case 'd':
94 | if (( tac != 5 )
95 | #ifdef __APPLE__
96 | && ( tac != 6 )
97 | #endif /* __APPLE__ */
98 | ) {
99 | fprintf( stderr,
100 | "%d: incorrect number of arguments\n", linenum );
101 | return( 1 );
102 | }
103 |
104 | mode = strtol( targv[ 2 ], (char **)NULL, 8 );
105 |
106 | if ( !present ) {
107 | if ( mkdir( path, mode ) != 0 ) {
108 | if ( create_prefix && errno == ENOENT ) {
109 | errno = 0;
110 | if ( mkprefix( path ) != 0 ) {
111 | perror( path );
112 | return( 1 );
113 | }
114 | if ( mkdir( path, mode ) != 0 ) {
115 | perror( path );
116 | return( 1 );
117 | }
118 | } else {
119 | perror( path );
120 | return( 1 );
121 | }
122 | }
123 | newfile = 1;
124 | if ( radstat( (char*)path, st, &type, afinfo ) < 0 ) {
125 | perror( path );
126 | return( 1 );
127 | }
128 | present = 1;
129 | }
130 |
131 | #ifdef __APPLE__
132 | /* Check finder info */
133 | if ( tac == 6 ) {
134 | memset( fi_data, 0, FINFOLEN );
135 | base64_d( targv[ 5 ], strlen( targv[ 5 ] ), fi_data );
136 | } else {
137 | memcpy( fi_data, null_buf, FINFOLEN );
138 | }
139 | if ( memcmp( afinfo->ai.ai_data, fi_data, FINFOLEN ) != 0 ) {
140 | if ( setattrlist( path, &setalist,
141 | fi_data, FINFOLEN, FSOPT_NOFOLLOW ) != 0 ) {
142 | fprintf( stderr,
143 | "retrieve %s failed: Could not set Finder Info attribute\n", path );
144 | return( -1 );
145 | }
146 | }
147 | #endif /* __APPLE__ */
148 | break;
149 |
150 | case 'h':
151 | if ( tac != 3 ) {
152 | fprintf( stderr,
153 | "%d: incorrect number of arguments\n", linenum );
154 | return( 1 );
155 | }
156 | if (( d_target = decode( targv[ 2 ] )) == NULL ) {
157 | fprintf( stderr, "line %d: target path too long\n", linenum );
158 | return( 1 );
159 | }
160 | if ( link( d_target, path ) != 0 ) {
161 | if ( create_prefix && errno == ENOENT ) {
162 | errno = 0;
163 | if ( mkprefix( path ) != 0 ) {
164 | perror( path );
165 | return( 1 );
166 | }
167 | if ( link( d_target, path ) != 0 ) {
168 | perror( path );
169 | return( 1 );
170 | }
171 | } else {
172 | perror( path );
173 | return( 1 );
174 | }
175 | }
176 | if ( !quiet && !showprogress ) {
177 | printf( "%s: hard linked to %s", displaypath, d_target);
178 | }
179 | goto done;
180 |
181 | case 'l':
182 | if ( tac == 3 ) {
183 | /* legacy symlink entries get defaults */
184 | mode = ( mode_t )0777;
185 | uid = 0;
186 | gid = 0;
187 | } else if ( tac == 6 ) {
188 | /* symlink with mode, uid, gid */
189 | mode = ( mode_t )strtol( targv[ 2 ], NULL, 8 );
190 | uid = atoi( targv[ 3 ] );
191 | gid = atoi( targv[ 4 ] );
192 | } else {
193 | fprintf( stderr, "%d: incorrect number of arguments\n", linenum );
194 | return( 1 );
195 | }
196 | if ( present ) {
197 | if ( unlink( path ) != 0 ) {
198 | perror( path );
199 | return( 1 );
200 | }
201 | present = 0;
202 | }
203 | if (( d_target = decode( targv[ tac - 1 ] )) == NULL ) {
204 | fprintf( stderr, "line %d: target path too long\n", linenum );
205 | return( 1 );
206 | }
207 | if ( symlink( d_target, path ) != 0 ) {
208 | if ( create_prefix && errno == ENOENT ) {
209 | errno = 0;
210 | if ( mkprefix( path ) != 0 ) {
211 | perror( path );
212 | return( 1 );
213 | }
214 | if ( symlink( d_target, path ) != 0 ) {
215 | perror( path );
216 | return( 1 );
217 | }
218 | } else {
219 | perror( path );
220 | return( 1 );
221 | }
222 | }
223 | if ( !quiet && !showprogress ) {
224 | printf( "%s: symbolic linked to %s", displaypath, d_target );
225 | }
226 | #if defined( HAVE_LCHOWN ) || defined( HAVE_LCHMOD )
227 | if ( !quiet && !showprogress ) {
228 | printf( " updating" );
229 | }
230 | #ifdef HAVE_LCHOWN
231 | if ( uid != st->st_uid || gid != st->st_gid ) {
232 | if ( lchown( path, uid, gid ) != 0 ) {
233 | perror( path );
234 | return( 1 );
235 | }
236 | }
237 | if ( uid != st->st_uid && !quiet && !showprogress ) {
238 | printf( " uid" );
239 | }
240 | if ( gid != st->st_gid && !quiet && !showprogress ) {
241 | printf( " gid" );
242 | }
243 | #endif /* HAVE_LCHOWN */
244 |
245 | #ifdef HAVE_LCHMOD
246 | /*
247 | * if we compiled with weak linking and lchmod
248 | * isn't in the library, the symbol may be NULL.
249 | */
250 | if ( lchmod != NULL ) {
251 | if (( mode != ( T_MODE & st->st_mode )) ||
252 | (( uid != st->st_uid || gid != st->st_gid ) &&
253 | (( mode & ( S_ISUID | S_ISGID )) != 0 ))) {
254 | if ( lchmod( path, mode ) != 0 ) {
255 | perror( path );
256 | return( 1 );
257 | }
258 | if ( !quiet && !showprogress ) {
259 | printf( " mode" );
260 | }
261 | }
262 | }
263 | #endif /* HAVE_LCHMOD */
264 | #endif /* defined( HAVE_LCHOWN ) || defined( HAVE_LCHMOD ) */
265 | goto done;
266 |
267 | case 'p':
268 | if ( tac != 5 ) {
269 | fprintf( stderr,
270 | "%d: incorrect number of arguments\n", linenum );
271 | return( 1 );
272 | }
273 |
274 | mode = strtol( targv[ 2 ], (char **)NULL, 8 ) | S_IFIFO;
275 |
276 | if ( !present ) {
277 | if ( mkfifo( path, mode ) != 0 ){
278 | if ( create_prefix && errno == ENOENT ) {
279 | errno = 0;
280 | if ( mkprefix( path ) != 0 ) {
281 | perror( path );
282 | return( 1 );
283 | }
284 | if ( mkfifo( path, mode ) != 0 ) {
285 | perror( path );
286 | return( 1 );
287 | }
288 | } else {
289 | perror( path );
290 | return( 1 );
291 | }
292 | }
293 | if ( lstat( path, st ) != 0 ) {
294 | perror( path );
295 | return( 1 );
296 | }
297 | present = 1;
298 | newfile = 1;
299 | }
300 | break;
301 |
302 | case 'b':
303 | case 'c':
304 | if ( tac != 7 ) {
305 | fprintf( stderr,
306 | "%d: incorrect number of arguments\n", linenum );
307 | return( 1 );
308 | }
309 |
310 | mode = strtol( targv[ 2 ], (char **)NULL, 8 );
311 |
312 | if ( present && (( minor( st->st_rdev ) != atoi( targv[ 6 ] )) ||
313 | ( major( st->st_rdev ) != atoi( targv[ 5 ] )))) {
314 | if ( unlink( path ) != 0 ) {
315 | perror( path );
316 | return( 1 );
317 | }
318 | present = 0;
319 | }
320 |
321 | if ( !present ) {
322 | #ifdef sun
323 | if ( ( dev = makedev( (major_t)atoi( targv[ 5 ] ),
324 | (minor_t)atoi( targv[ 6 ] ) ) ) == NODEV ) {
325 | perror( path );
326 | return( 1 );
327 | }
328 | #else /* !sun */
329 | dev = makedev( atoi( targv[ 5 ] ), atoi( targv[ 6 ] ));
330 | #endif /* sun */
331 |
332 | if( *targv[ 0 ] == 'b' ) {
333 | mode |= S_IFBLK;
334 | } else {
335 | mode |= S_IFCHR;
336 | }
337 |
338 | if ( mknod( path, mode, dev ) != 0 ) {
339 | if ( create_prefix && errno == ENOENT ) {
340 | errno = 0;
341 | if ( mkprefix( path ) != 0 ) {
342 | perror( path );
343 | return( 1 );
344 | }
345 | if ( mknod( path, mode, dev ) != 0 ) {
346 | perror( path );
347 | return( 1 );
348 | }
349 | } else {
350 | perror( path );
351 | return( 1 );
352 | }
353 | }
354 | if ( lstat( path, st ) != 0 ) {
355 | perror( path );
356 | return( 1 );
357 | }
358 | present = 1;
359 | newfile = 1;
360 | }
361 | break;
362 |
363 | case 's':
364 | case 'D':
365 | if ( tac != 5 ) {
366 | fprintf( stderr,
367 | "%d: incorrect number of arguments\n", linenum );
368 | return( 1 );
369 | }
370 |
371 | mode = strtol( targv[ 2 ], (char **)NULL, 8 );
372 |
373 | if ( !present ) {
374 | fprintf( stderr, "%d: Warning: %c %s not created...continuing\n",
375 | linenum, *targv[ 0 ], path );
376 | return( 2 );
377 | }
378 |
379 | break;
380 |
381 | default :
382 | fprintf( stderr, "%d: Unknown type %s\n", linenum, targv[ 0 ] );
383 | return( 1 );
384 | }
385 |
386 | if ( !quiet && !showprogress ) {
387 | if ( newfile ) {
388 | printf( "%s: created updating", displaypath );
389 | } else {
390 | printf( "%s: updating", displaypath );
391 | }
392 | }
393 |
394 | /* check uid & gid */
395 | uid = atoi( targv[ 3 ] );
396 | gid = atoi( targv[ 4 ] );
397 | if ( uid != st->st_uid || gid != st->st_gid ) {
398 | if ( chown( path, uid, gid ) != 0 ) {
399 | perror( path );
400 | return( 1 );
401 | }
402 | if ( uid != st->st_uid ) {
403 | if ( !quiet && !showprogress ) printf( " uid" );
404 | }
405 | if ( gid != st->st_gid ) {
406 | if ( !quiet && !showprogress ) printf( " gid" );
407 | }
408 | }
409 | /*
410 | * chmod after chown to preserve S_ISUID and S_ISGID mode bits
411 | * We also need an extra chmod if we did a chown on a set-uid or -gid
412 | * file.
413 | */
414 | if (( mode != ( T_MODE & st->st_mode )) ||
415 | (( uid != st->st_uid || gid != st->st_gid ) &&
416 | (( mode & ( S_ISUID | S_ISGID )) != 0 ))) {
417 | if ( chmod( path, mode ) != 0 ) {
418 | perror( path );
419 | return( 1 );
420 | }
421 | if ( !quiet && !showprogress ) printf( " mode" );
422 | }
423 |
424 | if ( timeupdated && !showprogress && !quiet ) {
425 | printf( " time" );
426 | }
427 |
428 | done:
429 | if ( !quiet && !showprogress ) printf( "\n" );
430 | if ( showprogress ) {
431 | progressupdate( PROGRESSUNIT, displaypath );
432 | }
433 |
434 | return( 0 );
435 | }
436 |
--------------------------------------------------------------------------------
/update.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int update( char *path, char *displaypath, int present, int newfile,
7 | struct stat *st, int tac, char **targv, struct applefileinfo *afinfo );
8 |
--------------------------------------------------------------------------------
/version.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | char *version = VERSION;
9 | char *checksumlist = "sha1\nsha\nmd5\nmd2\ndss1\nmdc2\nripemd160";
10 |
--------------------------------------------------------------------------------
/wildcard.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2008 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | #include "config.h"
7 |
8 | #include
9 | #include
10 |
11 | #include "wildcard.h"
12 |
13 | int
14 | wildcard( char *wild, char *p, int sensitive )
15 | {
16 | int min, max;
17 | int i, len;
18 | char *comma, *end;
19 |
20 | for (;;) {
21 | switch ( *wild ) {
22 | case '*' :
23 | wild++;
24 |
25 | if ( *wild == '\0' ) {
26 | return( 1 );
27 | }
28 | for ( i = 0; p[ i ] != '\0'; i++ ) {
29 | if ( wildcard( wild, &p[ i ], sensitive )) {
30 | return( 1 );
31 | }
32 | }
33 | return( 0 );
34 |
35 | case '<' :
36 | wild++;
37 |
38 | if ( ! isdigit( (int)*p )) {
39 | return( 0 );
40 | }
41 | i = atoi( p );
42 | while ( isdigit( (int)*p )) p++;
43 |
44 | if ( ! isdigit( (int)*wild )) {
45 | return( 0 );
46 | }
47 | min = atoi( wild );
48 | while ( isdigit( (int)*wild )) wild++;
49 |
50 | if ( *wild++ != '-' ) {
51 | return( 0 );
52 | }
53 |
54 | if ( ! isdigit( (int)*wild )) {
55 | return( 0 );
56 | }
57 | max = atoi( wild );
58 | while ( isdigit( (int)*wild )) wild++;
59 |
60 | if ( *wild++ != '>' ) {
61 | return( 0 );
62 | }
63 |
64 | if (( i < min ) || ( i > max )) {
65 | return( 0 );
66 | }
67 | break;
68 |
69 | case '?' :
70 | wild++;
71 | p++;
72 | break;
73 |
74 | case '[' :
75 | for ( wild++; *wild != ']'; wild++ ) {
76 | if ( sensitive ) {
77 | if ( *wild != *p ) break;
78 | } else {
79 | if ( tolower(*wild) != tolower(*p) ) break;
80 | }
81 | }
82 | if ( *wild == ']' ) {
83 | return( 0 );
84 | }
85 | for ( ; *wild; wild++ ) {
86 | if ( *wild == ']' ) {
87 | break;
88 | }
89 | }
90 | if ( *wild == '\0' ) {
91 | return( 0 );
92 | }
93 |
94 | p++;
95 | wild++;
96 | break;
97 |
98 | case '{' :
99 | comma = wild;
100 |
101 | for ( end = wild + 1; *end != '}'; end++ ) {
102 | if ( *end == '{' || *end == '\0' ) {
103 | /* malformed pattern */
104 | return( 0 );
105 | }
106 | }
107 | end++;
108 |
109 | do {
110 | for ( wild = ++comma; *comma != ',' && *comma != '}'; comma++ )
111 | ;
112 | len = comma - wild;
113 |
114 | for ( i = 0; i < len; i++ ) {
115 | if ( sensitive ) {
116 | if ( wild[ i ] != p[ i ] ) break;
117 | } else {
118 | if ( tolower( wild[ i ] ) != tolower( p[ i ] )) break;
119 | }
120 | }
121 | if ( i >= len && wildcard( end, &p[ i ], sensitive )) {
122 | return( 1 );
123 | }
124 | } while ( *comma != '}' );
125 | return( 0 );
126 |
127 | case '\\' :
128 | wild++;
129 | default :
130 | if ( sensitive ) {
131 | if ( *wild != *p ) return( 0 );
132 | } else {
133 | if ( tolower(*wild) != tolower(*p) ) return( 0 );
134 | }
135 | if ( *wild == '\0' ) {
136 | return( 1 );
137 | }
138 | wild++, p++;
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/wildcard.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2003 Regents of The University of Michigan.
3 | * All Rights Reserved. See COPYRIGHT.
4 | */
5 |
6 | int wildcard( char *, char *, int );
7 |
--------------------------------------------------------------------------------