summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorlulf <lulf@FreeBSD.org>2010-03-02 07:26:07 +0000
committerlulf <lulf@FreeBSD.org>2010-03-02 07:26:07 +0000
commitc6aa3ac44645e36e9cc1e29aa598a706779c2c29 (patch)
tree34e14c6edd4db3c9e2addc2e9b8af07a970b71ed /contrib
parentb86208843f144382d49d980b9908eb8618cfc5cd (diff)
downloadFreeBSD-src-c6aa3ac44645e36e9cc1e29aa598a706779c2c29.zip
FreeBSD-src-c6aa3ac44645e36e9cc1e29aa598a706779c2c29.tar.gz
- Move csup away from contrib/ and into usr.bin/. Software is no longer
contributed, and main development is happening in the FreeBSD repo. Suggested by: joel
Diffstat (limited to 'contrib')
-rw-r--r--contrib/csup/GNUmakefile64
-rw-r--r--contrib/csup/Makefile48
-rw-r--r--contrib/csup/README39
-rw-r--r--contrib/csup/TODO29
-rw-r--r--contrib/csup/attrstack.c90
-rw-r--r--contrib/csup/attrstack.h40
-rw-r--r--contrib/csup/auth.c331
-rw-r--r--contrib/csup/auth.h38
-rw-r--r--contrib/csup/config.c579
-rw-r--r--contrib/csup/config.h127
-rw-r--r--contrib/csup/cpasswd.1120
-rwxr-xr-xcontrib/csup/cpasswd.sh135
-rw-r--r--contrib/csup/csup.11000
-rw-r--r--contrib/csup/detailer.c603
-rw-r--r--contrib/csup/detailer.h33
-rw-r--r--contrib/csup/diff.c438
-rw-r--r--contrib/csup/diff.h52
-rw-r--r--contrib/csup/fattr.c981
-rw-r--r--contrib/csup/fattr.h118
-rw-r--r--contrib/csup/fattr_bsd.h52
-rw-r--r--contrib/csup/fattr_posix.h48
-rw-r--r--contrib/csup/fixups.c198
-rw-r--r--contrib/csup/fixups.h48
-rw-r--r--contrib/csup/fnmatch.c199
-rw-r--r--contrib/csup/fnmatch.h58
-rw-r--r--contrib/csup/globtree.c393
-rw-r--r--contrib/csup/globtree.h45
-rw-r--r--contrib/csup/idcache.c421
-rw-r--r--contrib/csup/idcache.h41
-rw-r--r--contrib/csup/keyword.c525
-rw-r--r--contrib/csup/keyword.h54
-rw-r--r--contrib/csup/lex.rcs.c2094
-rw-r--r--contrib/csup/lister.c569
-rw-r--r--contrib/csup/lister.h33
-rw-r--r--contrib/csup/main.c347
-rw-r--r--contrib/csup/main.h29
-rw-r--r--contrib/csup/misc.c645
-rw-r--r--contrib/csup/misc.h138
-rw-r--r--contrib/csup/mux.c1202
-rw-r--r--contrib/csup/mux.h45
-rw-r--r--contrib/csup/parse.y91
-rw-r--r--contrib/csup/pathcomp.c182
-rw-r--r--contrib/csup/pathcomp.h44
-rw-r--r--contrib/csup/proto.c997
-rw-r--r--contrib/csup/proto.h50
-rw-r--r--contrib/csup/queue.h227
-rw-r--r--contrib/csup/rcsfile.c1412
-rw-r--r--contrib/csup/rcsfile.h73
-rw-r--r--contrib/csup/rcsparse.c357
-rw-r--r--contrib/csup/rcsparse.h41
-rw-r--r--contrib/csup/rcstokenizer.h333
-rw-r--r--contrib/csup/rcstokenizer.l73
-rw-r--r--contrib/csup/rsyncfile.c223
-rw-r--r--contrib/csup/rsyncfile.h41
-rw-r--r--contrib/csup/status.c874
-rw-r--r--contrib/csup/status.h72
-rw-r--r--contrib/csup/stream.c1303
-rw-r--r--contrib/csup/stream.h84
-rw-r--r--contrib/csup/threads.c176
-rw-r--r--contrib/csup/threads.h38
-rw-r--r--contrib/csup/token.h49
-rw-r--r--contrib/csup/token.l80
-rw-r--r--contrib/csup/updater.c2044
-rw-r--r--contrib/csup/updater.h33
64 files changed, 0 insertions, 20946 deletions
diff --git a/contrib/csup/GNUmakefile b/contrib/csup/GNUmakefile
deleted file mode 100644
index 18fb071..0000000
--- a/contrib/csup/GNUmakefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# A simple gmake Makefile, to be used on Linux and Darwin. It shouldn't
-# be used elsewhere because it assumes that the target system doesn't
-# support BSD extended file flags.
-#
-# $FreeBSD$
-#
-
-PREFIX?=/usr/local
-OWNER?= 0
-GROUP?= 0
-
-UNAME= $(shell uname -s)
-
-SRCS= attrstack.c config.c detailer.c diff.c fattr.c fixups.c fnmatch.c \
- globtree.c idcache.c keyword.c lex.rcs.c lister.c main.c misc.c mux.c \
- pathcomp.c parse.c proto.c rcsfile.c rcsparse.c rsyncfile.c status.c \
- stream.c threads.c token.c updater.c
-OBJS= $(SRCS:.c=.o)
-
-WARNS= -Wall -W -Wno-unused-parameter -Wmissing-prototypes -Wpointer-arith \
- -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow \
- -Wcast-align -Wunused-parameter -Wchar-subscripts -Winline \
- -Wnested-externs -Wredundant-decls -Wno-format-y2k
-
-CFLAGS+= -g -O -pipe -DNDEBUG -I$(PREFIX)/include
-ifeq ($(UNAME), Linux)
- CFLAGS+= -D_XOPEN_SOURCE -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
-endif
-ifeq ($(UNAME), Darwin)
- CFLAGS+= -DHAVE_FFLAGS
-endif
-CFLAGS+= $(WARNS)
-LDFLAGS= -L$(PREFIX)/lib -lcrypto -lz -lpthread
-
-.PHONY: all clean install
-
-all: csup csup.1.gz
-
-csup: $(OBJS)
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
-
-config.c: parse.h
-
-token.c: token.l
-
-parse.c: parse.y
-
-parse.h: parse.c
-
-clean:
- rm -f csup $(OBJS) parse.c parse.h token.c csup.1.gz
-
-%.o: %.c
- $(CC) $(CFLAGS) -c -o $@ $<
-
-%.c: %.y
- $(YACC) -d -o $@ $<
-
-csup.1.gz: csup.1
- gzip -cn $< > $@
-
-install: csup csup.1.gz
- install -s -o $(OWNER) -g $(GROUP) csup $(PREFIX)/bin
- install -s -o $(OWNER) -g $(GROUP) csup.1.gz $(PREFIX)/share/man/man1
diff --git a/contrib/csup/Makefile b/contrib/csup/Makefile
deleted file mode 100644
index ae34e75..0000000
--- a/contrib/csup/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-# $FreeBSD$
-
-PREFIX?= /usr/local
-BINDIR?= ${PREFIX}/bin
-MANDIR?= ${PREFIX}/man/man
-
-UNAME!= /usr/bin/uname -s
-
-PROG= csup
-SRCS= attrstack.c auth.c config.c detailer.c diff.c fattr.c fixups.c fnmatch.c \
- globtree.c idcache.c keyword.c lister.c main.c misc.c mux.c parse.y \
- pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
- rcsfile.c rcsparse.c lex.rcs.c rsyncfile.c
-
-CFLAGS+= -I. -I${.CURDIR} -g -pthread -DHAVE_FFLAGS -DNDEBUG
-WARNS?= 1
-
-# A bit of tweaking is needed to get this Makefile working
-# with the bsd.prog.mk of all the *BSD OSes...
-.if (${UNAME} == "NetBSD")
-LDFLAGS+= -pthread
-YHEADER= yes
-
-.elif (${UNAME} == "OpenBSD")
-# I bet there's a better way to do this with the OpenBSD mk
-# framework but well, this works and I got bored.
-LDFLAGS+= -pthread
-YFLAGS= -d
-CLEANFILES+= parse.c parse.h y.tab.h
-
-config.c: parse.h
-
-token.l: parse.h
-
-y.tab.h: parse.c
-
-parse.h: y.tab.h
- cp ${.ALLSRC} ${.TARGET}
-
-.endif
-
-DPADD= ${LIBCRYPTO} ${LIBZ}
-LDADD= -lcrypto -lz
-
-SCRIPTS= cpasswd.sh
-MAN= csup.1 cpasswd.1
-
-.include <bsd.prog.mk>
diff --git a/contrib/csup/README b/contrib/csup/README
deleted file mode 100644
index 879c481..0000000
--- a/contrib/csup/README
+++ /dev/null
@@ -1,39 +0,0 @@
-$FreeBSD$
-
-Authors
--------
-
-CVSup was originally written in Modula-3 by
- John Polstra <jdp@polstra.com>.
-
-Csup is a rewrite of CVSup in C. It has been mostly written by
- Maxime Henrion <mux@FreeBSD.org>.
-
-A few contributors have helped him in his task and they are listed here in
-alphabetical order :
-
- Olivier Houchard <cognet@FreeBSD.org>
- Ulf Lilleengen <lulf@kerneled.org>
- Christoph Mathys <cmathys@bluewin.ch> (Google SoC Project)
- Etienne Vidal <etienne.vidal@gmail.com>
-
-
-Building & Installing
----------------------
-
-Csup should build and run fine under any *BSD OS (that includes FreeBSD,
-NetBSD, OpenBSD and DragonFlyBSD), as well as Linux and Darwin. If you
-have a problem building from source, drop me a mail!
-
-There is one Makefile specifically tailored for *BSD systems named
-Makefile and another one that is gmake-specific for Darwin and Linux
-users named GNUmakefile. You don't really need to worry about that
-since whatever your "make" command is, it should pick up the correct
-Makefile.
-
-As usual, to build the source code, just run "make". Once this is done,
-just run "make install" to install the binary and manual page.
-
-Be warned however that if the packaging system of your OS knows about
-csup, it is certainly better to install it from there rather than by
-hand, so that it can then be properly deinstalled.
diff --git a/contrib/csup/TODO b/contrib/csup/TODO
deleted file mode 100644
index f4f0b31..0000000
--- a/contrib/csup/TODO
+++ /dev/null
@@ -1,29 +0,0 @@
-$FreeBSD$
-
-BUGS:
-
-- Fix every XXX in the code :-).
-- The stream API needs some polishing. It needs proper error numbers
- and a stream_error() function similar to the ferror() function.
-- The yacc/lex code to parse the configuration file is sub-optimal. It
- has global variables because of yacc, but I think it should be possible
- to do it better by using YYFUNC_PROTOTYPE or something. I think it
- should also be possible to completely get rid of the lex file.
-- The $Log$ CVS keyword is not supported.
-- Add missing support for supfile keywords and add sanity checks for
- some of them. Also, we're not supposed to choke on unknown keywords
- to stay in line with CVSup, which just ignores them in order to
- maintain compatibility with sup configuration files.
-
-MISSING FEATURES:
-
-- Add support for shell commands sent by the server.
-- Add missing support for various CVSup options : -D, -a (requires
- authentication support), -e and -E (requires shell commands support)
- and the destDir parameter.
-- For now, this code should build fine on FreeBSD, NetBSD, OpenBSD,
- Linux and Darwin. Solaris support would also be nice at some point.
-- Implement some new useful options : the ability to generate CVS
- checkout files (files in CVS/ subdirectores), a command line override
- to only update a specific collection and a third verbosity level to
- display commit log messages.
diff --git a/contrib/csup/attrstack.c b/contrib/csup/attrstack.c
deleted file mode 100644
index f5f56b3..0000000
--- a/contrib/csup/attrstack.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "attrstack.h"
-#include "fattr.h"
-#include "misc.h"
-
-#define ATTRSTACK_DEFSIZE 16 /* Initial size of the stack. */
-
-struct attrstack {
- struct fattr **stack;
- size_t cur;
- size_t size;
-};
-
-struct attrstack *
-attrstack_new(void)
-{
- struct attrstack *as;
-
- as = xmalloc(sizeof(struct attrstack));
- as->stack = xmalloc(sizeof(struct fattr *) * ATTRSTACK_DEFSIZE);
- as->size = ATTRSTACK_DEFSIZE;
- as->cur = 0;
- return (as);
-}
-
-struct fattr *
-attrstack_pop(struct attrstack *as)
-{
-
- assert(as->cur > 0);
- return (as->stack[--as->cur]);
-}
-
-void
-attrstack_push(struct attrstack *as, struct fattr *fa)
-{
-
- if (as->cur >= as->size) {
- as->size *= 2;
- as->stack = xrealloc(as->stack,
- sizeof(struct fattr *) * as->size);
- }
- as->stack[as->cur++] = fa;
-}
-
-size_t
-attrstack_size(struct attrstack *as)
-{
-
- return (as->cur);
-}
-
-void
-attrstack_free(struct attrstack *as)
-{
-
- assert(as->cur == 0);
- free(as->stack);
- free(as);
-}
diff --git a/contrib/csup/attrstack.h b/contrib/csup/attrstack.h
deleted file mode 100644
index 721313c..0000000
--- a/contrib/csup/attrstack.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-#ifndef _ATTRSTACK_H_
-#define _ATTRSTACK_H_
-
-struct fattr;
-struct attrstack;
-
-struct attrstack *attrstack_new(void);
-void attrstack_push(struct attrstack *, struct fattr *);
-struct fattr *attrstack_pop(struct attrstack *);
-size_t attrstack_size(struct attrstack *);
-void attrstack_free(struct attrstack *);
-
-#endif /* !_ATTRSTACK_H_ */
diff --git a/contrib/csup/auth.c b/contrib/csup/auth.c
deleted file mode 100644
index 4e79bc5..0000000
--- a/contrib/csup/auth.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*-
- * Copyright (c) 2003-2007, Petar Zhivkov Petrov <pesho.petrov@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-#include <ctype.h>
-#include <openssl/md5.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "auth.h"
-#include "config.h"
-#include "misc.h"
-#include "proto.h"
-#include "stream.h"
-
-#define MD5_BYTES 16
-
-/* This should be at least 2 * MD5_BYTES + 6 (length of "$md5$" + 1) */
-#define MD5_CHARS_MAX (2*(MD5_BYTES)+6)
-
-struct srvrecord {
- char server[MAXHOSTNAMELEN];
- char client[256];
- char password[256];
-};
-
-static int auth_domd5auth(struct config *);
-static int auth_lookuprecord(char *, struct srvrecord *);
-static int auth_parsetoken(char **, char *, int);
-static void auth_makesecret(struct srvrecord *, char *);
-static void auth_makeresponse(char *, char *, char *);
-static void auth_readablesum(unsigned char *, char *);
-static void auth_makechallenge(struct config *, char *);
-static int auth_checkresponse(char *, char *, char *);
-
-int auth_login(struct config *config)
-{
- struct stream *s;
- char hostbuf[MAXHOSTNAMELEN];
- char *login, *host;
- int error;
-
- s = config->server;
- error = gethostname(hostbuf, sizeof(hostbuf));
- hostbuf[sizeof(hostbuf) - 1] = '\0';
- if (error)
- host = NULL;
- else
- host = hostbuf;
- login = getlogin();
- proto_printf(s, "USER %s %s\n", login != NULL ? login : "?",
- host != NULL ? host : "?");
- stream_flush(s);
- error = auth_domd5auth(config);
- return (error);
-}
-
-static int
-auth_domd5auth(struct config *config)
-{
- struct stream *s;
- char *line, *cmd, *challenge, *realm, *client, *srvresponse, *msg;
- char shrdsecret[MD5_CHARS_MAX], response[MD5_CHARS_MAX];
- char clichallenge[MD5_CHARS_MAX];
- struct srvrecord auth;
- int error;
-
- lprintf(2, "MD5 authentication started\n");
- s = config->server;
- line = stream_getln(s, NULL);
- cmd = proto_get_ascii(&line);
- realm = proto_get_ascii(&line);
- challenge = proto_get_ascii(&line);
- if (challenge == NULL ||
- line != NULL ||
- (strcmp(cmd, "AUTHMD5") != 0)) {
- lprintf(-1, "Invalid server reply to USER\n");
- return (STATUS_FAILURE);
- }
-
- client = NULL;
- response[0] = clichallenge[0] = '.';
- response[1] = clichallenge[1] = 0;
- if (config->reqauth || (strcmp(challenge, ".") != 0)) {
- if (strcmp(realm, ".") == 0) {
- lprintf(-1, "Authentication required, but not enabled on server\n");
- return (STATUS_FAILURE);
- }
- error = auth_lookuprecord(realm, &auth);
- if (error != STATUS_SUCCESS)
- return (error);
- client = auth.client;
- auth_makesecret(&auth, shrdsecret);
- }
-
- if (strcmp(challenge, ".") != 0)
- auth_makeresponse(challenge, shrdsecret, response);
- if (config->reqauth)
- auth_makechallenge(config, clichallenge);
- proto_printf(s, "AUTHMD5 %s %s %s\n",
- client == NULL ? "." : client, response, clichallenge);
- stream_flush(s);
- line = stream_getln(s, NULL);
- cmd = proto_get_ascii(&line);
- if (cmd == NULL || line == NULL)
- goto bad;
- if (strcmp(cmd, "OK") == 0) {
- srvresponse = proto_get_ascii(&line);
- if (srvresponse == NULL)
- goto bad;
- if (config->reqauth &&
- !auth_checkresponse(srvresponse, clichallenge, shrdsecret)) {
- lprintf(-1, "Server failed to authenticate itself to client\n");
- return (STATUS_FAILURE);
- }
- lprintf(2, "MD5 authentication successfull\n");
- return (STATUS_SUCCESS);
- }
- if (strcmp(cmd, "!") == 0) {
- msg = proto_get_rest(&line);
- if (msg == NULL)
- goto bad;
- lprintf(-1, "Server error: %s\n", msg);
- return (STATUS_FAILURE);
- }
-bad:
- lprintf(-1, "Invalid server reply to AUTHMD5\n");
- return (STATUS_FAILURE);
-}
-
-static int
-auth_lookuprecord(char *server, struct srvrecord *auth)
-{
- char *home, *line, authfile[FILENAME_MAX];
- struct stream *s;
- int linenum = 0, error;
-
- home = getenv("HOME");
- if (home == NULL) {
- lprintf(-1, "Environment variable \"HOME\" is not set\n");
- return (STATUS_FAILURE);
- }
- snprintf(authfile, sizeof(authfile), "%s/%s", home, AUTHFILE);
- s = stream_open_file(authfile, O_RDONLY);
- if (s == NULL) {
- lprintf(-1, "Could not open file %s\n", authfile);
- return (STATUS_FAILURE);
- }
-
- while ((line = stream_getln(s, NULL)) != NULL) {
- linenum++;
- if (line[0] == '#' || line[0] == '\0')
- continue;
- error = auth_parsetoken(&line, auth->server,
- sizeof(auth->server));
- if (error != STATUS_SUCCESS) {
- lprintf(-1, "%s:%d Missng client name\n", authfile, linenum);
- goto close;
- }
- /* Skip the rest of this line, it isn't what we are looking for. */
- if (strcmp(auth->server, server) != 0)
- continue;
- error = auth_parsetoken(&line, auth->client,
- sizeof(auth->client));
- if (error != STATUS_SUCCESS) {
- lprintf(-1, "%s:%d Missng password\n", authfile, linenum);
- goto close;
- }
- error = auth_parsetoken(&line, auth->password,
- sizeof(auth->password));
- if (error != STATUS_SUCCESS) {
- lprintf(-1, "%s:%d Missng comment\n", authfile, linenum);
- goto close;
- }
- stream_close(s);
- lprintf(2, "Found authentication record for server \"%s\"\n",
- server);
- return (STATUS_SUCCESS);
- }
- lprintf(-1, "Unknown server \"%s\". Fix your %s\n", server , authfile);
- memset(auth->password, 0, sizeof(auth->password));
-close:
- stream_close(s);
- return (STATUS_FAILURE);
-}
-
-static int
-auth_parsetoken(char **line, char *buf, int len)
-{
- char *colon;
-
- colon = strchr(*line, ':');
- if (colon == NULL)
- return (STATUS_FAILURE);
- *colon = 0;
- buf[len - 1] = 0;
- strncpy(buf, *line, len - 1);
- *line = colon + 1;
- return (STATUS_SUCCESS);
-}
-
-static void
-auth_makesecret(struct srvrecord *auth, char *secret)
-{
- char *s, ch;
- const char *md5salt = "$md5$";
- unsigned char md5sum[MD5_BYTES];
- MD5_CTX md5;
-
- MD5_Init(&md5);
- for (s = auth->client; *s != 0; ++s) {
- ch = tolower(*s);
- MD5_Update(&md5, &ch, 1);
- }
- MD5_Update(&md5, ":", 1);
- for (s = auth->server; *s != 0; ++s) {
- ch = tolower(*s);
- MD5_Update(&md5, &ch, 1);
- }
- MD5_Update(&md5, ":", 1);
- MD5_Update(&md5, auth->password, strlen(auth->password));
- MD5_Final(md5sum, &md5);
- memset(secret, 0, sizeof(secret));
- strcpy(secret, md5salt);
- auth_readablesum(md5sum, secret + strlen(md5salt));
-}
-
-static void
-auth_makeresponse(char *challenge, char *sharedsecret, char *response)
-{
- MD5_CTX md5;
- unsigned char md5sum[MD5_BYTES];
-
- MD5_Init(&md5);
- MD5_Update(&md5, sharedsecret, strlen(sharedsecret));
- MD5_Update(&md5, ":", 1);
- MD5_Update(&md5, challenge, strlen(challenge));
- MD5_Final(md5sum, &md5);
- auth_readablesum(md5sum, response);
-}
-
-/*
- * Generates a challenge string which is an MD5 sum
- * of a fairly random string. The purpose is to decrease
- * the possibility of generating the same challenge
- * string (even by different clients) more then once
- * for the same server.
- */
-static void
-auth_makechallenge(struct config *config, char *challenge)
-{
- MD5_CTX md5;
- unsigned char md5sum[MD5_BYTES];
- char buf[128];
- struct timeval tv;
- struct sockaddr_in laddr;
- pid_t pid, ppid;
- int error, addrlen;
-
- gettimeofday(&tv, NULL);
- pid = getpid();
- ppid = getppid();
- srand(tv.tv_usec ^ tv.tv_sec ^ pid);
- addrlen = sizeof(laddr);
- error = getsockname(config->socket, (struct sockaddr *)&laddr, &addrlen);
- if (error < 0) {
- memset(&laddr, 0, sizeof(laddr));
- }
- gettimeofday(&tv, NULL);
- MD5_Init(&md5);
- snprintf(buf, sizeof(buf), "%s:%ld:%ld:%ld:%d:%d",
- inet_ntoa(laddr.sin_addr), tv.tv_sec, tv.tv_usec, random(), pid, ppid);
- MD5_Update(&md5, buf, strlen(buf));
- MD5_Final(md5sum, &md5);
- auth_readablesum(md5sum, challenge);
-}
-
-static int
-auth_checkresponse(char *response, char *challenge, char *secret)
-{
- char correctresponse[MD5_CHARS_MAX];
-
- auth_makeresponse(challenge, secret, correctresponse);
- return (strcmp(response, correctresponse) == 0);
-}
-
-static void
-auth_readablesum(unsigned char *md5sum, char *readable)
-{
- unsigned int i;
- char *s = readable;
-
- for (i = 0; i < MD5_BYTES; ++i, s+=2) {
- sprintf(s, "%.2x", md5sum[i]);
- }
-}
-
diff --git a/contrib/csup/auth.h b/contrib/csup/auth.h
deleted file mode 100644
index 61052e3..0000000
--- a/contrib/csup/auth.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-
- * Copyright (c) 2003-2007, Petar Zhivkov Petrov <pesho.petrov@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _AUTH_H_
-#define _AUTH_H_
-
-#define AUTHFILE ".csup/auth" /* user home relative */
-
-struct config;
-
-int auth_login(struct config *);
-
-#endif /* !_AUTH_H_ */
-
diff --git a/contrib/csup/config.c b/contrib/csup/config.c
deleted file mode 100644
index 46ae6cd..0000000
--- a/contrib/csup/config.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "globtree.h"
-#include "keyword.h"
-#include "misc.h"
-#include "parse.h"
-#include "stream.h"
-#include "token.h"
-
-static int config_parse_refusefiles(struct coll *);
-static int config_parse_refusefile(struct coll *, char *);
-
-extern FILE *yyin;
-
-/* These are globals because I can't think of a better way with yacc. */
-static STAILQ_HEAD(, coll) colls;
-static struct coll *cur_coll;
-static struct coll *defaults;
-static struct coll *ovcoll;
-static int ovmask;
-static const char *cfgfile;
-
-/*
- * Extract all the configuration information from the config
- * file and some command line parameters.
- */
-struct config *
-config_init(const char *file, struct coll *override, int overridemask)
-{
- struct config *config;
- struct coll *coll;
- size_t slen;
- char *prefix;
- int error;
- mode_t mask;
-
- config = xmalloc(sizeof(struct config));
- memset(config, 0, sizeof(struct config));
- STAILQ_INIT(&colls);
-
- defaults = coll_new(NULL);
- /* Set the default umask. */
- mask = umask(0);
- umask(mask);
- defaults->co_umask = mask;
- ovcoll = override;
- ovmask = overridemask;
-
- /* Extract a list of collections from the configuration file. */
- cur_coll = coll_new(defaults);
- yyin = fopen(file, "r");
- if (yyin == NULL) {
- lprintf(-1, "Cannot open \"%s\": %s\n", file, strerror(errno));
- goto bad;
- }
- cfgfile = file;
- error = yyparse();
- fclose(yyin);
- if (error)
- goto bad;
-
- memcpy(&config->colls, &colls, sizeof(colls));
- if (STAILQ_EMPTY(&config->colls)) {
- lprintf(-1, "Empty supfile\n");
- goto bad;
- }
-
- /* Fixup the list of collections. */
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- if (coll->co_base == NULL)
- coll->co_base = xstrdup("/usr/local/etc/cvsup");
- if (coll->co_colldir == NULL)
- coll->co_colldir = "sup";
- if (coll->co_prefix == NULL) {
- coll->co_prefix = xstrdup(coll->co_base);
- /*
- * If prefix is not an absolute pathname, it is
- * interpreted relative to base.
- */
- } else if (coll->co_prefix[0] != '/') {
- slen = strlen(coll->co_base);
- if (slen > 0 && coll->co_base[slen - 1] != '/')
- xasprintf(&prefix, "%s/%s", coll->co_base,
- coll->co_prefix);
- else
- xasprintf(&prefix, "%s%s", coll->co_base,
- coll->co_prefix);
- free(coll->co_prefix);
- coll->co_prefix = prefix;
- }
- coll->co_prefixlen = strlen(coll->co_prefix);
- /* Determine whether to checksum RCS files or not. */
- if (coll->co_options & CO_EXACTRCS)
- coll->co_options |= CO_CHECKRCS;
- else
- coll->co_options &= ~CO_CHECKRCS;
- /* In recent versions, we always try to set the file modes. */
- coll->co_options |= CO_SETMODE;
- coll->co_options |= CO_NORSYNC;
- error = config_parse_refusefiles(coll);
- if (error)
- goto bad;
- }
-
- coll_free(cur_coll);
- coll_free(defaults);
- config->host = STAILQ_FIRST(&config->colls)->co_host;
- return (config);
-bad:
- coll_free(cur_coll);
- coll_free(defaults);
- config_free(config);
- return (NULL);
-}
-
-int
-config_checkcolls(struct config *config)
-{
- char linkname[4];
- struct stat sb;
- struct coll *coll;
- int error, numvalid, ret;
-
- numvalid = 0;
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- error = stat(coll->co_prefix, &sb);
- if (error || !S_ISDIR(sb.st_mode)) {
- /* Skip this collection, and warn about it unless its
- prefix is a symbolic link pointing to "SKIP". */
- coll->co_options |= CO_SKIP;
- ret = readlink(coll->co_prefix, linkname,
- sizeof(linkname));
- if (ret != 4 || memcmp(linkname, "SKIP", 4) != 0) {
- lprintf(-1,"Nonexistent prefix \"%s\" for "
- "%s/%s\n", coll->co_prefix, coll->co_name,
- coll->co_release);
- }
- continue;
- }
- numvalid++;
- }
- return (numvalid);
-}
-
-static int
-config_parse_refusefiles(struct coll *coll)
-{
- char *collstem, *suffix, *supdir, *path;
- int error;
-
- if (coll->co_colldir[0] == '/')
- supdir = xstrdup(coll->co_colldir);
- else
- xasprintf(&supdir, "%s/%s", coll->co_base, coll->co_colldir);
-
- /* First, the global refuse file that applies to all collections. */
- xasprintf(&path, "%s/refuse", supdir);
- error = config_parse_refusefile(coll, path);
- free(path);
- if (error) {
- free(supdir);
- return (error);
- }
-
- /* Next the per-collection refuse files that applies to all release/tag
- combinations. */
- xasprintf(&collstem, "%s/%s/refuse", supdir, coll->co_name);
- free(supdir);
- error = config_parse_refusefile(coll, collstem);
- if (error) {
- free(collstem);
- return (error);
- }
-
- /* Finally, the per-release and per-tag refuse file. */
- suffix = coll_statussuffix(coll);
- if (suffix != NULL) {
- xasprintf(&path, "%s%s", collstem, suffix);
- free(suffix);
- error = config_parse_refusefile(coll, path);
- free(path);
- }
- free(collstem);
- return (error);
-}
-
-/*
- * Parses a "refuse" file, and records the relevant information in
- * coll->co_refusals. If the file does not exist, it is silently
- * ignored.
- */
-static int
-config_parse_refusefile(struct coll *coll, char *path)
-{
- struct stream *rd;
- char *cp, *line, *pat;
-
- rd = stream_open_file(path, O_RDONLY);
- if (rd == NULL)
- return (0);
- while ((line = stream_getln(rd, NULL)) != NULL) {
- pat = line;
- for (;;) {
- /* Trim leading whitespace. */
- pat += strspn(pat, " \t");
- if (pat[0] == '\0')
- break;
- cp = strpbrk(pat, " \t");
- if (cp != NULL)
- *cp = '\0';
- pattlist_add(coll->co_refusals, pat);
- if (cp == NULL)
- break;
- pat = cp + 1;
- }
- }
- if (!stream_eof(rd)) {
- stream_close(rd);
- lprintf(-1, "Read failure from \"%s\": %s\n", path,
- strerror(errno));
- return (-1);
- }
- stream_close(rd);
- return (0);
-}
-
-void
-config_free(struct config *config)
-{
- struct coll *coll;
-
- while (!STAILQ_EMPTY(&config->colls)) {
- coll = STAILQ_FIRST(&config->colls);
- STAILQ_REMOVE_HEAD(&config->colls, co_next);
- coll_free(coll);
- }
- if (config->server != NULL)
- stream_close(config->server);
- if (config->laddr != NULL)
- free(config->laddr);
- free(config);
-}
-
-/* Create a new collection, inheriting options from the default collection. */
-struct coll *
-coll_new(struct coll *def)
-{
- struct coll *new;
-
- new = xmalloc(sizeof(struct coll));
- memset(new, 0, sizeof(struct coll));
- if (def != NULL) {
- new->co_options = def->co_options;
- new->co_umask = def->co_umask;
- if (def->co_host != NULL)
- new->co_host = xstrdup(def->co_host);
- if (def->co_base != NULL)
- new->co_base = xstrdup(def->co_base);
- if (def->co_date != NULL)
- new->co_date = xstrdup(def->co_date);
- if (def->co_prefix != NULL)
- new->co_prefix = xstrdup(def->co_prefix);
- if (def->co_release != NULL)
- new->co_release = xstrdup(def->co_release);
- if (def->co_tag != NULL)
- new->co_tag = xstrdup(def->co_tag);
- if (def->co_listsuffix != NULL)
- new->co_listsuffix = xstrdup(def->co_listsuffix);
- } else {
- new->co_tag = xstrdup(".");
- new->co_date = xstrdup(".");
- }
- new->co_keyword = keyword_new();
- new->co_accepts = pattlist_new();
- new->co_refusals = pattlist_new();
- new->co_attrignore = FA_DEV | FA_INODE;
- return (new);
-}
-
-void
-coll_override(struct coll *coll, struct coll *from, int mask)
-{
- size_t i;
- int newoptions, oldoptions;
-
- newoptions = from->co_options & mask;
- oldoptions = coll->co_options & (CO_MASK & ~mask);
-
- if (from->co_release != NULL) {
- if (coll->co_release != NULL)
- free(coll->co_release);
- coll->co_release = xstrdup(from->co_release);
- }
- if (from->co_host != NULL) {
- if (coll->co_host != NULL)
- free(coll->co_host);
- coll->co_host = xstrdup(from->co_host);
- }
- if (from->co_base != NULL) {
- if (coll->co_base != NULL)
- free(coll->co_base);
- coll->co_base = xstrdup(from->co_base);
- }
- if (from->co_colldir != NULL)
- coll->co_colldir = from->co_colldir;
- if (from->co_prefix != NULL) {
- if (coll->co_prefix != NULL)
- free(coll->co_prefix);
- coll->co_prefix = xstrdup(from->co_prefix);
- }
- if (newoptions & CO_CHECKOUTMODE) {
- if (from->co_tag != NULL) {
- if (coll->co_tag != NULL)
- free(coll->co_tag);
- coll->co_tag = xstrdup(from->co_tag);
- }
- if (from->co_date != NULL) {
- if (coll->co_date != NULL)
- free(coll->co_date);
- coll->co_date = xstrdup(from->co_date);
- }
- }
- if (from->co_listsuffix != NULL) {
- if (coll->co_listsuffix != NULL)
- free(coll->co_listsuffix);
- coll->co_listsuffix = xstrdup(from->co_listsuffix);
- }
- for (i = 0; i < pattlist_size(from->co_accepts); i++) {
- pattlist_add(coll->co_accepts,
- pattlist_get(from->co_accepts, i));
- }
- for (i = 0; i < pattlist_size(from->co_refusals); i++) {
- pattlist_add(coll->co_refusals,
- pattlist_get(from->co_refusals, i));
- }
- coll->co_options = oldoptions | newoptions;
-}
-
-char *
-coll_statussuffix(struct coll *coll)
-{
- const char *tag;
- char *suffix;
-
- if (coll->co_listsuffix != NULL) {
- xasprintf(&suffix, ".%s", coll->co_listsuffix);
- } else if (coll->co_options & CO_USERELSUFFIX) {
- if (coll->co_tag == NULL)
- tag = ".";
- else
- tag = coll->co_tag;
- if (coll->co_release != NULL) {
- if (coll->co_options & CO_CHECKOUTMODE) {
- xasprintf(&suffix, ".%s:%s",
- coll->co_release, tag);
- } else {
- xasprintf(&suffix, ".%s", coll->co_release);
- }
- } else if (coll->co_options & CO_CHECKOUTMODE) {
- xasprintf(&suffix, ":%s", tag);
- }
- } else
- suffix = NULL;
- return (suffix);
-}
-
-char *
-coll_statuspath(struct coll *coll)
-{
- char *path, *suffix;
-
- suffix = coll_statussuffix(coll);
- if (suffix != NULL) {
- if (coll->co_colldir[0] == '/')
- xasprintf(&path, "%s/%s/checkouts%s", coll->co_colldir,
- coll->co_name, suffix);
- else
- xasprintf(&path, "%s/%s/%s/checkouts%s", coll->co_base,
- coll->co_colldir, coll->co_name, suffix);
- } else {
- if (coll->co_colldir[0] == '/')
- xasprintf(&path, "%s/%s/checkouts", coll->co_colldir,
- coll->co_name);
- else
- xasprintf(&path, "%s/%s/%s/checkouts", coll->co_base,
- coll->co_colldir, coll->co_name);
- }
- free(suffix);
- return (path);
-}
-
-void
-coll_add(char *name)
-{
- struct coll *coll;
-
- cur_coll->co_name = name;
- coll_override(cur_coll, ovcoll, ovmask);
- if (cur_coll->co_release == NULL) {
- lprintf(-1, "Release not specified for collection "
- "\"%s\"\n", cur_coll->co_name);
- exit(1);
- }
- if (cur_coll->co_host == NULL) {
- lprintf(-1, "Host not specified for collection "
- "\"%s\"\n", cur_coll->co_name);
- exit(1);
- }
- if (!STAILQ_EMPTY(&colls)) {
- coll = STAILQ_LAST(&colls, coll, co_next);
- if (strcmp(coll->co_host, cur_coll->co_host) != 0) {
- lprintf(-1, "All \"host\" fields in the supfile "
- "must be the same\n");
- exit(1);
- }
- }
- STAILQ_INSERT_TAIL(&colls, cur_coll, co_next);
- cur_coll = coll_new(defaults);
-}
-
-void
-coll_free(struct coll *coll)
-{
-
- if (coll == NULL)
- return;
- if (coll->co_host != NULL)
- free(coll->co_host);
- if (coll->co_base != NULL)
- free(coll->co_base);
- if (coll->co_date != NULL)
- free(coll->co_date);
- if (coll->co_prefix != NULL)
- free(coll->co_prefix);
- if (coll->co_release != NULL)
- free(coll->co_release);
- if (coll->co_tag != NULL)
- free(coll->co_tag);
- if (coll->co_cvsroot != NULL)
- free(coll->co_cvsroot);
- if (coll->co_name != NULL)
- free(coll->co_name);
- if (coll->co_listsuffix != NULL)
- free(coll->co_listsuffix);
- keyword_free(coll->co_keyword);
- if (coll->co_dirfilter != NULL)
- globtree_free(coll->co_dirfilter);
- if (coll->co_dirfilter != NULL)
- globtree_free(coll->co_filefilter);
- if (coll->co_norsync != NULL)
- globtree_free(coll->co_norsync);
- if (coll->co_accepts != NULL)
- pattlist_free(coll->co_accepts);
- if (coll->co_refusals != NULL)
- pattlist_free(coll->co_refusals);
- free(coll);
-}
-
-void
-coll_setopt(int opt, char *value)
-{
- struct coll *coll;
- int error, mask;
-
- coll = cur_coll;
- switch (opt) {
- case PT_HOST:
- if (coll->co_host != NULL)
- free(coll->co_host);
- coll->co_host = value;
- break;
- case PT_BASE:
- if (coll->co_base != NULL)
- free(coll->co_base);
- coll->co_base = value;
- break;
- case PT_DATE:
- if (coll->co_date != NULL)
- free(coll->co_date);
- coll->co_date = value;
- coll->co_options |= CO_CHECKOUTMODE;
- break;
- case PT_PREFIX:
- if (coll->co_prefix != NULL)
- free(coll->co_prefix);
- coll->co_prefix = value;
- break;
- case PT_RELEASE:
- if (coll->co_release != NULL)
- free(coll->co_release);
- coll->co_release = value;
- break;
- case PT_TAG:
- if (coll->co_tag != NULL)
- free(coll->co_tag);
- coll->co_tag = value;
- coll->co_options |= CO_CHECKOUTMODE;
- break;
- case PT_LIST:
- if (strchr(value, '/') != NULL) {
- lprintf(-1, "Parse error in \"%s\": \"list\" suffix "
- "must not contain slashes\n", cfgfile);
- exit(1);
- }
- if (coll->co_listsuffix != NULL)
- free(coll->co_listsuffix);
- coll->co_listsuffix = value;
- break;
- case PT_UMASK:
- error = asciitoint(value, &mask, 8);
- free(value);
- if (error) {
- lprintf(-1, "Parse error in \"%s\": Invalid "
- "umask value\n", cfgfile);
- exit(1);
- }
- coll->co_umask = mask;
- break;
- case PT_USE_REL_SUFFIX:
- coll->co_options |= CO_USERELSUFFIX;
- break;
- case PT_DELETE:
- coll->co_options |= CO_DELETE | CO_EXACTRCS;
- break;
- case PT_COMPRESS:
- coll->co_options |= CO_COMPRESS;
- break;
- case PT_NORSYNC:
- coll->co_options |= CO_NORSYNC;
- break;
- }
-}
-
-/* Set "coll" as being the default collection. */
-void
-coll_setdef(void)
-{
-
- coll_free(defaults);
- defaults = cur_coll;
- cur_coll = coll_new(defaults);
-}
diff --git a/contrib/csup/config.h b/contrib/csup/config.h
deleted file mode 100644
index 859013c..0000000
--- a/contrib/csup/config.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _CONFIG_H_
-#define _CONFIG_H_
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <time.h>
-
-#include "fattr.h"
-#include "queue.h"
-#include "misc.h"
-
-/*
- * Collection options.
- */
-#define CO_BACKUP 0x00000001
-#define CO_DELETE 0x00000002
-#define CO_KEEP 0x00000004
-#define CO_OLD 0x00000008
-#define CO_UNLINKBUSY 0x00000010
-#define CO_NOUPDATE 0x00000020
-#define CO_COMPRESS 0x00000040
-#define CO_USERELSUFFIX 0x00000080
-#define CO_EXACTRCS 0x00000100
-#define CO_CHECKRCS 0x00000200
-#define CO_SKIP 0x00000400
-#define CO_CHECKOUTMODE 0x00000800
-#define CO_NORSYNC 0x00001000
-#define CO_KEEPBADFILES 0x00002000
-#define CO_EXECUTE 0x00004000
-#define CO_SETOWNER 0x00008000
-#define CO_SETMODE 0x00010000
-#define CO_SETFLAGS 0x00020000
-#define CO_NORCS 0x00040000
-#define CO_STRICTCHECKRCS 0x00080000
-#define CO_TRUSTSTATUSFILE 0x00100000
-#define CO_DODELETESONLY 0x00200000
-#define CO_DETAILALLRCSFILES 0x00400000
-
-#define CO_MASK 0x007fffff
-
-/* Options that the server is allowed to set. */
-#define CO_SERVMAYSET (CO_SKIP | CO_NORSYNC | CO_NORCS)
-/* Options that the server is allowed to clear. */
-#define CO_SERVMAYCLEAR CO_CHECKRCS
-
-struct coll {
- char *co_name;
- char *co_host;
- char *co_base;
- char *co_date;
- char *co_prefix;
- size_t co_prefixlen;
- char *co_release;
- char *co_tag;
- char *co_cvsroot;
- int co_attrignore;
- struct pattlist *co_accepts;
- struct pattlist *co_refusals;
- struct globtree *co_dirfilter;
- struct globtree *co_filefilter;
- struct globtree *co_norsync;
- const char *co_colldir;
- char *co_listsuffix;
- time_t co_scantime; /* Set by the detailer thread. */
- int co_options;
- mode_t co_umask;
- struct keyword *co_keyword;
- STAILQ_ENTRY(coll) co_next;
-};
-
-struct config {
- STAILQ_HEAD(, coll) colls;
- struct fixups *fixups;
- char *host;
- struct sockaddr *laddr;
- socklen_t laddrlen;
- int deletelim;
- int socket;
- struct chan *chan0;
- struct chan *chan1;
- struct stream *server;
- fattr_support_t fasupport;
- int reqauth;
-};
-
-struct config *config_init(const char *, struct coll *, int);
-int config_checkcolls(struct config *);
-void config_free(struct config *);
-
-struct coll *coll_new(struct coll *);
-void coll_override(struct coll *, struct coll *, int);
-char *coll_statuspath(struct coll *);
-char *coll_statussuffix(struct coll *);
-void coll_add(char *);
-void coll_free(struct coll *);
-void coll_setdef(void);
-void coll_setopt(int, char *);
-
-#endif /* !_CONFIG_H_ */
diff --git a/contrib/csup/cpasswd.1 b/contrib/csup/cpasswd.1
deleted file mode 100644
index 946783f..0000000
--- a/contrib/csup/cpasswd.1
+++ /dev/null
@@ -1,120 +0,0 @@
-.\" Copyright 1999-2003 John D. Polstra.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by John D. Polstra.
-.\" 4. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $Id: cvpasswd.1,v 1.4 2003/03/04 18:24:42 jdp Exp $
-.\" $FreeBSD $
-.\"
-.Dd June 27, 2007
-.Os FreeBSD
-.Dt CPASSWD 1
-.Sh NAME
-.Nm cpasswd
-.Nd scramble passwords for csup authentication
-.Sh SYNOPSIS
-.Nm
-.Ar clientName
-.Ar serverName
-.Sh DESCRIPTION
-The
-.Nm
-utility creates scrambled passwords for the
-.Nm CVSup
-server's authentication database. It is invoked with a client name
-and a server name.
-.Ar ClientName
-is the name the client uses to gain access to the
-server. By convention, e-mail addresses are used for all client
-names, e.g.,
-.Ql BillyJoe@FreeBSD.ORG .
-Client names are case-insensitive.
-.Pp
-.Ar ServerName
-is the name of the
-.Nm CVSup
-server which the client wishes to access. By convention,
-it is the canonical fully-qualified domain name of the server, e.g.,
-.Ql CVSup.FreeBSD.ORG .
-This must agree with the server's own idea of its name. The name is
-case-insensitive.
-.Pp
-To set up authentication for a given server, one must perform the
-following steps:
-.Bl -enum
-.It
-Obtain the official
-.Ar serverName
-from the administrator of the server or from some other source.
-.It
-Choose an appropriate
-.Ar clientName .
-It should be in the form of a valid e-mail address, to make it easy
-for the server administrator to contact the user if necessary.
-.It
-Choose an arbitrary secret
-.Ar password .
-.It
-Run
-.Nm cpasswd ,
-and type in the
-.Ar password
-when prompted for it. The utility will print out a line to send
-to the server administrator, and instruct you how to modify your
-.Li $ Ns Ev HOME Ns Pa /.csup/auth
-file. You should use a secure channel to send the line to the
-server administrator.
-.El
-.Pp
-Since
-.Li $ Ns Ev HOME Ns Pa /.csup/auth
-contains passwords, you should ensure that it is not readable by
-anyone except yourself.
-.Sh FILES
-.Bl -tag -width $HOME/.csup/authxx -compact
-.It Li $ Ns Ev HOME Ns Pa /.csup/auth
-Authentication password file.
-.El
-.Sh SEE ALSO
-.Xr csup 1 ,
-.Xr cvsup 1 ,
-.Xr cvsupd 8 .
-.Pp
-.Bd -literal
-http://www.cvsup.org/
-.Ed
-.Sh AUTHORS
-.An -nosplit
-.An Petar Zhivkov Petrov Aq pesho.petrov@gmail.com
-is the author of
-.Nm ,
-the rewrite of
-.Nm cvpasswd .
-.An John Polstra Aq jdp@polstra.com
-is the author of
-.Nm CVSup .
-.Sh LEGALITIES
-CVSup is a registered trademark of John D. Polstra.
diff --git a/contrib/csup/cpasswd.sh b/contrib/csup/cpasswd.sh
deleted file mode 100755
index 71e17c5..0000000
--- a/contrib/csup/cpasswd.sh
+++ /dev/null
@@ -1,135 +0,0 @@
-#! /bin/sh
-#
-# Copyright 2007. Petar Zhivkov Petrov
-# pesho.petrov@gmail.com
-#
-# $FreeBSD$
-
-usage() {
- echo "Usage: $0 clientName serverName"
- echo " $0 -v"
-}
-
-countChars() {
- _count="`echo "$1" | sed -e "s/[^$2]//g" | tr -d "\n" | wc -c`"
- return 0
-}
-
-readPassword() {
- while [ true ]; do
- stty -echo
- read -p "$1" _password
- stty echo
- echo ""
- countChars "$_password" ":"
- if [ $_count != 0 ]; then
- echo "Sorry, password must not contain \":\" characters"
- echo ""
- else
- break
- fi
- done
- return 0
-}
-
-makeSecret() {
- local clientLower="`echo "$1" | tr "[:upper:]" "[:lower:]"`"
- local serverLower="`echo "$2" | tr "[:upper:]" "[:lower:]"`"
- local secret="`md5 -qs "$clientLower:$serverLower:$3"`"
- _secret="\$md5\$$secret"
-}
-
-if [ $# -eq 1 -a "X$1" = "X-v" ]; then
- echo "Csup authentication key generator"
- usage
- exit
-elif [ $# -ne 2 ]; then
- usage
- exit
-fi
-
-clientName=$1
-serverName=$2
-
-#
-# Client name must contain exactly one '@' and at least one '.'.
-# It must not contain a ':'.
-#
-
-countChars "$clientName" "@"
-aCount=$_count
-
-countChars "$clientName" "."
-dotCount=$_count
-if [ $aCount -ne 1 -o $dotCount -eq 0 ]; then
- echo "Client name must have the form of an e-mail address,"
- echo "e.g., \"user@domain.com\""
- exit
-fi
-
-countChars "$clientName" ":"
-colonCount=$_count
-if [ $colonCount -gt 0 ]; then
- echo "Client name must not contain \":\" characters"
- exit
-fi
-
-#
-# Server name must not contain '@' and must have at least one '.'.
-# It also must not contain a ':'.
-#
-
-countChars "$serverName" "@"
-aCount=$_count
-
-countChars "$serverName" "."
-dotCount=$_count
-if [ $aCount != 0 -o $dotCount = 0 ]; then
- echo "Server name must be a fully-qualified domain name."
- echo "e.g., \"host.domain.com\""
- exit
-fi
-
-countChars "$serverName" ":"
-colonCount=$_count
-if [ $colonCount -gt 0 ]; then
- echo "Server name must not contain \":\" characters"
- exit
-fi
-
-#
-# Ask for password and generate secret.
-#
-
-while [ true ]; do
- readPassword "Enter password: "
- makeSecret "$clientName" "$serverName" "$_password"
- secret=$_secret
-
- readPassword "Enter same password again: "
- makeSecret "$clientName" "$serverName" "$_password"
- secret2=$_secret
-
- if [ "X$secret" = "X$secret2" ]; then
- break
- else
- echo "Passwords did not match. Try again."
- echo ""
- fi
-done
-
-echo ""
-echo "Send this line to the server administrator at $serverName:"
-echo "-------------------------------------------------------------------------------"
-echo "$clientName:$secret::"
-echo "-------------------------------------------------------------------------------"
-echo "Be sure to send it using a secure channel!"
-echo ""
-echo "Add this line to your file \"$HOME/.csup/auth\", replacing \"XXX\""
-echo "with the password you typed in:"
-echo "-------------------------------------------------------------------------------"
-echo "$serverName:$clientName:XXX:"
-echo "-------------------------------------------------------------------------------"
-echo "Make sure the file is readable and writable only by you!"
-echo ""
-
diff --git a/contrib/csup/csup.1 b/contrib/csup/csup.1
deleted file mode 100644
index 2690863..0000000
--- a/contrib/csup/csup.1
+++ /dev/null
@@ -1,1000 +0,0 @@
-.\" Copyright 1996-2003 John D. Polstra.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $Id: cvsup.1,v 1.70 2003/03/04 18:23:46 jdp Exp $
-.\" $FreeBSD$
-.\"
-.Dd February 1, 2006
-.Os FreeBSD
-.Dt CSUP 1
-.Sh NAME
-.Nm csup
-.Nd network distribution package for CVS repositories
-.Sh SYNOPSIS
-.Nm
-.Op Fl 146aksvzZ
-.Op Fl A Ar addr
-.Op Fl b Ar base
-.Op Fl c Ar collDir
-.Op Fl d Ar delLimit
-.Op Fl h Ar host
-.Op Fl i Ar pattern
-.Op Fl l Ar lockfile
-.Op Fl L Ar verbosity
-.Op Fl p Ar port
-.Op Fl r Ar maxRetries
-.Ar supfile
-.Sh DESCRIPTION
-.Nm
-is a software package for updating collections of files across a network.
-It is a rewrite of the
-.Nm CVSup
-software in C.
-This manual page describes the usage of the
-.Nm
-client program.
-.Pp
-Unlike more traditional network distribution packages, such as
-.Nm rdist
-and
-.Nm sup ,
-.Nm
-has specific optimizations for distributing CVS repositories.
-.Nm
-takes advantage of the properties of CVS repositories and the files they
-contain (in particular, RCS files), enabling it to perform updates much
-faster than traditional systems.
-.Pp
-.Nm
-is a general-purpose network file updating package.
-It is extremely fast,
-even for collections of files which have nothing to do with CVS or
-RCS.
-.Sh OPTIONS
-The client program
-.Nm
-requires at least a single argument,
-.Ar supfile .
-It names a file describing one or more collections of files to be
-transferred and/or updated from the server.
-The
-.Ar supfile
-has a format similar to the corresponding file used by
-.Nm sup .
-In most cases,
-.Nm
-can use existing
-.Nm sup Ar supfiles .
-.Pp
-The following options are supported by
-.Nm :
-.Bl -tag -width Fl
-.It Fl 1
-Disables automatic retries when transient failures occur.
-Without this option, a transient failure such as a dropped network
-connection causes
-.Nm
-to retry repeatedly, using randomized exponential backoff to space the
-retries.
-This option is equivalent to
-.Fl r Cm 0 .
-.It Fl 4
-Forces
-.Nm
-to use IPv4 addresses only.
-.It Fl 6
-Forces
-.Nm
-to use IPv6 addresses only.
-.It Fl a
-Requires the server to authenticate itself (prove its identity) to
-the client. If authentication of the server fails, the update is
-canceled. See
-.Sx AUTHENTICATION ,
-below.
-.It Fl A Ar addr
-Specifies a local address to bind to when connecting to the server.
-The local address might be a hostname or a numeric host address string
-consisting of a dotted decimal IPv4 address or an IPv6 address.
-This may be useful on hosts which have multiple IP addresses.
-.It Fl b Ar base
-Specifies the base directory under which
-.Nm
-will maintain its bookkeeping files, overriding any
-.Cm base
-specifications in the
-.Ar supfile .
-.It Fl c Ar collDir
-Specifies the subdirectory of
-.Ar base
-where the information about the collections is maintained.
-The default is
-.Pa sup .
-.It Fl d Ar delLimit
-Specifies the maximum number of files that may be deleted in a
-single update run.
-Any attempt to exceed the limit results in a fatal error.
-This can provide some protection against temporary configuration
-mistakes on the server.
-The default limit is infinity.
-.It Fl h Ar host
-Specifies the server host to contact, overriding any
-.Cm host
-specifications in the
-.Ar supfile .
-.It Fl i Ar pattern
-Causes
-.Nm
-to include only files and directories matching
-.Ar pattern
-in the update. If a directory matches the pattern, then the entire
-subtree rooted at the directory is included. If this option is
-specified multiple times, the patterns are combined using the
-.Ql or
-operation. If no
-.Fl i
-options are given, the default is to update all files in each
-collection.
-.Pp
-The
-.Ar pattern
-is a standard file name pattern.
-It is interpreted relative to the collection's prefix directory.
-Slash characters are matched only by explicit slashes in the pattern.
-Leading periods in file name are not treated specially.
-.It Fl k
-Causes
-.Nm
-to keep the temporary copies of any incorrectly edited files, in the
-event of checksum mismatches.
-This option is for debugging, to help determine why the files were
-edited incorrectly.
-Regardless of whether this option is specified, the permanent versions
-of faulty files are replaced with correct versions obtained by
-transferring the files in their entirety.
-Such transfers are called fixups.
-.It Fl l Ar lockfile
-Creates and locks the
-.Ar lockfile
-while the update is in progress.
-If
-.Ar lockfile
-is already locked,
-.Nm
-fails without performing automatic retries.
-This option is useful when
-.Nm
-is executed periodically from
-.Nm cron .
-It prevents a job from interfering with an earlier job that is perhaps
-taking extra long because of network problems.
-.Pp
-The process-ID is written to the lock file in text form when the lock
-is successfully acquired.
-Upon termination of the update, the lock file is removed.
-.It Fl L Ar verbosity
-Sets the verbosity level for output.
-A level of 0 causes
-.Nm
-to be completely silent unless errors occur.
-A level of 1 (the default) causes each updated file to be listed.
-A level of 2 provides more detailed information about the updates
-performed on each file.
-All messages are directed to the standard output.
-.It Fl p Ar port
-Sets the TCP port to which
-.Nm
-attempts to connect on the server host.
-The default port is 5999.
-.It Fl r Ar maxRetries
-Limits the number of automatic retries that will be attempted when
-transient errors such as lost network connections are encountered.
-By default,
-.Nm
-will retry indefinitely until an update is successfully completed.
-The retries are spaced using randomized exponential backoff.
-Note that
-.Fl r Cm 0
-is equivalent to the
-.Fl 1
-option.
-.It Fl s
-Suppresses the check of each client file's status against what is
-recorded in the list file. Instead, the list file is assumed to be
-accurate. This option greatly reduces the amount of disk activity and
-results in faster updates with less load on the client host. However
-it should only be used if client's files are never modified locally in
-any way. Mirror sites may find this option beneficial to reduce the
-disk load on their systems. For safety, even mirror sites should run
-.Nm
-occasionally (perhaps once a day) without the
-.Fl s
-option.
-.Pp
-Without the
-.Fl s
-option,
-.Nm
-performs a
-.Xr stat 2
-call on each file and verifies that its attributes match those
-recorded in the list file. This ensures that any file changes made
-outside of
-.Nm
-are detected and corrected.
-.Pp
-If the
-.Fl s
-option is used when one or more files have been modified locally, the
-results are undefined. Local file damage may remain uncorrected,
-updates may be missed, or
-.Nm
-may abort prematurely.
-.It Fl v
-Prints the version number and exits, without contacting the server.
-.It Fl z
-Enables compression for all collections, as if the
-.Cm compress
-keyword were added to every collection in the
-.Ar supfile .
-.It Fl Z
-Disables compression for all collections, as if the
-.Cm compress
-keyword were removed from every collection in the
-.Ar supfile .
-.El
-.Pp
-The
-.Ar supfile
-is a text file which specifies the file collections to be updated.
-Comments begin with
-.Ql #
-and extend to the end of the line. Lines that are empty except for
-comments and white space are ignored. Each remaining line begins
-with the name of a server-defined collection of files. Following the
-collection name on the line are zero or more keywords or keyword=value
-pairs.
-.Pp
-Default settings may be specified in lines whose collection name is
-.Cm *default .
-Such defaults will apply to subsequent lines in the
-.Ar supfile .
-Multiple
-.Cm *default
-lines may be present.
-New values augment or override any defaults specified earlier in the
-.Ar supfile .
-Values specified explicitly for a collection override any default
-values.
-.Pp
-The most commonly used keywords are:
-.Bl -tag -width Fl
-.It Cm release= Ns Ar releaseName
-This specifies the release of the files within a collection.
-Like collection names, release names are defined by the server
-configuration files. Usually there is only one release in each
-collection, but there may be any number. Collections which come from
-a CVS repository often use
-.Cm release=cvs
-by convention. Non-CVS collections conventionally use
-.Cm release=current .
-.It Cm base= Ns Ar base
-This specifies a directory under which
-.Nm
-will maintain its bookkeeping files, describing the state of each
-collection on the client machine.
-The
-.Ar base
-directory must already exist;
-.Nm
-will not create it.
-The default
-.Ar base
-directory is
-.Pa /usr/local/etc/csup .
-.It Cm prefix= Ns Ar prefix
-This is the directory under which updated files will be placed.
-By default, it is the same as
-.Ar base .
-If it is not an absolute pathname, it is interpreted relative to
-.Ar base .
-The
-.Ar prefix
-directory must already exist;
-.Nm
-will not create it.
-.Pp
-As a special case, if
-.Ar prefix
-is a symbolic link pointing to a nonexistent file named
-.Ql SKIP ,
-then
-.Nm
-will skip the collection.
-The parameters associated with the collection are still checked for
-validity, but none of its files will be updated.
-This feature allows a site to use a standard
-.Ar supfile
-on several machines, yet control which collections get updated on a
-per-machine basis.
-.It Cm host= Ns Ar hostname
-This specifies the server machine from which all files will be taken.
-.Nm
-requires that all collections in a single run come from the same host.
-If you wish to update collections from several different hosts, you must
-run
-.Nm
-several times.
-.It Cm delete
-The presence of this keyword gives
-.Nm
-permission to delete files.
-If it is missing, no files will be deleted.
-.Pp
-The presence of the
-.Cm delete
-keyword puts
-.Nm
-into so-called
-.Em exact
-mode. In exact mode,
-.Nm
-does its best to make the client's files correspond to those on the server.
-This includes deleting individual deltas and symbolic tags from RCS
-files, as well as deleting entire files.
-In exact mode,
-.Nm
-verifies every edited file with a checksum, to ensure that the edits
-have produced a file identical to the master copy on the server.
-If the checksum test fails for a file, then
-.Nm
-falls back upon transferring the entire file.
-.Pp
-In general,
-.Nm
-deletes only files which are known to the server.
-Extra files present in the client's tree are left alone, even in exact
-mode.
-More precisely,
-.Nm
-is willing to delete two classes of files:
-.Bl -bullet -compact
-.It
-Files that were previously created or updated by
-.Nm
-itself.
-.It
-Checked-out versions of files which are marked as dead on the server.
-.El
-.It Cm use-rel-suffix
-Causes
-.Nm
-to append a suffix constructed from the release and tag to the name of
-each list file that it maintains.
-See
-.Sx THE LIST FILE
-for details.
-.It Cm compress
-This enables compression of all data sent across the network.
-Compression is quite effective, normally eliminating 65% to 75% of the
-bytes that would otherwise need to be transferred.
-However, it is costly in terms of CPU time on both the client and the
-server.
-On local area networks, compression is generally counter-productive; it
-actually slows down file updates.
-On links with speeds of 56K bits/second or less, compression is almost
-always beneficial.
-For network links with speeds between these two extremes, let
-experimentation be your guide.
-.Pp
-The
-.Fl z
-command line option enables the
-.Cm compress
-keyword for all collections, regardless of what is specified in the supfile.
-Likewise, the
-.Fl Z
-command line option disables the
-.Cm compress
-option for all collections.
-.Nm
-uses a looser checksum for RCS files, which ignores harmless
-differences in white space. Different versions of CVS and RCS produce
-a variety of differences in white space for the same RCS files. Thus
-the strict checksum can report spurious mismatches for files which are
-logically identical. This can lead to numerous unneeded
-.Dq fixups ,
-and thus to slow updates.
-.It Cm umask= Ns Ar n
-Causes
-.Nm
-to use a umask value of
-.Ar n
-(an octal number) when updating the files in the collection.
-This option is ignored if
-.Cm preserve
-is specified.
-.El
-.Pp
-Some additional, more specialized keywords are described below.
-Unrecognized keywords are silently ignored for backward compatibility
-with
-.Nm sup .
-.Sh CVS MODE
-.Nm CVSup
-supports two primary modes of operation.
-They are called
-.Em CVS
-mode and
-.Em checkout
-mode.
-.Pp
-In CVS mode, the client receives copies of the actual RCS files making
-up the master CVS repository. CVS mode is the default mode of operation.
-It is appropriate when the user wishes to maintain a full copy of the
-CVS repository on the client machine.
-.Pp
-CVS mode is also appropriate for file collections which are not
-based upon a CVS repository. The files are simply transferred
-verbatim, without interpretation.
-.Sh CHECKOUT MODE
-In checkout mode, the client receives specific revisions of files,
-checked out directly from the server's CVS repository.
-Checkout mode allows the client to receive any version from the
-repository, without requiring any extra disk space on the server for
-storing multiple versions in checked-out form.
-Checkout mode provides much flexibility beyond that basic functionality,
-however.
-The client can specify any CVS symbolic tag, or any date, or both, and
-.Nm
-will provide the corresponding checked-out versions of the files in the
-repository.
-.Pp
-Checkout mode is selected on a per-collection basis, by the presence of
-one or both of the following keywords in the
-.Ar supfile :
-.Bl -tag -width Fl
-.It Cm tag= Ns Ar tagname
-This specifies a symbolic tag that should be used to select the
-revisions that are checked out from the CVS repository.
-The tag may refer to either a branch or a specific revision.
-It must be symbolic; numeric revision numbers are not supported.
-.Pp
-For the FreeBSD source repository, the most commonly used tags will be:
-.Bl -tag -width RELENG_6
-.It Li RELENG_6
-The
-.Ql stable
-branch.
-.It Li \&.
-The main branch (the
-.Ql current
-release).
-This is the default, if only the
-.Cm date
-keyword is given.
-.El
-.Sm off
-.It Xo Cm date=
-.Op Ar cc
-.Ar yy.mm.dd.hh.mm.ss
-.Xc
-.Sm on
-This specifies a date that should be used to select the revisions that
-are checked out from the CVS repository.
-The client will receive the revisions that were in effect at the
-specified date and time.
-.Pp
-At present, the date format is inflexible. All 17 or 19 characters must
-be specified, exactly as shown.
-For the years 2000 and beyond, specify the century
-.Ar cc .
-For earlier years, specify only the last two digits
-.Ar yy .
-Dates and times are considered to
-be GMT.
-The default date is
-.Ql \&. ,
-which means
-.Dq as late as possible .
-.El
-.Pp
-To enable checkout mode, you must specify at least one of these keywords.
-If both are missing,
-.Nm
-defaults to CVS mode.
-.Pp
-If both a branch tag and a date are specified, then the revisions on the
-given branch, as of the given date, will be checked out. It is
-permitted, but not particularly useful, to specify a date with a
-specific release tag.
-.Pp
-In checkout mode, the tag and/or date may be changed between updates.
-For example, suppose that a collection has been transferred using the
-specification
-.Ql tag=. .
-The user could later change the specification to
-.Ql tag=RELENG_3 .
-This would cause
-.Nm
-to edit the checked-out files in such a way as to transform them from the
-.Ql current
-versions to the
-.Ql stable
-versions.
-In general,
-.Nm
-is willing to transform any tag/date combination into any other tag/date
-combination, by applying the intervening RCS deltas to the existing files.
-.Pp
-When transforming a collection of checked-out files from one tag to
-another, it is important to specify the
-.Cm list
-keyword in the
-.Ar supfile ,
-to ensure that the same list file is used both before and after the
-transformation.
-The list file is described in
-.Sx THE LIST FILE ,
-below.
-.Sh THE LIST FILE
-For efficiency,
-.Nm
-maintains a bookkeeping file for each collection, called the list file.
-The list file contains information about which files and revisions the client
-currently possesses.
-It also contains information used for verifying that the list file
-is consistent with the actual files in the client's tree.
-.Pp
-The list file is not strictly necessary. If it is deleted, or becomes
-inconsistent with the actual client files,
-.Nm
-falls back upon a less efficient method of identifying the client's
-files and performing its updates.
-Depending on
-.Nm csup Ns No 's
-mode of operation, the fallback method employs time stamps, checksums, or
-analysis of RCS files.
-.Pp
-Because the list file is not essential,
-.Nm
-is able to
-.Dq adopt
-an existing file tree acquired by FTP or from a CD-ROM.
-.Nm
-identifies the client's versions of the files, updates them as
-necessary, and creates a list file for future use.
-Adopting a foreign file tree is not as fast as performing a normal
-update.
-It also produces a heavier load on the server.
-.Pp
-The list file is stored in a collection-specific directory; see
-.Sx FILES
-for details.
-Its name always begins with
-.Ql checkouts .
-If the keyword
-.Cm use-rel-suffix
-is specified in the
-.Ar supfile ,
-a suffix, formed from the release and tag, is appended to the name.
-The default suffix can be overridden by specifying an explicit suffix in
-the
-.Ar supfile :
-.Bl -tag -width Fl
-.It Cm list= Ns Ar suffix
-This specifies a suffix for the name of the list file. A leading dot is
-provided automatically.
-For example,
-.Ql list=stable
-would produce a list file named
-.Pa checkouts.stable ,
-regardless of the release, tag, or
-.Cm use-rel-suffix
-keyword.
-.El
-.Sh REFUSE FILES
-The user can specify sets of files that he does not wish to receive.
-The files are specified as file name patterns in so-called
-.Em refuse
-files.
-The patterns are separated by whitespace, and multiple patterns are
-permitted on each line.
-Files and directories matching the patterns are neither updated nor
-deleted; they are simply ignored.
-.Pp
-There is currently no provision for comments in refuse files.
-.Pp
-The patterns are similar to those of
-.Xr sh 1 ,
-except that there is no special treatment for slashes or for
-filenames that begin with a period.
-For example, the pattern
-.Ql *.c
-will match any file name ending with
-.Ql \&.c
-including those in subdirectories, such as
-.Ql foo/bar/lam.c .
-All patterns are interpreted relative to the collection's prefix
-directory.
-.Pp
-If the files are coming from a CVS repository, as is usually
-the case, then they will be RCS files. These have a
-.Ql \&,v
-suffix which must be taken into account in the patterns. For
-example, the FreeBSD documentation files are in a sub-directory of
-.Ar base
-called
-.Ql doc .
-If
-.Ql Makefile
-from that directory is not required then the line
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa doc/Makefile
-.El
-.Pp
-will not work because the file on the server is called
-.Ql Makefile,v.
-A better solution would be
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa doc/Makefile*
-.El
-.Pp
-which will match whether
-.Ql Makefile
-is an RCS file or not.
-.Pp
-As another example, to receive the FreeBSD documentation files without
-the Japanese, Russian, and Chinese translations, create a refuse file
-containing the following lines:
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa doc/ja*
-.It
-.Pa doc/ru*
-.It
-.Pa doc/zh*
-.El
-.Pp
-As many as three refuse files are examined for each
-.Ar supfile
-line.
-There can be a global refuse file named
-.Sm off
-.Ar base / Ar collDir Pa /refuse
-.Sm on
-which applies to all collections and releases.
-There can be a per-collection refuse file named
-.Sm off
-.Xo Ar base / Ar collDir / Ar collection
-.Pa /refuse
-.Xc
-.Sm on
-which applies to a specific collection.
-Finally, there can be a per-release and tag refuse file which applies only
-to a given release/tag combination within a collection.
-The name of the latter is formed by suffixing the name of the
-per-collection refuse file in the same manner as described above for the
-list file.
-None of the refuse files are required to exist.
-.Pp
-.Nm
-has a built-in default value of
-.Ar /usr/local/etc/cvsup
-for
-.Ar base
-and
-.Ar sup
-for
-.Ar collDir
-but it is possible to override both of these. The value of
-.Ar base
-can be changed using the
-.Fl b
-option or a
-.Ar base=pathname
-entry in the
-.Ar supfile .
-(If both are used the
-.Fl b
-option will override the
-.Ar supfile
-entry.) The value of
-.Ar collDir
-can only be changed with the
-.Fl c
-option; there is no
-.Ar supfile
-command to change it.
-.Pp
-As an example, suppose that the
-.Ar base
-and
-.Ar collDir
-both have their default values, and that the collection and release are
-.Ql src-all
-and
-.Ql cvs ,
-respectively.
-Assume further that checkout mode is being used with
-.Ql tag=RELENG_3 .
-The three possible refuse files would then be named:
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa /usr/local/etc/cvsup/sup/refuse
-.It
-.Pa /usr/local/etc/cvsup/sup/src-all/refuse
-.It
-.Pa /usr/local/etc/cvsup/sup/src-all/refuse.cvs:RELENG_3
-.El
-.Pp
-If the
-.Ar supfile
-includes the command
-.Ar base=/foo
-the refuse files would be:
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa /foo/sup/refuse
-.It
-.Pa /foo/sup/src-all/refuse
-.It
-.Pa /foo/sup/src-all/refuse.cvs:RELENG_3
-.El
-.Pp
-If
-.Fl b
-.Ar /bar
-is used (even with
-.Ar base=/foo
-in the
-.Ar supfile ) :
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa /bar/sup/refuse
-.It
-.Pa /bar/sup/src-all/refuse
-.It
-.Pa /bar/sup/src-all/refuse.cvs:RELENG_3
-.El
-.Pp
-and with
-.Fl c
-.Ar stool
-as well:
-.Pp
-.Bl -item -compact -offset indent
-.It
-.Pa /bar/stool/refuse
-.It
-.Pa /bar/stool/src-all/refuse
-.It
-.Pa /bar/stool/src-all/refuse.cvs:RELENG_3
-.El
-.Sh AUTHENTICATION
-.Nm
-implements an optional authentication mechanism which can be used by the
-client and server to verify each other's identities.
-Public CVSup servers normally do not enable authentication.
-.Nm
-users may ignore this section unless they have been informed
-that authentication is required by the administrator of their server.
-.Pp
-The authentication subsystem uses a
-challenge-response protocol which is immune to packet sniffing and
-replay attacks. No passwords are sent over the network in either
-direction. Both the client and the server can independently verify
-the identities of each other.
-.Pp
-The file
-.Li $ Ns Ev HOME Ns Pa /.csup/auth
-holds the information used for authentication. This file contains a
-record for each server that the client is allowed to access. Each
-record occupies one line in the file. Lines beginning with
-.Ql #
-are ignored, as are lines containing only white space. White space is
-significant everywhere else in the file. Fields are separated by
-.Ql \&:
-characters.
-.Pp
-Each record of the file has the following form:
-.Bd -literal -offset indent
-.Sm off
-.Xo Ar serverName No : Ar clientName No :
-.Ar password No : Ar comment
-.Xc
-.Sm on
-.Ed
-.Pp
-All fields must be present even if some of them are empty.
-.Ar ServerName
-is the name of the server to which the record applies. By convention,
-it is the canonical fully-qualified domain name of the server, e.g.,
-.Ql CVSup177.FreeBSD.ORG .
-This must agree with the server's own idea of its name. The name is
-case-insensitive.
-.Pp
-.Ar ClientName
-is the name the client uses to gain access to the server. By
-convention, e-mail addresses are used for all client names, e.g.,
-.Ql BillyJoe@FreeBSD.ORG .
-Client names are case-insensitive.
-.Pp
-.Ar Password
-is a secret string of characters that the client uses to prove its
-identity. It may not contain any
-.Ql \&:
-or newline characters.
-.Pp
-.Ar Comment
-may contain any additional information to identify the record. It
-is not interpreted by the program.
-.Pp
-To set up authentication for a given server, one must perform the
-following steps:
-.Bl -enum
-.It
-Obtain the official
-.Ar serverName
-from the administrator of the server or from some other source.
-.It
-Choose an appropriate
-.Ar clientName .
-It should be in the form of a valid e-mail address, to make it easy
-for the server administrator to contact the user if necessary.
-.It
-Choose an arbitrary secret
-.Ar password .
-.It
-Run the
-.Nm cpasswd
-utility, and type in the
-.Ar password
-when prompted for it. The utility will print out a line to send
-to the server administrator, and instruct you how to modify your
-.Li $ Ns Ev HOME Ns Pa /.csup/auth
-file. You should use a secure channel to send the line to the
-server administrator.
-.El
-.Pp
-Since
-.Li $ Ns Ev HOME Ns Pa /.csup/auth
-contains passwords, you should ensure that it is not readable by
-anyone except yourself.
-.Pp
-Authentication works independently in both directions. The server
-administrator controls whether you must prove your identity.
-You control whether to check the server's identity, by means of the
-.Fl a
-command line option.
-.Sh csup AND FIREWALLS
-In its default mode,
-.Nm
-will work through any firewall which permits outbound connections to
-port 5999 of the server host.
-.Sh USING csup WITH SOCKS
-.Nm
-can be used through a SOCKS proxy server with the standard
-.Nm runsocks
-command.
-Your
-.Nm
-executable needs to be dynamically-linked with the system
-libraries for
-.Nm runsocks
-to work properly.
-.Sh USING ssh PORT FORWARDING
-As an alternative to SOCKS, a user behind a firewall can penetrate it
-with the TCP port forwarding provided by the Secure Shell package
-.Nm ssh .
-The user must have a login account on the
-.Nm CVSup
-server host in order to do this.
-The procedure is as follows:
-.Bl -enum
-.It
-Establish a connection to the server host with
-.Nm ssh ,
-like this:
-.Bd -literal
-ssh -f -x -L 5999:localhost:5999 serverhost sleep 60
-.Ed
-.Pp
-Replace
-.Ar serverhost
-with the hostname of the CVSup server, but type
-.Ql localhost
-literally.
-This sets up the required port forwarding.
-You must start
-.Nm
-before the 60-second
-.Nm sleep
-finishes.
-Once the update has begun,
-.Nm ssh
-will keep the forwarded channels open as long as they are needed.
-.It
-Run
-.Nm
-on the local host, including the arguments
-.Ql -h localhost
-on the command line.
-.El
-.Sh FILES
-.Bl -tag -width base/sup/collection/checkouts*xx -compact
-.It Pa /usr/local/etc/cvsup
-Default
-.Ar base
-directory.
-.It Pa sup
-Default
-.Ar collDir
-subdirectory.
-.Sm off
-.It Xo Ar base / Ar collDir / Ar collection
-.Pa /checkouts*
-.Xc
-.Sm on
-List files.
-.El
-.Sh SEE ALSO
-.Xr cpasswd 1 ,
-.Xr cvs 1 ,
-.Xr rcsintro 1 ,
-.Xr ssh 1 .
-.Pp
-.Bd -literal
-http://mu.org/~mux/csup.html
-.Ed
-.Sh AUTHORS
-.An -nosplit
-.An Maxime Henrion Aq mux@FreeBSD.org
-is the author of
-.Nm ,
-the rewrite of
-.Nm CVSup
-in C.
-.An John Polstra Aq jdp@polstra.com
-is the author of
-.Nm CVSup .
-.Sh LEGALITIES
-CVSup is a registered trademark of John D. Polstra.
-.Pp
-.Nm
-is released under a 2-clauses BSD license.
-.Sh BUGS
-An RCS file is not recognized as such unless its name ends with
-.Ql \&,v .
-.Pp
-Any directory named
-.Ql Attic
-is assumed to be a CVS Attic, and is treated specially.
diff --git a/contrib/csup/detailer.c b/contrib/csup/detailer.c
deleted file mode 100644
index 5592655..0000000
--- a/contrib/csup/detailer.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "detailer.h"
-#include "fixups.h"
-#include "globtree.h"
-#include "misc.h"
-#include "mux.h"
-#include "proto.h"
-#include "rcsfile.h"
-#include "rsyncfile.h"
-#include "status.h"
-#include "stream.h"
-
-/* Internal error codes. */
-#define DETAILER_ERR_PROTO (-1) /* Protocol error. */
-#define DETAILER_ERR_MSG (-2) /* Error is in detailer->errmsg. */
-#define DETAILER_ERR_READ (-3) /* Error reading from server. */
-#define DETAILER_ERR_WRITE (-4) /* Error writing to server. */
-
-struct detailer {
- struct config *config;
- struct stream *rd;
- struct stream *wr;
- char *errmsg;
-};
-
-static int detailer_batch(struct detailer *);
-static int detailer_coll(struct detailer *, struct coll *,
- struct status *);
-static int detailer_dofile_co(struct detailer *, struct coll *,
- struct status *, char *);
-static int detailer_dofile_rcs(struct detailer *, struct coll *,
- char *, char *);
-static int detailer_dofile_regular(struct detailer *, char *, char *);
-static int detailer_dofile_rsync(struct detailer *, char *, char *);
-static int detailer_checkrcsattr(struct detailer *, struct coll *, char *,
- struct fattr *, int);
-int detailer_send_details(struct detailer *, struct coll *, char *,
- char *, struct fattr *);
-
-void *
-detailer(void *arg)
-{
- struct thread_args *args;
- struct detailer dbuf, *d;
- int error;
-
- args = arg;
-
- d = &dbuf;
- d->config = args->config;
- d->rd = args->rd;
- d->wr = args->wr;
- d->errmsg = NULL;
-
- error = detailer_batch(d);
- switch (error) {
- case DETAILER_ERR_PROTO:
- xasprintf(&args->errmsg, "Detailer failed: Protocol error");
- args->status = STATUS_FAILURE;
- break;
- case DETAILER_ERR_MSG:
- xasprintf(&args->errmsg, "Detailer failed: %s", d->errmsg);
- free(d->errmsg);
- args->status = STATUS_FAILURE;
- break;
- case DETAILER_ERR_READ:
- if (stream_eof(d->rd)) {
- xasprintf(&args->errmsg, "Detailer failed: "
- "Premature EOF from server");
- } else {
- xasprintf(&args->errmsg, "Detailer failed: "
- "Network read failure: %s", strerror(errno));
- }
- args->status = STATUS_TRANSIENTFAILURE;
- break;
- case DETAILER_ERR_WRITE:
- xasprintf(&args->errmsg, "Detailer failed: "
- "Network write failure: %s", strerror(errno));
- args->status = STATUS_TRANSIENTFAILURE;
- break;
- default:
- assert(error == 0);
- args->status = STATUS_SUCCESS;
- }
- return (NULL);
-}
-
-static int
-detailer_batch(struct detailer *d)
-{
- struct config *config;
- struct stream *rd, *wr;
- struct coll *coll;
- struct status *st;
- struct fixup *fixup;
- char *cmd, *collname, *line, *release;
- int error, fixupseof;
-
- config = d->config;
- rd = d->rd;
- wr = d->wr;
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- if (coll->co_options & CO_SKIP)
- continue;
- line = stream_getln(rd, NULL);
- cmd = proto_get_ascii(&line);
- collname = proto_get_ascii(&line);
- release = proto_get_ascii(&line);
- error = proto_get_time(&line, &coll->co_scantime);
- if (error || line != NULL || strcmp(cmd, "COLL") != 0 ||
- strcmp(collname, coll->co_name) != 0 ||
- strcmp(release, coll->co_release) != 0)
- return (DETAILER_ERR_PROTO);
- error = proto_printf(wr, "COLL %s %s\n", coll->co_name,
- coll->co_release);
- if (error)
- return (DETAILER_ERR_WRITE);
- stream_flush(wr);
- if (coll->co_options & CO_COMPRESS) {
- stream_filter_start(rd, STREAM_FILTER_ZLIB, NULL);
- stream_filter_start(wr, STREAM_FILTER_ZLIB, NULL);
- }
- st = status_open(coll, -1, &d->errmsg);
- if (st == NULL)
- return (DETAILER_ERR_MSG);
- error = detailer_coll(d, coll, st);
- status_close(st, NULL);
- if (error)
- return (error);
- if (coll->co_options & CO_COMPRESS) {
- stream_filter_stop(rd);
- stream_filter_stop(wr);
- }
- stream_flush(wr);
- }
- line = stream_getln(rd, NULL);
- if (line == NULL)
- return (DETAILER_ERR_READ);
- if (strcmp(line, ".") != 0)
- return (DETAILER_ERR_PROTO);
- error = proto_printf(wr, ".\n");
- if (error)
- return (DETAILER_ERR_WRITE);
- stream_flush(wr);
-
- /* Now send fixups if needed. */
- fixup = NULL;
- fixupseof = 0;
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- if (coll->co_options & CO_SKIP)
- continue;
- error = proto_printf(wr, "COLL %s %s\n", coll->co_name,
- coll->co_release);
- if (error)
- return (DETAILER_ERR_WRITE);
- if (coll->co_options & CO_COMPRESS)
- stream_filter_start(wr, STREAM_FILTER_ZLIB, NULL);
- while (!fixupseof) {
- if (fixup == NULL)
- fixup = fixups_get(config->fixups);
- if (fixup == NULL) {
- fixupseof = 1;
- break;
- }
- if (fixup->f_coll != coll)
- break;
- if (coll->co_options & CO_CHECKOUTMODE)
- error = proto_printf(wr, "Y %s %s %s\n",
- fixup->f_name, coll->co_tag, coll->co_date);
- else {
- error = proto_printf(wr, "A %s\n",
- fixup->f_name);
- }
- if (error)
- return (DETAILER_ERR_WRITE);
- fixup = NULL;
- }
- error = proto_printf(wr, ".\n");
- if (error)
- return (DETAILER_ERR_WRITE);
- if (coll->co_options & CO_COMPRESS)
- stream_filter_stop(wr);
- stream_flush(wr);
- }
- error = proto_printf(wr, ".\n");
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
-}
-
-static int
-detailer_coll(struct detailer *d, struct coll *coll, struct status *st)
-{
- struct fattr *rcsattr;
- struct stream *rd, *wr;
- char *attr, *cmd, *file, *line, *msg, *path, *target;
- int error, attic;
-
- rd = d->rd;
- wr = d->wr;
- attic = 0;
- line = stream_getln(rd, NULL);
- if (line == NULL)
- return (DETAILER_ERR_READ);
- while (strcmp(line, ".") != 0) {
- cmd = proto_get_ascii(&line);
- if (cmd == NULL || strlen(cmd) != 1)
- return (DETAILER_ERR_PROTO);
- switch (cmd[0]) {
- case 'D':
- /* Delete file. */
- file = proto_get_ascii(&line);
- if (file == NULL || line != NULL)
- return (DETAILER_ERR_PROTO);
- error = proto_printf(wr, "D %s\n", file);
- if (error)
- return (DETAILER_ERR_WRITE);
- break;
- case 'I':
- case 'i':
- case 'j':
- /* Directory operations. */
- file = proto_get_ascii(&line);
- if (file == NULL || line != NULL)
- return (DETAILER_ERR_PROTO);
- error = proto_printf(wr, "%s %s\n", cmd, file);
- if (error)
- return (DETAILER_ERR_WRITE);
- break;
- case 'J':
- /* Set directory attributes. */
- file = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (file == NULL || line != NULL || attr == NULL)
- return (DETAILER_ERR_PROTO);
- error = proto_printf(wr, "%s %s %s\n", cmd, file, attr);
- if (error)
- return (DETAILER_ERR_WRITE);
- break;
- case 'H':
- case 'h':
- /* Create a hard link. */
- file = proto_get_ascii(&line);
- target = proto_get_ascii(&line);
- if (file == NULL || target == NULL)
- return (DETAILER_ERR_PROTO);
- error = proto_printf(wr, "%s %s %s\n", cmd, file,
- target);
- break;
- case 't':
- file = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (file == NULL || attr == NULL || line != NULL) {
- return (DETAILER_ERR_PROTO);
- }
- rcsattr = fattr_decode(attr);
- if (rcsattr == NULL) {
- return (DETAILER_ERR_PROTO);
- }
- error = detailer_checkrcsattr(d, coll, file, rcsattr,
- 1);
- break;
-
- case 'T':
- file = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (file == NULL || attr == NULL || line != NULL)
- return (DETAILER_ERR_PROTO);
- rcsattr = fattr_decode(attr);
- if (rcsattr == NULL)
- return (DETAILER_ERR_PROTO);
- error = detailer_checkrcsattr(d, coll, file, rcsattr,
- 0);
- break;
-
- case 'U':
- /* Add or update file. */
- file = proto_get_ascii(&line);
- if (file == NULL || line != NULL)
- return (DETAILER_ERR_PROTO);
- if (coll->co_options & CO_CHECKOUTMODE) {
- error = detailer_dofile_co(d, coll, st, file);
- } else {
- path = cvspath(coll->co_prefix, file, 0);
- rcsattr = fattr_frompath(path, FATTR_NOFOLLOW);
- error = detailer_send_details(d, coll, file,
- path, rcsattr);
- if (rcsattr != NULL)
- fattr_free(rcsattr);
- free(path);
- }
- if (error)
- return (error);
- break;
- case '!':
- /* Warning from server. */
- msg = proto_get_rest(&line);
- if (msg == NULL)
- return (DETAILER_ERR_PROTO);
- lprintf(-1, "Server warning: %s\n", msg);
- break;
- default:
- return (DETAILER_ERR_PROTO);
- }
- stream_flush(wr);
- line = stream_getln(rd, NULL);
- if (line == NULL)
- return (DETAILER_ERR_READ);
- }
- error = proto_printf(wr, ".\n");
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
-}
-
-/*
- * Tell the server to update a regular file.
- */
-static int
-detailer_dofile_regular(struct detailer *d, char *name, char *path)
-{
- struct stream *wr;
- struct stat st;
- char md5[MD5_DIGEST_SIZE];
- int error;
-
- wr = d->wr;
- error = stat(path, &st);
- /* If we don't have it or it's unaccessible, we want it again. */
- if (error) {
- proto_printf(wr, "A %s\n", name);
- return (0);
- }
-
- /* If not, we want the file to be updated. */
- error = MD5_File(path, md5);
- if (error) {
- lprintf(-1, "Error reading \"%s\"\n", name);
- return (error);
- }
- error = proto_printf(wr, "R %s %O %s\n", name, st.st_size, md5);
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
-}
-
-/*
- * Tell the server to update a file with the rsync algorithm.
- */
-static int
-detailer_dofile_rsync(struct detailer *d, char *name, char *path)
-{
- struct stream *wr;
- struct rsyncfile *rf;
-
- wr = d->wr;
- rf = rsync_open(path, 0, 1);
- if (rf == NULL) {
- /* Fallback if we fail in opening it. */
- proto_printf(wr, "A %s\n", name);
- return (0);
- }
- proto_printf(wr, "r %s %z %z\n", name, rsync_filesize(rf),
- rsync_blocksize(rf));
- /* Detail the blocks. */
- while (rsync_nextblock(rf) != 0)
- proto_printf(wr, "%s %s\n", rsync_rsum(rf), rsync_blockmd5(rf));
- proto_printf(wr, ".\n");
- rsync_close(rf);
- return (0);
-}
-
-/*
- * Tell the server to update an RCS file that we have, or send it if we don't.
- */
-static int
-detailer_dofile_rcs(struct detailer *d, struct coll *coll, char *name,
- char *path)
-{
- struct stream *wr;
- struct fattr *fa;
- struct rcsfile *rf;
- int error;
-
- wr = d->wr;
- path = atticpath(coll->co_prefix, name);
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- if (fa == NULL) {
- /* We don't have it, so send request to get it. */
- error = proto_printf(wr, "A %s\n", name);
- if (error)
- return (DETAILER_ERR_WRITE);
- free(path);
- return (0);
- }
-
- rf = rcsfile_frompath(path, name, coll->co_cvsroot, coll->co_tag, 1);
- free(path);
- if (rf == NULL) {
- error = proto_printf(wr, "A %s\n", name);
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
- }
- /* Tell to update the RCS file. The client version details follow. */
- rcsfile_send_details(rf, wr);
- rcsfile_free(rf);
- fattr_free(fa);
- return (0);
-}
-
-static int
-detailer_dofile_co(struct detailer *d, struct coll *coll, struct status *st,
- char *file)
-{
- struct stream *wr;
- struct fattr *fa;
- struct statusrec *sr;
- char md5[MD5_DIGEST_SIZE];
- char *path;
- int error, ret;
-
- wr = d->wr;
- path = checkoutpath(coll->co_prefix, file);
- if (path == NULL)
- return (DETAILER_ERR_PROTO);
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- if (fa == NULL) {
- /* We don't have the file, so the only option at this
- point is to tell the server to send it. The server
- may figure out that the file is dead, in which case
- it will tell us. */
- error = proto_printf(wr, "C %s %s %s\n",
- file, coll->co_tag, coll->co_date);
- free(path);
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
- }
- ret = status_get(st, file, 0, 0, &sr);
- if (ret == -1) {
- d->errmsg = status_errmsg(st);
- free(path);
- return (DETAILER_ERR_MSG);
- }
- if (ret == 0)
- sr = NULL;
-
- /* If our recorded information doesn't match the file that the
- client has, then ignore the recorded information. */
- if (sr != NULL && (sr->sr_type != SR_CHECKOUTLIVE ||
- !fattr_equal(sr->sr_clientattr, fa)))
- sr = NULL;
- fattr_free(fa);
- if (sr != NULL && strcmp(sr->sr_revdate, ".") != 0) {
- error = proto_printf(wr, "U %s %s %s %s %s\n", file,
- coll->co_tag, coll->co_date, sr->sr_revnum, sr->sr_revdate);
- free(path);
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
- }
-
- /*
- * We don't have complete and/or accurate recorded information
- * about what version of the file we have. Compute the file's
- * checksum as an aid toward identifying which version it is.
- */
- error = MD5_File(path, md5);
- if (error) {
- xasprintf(&d->errmsg,
- "Cannot calculate checksum for \"%s\": %s", path,
- strerror(errno));
- return (DETAILER_ERR_MSG);
- }
- free(path);
- if (sr == NULL) {
- error = proto_printf(wr, "S %s %s %s %s\n", file,
- coll->co_tag, coll->co_date, md5);
- } else {
- error = proto_printf(wr, "s %s %s %s %s %s\n", file,
- coll->co_tag, coll->co_date, sr->sr_revnum, md5);
- }
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
-}
-
-int
-detailer_checkrcsattr(struct detailer *d, struct coll *coll, char *name,
- struct fattr *server_attr, int attic)
-{
- struct fattr *client_attr;
- char *attr, *path;
- int error;
-
- /*
- * I don't think we can use the status file, since it only records file
- * attributes in cvsmode.
- */
- client_attr = NULL;
- path = cvspath(coll->co_prefix, name, attic);
- if (path == NULL) {
- return (DETAILER_ERR_PROTO);
- }
-
- if (access(path, F_OK) == 0 &&
- ((client_attr = fattr_frompath(path, FATTR_NOFOLLOW)) != NULL) &&
- fattr_equal(client_attr, server_attr)) {
- attr = fattr_encode(client_attr, NULL, 0);
- if (attic) {
- error = proto_printf(d->wr, "l %s %s\n", name, attr);
- } else {
- error = proto_printf(d->wr, "L %s %s\n", name, attr);
- }
- free(attr);
- free(path);
- fattr_free(client_attr);
- if (error)
- return (DETAILER_ERR_WRITE);
- return (0);
- }
- /* We don't have it, so tell the server to send it. */
- error = detailer_send_details(d, coll, name, path, client_attr);
- fattr_free(client_attr);
- free(path);
- return (error);
-}
-
-int
-detailer_send_details(struct detailer *d, struct coll *coll, char *name,
- char *path, struct fattr *fa)
-{
- int error;
- size_t len;
-
- /*
- * Try to check if the file exists either live or dead to see if we can
- * edit it and put it live or dead, rather than receiving the entire
- * file.
- */
- if (fa == NULL) {
- path = atticpath(coll->co_prefix, name);
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- }
- if (fa == NULL) {
- error = proto_printf(d->wr, "A %s\n", name);
- if (error)
- return (DETAILER_ERR_WRITE);
- } else if (fattr_type(fa) == FT_FILE) {
- if (isrcs(name, &len) && !(coll->co_options & CO_NORCS)) {
- detailer_dofile_rcs(d, coll, name, path);
- } else if (!(coll->co_options & CO_NORSYNC) &&
- !globtree_test(coll->co_norsync, name)) {
- detailer_dofile_rsync(d, name, path);
- } else {
- detailer_dofile_regular(d, name, path);
- }
- } else {
- error = proto_printf(d->wr, "N %s\n", name);
- if (error)
- return (DETAILER_ERR_WRITE);
- }
- return (0);
-}
diff --git a/contrib/csup/detailer.h b/contrib/csup/detailer.h
deleted file mode 100644
index fe82b27..0000000
--- a/contrib/csup/detailer.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _DETAILER_H_
-#define _DETAILER_H_
-
-void *detailer(void *);
-
-#endif /* !_DETAILER_H_ */
diff --git a/contrib/csup/diff.c b/contrib/csup/diff.c
deleted file mode 100644
index 8059676..0000000
--- a/contrib/csup/diff.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/limits.h>
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "diff.h"
-#include "keyword.h"
-#include "misc.h"
-#include "stream.h"
-#include "queue.h"
-
-typedef long lineno_t;
-
-#define EC_ADD 0
-#define EC_DEL 1
-#define MAXKEY LONG_MAX
-
-/* Editing command and state. */
-struct editcmd {
- int cmd;
- long key;
- int havetext;
- int offset;
- lineno_t where;
- lineno_t count;
- lineno_t lasta;
- lineno_t lastd;
- lineno_t editline;
- /* For convenience. */
- struct keyword *keyword;
- struct diffinfo *di;
- struct stream *orig;
- struct stream *dest;
- LIST_ENTRY(editcmd) next;
-};
-
-struct diffstart {
- LIST_HEAD(, editcmd) dhead;
-};
-
-static int diff_geteditcmd(struct editcmd *, char *);
-static int diff_copyln(struct editcmd *, lineno_t);
-static int diff_ignoreln(struct editcmd *, lineno_t);
-static void diff_write(struct editcmd *, void *, size_t);
-static int diff_insert_edit(struct diffstart *, struct editcmd *);
-static void diff_free(struct diffstart *);
-
-int
-diff_apply(struct stream *rd, struct stream *orig, struct stream *dest,
- struct keyword *keyword, struct diffinfo *di, int comode)
-{
- struct editcmd ec;
- lineno_t i;
- size_t size;
- char *line;
- int empty, error, noeol;
-
- memset(&ec, 0, sizeof(ec));
- empty = 0;
- noeol = 0;
- ec.di = di;
- ec.keyword = keyword;
- ec.orig = orig;
- ec.dest = dest;
- line = stream_getln(rd, NULL);
- while (line != NULL && strcmp(line, ".") != 0 &&
- strcmp(line, ".+") != 0) {
- /*
- * The server sends an empty line and then terminates
- * with .+ for forced (and thus empty) commits.
- */
- if (*line == '\0') {
- if (empty)
- return (-1);
- empty = 1;
- line = stream_getln(rd, NULL);
- continue;
- }
- error = diff_geteditcmd(&ec, line);
- if (error)
- return (-1);
-
- if (ec.cmd == EC_ADD) {
- error = diff_copyln(&ec, ec.where);
- if (error)
- return (-1);
- for (i = 0; i < ec.count; i++) {
- line = stream_getln(rd, &size);
- if (line == NULL)
- return (-1);
- if (comode && line[0] == '.') {
- line++;
- size--;
- }
- diff_write(&ec, line, size);
- }
- } else {
- assert(ec.cmd == EC_DEL);
- error = diff_copyln(&ec, ec.where - 1);
- if (error)
- return (-1);
- for (i = 0; i < ec.count; i++) {
- line = stream_getln(orig, NULL);
- if (line == NULL)
- return (-1);
- ec.editline++;
- }
- }
- line = stream_getln(rd, NULL);
- }
- if (comode && line == NULL)
- return (-1);
- /* If we got ".+", there's no ending newline. */
- if (comode && strcmp(line, ".+") == 0 && !empty)
- noeol = 1;
- ec.where = 0;
- while ((line = stream_getln(orig, &size)) != NULL)
- diff_write(&ec, line, size);
- stream_flush(dest);
- if (noeol) {
- error = stream_truncate_rel(dest, -1);
- if (error) {
- warn("stream_truncate_rel");
- return (-1);
- }
- }
- return (0);
-}
-
-/*
- * Reverse a diff using the same algorithm as in cvsup.
- */
-static int
-diff_write_reverse(struct stream *dest, struct diffstart *ds)
-{
- struct editcmd *ec, *nextec;
- long editline, endline, firstoutputlinedeleted;
- long num_added, num_deleted, startline;
- int num;
-
- nextec = LIST_FIRST(&ds->dhead);
- editline = 0;
- num = 0;
- while (nextec != NULL) {
- ec = nextec;
- nextec = LIST_NEXT(nextec, next);
- if (nextec == NULL)
- break;
- num++;
- num_deleted = 0;
- if (ec->havetext)
- num_deleted = ec->count;
- num_added = num_deleted + nextec->offset - ec->offset;
- if (num_deleted > 0) {
- firstoutputlinedeleted = ec->key - num_deleted + 1;
- stream_printf(dest, "d%ld %ld\n", firstoutputlinedeleted,
- num_deleted);
- if (num_added <= 0)
- continue;
- }
- if (num_added > 0) {
- stream_printf(dest, "a%ld %ld\n", ec->key, num_added);
- startline = ec->key - num_deleted + 1 + ec->offset;
- endline = startline + num_added - 1;
-
- /* Copy lines from original file. First ignore some. */
- ec->editline = editline;
- diff_ignoreln(ec, startline - 1);
- diff_copyln(ec, endline);
- editline = ec->editline;
- }
- }
- return (0);
-}
-
-/*
- * Insert a diff into the list sorted on key. Should perhaps use quicker
- * algorithms than insertion sort, but do this for now.
- */
-static int
-diff_insert_edit(struct diffstart *ds, struct editcmd *ec)
-{
- struct editcmd *curec;
-
- if (ec == NULL)
- return (0);
-
- if (LIST_EMPTY(&ds->dhead)) {
- LIST_INSERT_HEAD(&ds->dhead, ec, next);
- return (0);
- }
-
- /* Insertion sort based on key. */
- LIST_FOREACH(curec, &ds->dhead, next) {
- if (ec->key < curec->key) {
- LIST_INSERT_BEFORE(curec, ec, next);
- return (0);
- }
- if (LIST_NEXT(curec, next) == NULL)
- break;
- }
- /* Just insert it after. */
- LIST_INSERT_AFTER(curec, ec, next);
- return (0);
-}
-
-static void
-diff_free(struct diffstart *ds)
-{
- struct editcmd *ec;
-
- while(!LIST_EMPTY(&ds->dhead)) {
- ec = LIST_FIRST(&ds->dhead);
- LIST_REMOVE(ec, next);
- free(ec);
- }
-}
-
-/*
- * Write the reverse diff from the diff in rd, and original file into
- * destination. This algorithm is the same as used in cvsup.
- */
-int
-diff_reverse(struct stream *rd, struct stream *orig, struct stream *dest,
- struct keyword *keyword, struct diffinfo *di)
-{
- struct diffstart ds;
- struct editcmd ec, *addec, *delec;
- lineno_t i;
- char *line;
- int error, offset;
-
- memset(&ec, 0, sizeof(ec));
- ec.orig = orig;
- ec.dest = dest;
- ec.keyword = keyword;
- ec.di = di;
- addec = NULL;
- delec = NULL;
- ec.havetext = 0;
- offset = 0;
- LIST_INIT(&ds.dhead);
-
- /* Start with next since we need it. */
- line = stream_getln(rd, NULL);
- /* First we build up the list of diffs from input. */
- while (line != NULL) {
- error = diff_geteditcmd(&ec, line);
- if (error)
- break;
- if (ec.cmd == EC_ADD) {
- addec = xmalloc(sizeof(struct editcmd));
- *addec = ec;
- addec->havetext = 1;
- /* Ignore the lines we was supposed to add. */
- for (i = 0; i < ec.count; i++) {
- line = stream_getln(rd, NULL);
- if (line == NULL)
- return (-1);
- }
-
- /* Get the next diff command if we have one. */
- addec->key = addec->where + addec->count - offset;
- if (delec != NULL &&
- delec->key == addec->key - addec->count) {
- delec->key = addec->key;
- delec->havetext = addec->havetext;
- delec->count = addec->count;
- diff_insert_edit(&ds, delec);
- free(addec);
- delec = NULL;
- addec = NULL;
- } else {
- if (delec != NULL) {
- diff_insert_edit(&ds, delec);
- }
- delec = NULL;
- addec->offset = offset;
- diff_insert_edit(&ds, addec);
- addec = NULL;
- }
- offset -= ec.count;
- } else if (ec.cmd == EC_DEL) {
- if (delec != NULL) {
- /* Update offset to our next. */
- diff_insert_edit(&ds, delec);
- delec = NULL;
- }
- delec = xmalloc(sizeof(struct editcmd));
- *delec = ec;
- delec->key = delec->where - 1 - offset;
- delec->offset = offset;
- delec->count = 0;
- delec->havetext = 0;
- /* Important to use the count we had before reset.*/
- offset += ec.count;
- }
- line = stream_getln(rd, NULL);
- }
-
- while (line != NULL)
- line = stream_getln(rd, NULL);
- if (delec != NULL) {
- diff_insert_edit(&ds, delec);
- delec = NULL;
- }
-
- addec = xmalloc(sizeof(struct editcmd));
- /* Should be filesize, but we set it to max value. */
- addec->key = MAXKEY;
- addec->offset = offset;
- addec->havetext = 0;
- addec->count = 0;
- diff_insert_edit(&ds, addec);
- addec = NULL;
- diff_write_reverse(dest, &ds);
- diff_free(&ds);
- stream_flush(dest);
- return (0);
-}
-
-/* Get an editing command from the diff. */
-static int
-diff_geteditcmd(struct editcmd *ec, char *line)
-{
- char *end;
-
- if (line[0] == 'a')
- ec->cmd = EC_ADD;
- else if (line[0] == 'd')
- ec->cmd = EC_DEL;
- else
- return (-1);
- errno = 0;
- ec->where = strtol(line + 1, &end, 10);
- if (errno || ec->where < 0 || *end != ' ')
- return (-1);
- line = end + 1;
- errno = 0;
- ec->count = strtol(line, &end, 10);
- if (errno || ec->count <= 0 || *end != '\0')
- return (-1);
- if (ec->cmd == EC_ADD) {
- if (ec->where < ec->lasta)
- return (-1);
- ec->lasta = ec->where + 1;
- } else {
- if (ec->where < ec->lasta || ec->where < ec->lastd)
- return (-1);
- ec->lasta = ec->where;
- ec->lastd = ec->where + ec->count;
- }
- return (0);
-}
-
-/* Copy lines from the original version of the file up to line "to". */
-static int
-diff_copyln(struct editcmd *ec, lineno_t to)
-{
- size_t size;
- char *line;
-
- while (ec->editline < to) {
- line = stream_getln(ec->orig, &size);
- if (line == NULL)
- return (-1);
- ec->editline++;
- diff_write(ec, line, size);
- }
- return (0);
-}
-
-/* Ignore lines from the original version of the file up to line "to". */
-static int
-diff_ignoreln(struct editcmd *ec, lineno_t to)
-{
- size_t size;
- char *line;
-
- while (ec->editline < to) {
- line = stream_getln(ec->orig, &size);
- if (line == NULL)
- return (-1);
- ec->editline++;
- }
- return (0);
-}
-
-/* Write a new line to the file, expanding RCS keywords appropriately. */
-static void
-diff_write(struct editcmd *ec, void *buf, size_t size)
-{
- size_t newsize;
- char *line, *newline;
- int ret;
-
- line = buf;
- ret = keyword_expand(ec->keyword, ec->di, line, size,
- &newline, &newsize);
- if (ret) {
- stream_write(ec->dest, newline, newsize);
- free(newline);
- } else {
- stream_write(ec->dest, buf, size);
- }
-}
diff --git a/contrib/csup/diff.h b/contrib/csup/diff.h
deleted file mode 100644
index b0c8c97..0000000
--- a/contrib/csup/diff.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _DIFF_H_
-#define _DIFF_H_
-
-struct stream;
-struct keyword;
-struct file_update;
-
-/* Description of an RCS delta. */
-struct diffinfo {
- char *di_rcsfile; /* RCS filename */
- char *di_cvsroot; /* CVS root prefix */
- char *di_revnum; /* Revision number */
- char *di_revdate; /* Revision date */
- char *di_author; /* Author of the delta */
- char *di_tag; /* CVS tag, if any */
- char *di_state; /* State of the branch */
- int di_expand; /* CVS expansion mode */
-};
-
-int diff_apply(struct stream *, struct stream *, struct stream *,
- struct keyword *, struct diffinfo *, int);
-int diff_reverse(struct stream *, struct stream *,
- struct stream *, struct keyword *, struct diffinfo *);
-
-#endif /* !_DIFF_H_ */
diff --git a/contrib/csup/fattr.c b/contrib/csup/fattr.c
deleted file mode 100644
index b141c2c..0000000
--- a/contrib/csup/fattr.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "fattr.h"
-#include "idcache.h"
-#include "misc.h"
-
-/*
- * Include the appropriate definition for the file attributes we support.
- * There are two different files: fattr_bsd.h for BSD-like systems that
- * support the extended file flags a la chflags() and fattr_posix.h for
- * bare POSIX systems that don't.
- */
-#ifdef HAVE_FFLAGS
-#include "fattr_bsd.h"
-#else
-#include "fattr_posix.h"
-#endif
-
-#ifdef __FreeBSD__
-#include <osreldate.h>
-#endif
-
-/* Define fflags_t if we're on a system that doesn't have it. */
-#if !defined(__FreeBSD_version) || __FreeBSD_version < 500030
-typedef uint32_t fflags_t;
-#endif
-
-#define FA_MASKRADIX 16
-#define FA_FILETYPERADIX 10
-#define FA_MODTIMERADIX 10
-#define FA_SIZERADIX 10
-#define FA_RDEVRADIX 16
-#define FA_MODERADIX 8
-#define FA_FLAGSRADIX 16
-#define FA_LINKCOUNTRADIX 10
-#define FA_DEVRADIX 16
-#define FA_INODERADIX 10
-
-#define FA_PERMMASK (S_IRWXU | S_IRWXG | S_IRWXO)
-#define FA_SETIDMASK (S_ISUID | S_ISGID | S_ISVTX)
-
-struct fattr {
- int mask;
- int type;
- time_t modtime;
- off_t size;
- char *linktarget;
- dev_t rdev;
- uid_t uid;
- gid_t gid;
- mode_t mode;
- fflags_t flags;
- nlink_t linkcount;
- dev_t dev;
- ino_t inode;
-};
-
-static const struct fattr bogus = {
- FA_MODTIME | FA_SIZE | FA_MODE,
- FT_UNKNOWN,
- 1,
- 0,
- NULL,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
-};
-
-static struct fattr *defaults[FT_NUMBER];
-
-void
-fattr_init(void)
-{
- struct fattr *fa;
- int i;
-
- for (i = 0; i < FT_NUMBER; i++) {
- fa = fattr_new(i, -1);
- if (i == FT_DIRECTORY)
- fa->mode = 0777;
- else
- fa->mode = 0666;
- fa->mask |= FA_MODE;
- defaults[i] = fa;
- }
- /* Initialize the uid/gid lookup cache. */
- idcache_init();
-}
-
-void
-fattr_fini(void)
-{
- int i;
-
- idcache_fini();
- for (i = 0; i < FT_NUMBER; i++)
- fattr_free(defaults[i]);
-}
-
-const struct fattr *fattr_bogus = &bogus;
-
-static char *fattr_scanattr(struct fattr *, int, const char *);
-
-int
-fattr_supported(int type)
-{
-
- return (fattr_support[type]);
-}
-
-struct fattr *
-fattr_new(int type, time_t modtime)
-{
- struct fattr *new;
-
- new = xmalloc(sizeof(struct fattr));
- memset(new, 0, sizeof(struct fattr));
- new->type = type;
- if (type != FT_UNKNOWN)
- new->mask |= FA_FILETYPE;
- if (modtime != -1) {
- new->modtime = modtime;
- new->mask |= FA_MODTIME;
- }
- if (fattr_supported(new->type) & FA_LINKCOUNT) {
- new->mask |= FA_LINKCOUNT;
- new->linkcount = 1;
- }
- return (new);
-}
-
-/* Returns a new file attribute structure based on a stat structure. */
-struct fattr *
-fattr_fromstat(struct stat *sb)
-{
- struct fattr *fa;
-
- fa = fattr_new(FT_UNKNOWN, -1);
- if (S_ISREG(sb->st_mode))
- fa->type = FT_FILE;
- else if (S_ISDIR(sb->st_mode))
- fa->type = FT_DIRECTORY;
- else if (S_ISCHR(sb->st_mode))
- fa->type = FT_CDEV;
- else if (S_ISBLK(sb->st_mode))
- fa->type = FT_BDEV;
- else if (S_ISLNK(sb->st_mode))
- fa->type = FT_SYMLINK;
- else
- fa->type = FT_UNKNOWN;
-
- fa->mask = FA_FILETYPE | fattr_supported(fa->type);
- if (fa->mask & FA_MODTIME)
- fa->modtime = sb->st_mtime;
- if (fa->mask & FA_SIZE)
- fa->size = sb->st_size;
- if (fa->mask & FA_RDEV)
- fa->rdev = sb->st_rdev;
- if (fa->mask & FA_OWNER)
- fa->uid = sb->st_uid;
- if (fa->mask & FA_GROUP)
- fa->gid = sb->st_gid;
- if (fa->mask & FA_MODE)
- fa->mode = sb->st_mode & (FA_SETIDMASK | FA_PERMMASK);
-#ifdef HAVE_FFLAGS
- if (fa->mask & FA_FLAGS)
- fa->flags = sb->st_flags;
-#endif
- if (fa->mask & FA_LINKCOUNT)
- fa->linkcount = sb->st_nlink;
- if (fa->mask & FA_DEV)
- fa->dev = sb->st_dev;
- if (fa->mask & FA_INODE)
- fa->inode = sb->st_ino;
- return (fa);
-}
-
-struct fattr *
-fattr_frompath(const char *path, int nofollow)
-{
- struct fattr *fa;
- struct stat sb;
- int error, len;
-
- if (nofollow)
- error = lstat(path, &sb);
- else
- error = stat(path, &sb);
- if (error)
- return (NULL);
- fa = fattr_fromstat(&sb);
- if (fa->mask & FA_LINKTARGET) {
- char buf[1024];
-
- len = readlink(path, buf, sizeof(buf));
- if (len == -1) {
- fattr_free(fa);
- return (NULL);
- }
- if ((unsigned)len > sizeof(buf) - 1) {
- fattr_free(fa);
- errno = ENAMETOOLONG;
- return (NULL);
- }
- buf[len] = '\0';
- fa->linktarget = xstrdup(buf);
- }
- return (fa);
-}
-
-struct fattr *
-fattr_fromfd(int fd)
-{
- struct fattr *fa;
- struct stat sb;
- int error;
-
- error = fstat(fd, &sb);
- if (error)
- return (NULL);
- fa = fattr_fromstat(&sb);
- return (fa);
-}
-
-int
-fattr_type(const struct fattr *fa)
-{
-
- return (fa->type);
-}
-
-/* Returns a new file attribute structure from its encoded text form. */
-struct fattr *
-fattr_decode(char *attr)
-{
- struct fattr *fa;
- char *next;
-
- fa = fattr_new(FT_UNKNOWN, -1);
- next = fattr_scanattr(fa, FA_MASK, attr);
- if (next == NULL || (fa->mask & ~FA_MASK) > 0)
- goto bad;
- if (fa->mask & FA_FILETYPE) {
- next = fattr_scanattr(fa, FA_FILETYPE, next);
- if (next == NULL)
- goto bad;
- if (fa->type < 0 || fa->type > FT_MAX)
- fa->type = FT_UNKNOWN;
- } else {
- /* The filetype attribute is always valid. */
- fa->mask |= FA_FILETYPE;
- fa->type = FT_UNKNOWN;
- }
- fa->mask = fa->mask & fattr_supported(fa->type);
- if (fa->mask & FA_MODTIME)
- next = fattr_scanattr(fa, FA_MODTIME, next);
- if (fa->mask & FA_SIZE)
- next = fattr_scanattr(fa, FA_SIZE, next);
- if (fa->mask & FA_LINKTARGET)
- next = fattr_scanattr(fa, FA_LINKTARGET, next);
- if (fa->mask & FA_RDEV)
- next = fattr_scanattr(fa, FA_RDEV, next);
- if (fa->mask & FA_OWNER)
- next = fattr_scanattr(fa, FA_OWNER, next);
- if (fa->mask & FA_GROUP)
- next = fattr_scanattr(fa, FA_GROUP, next);
- if (fa->mask & FA_MODE)
- next = fattr_scanattr(fa, FA_MODE, next);
- if (fa->mask & FA_FLAGS)
- next = fattr_scanattr(fa, FA_FLAGS, next);
- if (fa->mask & FA_LINKCOUNT) {
- next = fattr_scanattr(fa, FA_LINKCOUNT, next);
- } else if (fattr_supported(fa->type) & FA_LINKCOUNT) {
- /* If the link count is missing but supported, fake it as 1. */
- fa->mask |= FA_LINKCOUNT;
- fa->linkcount = 1;
- }
- if (fa->mask & FA_DEV)
- next = fattr_scanattr(fa, FA_DEV, next);
- if (fa->mask & FA_INODE)
- next = fattr_scanattr(fa, FA_INODE, next);
- if (next == NULL)
- goto bad;
- return (fa);
-bad:
- fattr_free(fa);
- return (NULL);
-}
-
-char *
-fattr_encode(const struct fattr *fa, fattr_support_t support, int ignore)
-{
- struct {
- char val[32];
- char len[4];
- int extval;
- char *ext;
- } pieces[FA_NUMBER], *piece;
- char *cp, *s, *username, *groupname;
- size_t len, vallen;
- mode_t mode, modemask;
- int mask, n, i;
-
- username = NULL;
- groupname = NULL;
- if (support == NULL)
- mask = fa->mask;
- else
- mask = fa->mask & support[fa->type];
- mask &= ~ignore;
- if (fa->mask & FA_OWNER) {
- username = getuserbyid(fa->uid);
- if (username == NULL)
- mask &= ~FA_OWNER;
- }
- if (fa->mask & FA_GROUP) {
- groupname = getgroupbyid(fa->gid);
- if (groupname == NULL)
- mask &= ~FA_GROUP;
- }
- if (fa->mask & FA_LINKCOUNT && fa->linkcount == 1)
- mask &= ~FA_LINKCOUNT;
-
- memset(pieces, 0, FA_NUMBER * sizeof(*pieces));
- len = 0;
- piece = pieces;
- vallen = snprintf(piece->val, sizeof(piece->val), "%x", mask);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- if (mask & FA_FILETYPE) {
- vallen = snprintf(piece->val, sizeof(piece->val),
- "%d", fa->type);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_MODTIME) {
- vallen = snprintf(piece->val, sizeof(piece->val),
- "%lld", (long long)fa->modtime);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_SIZE) {
- vallen = snprintf(piece->val, sizeof(piece->val),
- "%lld", (long long)fa->size);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_LINKTARGET) {
- vallen = strlen(fa->linktarget);
- piece->extval = 1;
- piece->ext = fa->linktarget;
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_RDEV) {
- vallen = snprintf(piece->val, sizeof(piece->val),
- "%lld", (long long)fa->rdev);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_OWNER) {
- vallen = strlen(username);
- piece->extval = 1;
- piece->ext = username;
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_GROUP) {
- vallen = strlen(groupname);
- piece->extval = 1;
- piece->ext = groupname;
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_MODE) {
- if (mask & FA_OWNER && mask & FA_GROUP)
- modemask = FA_SETIDMASK | FA_PERMMASK;
- else
- modemask = FA_PERMMASK;
- mode = fa->mode & modemask;
- vallen = snprintf(piece->val, sizeof(piece->val),
- "%o", mode);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_FLAGS) {
- vallen = snprintf(piece->val, sizeof(piece->val), "%llx",
- (long long)fa->flags);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_LINKCOUNT) {
- vallen = snprintf(piece->val, sizeof(piece->val), "%lld",
- (long long)fa->linkcount);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_DEV) {
- vallen = snprintf(piece->val, sizeof(piece->val), "%llx",
- (long long)fa->dev);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
- if (mask & FA_INODE) {
- vallen = snprintf(piece->val, sizeof(piece->val), "%lld",
- (long long)fa->inode);
- len += snprintf(piece->len, sizeof(piece->len), "%lld",
- (long long)vallen) + vallen + 1;
- piece++;
- }
-
- s = xmalloc(len + 1);
-
- n = piece - pieces;
- piece = pieces;
- cp = s;
- for (i = 0; i < n; i++) {
- if (piece->extval)
- len = sprintf(cp, "%s#%s", piece->len, piece->ext);
- else
- len = sprintf(cp, "%s#%s", piece->len, piece->val);
- cp += len;
- piece++;
- }
- return (s);
-}
-
-struct fattr *
-fattr_dup(const struct fattr *from)
-{
- struct fattr *fa;
-
- fa = fattr_new(FT_UNKNOWN, -1);
- fattr_override(fa, from, FA_MASK);
- return (fa);
-}
-
-void
-fattr_free(struct fattr *fa)
-{
-
- if (fa == NULL)
- return;
- if (fa->linktarget != NULL)
- free(fa->linktarget);
- free(fa);
-}
-
-void
-fattr_umask(struct fattr *fa, mode_t newumask)
-{
-
- if (fa->mask & FA_MODE)
- fa->mode = fa->mode & ~newumask;
-}
-
-void
-fattr_maskout(struct fattr *fa, int mask)
-{
-
- /* Don't forget to free() the linktarget attribute if we remove it. */
- if (mask & FA_LINKTARGET && fa->mask & FA_LINKTARGET) {
- free(fa->linktarget);
- fa->linktarget = NULL;
- }
- fa->mask &= ~mask;
-}
-
-int
-fattr_getmask(const struct fattr *fa)
-{
-
- return (fa->mask);
-}
-
-nlink_t
-fattr_getlinkcount(const struct fattr *fa)
-{
-
- return (fa->linkcount);
-}
-
-char *
-fattr_getlinktarget(const struct fattr *fa)
-{
-
- return (fa->linktarget);
-}
-
-/*
- * Eat the specified attribute and put it in the file attribute
- * structure. Returns NULL on error, or a pointer to the next
- * attribute to parse.
- *
- * This would be much prettier if we had strntol() so that we're
- * not forced to write '\0' to the string before calling strtol()
- * and then put back the old value...
- *
- * We need to use (unsigned) long long types here because some
- * of the opaque types we're parsing (off_t, time_t...) may need
- * 64bits to fit.
- */
-static char *
-fattr_scanattr(struct fattr *fa, int type, const char *attr)
-{
- char *attrend, *attrstart, *end;
- size_t len;
- unsigned long attrlen;
- int error;
- mode_t modemask;
- char tmp;
-
- if (attr == NULL)
- return (NULL);
- errno = 0;
- attrlen = strtoul(attr, &end, 10);
- if (errno || *end != '#')
- return (NULL);
- len = strlen(attr);
- attrstart = end + 1;
- attrend = attrstart + attrlen;
- tmp = *attrend;
- *attrend = '\0';
- switch (type) {
- /* Using FA_MASK here is a bit bogus semantically. */
- case FA_MASK:
- errno = 0;
- fa->mask = (int)strtol(attrstart, &end, FA_MASKRADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_FILETYPE:
- errno = 0;
- fa->type = (int)strtol(attrstart, &end, FA_FILETYPERADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_MODTIME:
- errno = 0;
- fa->modtime = (time_t)strtoll(attrstart, &end, FA_MODTIMERADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_SIZE:
- errno = 0;
- fa->size = (off_t)strtoll(attrstart, &end, FA_SIZERADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_LINKTARGET:
- fa->linktarget = xstrdup(attrstart);
- break;
- case FA_RDEV:
- errno = 0;
- fa->rdev = (dev_t)strtoll(attrstart, &end, FA_RDEVRADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_OWNER:
- error = getuidbyname(attrstart, &fa->uid);
- if (error)
- fa->mask &= ~FA_OWNER;
- break;
- case FA_GROUP:
- error = getgidbyname(attrstart, &fa->gid);
- if (error)
- fa->mask &= ~FA_GROUP;
- break;
- case FA_MODE:
- errno = 0;
- fa->mode = (mode_t)strtol(attrstart, &end, FA_MODERADIX);
- if (errno || end != attrend)
- goto bad;
- if (fa->mask & FA_OWNER && fa->mask & FA_GROUP)
- modemask = FA_SETIDMASK | FA_PERMMASK;
- else
- modemask = FA_PERMMASK;
- fa->mode &= modemask;
- break;
- case FA_FLAGS:
- errno = 0;
- fa->flags = (fflags_t)strtoul(attrstart, &end, FA_FLAGSRADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_LINKCOUNT:
- errno = 0;
- fa->linkcount = (nlink_t)strtol(attrstart, &end, FA_FLAGSRADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_DEV:
- errno = 0;
- fa->dev = (dev_t)strtoll(attrstart, &end, FA_DEVRADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- case FA_INODE:
- errno = 0;
- fa->inode = (ino_t)strtoll(attrstart, &end, FA_INODERADIX);
- if (errno || end != attrend)
- goto bad;
- break;
- }
- *attrend = tmp;
- return (attrend);
-bad:
- *attrend = tmp;
- return (NULL);
-}
-
-/* Return a file attribute structure built from the RCS file attributes. */
-struct fattr *
-fattr_forcheckout(const struct fattr *rcsattr, mode_t mask)
-{
- struct fattr *fa;
-
- fa = fattr_new(FT_FILE, -1);
- if (rcsattr->mask & FA_MODE) {
- if ((rcsattr->mode & 0111) > 0)
- fa->mode = 0777;
- else
- fa->mode = 0666;
- fa->mode &= ~mask;
- fa->mask |= FA_MODE;
- }
- return (fa);
-}
-
-/* Merge attributes from "from" that aren't present in "fa". */
-void
-fattr_merge(struct fattr *fa, const struct fattr *from)
-{
-
- fattr_override(fa, from, from->mask & ~fa->mask);
-}
-
-/* Merge default attributes. */
-void
-fattr_mergedefault(struct fattr *fa)
-{
-
- fattr_merge(fa, defaults[fa->type]);
-}
-
-/* Override selected attributes of "fa" with values from "from". */
-void
-fattr_override(struct fattr *fa, const struct fattr *from, int mask)
-{
-
- mask &= from->mask;
- if (fa->mask & FA_LINKTARGET && mask & FA_LINKTARGET)
- free(fa->linktarget);
- fa->mask |= mask;
- if (mask & FA_FILETYPE)
- fa->type = from->type;
- if (mask & FA_MODTIME)
- fa->modtime = from->modtime;
- if (mask & FA_SIZE)
- fa->size = from->size;
- if (mask & FA_LINKTARGET)
- fa->linktarget = xstrdup(from->linktarget);
- if (mask & FA_RDEV)
- fa->rdev = from->rdev;
- if (mask & FA_OWNER)
- fa->uid = from->uid;
- if (mask & FA_GROUP)
- fa->gid = from->gid;
- if (mask & FA_MODE)
- fa->mode = from->mode;
- if (mask & FA_FLAGS)
- fa->flags = from->flags;
- if (mask & FA_LINKCOUNT)
- fa->linkcount = from->linkcount;
- if (mask & FA_DEV)
- fa->dev = from->dev;
- if (mask & FA_INODE)
- fa->inode = from->inode;
-}
-
-/* Create a node. */
-int
-fattr_makenode(const struct fattr *fa, const char *path)
-{
- mode_t modemask, mode;
- int error;
-
- error = 0;
-
- if (fa->mask & FA_OWNER && fa->mask & FA_GROUP)
- modemask = FA_SETIDMASK | FA_PERMMASK;
- else
- modemask = FA_PERMMASK;
-
- /* We only implement fattr_makenode() for dirs for now. */
- if (fa->mask & FA_MODE)
- mode = fa->mode & modemask;
- else
- mode = 0700;
-
- if (fa->type == FT_DIRECTORY)
- error = mkdir(path, mode);
- else if (fa->type == FT_SYMLINK) {
- error = symlink(fa->linktarget, path);
- } else if (fa->type == FT_CDEV) {
- lprintf(-1, "Character devices not supported!\n");
- } else if (fa->type == FT_BDEV) {
- lprintf(-1, "Block devices not supported!\n");
- }
- return (error);
-}
-
-int
-fattr_delete(const char *path)
-{
- struct fattr *fa;
- int error;
-
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- if (fa == NULL) {
- if (errno == ENOENT)
- return (0);
- return (-1);
- }
-
-#ifdef HAVE_FFLAGS
- /* Clear flags. */
- if (fa->mask & FA_FLAGS && fa->flags != 0) {
- fa->flags = 0;
- (void)chflags(path, fa->flags);
- }
-#endif
-
- if (fa->type == FT_DIRECTORY)
- error = rmdir(path);
- else
- error = unlink(path);
- fattr_free(fa);
- return (error);
-}
-
-/*
- * Changes those attributes we can change. Returns -1 on error,
- * 0 if no update was needed, and 1 if an update was needed and
- * it has been applied successfully.
- */
-int
-fattr_install(struct fattr *fa, const char *topath, const char *frompath)
-{
- struct timeval tv[2];
- struct fattr *old;
- int error, inplace, mask;
- mode_t modemask, newmode;
- uid_t uid;
- gid_t gid;
-
- mask = fa->mask & fattr_supported(fa->type);
- if (mask & FA_OWNER && mask & FA_GROUP)
- modemask = FA_SETIDMASK | FA_PERMMASK;
- else
- modemask = FA_PERMMASK;
-
- inplace = 0;
- if (frompath == NULL) {
- /* Changing attributes in place. */
- frompath = topath;
- inplace = 1;
- }
- old = fattr_frompath(topath, FATTR_NOFOLLOW);
- if (old != NULL) {
- if (inplace && fattr_equal(fa, old)) {
- fattr_free(old);
- return (0);
- }
-
-#ifdef HAVE_FFLAGS
- /*
- * Determine whether we need to clear the flags of the target.
- * This is bogus in that it assumes a value of 0 is safe and
- * that non-zero is unsafe. I'm not really worried by that
- * since as far as I know that's the way things are.
- */
- if ((old->mask & FA_FLAGS) && old->flags > 0) {
- (void)chflags(topath, 0);
- old->flags = 0;
- }
-#endif
-
- /*
- * If it is changed from a file to a symlink, remove the file
- * and create the symlink.
- */
- if (inplace && (fa->type == FT_SYMLINK) &&
- (old->type == FT_FILE)) {
- error = unlink(topath);
- if (error)
- goto bad;
- error = symlink(fa->linktarget, topath);
- if (error)
- goto bad;
- }
- /* Determine whether we need to remove the target first. */
- if (!inplace && (fa->type == FT_DIRECTORY) !=
- (old->type == FT_DIRECTORY)) {
- if (old->type == FT_DIRECTORY)
- error = rmdir(topath);
- else
- error = unlink(topath);
- if (error)
- goto bad;
- }
- }
-
- /* Change those attributes that we can before moving the file
- * into place. That makes installation atomic in most cases. */
- if (mask & FA_MODTIME) {
- gettimeofday(tv, NULL); /* Access time. */
- tv[1].tv_sec = fa->modtime; /* Modification time. */
- tv[1].tv_usec = 0;
- error = utimes(frompath, tv);
- if (error)
- goto bad;
- }
- if (mask & FA_OWNER || mask & FA_GROUP) {
- uid = -1;
- gid = -1;
- if (mask & FA_OWNER)
- uid = fa->uid;
- if (mask & FA_GROUP)
- gid = fa->gid;
- error = chown(frompath, uid, gid);
- if (error) {
- goto bad;
- }
- }
- if (mask & FA_MODE) {
- newmode = fa->mode & modemask;
- /* Merge in set*id bits from the old attribute. */
- if (old != NULL && old->mask & FA_MODE) {
- newmode |= (old->mode & ~modemask);
- newmode &= (FA_SETIDMASK | FA_PERMMASK);
- }
- error = chmod(frompath, newmode);
- if (error)
- goto bad;
- }
-
- if (!inplace) {
- error = rename(frompath, topath);
- if (error)
- goto bad;
- }
-
-#ifdef HAVE_FFLAGS
- /* Set the flags. */
- if (mask & FA_FLAGS)
- (void)chflags(topath, fa->flags);
-#endif
- fattr_free(old);
- return (1);
-bad:
- fattr_free(old);
- return (-1);
-}
-
-/*
- * Returns 1 if both attributes are equal, 0 otherwise.
- *
- * This function only compares attributes that are valid in both
- * files. A file of unknown type ("FT_UNKNOWN") is unequal to
- * anything, including itself.
- */
-int
-fattr_equal(const struct fattr *fa1, const struct fattr *fa2)
-{
- int mask;
-
- mask = fa1->mask & fa2->mask;
- if (fa1->type == FT_UNKNOWN || fa2->type == FT_UNKNOWN)
- return (0);
- if (mask & FA_FILETYPE)
- if (fa1->type != fa2->type)
- return (0);
- if (mask & FA_MODTIME)
- if (fa1->modtime != fa2->modtime)
- return (0);
- if (mask & FA_SIZE)
- if (fa1->size != fa2->size)
- return (0);
- if (mask & FA_LINKTARGET)
- if (strcmp(fa1->linktarget, fa2->linktarget) != 0)
- return (0);
- if (mask & FA_RDEV)
- if (fa1->rdev != fa2->rdev)
- return (0);
- if (mask & FA_OWNER)
- if (fa1->uid != fa2->uid)
- return (0);
- if (mask & FA_GROUP)
- if (fa1->gid != fa2->gid)
- return (0);
- if (mask & FA_MODE)
- if (fa1->mode != fa2->mode)
- return (0);
- if (mask & FA_FLAGS)
- if (fa1->flags != fa2->flags)
- return (0);
- if (mask & FA_LINKCOUNT)
- if (fa1->linkcount != fa2->linkcount)
- return (0);
- if (mask & FA_DEV)
- if (fa1->dev != fa2->dev)
- return (0);
- if (mask & FA_INODE)
- if (fa1->inode != fa2->inode)
- return (0);
- return (1);
-}
-
-/*
- * Must have to get the correct filesize sendt by the server.
- */
-off_t
-fattr_filesize(const struct fattr *fa)
-{
- return (fa->size);
-}
diff --git a/contrib/csup/fattr.h b/contrib/csup/fattr.h
deleted file mode 100644
index bd4e649..0000000
--- a/contrib/csup/fattr.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _FATTR_H_
-#define _FATTR_H_
-
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <time.h>
-
-/*
- * File types.
- */
-#define FT_UNKNOWN 0 /* Unknown file type. */
-#define FT_FILE 1 /* Regular file. */
-#define FT_DIRECTORY 2 /* Directory. */
-#define FT_CDEV 3 /* Character device. */
-#define FT_BDEV 4 /* Block device. */
-#define FT_SYMLINK 5 /* Symbolic link. */
-#define FT_MAX FT_SYMLINK /* Maximum file type number. */
-#define FT_NUMBER (FT_MAX + 1) /* Number of file types. */
-
-/*
- * File attributes.
- */
-#define FA_FILETYPE 0x0001 /* True for all supported file types. */
-#define FA_MODTIME 0x0002 /* Last file modification time. */
-#define FA_SIZE 0x0004 /* Size of the file. */
-#define FA_LINKTARGET 0x0008 /* Target of a symbolic link. */
-#define FA_RDEV 0x0010 /* Device for a device node. */
-#define FA_OWNER 0x0020 /* Owner of the file. */
-#define FA_GROUP 0x0040 /* Group of the file. */
-#define FA_MODE 0x0080 /* File permissions. */
-#define FA_FLAGS 0x0100 /* 4.4BSD flags, a la chflags(2). */
-#define FA_LINKCOUNT 0x0200 /* Hard link count. */
-#define FA_DEV 0x0400 /* Device holding the inode. */
-#define FA_INODE 0x0800 /* Inode number. */
-
-#define FA_MASK 0x0fff
-
-#define FA_NUMBER 12 /* Number of file attributes. */
-
-/* Attributes that we might be able to change. */
-#define FA_CHANGEABLE (FA_MODTIME | FA_OWNER | FA_GROUP | FA_MODE | FA_FLAGS)
-
-/*
- * Attributes that we don't want to save in the "checkouts" file
- * when in checkout mode.
- */
-#define FA_COIGNORE (FA_MASK & ~(FA_FILETYPE|FA_MODTIME|FA_SIZE|FA_MODE))
-
-/* These are for fattr_frompath(). */
-#define FATTR_FOLLOW 0
-#define FATTR_NOFOLLOW 1
-
-struct stat;
-struct fattr;
-
-typedef int fattr_support_t[FT_NUMBER];
-
-extern const struct fattr *fattr_bogus;
-
-void fattr_init(void);
-void fattr_fini(void);
-
-struct fattr *fattr_new(int, time_t);
-struct fattr *fattr_default(int);
-struct fattr *fattr_fromstat(struct stat *);
-struct fattr *fattr_frompath(const char *, int);
-struct fattr *fattr_fromfd(int);
-struct fattr *fattr_decode(char *);
-struct fattr *fattr_forcheckout(const struct fattr *, mode_t);
-struct fattr *fattr_dup(const struct fattr *);
-char *fattr_encode(const struct fattr *, fattr_support_t, int);
-int fattr_type(const struct fattr *);
-void fattr_maskout(struct fattr *, int);
-int fattr_getmask(const struct fattr *);
-nlink_t fattr_getlinkcount(const struct fattr *);
-char *fattr_getlinktarget(const struct fattr *);
-void fattr_umask(struct fattr *, mode_t);
-void fattr_merge(struct fattr *, const struct fattr *);
-void fattr_mergedefault(struct fattr *);
-void fattr_override(struct fattr *, const struct fattr *, int);
-int fattr_makenode(const struct fattr *, const char *);
-int fattr_delete(const char *path);
-int fattr_install(struct fattr *, const char *, const char *);
-int fattr_equal(const struct fattr *, const struct fattr *);
-void fattr_free(struct fattr *);
-int fattr_supported(int);
-off_t fattr_filesize(const struct fattr *);
-
-
-#endif /* !_FATTR_H_ */
diff --git a/contrib/csup/fattr_bsd.h b/contrib/csup/fattr_bsd.h
deleted file mode 100644
index 112a824..0000000
--- a/contrib/csup/fattr_bsd.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-/*
- * The file attributes we support in a BSD environment.
- *
- * This is similar to fattr_posix.h, except that we support the FA_FLAGS
- * attribute when it makes sense. The FA_FLAGS attribute is for the
- * extended BSD file flags, see chflags(2).
- */
-fattr_support_t fattr_support = {
- /* FT_UNKNOWN */
- 0,
- /* FT_FILE */
- FA_FILETYPE | FA_MODTIME | FA_SIZE | FA_OWNER | FA_GROUP | FA_MODE |
- FA_FLAGS | FA_LINKCOUNT | FA_INODE | FA_DEV,
- /* FT_DIRECTORY */
- FA_FILETYPE | FA_OWNER | FA_GROUP | FA_MODE | FA_FLAGS,
- /* FT_CDEV */
- FA_FILETYPE | FA_RDEV | FA_OWNER | FA_GROUP | FA_MODE | FA_FLAGS |
- FA_LINKCOUNT | FA_DEV | FA_INODE,
- /* FT_BDEV */
- FA_FILETYPE | FA_RDEV | FA_OWNER | FA_GROUP | FA_MODE | FA_FLAGS |
- FA_LINKCOUNT | FA_DEV | FA_INODE,
- /* FT_SYMLINK */
- FA_FILETYPE | FA_LINKTARGET
-};
diff --git a/contrib/csup/fattr_posix.h b/contrib/csup/fattr_posix.h
deleted file mode 100644
index c4650e4..0000000
--- a/contrib/csup/fattr_posix.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-/*
- * The file attributes we support in a POSIX environment.
- */
-fattr_support_t fattr_support = {
- /* FT_UNKNOWN */
- 0,
- /* FT_FILE */
- FA_FILETYPE | FA_MODTIME | FA_SIZE | FA_OWNER | FA_GROUP | FA_MODE |
- FA_LINKCOUNT | FA_INODE | FA_DEV,
- /* FT_DIRECTORY */
- FA_FILETYPE | FA_OWNER | FA_GROUP | FA_MODE,
- /* FT_CDEV */
- FA_FILETYPE | FA_RDEV | FA_OWNER | FA_GROUP | FA_MODE | FA_LINKCOUNT |
- FA_DEV | FA_INODE,
- /* FT_BDEV */
- FA_FILETYPE | FA_RDEV | FA_OWNER | FA_GROUP | FA_MODE | FA_LINKCOUNT |
- FA_DEV | FA_INODE,
- /* FT_SYMLINK */
- FA_FILETYPE | FA_LINKTARGET
-};
diff --git a/contrib/csup/fixups.c b/contrib/csup/fixups.c
deleted file mode 100644
index b105a8f..0000000
--- a/contrib/csup/fixups.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "fixups.h"
-#include "misc.h"
-#include "queue.h"
-
-/*
- * A synchronized queue to implement fixups. The updater thread adds
- * fixup requests to the queue with fixups_put() when a checksum
- * mismatch error occured. It then calls fixups_close() when he's
- * done requesting fixups. The detailer thread gets the fixups with
- * fixups_get() and then send the requests to the server.
- *
- * The queue is synchronized with a mutex and a condition variable.
- */
-
-struct fixups {
- pthread_mutex_t lock;
- pthread_cond_t cond;
- STAILQ_HEAD(, fixup) fixupq;
- struct fixup *cur;
- size_t size;
- int closed;
-};
-
-static void fixups_lock(struct fixups *);
-static void fixups_unlock(struct fixups *);
-
-static struct fixup *fixup_new(struct coll *, const char *);
-static void fixup_free(struct fixup *);
-
-static void
-fixups_lock(struct fixups *f)
-{
- int error;
-
- error = pthread_mutex_lock(&f->lock);
- assert(!error);
-}
-
-static void
-fixups_unlock(struct fixups *f)
-{
- int error;
-
- error = pthread_mutex_unlock(&f->lock);
- assert(!error);
-}
-
-static struct fixup *
-fixup_new(struct coll *coll, const char *name)
-{
- struct fixup *fixup;
-
- fixup = xmalloc(sizeof(struct fixup));
- fixup->f_name = xstrdup(name);
- fixup->f_coll = coll;
- return (fixup);
-}
-
-static void
-fixup_free(struct fixup *fixup)
-{
-
- free(fixup->f_name);
- free(fixup);
-}
-
-/* Create a new fixup queue. */
-struct fixups *
-fixups_new(void)
-{
- struct fixups *f;
-
- f = xmalloc(sizeof(struct fixups));
- f->size = 0;
- f->closed = 0;
- f->cur = NULL;
- STAILQ_INIT(&f->fixupq);
- pthread_mutex_init(&f->lock, NULL);
- pthread_cond_init(&f->cond, NULL);
- return (f);
-}
-
-/* Add a fixup request to the queue. */
-void
-fixups_put(struct fixups *f, struct coll *coll, const char *name)
-{
- struct fixup *fixup;
- int dosignal;
-
- dosignal = 0;
- fixup = fixup_new(coll, name);
- fixups_lock(f);
- assert(!f->closed);
- STAILQ_INSERT_TAIL(&f->fixupq, fixup, f_link);
- if (f->size++ == 0)
- dosignal = 1;
- fixups_unlock(f);
- if (dosignal)
- pthread_cond_signal(&f->cond);
-}
-
-/* Get a fixup request from the queue. */
-struct fixup *
-fixups_get(struct fixups *f)
-{
- struct fixup *fixup, *tofree;
-
- fixups_lock(f);
- while (f->size == 0 && !f->closed)
- pthread_cond_wait(&f->cond, &f->lock);
- if (f->closed) {
- fixups_unlock(f);
- return (NULL);
- }
- assert(f->size > 0);
- fixup = STAILQ_FIRST(&f->fixupq);
- tofree = f->cur;
- f->cur = fixup;
- STAILQ_REMOVE_HEAD(&f->fixupq, f_link);
- f->size--;
- fixups_unlock(f);
- if (tofree != NULL)
- fixup_free(tofree);
- return (fixup);
-}
-
-/* Close the writing end of the queue. */
-void
-fixups_close(struct fixups *f)
-{
- int dosignal;
-
- dosignal = 0;
- fixups_lock(f);
- if (f->size == 0 && !f->closed)
- dosignal = 1;
- f->closed = 1;
- fixups_unlock(f);
- if (dosignal)
- pthread_cond_signal(&f->cond);
-}
-
-/* Free a fixups queue. */
-void
-fixups_free(struct fixups *f)
-{
- struct fixup *fixup, *fixup2;
-
- assert(f->closed);
- /*
- * Free any fixup that has been left on the queue.
- * This can happen if we have been aborted prematurely.
- */
- fixup = STAILQ_FIRST(&f->fixupq);
- while (fixup != NULL) {
- fixup2 = STAILQ_NEXT(fixup, f_link);
- fixup_free(fixup);
- fixup = fixup2;
- }
- if (f->cur != NULL)
- fixup_free(f->cur);
- pthread_cond_destroy(&f->cond);
- pthread_mutex_destroy(&f->lock);
- free(f);
-}
diff --git a/contrib/csup/fixups.h b/contrib/csup/fixups.h
deleted file mode 100644
index 0dddc90..0000000
--- a/contrib/csup/fixups.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _FIXUPS_H_
-#define _FIXUPS_H_
-
-#include "queue.h"
-
-struct coll;
-struct fixups;
-
-struct fixup {
- struct coll *f_coll;
- char *f_name;
- STAILQ_ENTRY(fixup) f_link; /* Not for consumers. */
-};
-
-struct fixups *fixups_new(void);
-void fixups_put(struct fixups *, struct coll *, const char *);
-struct fixup *fixups_get(struct fixups *);
-void fixups_close(struct fixups *);
-void fixups_free(struct fixups *);
-
-#endif /* !_FIXUPS_H_ */
diff --git a/contrib/csup/fnmatch.c b/contrib/csup/fnmatch.c
deleted file mode 100644
index a63f016..0000000
--- a/contrib/csup/fnmatch.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 1989, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Guido van Rossum.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * From FreeBSD fnmatch.c 1.11
- * $Id: fnmatch.c,v 1.3 1997/08/19 02:34:30 jdp Exp $
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
-#endif /* LIBC_SCCS and not lint */
-
-/*
- * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
- * Compares a filename or pathname to a pattern.
- */
-
-#include <ctype.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "fnmatch.h"
-
-#define EOS '\0'
-
-static const char *rangematch(const char *, char, int);
-
-int
-fnmatch(const char *pattern, const char *string, int flags)
-{
- const char *stringstart;
- char c, test;
-
- for (stringstart = string;;)
- switch (c = *pattern++) {
- case EOS:
- if ((flags & FNM_LEADING_DIR) && *string == '/')
- return (0);
- return (*string == EOS ? 0 : FNM_NOMATCH);
- case '?':
- if (*string == EOS)
- return (FNM_NOMATCH);
- if (*string == '/' && (flags & FNM_PATHNAME))
- return (FNM_NOMATCH);
- if (*string == '.' && (flags & FNM_PERIOD) &&
- (string == stringstart ||
- ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
- return (FNM_NOMATCH);
- ++string;
- break;
- case '*':
- c = *pattern;
- /* Collapse multiple stars. */
- while (c == '*')
- c = *++pattern;
-
- if (*string == '.' && (flags & FNM_PERIOD) &&
- (string == stringstart ||
- ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
- return (FNM_NOMATCH);
-
- /* Optimize for pattern with * at end or before /. */
- if (c == EOS)
- if (flags & FNM_PATHNAME)
- return ((flags & FNM_LEADING_DIR) ||
- strchr(string, '/') == NULL ?
- 0 : FNM_NOMATCH);
- else
- return (0);
- else if (c == '/' && flags & FNM_PATHNAME) {
- if ((string = strchr(string, '/')) == NULL)
- return (FNM_NOMATCH);
- break;
- }
-
- /* General case, use recursion. */
- while ((test = *string) != EOS) {
- if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
- return (0);
- if (test == '/' && flags & FNM_PATHNAME)
- break;
- ++string;
- }
- return (FNM_NOMATCH);
- case '[':
- if (*string == EOS)
- return (FNM_NOMATCH);
- if (*string == '/' && flags & FNM_PATHNAME)
- return (FNM_NOMATCH);
- if ((pattern =
- rangematch(pattern, *string, flags)) == NULL)
- return (FNM_NOMATCH);
- ++string;
- break;
- case '\\':
- if (!(flags & FNM_NOESCAPE)) {
- if ((c = *pattern++) == EOS) {
- c = '\\';
- --pattern;
- }
- }
- /* FALLTHROUGH */
- default:
- if (c == *string)
- ;
- else if ((flags & FNM_CASEFOLD) &&
- (tolower((unsigned char)c) ==
- tolower((unsigned char)*string)))
- ;
- else if ((flags & FNM_PREFIX_DIRS) && *string == EOS &&
- ((c == '/' && string != stringstart) ||
- (string == stringstart+1 && *stringstart == '/')))
- return (0);
- else
- return (FNM_NOMATCH);
- string++;
- break;
- }
- /* NOTREACHED */
-}
-
-static const char *
-rangematch(const char *pattern, char test, int flags)
-{
- int negate, ok;
- char c, c2;
-
- /*
- * A bracket expression starting with an unquoted circumflex
- * character produces unspecified results (IEEE 1003.2-1992,
- * 3.13.2). This implementation treats it like '!', for
- * consistency with the regular expression syntax.
- * J.T. Conklin (conklin@ngai.kaleida.com)
- */
- if ( (negate = (*pattern == '!' || *pattern == '^')) )
- ++pattern;
-
- if (flags & FNM_CASEFOLD)
- test = tolower((unsigned char)test);
-
- for (ok = 0; (c = *pattern++) != ']';) {
- if (c == '\\' && !(flags & FNM_NOESCAPE))
- c = *pattern++;
- if (c == EOS)
- return (NULL);
-
- if (flags & FNM_CASEFOLD)
- c = tolower((unsigned char)c);
-
- if (*pattern == '-'
- && (c2 = *(pattern+1)) != EOS && c2 != ']') {
- pattern += 2;
- if (c2 == '\\' && !(flags & FNM_NOESCAPE))
- c2 = *pattern++;
- if (c2 == EOS)
- return (NULL);
-
- if (flags & FNM_CASEFOLD)
- c2 = tolower((unsigned char)c2);
-
- if ((unsigned char)c <= (unsigned char)test &&
- (unsigned char)test <= (unsigned char)c2)
- ok = 1;
- } else if (c == test)
- ok = 1;
- }
- return (ok == negate ? NULL : pattern);
-}
diff --git a/contrib/csup/fnmatch.h b/contrib/csup/fnmatch.h
deleted file mode 100644
index 21d2f64..0000000
--- a/contrib/csup/fnmatch.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
- *
- * From FreeBSD fnmatch.h 1.7
- * $Id: fnmatch.h,v 1.4 2001/10/04 02:46:21 jdp Exp $
- */
-
-#ifndef _FNMATCH_H_
-#define _FNMATCH_H_
-
-#define FNM_NOMATCH 1 /* Match failed. */
-
-#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
-#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
-#define FNM_PERIOD 0x04 /* Period must be matched by period. */
-#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
-#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
-#define FNM_PREFIX_DIRS 0x20 /* Directory prefixes of pattern match too. */
-
-/* Make this compile successfully with "gcc -traditional" */
-#ifndef __STDC__
-#define const /* empty */
-#endif
-
-int fnmatch(const char *, const char *, int);
-
-#endif /* !_FNMATCH_H_ */
diff --git a/contrib/csup/globtree.c b/contrib/csup/globtree.c
deleted file mode 100644
index 74ac2c1..0000000
--- a/contrib/csup/globtree.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <regex.h>
-#include <stdlib.h>
-
-#include "fnmatch.h"
-#include "globtree.h"
-#include "misc.h"
-
-/*
- * The "GlobTree" interface allows one to construct arbitrarily complex
- * boolean expressions for evaluating whether to accept or reject a
- * filename. The globtree_test() function returns true or false
- * according to whether the name is accepted or rejected by the
- * expression.
- *
- * Expressions are trees constructed from nodes representing either
- * primitive matching operations (primaries) or operators that are
- * applied to their subexpressions. The simplest primitives are
- * globtree_false(), which matches nothing, and globtree_true(), which
- * matches everything.
- *
- * A more useful primitive is the matching operation, constructed with
- * globtree_match(). It will call fnmatch() with the suppliedi
- * shell-style pattern to determine if the filename matches.
- *
- * Expressions can be combined with the boolean operators AND, OR, and
- * NOT, to form more complex expressions.
- */
-
-/* Node types. */
-#define GLOBTREE_NOT 0
-#define GLOBTREE_AND 1
-#define GLOBTREE_OR 2
-#define GLOBTREE_MATCH 3
-#define GLOBTREE_REGEX 4
-#define GLOBTREE_TRUE 5
-#define GLOBTREE_FALSE 6
-
-/* A node. */
-struct globtree {
- int type;
- struct globtree *left;
- struct globtree *right;
-
- /* The "data" field points to the text pattern for GLOBTREE_MATCH
- nodes, and to the regex_t for GLOBTREE_REGEX nodes. For any
- other node, it is set to NULL. */
- void *data;
- /* The "flags" field contains the flags to pass to fnmatch() for
- GLOBTREE_MATCH nodes. */
- int flags;
-};
-
-static struct globtree *globtree_new(int);
-static int globtree_eval(struct globtree *, const char *);
-
-static struct globtree *
-globtree_new(int type)
-{
- struct globtree *gt;
-
- gt = xmalloc(sizeof(struct globtree));
- gt->type = type;
- gt->data = NULL;
- gt->flags = 0;
- gt->left = NULL;
- gt->right = NULL;
- return (gt);
-}
-
-struct globtree *
-globtree_true(void)
-{
- struct globtree *gt;
-
- gt = globtree_new(GLOBTREE_TRUE);
- return (gt);
-}
-
-struct globtree *
-globtree_false(void)
-{
- struct globtree *gt;
-
- gt = globtree_new(GLOBTREE_FALSE);
- return (gt);
-}
-
-struct globtree *
-globtree_match(const char *pattern, int flags)
-{
- struct globtree *gt;
-
- gt = globtree_new(GLOBTREE_MATCH);
- gt->data = xstrdup(pattern);
- gt->flags = flags;
- return (gt);
-}
-
-struct globtree *
-globtree_regex(const char *pattern)
-{
- struct globtree *gt;
- int error;
-
- gt = globtree_new(GLOBTREE_REGEX);
- gt->data = xmalloc(sizeof(regex_t));
- error = regcomp(gt->data, pattern, REG_NOSUB);
- assert(!error);
- return (gt);
-}
-
-struct globtree *
-globtree_and(struct globtree *left, struct globtree *right)
-{
- struct globtree *gt;
-
- if (left->type == GLOBTREE_FALSE || right->type == GLOBTREE_FALSE) {
- globtree_free(left);
- globtree_free(right);
- gt = globtree_false();
- return (gt);
- }
- if (left->type == GLOBTREE_TRUE) {
- globtree_free(left);
- return (right);
- }
- if (right->type == GLOBTREE_TRUE) {
- globtree_free(right);
- return (left);
- }
- gt = globtree_new(GLOBTREE_AND);
- gt->left = left;
- gt->right = right;
- return (gt);
-}
-
-struct globtree *
-globtree_or(struct globtree *left, struct globtree *right)
-{
- struct globtree *gt;
-
- if (left->type == GLOBTREE_TRUE || right->type == GLOBTREE_TRUE) {
- globtree_free(left);
- globtree_free(right);
- gt = globtree_true();
- return (gt);
- }
- if (left->type == GLOBTREE_FALSE) {
- globtree_free(left);
- return (right);
- }
- if (right->type == GLOBTREE_FALSE) {
- globtree_free(right);
- return (left);
- }
- gt = globtree_new(GLOBTREE_OR);
- gt->left = left;
- gt->right = right;
- return (gt);
-}
-
-struct globtree *
-globtree_not(struct globtree *child)
-{
- struct globtree *gt;
-
- if (child->type == GLOBTREE_TRUE) {
- globtree_free(child);
- gt = globtree_new(GLOBTREE_FALSE);
- return (gt);
- }
- if (child->type == GLOBTREE_FALSE) {
- globtree_free(child);
- gt = globtree_new(GLOBTREE_TRUE);
- return (gt);
- }
- gt = globtree_new(GLOBTREE_NOT);
- gt->left = child;
- return (gt);
-}
-
-/* Evaluate one node (must be a leaf node). */
-static int
-globtree_eval(struct globtree *gt, const char *path)
-{
- int rv;
-
- switch (gt->type) {
- case GLOBTREE_TRUE:
- return (1);
- case GLOBTREE_FALSE:
- return (0);
- case GLOBTREE_MATCH:
- assert(gt->data != NULL);
- rv = fnmatch(gt->data, path, gt->flags);
- if (rv == 0)
- return (1);
- assert(rv == FNM_NOMATCH);
- return (0);
- case GLOBTREE_REGEX:
- assert(gt->data != NULL);
- rv = regexec(gt->data, path, 0, NULL, 0);
- if (rv == 0)
- return (1);
- assert(rv == REG_NOMATCH);
- return (0);
- }
-
- assert(0);
- return (-1);
-}
-
-/* Small stack API to walk the tree iteratively. */
-typedef enum {
- STATE_DOINGLEFT,
- STATE_DOINGRIGHT
-} walkstate_t;
-
-struct stack {
- struct stackelem *stack;
- size_t size;
- size_t in;
-};
-
-struct stackelem {
- struct globtree *node;
- walkstate_t state;
-};
-
-static void
-stack_init(struct stack *stack)
-{
-
- stack->in = 0;
- stack->size = 8; /* Initial size. */
- stack->stack = xmalloc(sizeof(struct stackelem) * stack->size);
-}
-
-static size_t
-stack_size(struct stack *stack)
-{
-
- return (stack->in);
-}
-
-static void
-stack_push(struct stack *stack, struct globtree *node, walkstate_t state)
-{
- struct stackelem *e;
-
- if (stack->in == stack->size) {
- stack->size *= 2;
- stack->stack = xrealloc(stack->stack,
- sizeof(struct stackelem) * stack->size);
- }
- e = stack->stack + stack->in++;
- e->node = node;
- e->state = state;
-}
-
-static void
-stack_pop(struct stack *stack, struct globtree **node, walkstate_t *state)
-{
- struct stackelem *e;
-
- assert(stack->in > 0);
- e = stack->stack + --stack->in;
- *node = e->node;
- *state = e->state;
-}
-
-static void
-stack_free(struct stack *s)
-{
-
- free(s->stack);
-}
-
-/* Tests if the supplied filename matches. */
-int
-globtree_test(struct globtree *gt, const char *path)
-{
- struct stack stack;
- walkstate_t state;
- int val;
-
- stack_init(&stack);
- for (;;) {
-doleft:
- /* Descend to the left until we hit bottom. */
- while (gt->left != NULL) {
- stack_push(&stack, gt, STATE_DOINGLEFT);
- gt = gt->left;
- }
-
- /* Now we're at a leaf node. Evaluate it. */
- val = globtree_eval(gt, path);
- /* Ascend, propagating the value through operator nodes. */
- for (;;) {
- if (stack_size(&stack) == 0) {
- stack_free(&stack);
- return (val);
- }
- stack_pop(&stack, &gt, &state);
- switch (gt->type) {
- case GLOBTREE_NOT:
- val = !val;
- break;
- case GLOBTREE_AND:
- /* If we haven't yet evaluated the right subtree
- and the partial result is true, descend to
- the right. Otherwise the result is already
- determined to be val. */
- if (state == STATE_DOINGLEFT && val) {
- stack_push(&stack, gt,
- STATE_DOINGRIGHT);
- gt = gt->right;
- goto doleft;
- }
- break;
- case GLOBTREE_OR:
- /* If we haven't yet evaluated the right subtree
- and the partial result is false, descend to
- the right. Otherwise the result is already
- determined to be val. */
- if (state == STATE_DOINGLEFT && !val) {
- stack_push(&stack, gt,
- STATE_DOINGRIGHT);
- gt = gt->right;
- goto doleft;
- }
- break;
- default:
- /* We only push nodes that have children. */
- assert(0);
- return (-1);
- }
- }
- }
-}
-
-/*
- * We could de-recursify this function using a stack, but it would be
- * overkill since it is never called from a thread context with a
- * limited stack size nor used in a critical path, so I think we can
- * afford keeping it recursive.
- */
-void
-globtree_free(struct globtree *gt)
-{
-
- if (gt->data != NULL) {
- if (gt->type == GLOBTREE_REGEX)
- regfree(gt->data);
- free(gt->data);
- }
- if (gt->left != NULL)
- globtree_free(gt->left);
- if (gt->right != NULL)
- globtree_free(gt->right);
- free(gt);
-}
diff --git a/contrib/csup/globtree.h b/contrib/csup/globtree.h
deleted file mode 100644
index 43882e3..0000000
--- a/contrib/csup/globtree.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _GLOBTREE_H_
-#define _GLOBTREE_H_
-
-#include "fnmatch.h"
-
-struct globtree;
-
-struct globtree *globtree_true(void);
-struct globtree *globtree_false(void);
-struct globtree *globtree_match(const char *, int);
-struct globtree *globtree_regex(const char *);
-struct globtree *globtree_and(struct globtree *, struct globtree *);
-struct globtree *globtree_or(struct globtree *, struct globtree *);
-struct globtree *globtree_not(struct globtree *);
-int globtree_test(struct globtree *, const char *);
-void globtree_free(struct globtree *);
-
-#endif /* !_GLOBTREE_H_ */
diff --git a/contrib/csup/idcache.c b/contrib/csup/idcache.c
deleted file mode 100644
index 47a3e71..0000000
--- a/contrib/csup/idcache.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <grp.h>
-#include <pthread.h>
-#include <pwd.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "idcache.h"
-#include "misc.h"
-
-/*
- * Constants and data structures used to implement the thread-safe
- * group and password file caches. Cache sizes must be prime.
- */
-#define UIDTONAME_SZ 317 /* Size of uid -> user name cache */
-#define NAMETOUID_SZ 317 /* Size of user name -> uid cache */
-#define GIDTONAME_SZ 317 /* Size of gid -> group name cache */
-#define NAMETOGID_SZ 317 /* Size of group name -> gid cache */
-
-/* Node structures used to cache lookups. */
-struct uidc {
- char *name; /* user name */
- uid_t uid; /* cached uid */
- int valid; /* is this a valid or a miss entry */
- struct uidc *next; /* for collisions */
-};
-
-struct gidc {
- char *name; /* group name */
- gid_t gid; /* cached gid */
- int valid; /* is this a valid or a miss entry */
- struct gidc *next; /* for collisions */
-};
-
-static struct uidc **uidtoname; /* uid to user name cache */
-static struct gidc **gidtoname; /* gid to group name cache */
-static struct uidc **nametouid; /* user name to uid cache */
-static struct gidc **nametogid; /* group name to gid cache */
-
-static pthread_mutex_t uid_mtx;
-static pthread_mutex_t gid_mtx;
-
-static void uid_lock(void);
-static void uid_unlock(void);
-static void gid_lock(void);
-static void gid_unlock(void);
-
-static uint32_t hash(const char *);
-
-/* A 32-bit version of Peter Weinberger's (PJW) hash algorithm,
- as used by ELF for hashing function names. */
-static uint32_t
-hash(const char *name)
-{
- uint32_t g, h;
-
- h = 0;
- while(*name != '\0') {
- h = (h << 4) + *name++;
- if ((g = h & 0xF0000000)) {
- h ^= g >> 24;
- h &= 0x0FFFFFFF;
- }
- }
- return (h);
-}
-
-static void
-uid_lock(void)
-{
- int error;
-
- error = pthread_mutex_lock(&uid_mtx);
- assert(!error);
-}
-
-static void
-uid_unlock(void)
-{
- int error;
-
- error = pthread_mutex_unlock(&uid_mtx);
- assert(!error);
-}
-
-static void
-gid_lock(void)
-{
- int error;
-
- error = pthread_mutex_lock(&gid_mtx);
- assert(!error);
-}
-
-static void
-gid_unlock(void)
-{
- int error;
-
- error = pthread_mutex_unlock(&gid_mtx);
- assert(!error);
-}
-
-static void
-uidc_insert(struct uidc **tbl, struct uidc *uidc, uint32_t key)
-{
-
- uidc->next = tbl[key];
- tbl[key] = uidc;
-}
-
-static void
-gidc_insert(struct gidc **tbl, struct gidc *gidc, uint32_t key)
-{
-
- gidc->next = tbl[key];
- tbl[key] = gidc;
-}
-
-/* Return the user name for this uid, or NULL if it's not found. */
-char *
-getuserbyid(uid_t uid)
-{
- struct passwd *pw;
- struct uidc *uidc, *uidc2;
- uint32_t key, key2;
-
- key = uid % UIDTONAME_SZ;
- uid_lock();
- uidc = uidtoname[key];
- while (uidc != NULL) {
- if (uidc->uid == uid)
- break;
- uidc = uidc->next;
- }
-
- if (uidc == NULL) {
- /* We didn't find this uid, look it up and add it. */
- uidc = xmalloc(sizeof(struct uidc));
- uidc->uid = uid;
- pw = getpwuid(uid);
- if (pw != NULL) {
- /* This uid is in the password file. */
- uidc->name = xstrdup(pw->pw_name);
- uidc->valid = 1;
- /* Also add it to the name -> gid table. */
- uidc2 = xmalloc(sizeof(struct uidc));
- uidc2->uid = uid;
- uidc2->name = uidc->name; /* We reuse the pointer. */
- uidc2->valid = 1;
- key2 = hash(uidc->name) % NAMETOUID_SZ;
- uidc_insert(nametouid, uidc2, key2);
- } else {
- /* Add a miss entry for this uid. */
- uidc->name = NULL;
- uidc->valid = 0;
- }
- uidc_insert(uidtoname, uidc, key);
- }
- /* It is safe to unlock here since the cache structure
- is not going to get freed or changed. */
- uid_unlock();
- return (uidc->name);
-}
-
-/* Return the group name for this gid, or NULL if it's not found. */
-char *
-getgroupbyid(gid_t gid)
-{
- struct group *gr;
- struct gidc *gidc, *gidc2;
- uint32_t key, key2;
-
- key = gid % GIDTONAME_SZ;
- gid_lock();
- gidc = gidtoname[key];
- while (gidc != NULL) {
- if (gidc->gid == gid)
- break;
- gidc = gidc->next;
- }
-
- if (gidc == NULL) {
- /* We didn't find this gid, look it up and add it. */
- gidc = xmalloc(sizeof(struct gidc));
- gidc->gid = gid;
- gr = getgrgid(gid);
- if (gr != NULL) {
- /* This gid is in the group file. */
- gidc->name = xstrdup(gr->gr_name);
- gidc->valid = 1;
- /* Also add it to the name -> gid table. */
- gidc2 = xmalloc(sizeof(struct gidc));
- gidc2->gid = gid;
- gidc2->name = gidc->name; /* We reuse the pointer. */
- gidc2->valid = 1;
- key2 = hash(gidc->name) % NAMETOGID_SZ;
- gidc_insert(nametogid, gidc2, key2);
- } else {
- /* Add a miss entry for this gid. */
- gidc->name = NULL;
- gidc->valid = 0;
- }
- gidc_insert(gidtoname, gidc, key);
- }
- /* It is safe to unlock here since the cache structure
- is not going to get freed or changed. */
- gid_unlock();
- return (gidc->name);
-}
-
-/* Finds the uid for this user name. If it's found, the gid is stored
- in *uid and 0 is returned. Otherwise, -1 is returned. */
-int
-getuidbyname(const char *name, uid_t *uid)
-{
- struct passwd *pw;
- struct uidc *uidc, *uidc2;
- uint32_t key, key2;
-
- uid_lock();
- key = hash(name) % NAMETOUID_SZ;
- uidc = nametouid[key];
- while (uidc != NULL) {
- if (strcmp(uidc->name, name) == 0)
- break;
- uidc = uidc->next;
- }
-
- if (uidc == NULL) {
- uidc = xmalloc(sizeof(struct uidc));
- uidc->name = xstrdup(name);
- pw = getpwnam(name);
- if (pw != NULL) {
- /* This user name is in the password file. */
- uidc->valid = 1;
- uidc->uid = pw->pw_uid;
- /* Also add it to the uid -> name table. */
- uidc2 = xmalloc(sizeof(struct uidc));
- uidc2->name = uidc->name; /* We reuse the pointer. */
- uidc2->uid = uidc->uid;
- uidc2->valid = 1;
- key2 = uidc2->uid % UIDTONAME_SZ;
- uidc_insert(uidtoname, uidc2, key2);
- } else {
- /* Add a miss entry for this user name. */
- uidc->valid = 0;
- uidc->uid = (uid_t)-1; /* Should not be accessed. */
- }
- uidc_insert(nametouid, uidc, key);
- }
- /* It is safe to unlock here since the cache structure
- is not going to get freed or changed. */
- uid_unlock();
- if (!uidc->valid)
- return (-1);
- *uid = uidc->uid;
- return (0);
-}
-
-/* Finds the gid for this group name. If it's found, the gid is stored
- in *gid and 0 is returned. Otherwise, -1 is returned. */
-int
-getgidbyname(const char *name, gid_t *gid)
-{
- struct group *gr;
- struct gidc *gidc, *gidc2;
- uint32_t key, key2;
-
- gid_lock();
- key = hash(name) % NAMETOGID_SZ;
- gidc = nametogid[key];
- while (gidc != NULL) {
- if (strcmp(gidc->name, name) == 0)
- break;
- gidc = gidc->next;
- }
-
- if (gidc == NULL) {
- gidc = xmalloc(sizeof(struct gidc));
- gidc->name = xstrdup(name);
- gr = getgrnam(name);
- if (gr != NULL) {
- /* This group name is in the group file. */
- gidc->gid = gr->gr_gid;
- gidc->valid = 1;
- /* Also add it to the gid -> name table. */
- gidc2 = xmalloc(sizeof(struct gidc));
- gidc2->name = gidc->name; /* We reuse the pointer. */
- gidc2->gid = gidc->gid;
- gidc2->valid = 1;
- key2 = gidc2->gid % GIDTONAME_SZ;
- gidc_insert(gidtoname, gidc2, key2);
- } else {
- /* Add a miss entry for this group name. */
- gidc->gid = (gid_t)-1; /* Should not be accessed. */
- gidc->valid = 0;
- }
- gidc_insert(nametogid, gidc, key);
- }
- /* It is safe to unlock here since the cache structure
- is not going to get freed or changed. */
- gid_unlock();
- if (!gidc->valid)
- return (-1);
- *gid = gidc->gid;
- return (0);
-}
-
-/* Initialize the cache structures. */
-void
-idcache_init(void)
-{
-
- pthread_mutex_init(&uid_mtx, NULL);
- pthread_mutex_init(&gid_mtx, NULL);
- uidtoname = xmalloc(UIDTONAME_SZ * sizeof(struct uidc *));
- gidtoname = xmalloc(GIDTONAME_SZ * sizeof(struct gidc *));
- nametouid = xmalloc(NAMETOUID_SZ * sizeof(struct uidc *));
- nametogid = xmalloc(NAMETOGID_SZ * sizeof(struct gidc *));
- memset(uidtoname, 0, UIDTONAME_SZ * sizeof(struct uidc *));
- memset(gidtoname, 0, GIDTONAME_SZ * sizeof(struct gidc *));
- memset(nametouid, 0, NAMETOUID_SZ * sizeof(struct uidc *));
- memset(nametogid, 0, NAMETOGID_SZ * sizeof(struct gidc *));
-}
-
-/* Cleanup the cache structures. */
-void
-idcache_fini(void)
-{
- struct uidc *uidc, *uidc2;
- struct gidc *gidc, *gidc2;
- size_t i;
-
- for (i = 0; i < UIDTONAME_SZ; i++) {
- uidc = uidtoname[i];
- while (uidc != NULL) {
- if (uidc->name != NULL) {
- assert(uidc->valid);
- free(uidc->name);
- }
- uidc2 = uidc->next;
- free(uidc);
- uidc = uidc2;
- }
- }
- free(uidtoname);
- for (i = 0; i < NAMETOUID_SZ; i++) {
- uidc = nametouid[i];
- while (uidc != NULL) {
- assert(uidc->name != NULL);
- /* If it's a valid entry, it has been added to both the
- uidtoname and nametouid tables, and the name pointer
- has been reused for both entries. Thus, the name
- pointer has already been freed in the loop above. */
- if (!uidc->valid)
- free(uidc->name);
- uidc2 = uidc->next;
- free(uidc);
- uidc = uidc2;
- }
- }
- free(nametouid);
- for (i = 0; i < GIDTONAME_SZ; i++) {
- gidc = gidtoname[i];
- while (gidc != NULL) {
- if (gidc->name != NULL) {
- assert(gidc->valid);
- free(gidc->name);
- }
- gidc2 = gidc->next;
- free(gidc);
- gidc = gidc2;
- }
- }
- free(gidtoname);
- for (i = 0; i < NAMETOGID_SZ; i++) {
- gidc = nametogid[i];
- while (gidc != NULL) {
- assert(gidc->name != NULL);
- /* See above comment. */
- if (!gidc->valid)
- free(gidc->name);
- gidc2 = gidc->next;
- free(gidc);
- gidc = gidc2;
- }
- }
- free(nametogid);
- pthread_mutex_destroy(&uid_mtx);
- pthread_mutex_destroy(&gid_mtx);
-}
diff --git a/contrib/csup/idcache.h b/contrib/csup/idcache.h
deleted file mode 100644
index 558af0c..0000000
--- a/contrib/csup/idcache.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _IDCACHE_H_
-#define _IDCACHE_H_
-
-#include <sys/types.h>
-
-void idcache_init(void);
-void idcache_fini(void);
-
-char *getuserbyid(uid_t);
-char *getgroupbyid(gid_t);
-int getuidbyname(const char *, uid_t *);
-int getgidbyname(const char *, gid_t *);
-
-#endif /* !_IDCACHE_H_ */
diff --git a/contrib/csup/keyword.c b/contrib/csup/keyword.c
deleted file mode 100644
index 049a011..0000000
--- a/contrib/csup/keyword.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "diff.h"
-#include "keyword.h"
-#include "misc.h"
-#include "queue.h"
-#include "stream.h"
-
-/*
- * The keyword API is used to expand the CVS/RCS keywords in files,
- * such as $Id$, $Revision$, etc. The server does it for us when it
- * sends us entire files, but we need to handle the expansion when
- * applying a diff update.
- */
-
-enum rcskey {
- RCSKEY_AUTHOR,
- RCSKEY_CVSHEADER,
- RCSKEY_DATE,
- RCSKEY_HEADER,
- RCSKEY_ID,
- RCSKEY_LOCKER,
- RCSKEY_LOG,
- RCSKEY_NAME,
- RCSKEY_RCSFILE,
- RCSKEY_REVISION,
- RCSKEY_SOURCE,
- RCSKEY_STATE
-};
-
-typedef enum rcskey rcskey_t;
-
-struct tag {
- char *ident;
- rcskey_t key;
- int enabled;
- STAILQ_ENTRY(tag) next;
-};
-
-static struct tag *tag_new(const char *, rcskey_t);
-static char *tag_expand(struct tag *, struct diffinfo *);
-static void tag_free(struct tag *);
-
-struct keyword {
- STAILQ_HEAD(, tag) keywords; /* Enabled keywords. */
- size_t minkeylen;
- size_t maxkeylen;
-};
-
-/* Default CVS keywords. */
-static struct {
- const char *ident;
- rcskey_t key;
-} tag_defaults[] = {
- { "Author", RCSKEY_AUTHOR },
- { "CVSHeader", RCSKEY_CVSHEADER },
- { "Date", RCSKEY_DATE },
- { "Header", RCSKEY_HEADER },
- { "Id", RCSKEY_ID },
- { "Locker", RCSKEY_LOCKER },
- { "Log", RCSKEY_LOG },
- { "Name", RCSKEY_NAME },
- { "RCSfile", RCSKEY_RCSFILE },
- { "Revision", RCSKEY_REVISION },
- { "Source", RCSKEY_SOURCE },
- { "State", RCSKEY_STATE },
- { NULL, 0, }
-};
-
-struct keyword *
-keyword_new(void)
-{
- struct keyword *new;
- struct tag *tag;
- size_t len;
- int i;
-
- new = xmalloc(sizeof(struct keyword));
- STAILQ_INIT(&new->keywords);
- new->minkeylen = ~0;
- new->maxkeylen = 0;
- for (i = 0; tag_defaults[i].ident != NULL; i++) {
- tag = tag_new(tag_defaults[i].ident, tag_defaults[i].key);
- STAILQ_INSERT_TAIL(&new->keywords, tag, next);
- len = strlen(tag->ident);
- /*
- * These values are only computed here and not updated when
- * adding an alias. This is a bug, but CVSup has it and we
- * need to be bug-to-bug compatible since the server will
- * expect us to do the same, and we will fail with an MD5
- * checksum mismatch if we don't.
- */
- new->minkeylen = min(new->minkeylen, len);
- new->maxkeylen = max(new->maxkeylen, len);
- }
- return (new);
-}
-
-int
-keyword_decode_expand(const char *expand)
-{
-
- if (strcmp(expand, ".") == 0)
- return (EXPAND_DEFAULT);
- else if (strcmp(expand, "kv") == 0)
- return (EXPAND_KEYVALUE);
- else if (strcmp(expand, "kvl") == 0)
- return (EXPAND_KEYVALUELOCKER);
- else if (strcmp(expand, "k") == 0)
- return (EXPAND_KEY);
- else if (strcmp(expand, "o") == 0)
- return (EXPAND_OLD);
- else if (strcmp(expand, "b") == 0)
- return (EXPAND_BINARY);
- else if (strcmp(expand, "v") == 0)
- return (EXPAND_VALUE);
- else
- return (-1);
-}
-
-const char *
-keyword_encode_expand(int expand)
-{
-
- switch (expand) {
- case EXPAND_DEFAULT:
- return (".");
- case EXPAND_KEYVALUE:
- return ("kv");
- case EXPAND_KEYVALUELOCKER:
- return ("kvl");
- case EXPAND_KEY:
- return ("k");
- case EXPAND_OLD:
- return ("o");
- case EXPAND_BINARY:
- return ("b");
- case EXPAND_VALUE:
- return ("v");
- }
- return (NULL);
-}
-
-void
-keyword_free(struct keyword *keyword)
-{
- struct tag *tag;
-
- if (keyword == NULL)
- return;
- while (!STAILQ_EMPTY(&keyword->keywords)) {
- tag = STAILQ_FIRST(&keyword->keywords);
- STAILQ_REMOVE_HEAD(&keyword->keywords, next);
- tag_free(tag);
- }
- free(keyword);
-}
-
-int
-keyword_alias(struct keyword *keyword, const char *ident, const char *rcskey)
-{
- struct tag *new, *tag;
-
- STAILQ_FOREACH(tag, &keyword->keywords, next) {
- if (strcmp(tag->ident, rcskey) == 0) {
- new = tag_new(ident, tag->key);
- STAILQ_INSERT_HEAD(&keyword->keywords, new, next);
- return (0);
- }
- }
- errno = ENOENT;
- return (-1);
-}
-
-int
-keyword_enable(struct keyword *keyword, const char *ident)
-{
- struct tag *tag;
- int all;
-
- all = 0;
- if (strcmp(ident, ".") == 0)
- all = 1;
-
- STAILQ_FOREACH(tag, &keyword->keywords, next) {
- if (!all && strcmp(tag->ident, ident) != 0)
- continue;
- tag->enabled = 1;
- if (!all)
- return (0);
- }
- if (!all) {
- errno = ENOENT;
- return (-1);
- }
- return (0);
-}
-
-int
-keyword_disable(struct keyword *keyword, const char *ident)
-{
- struct tag *tag;
- int all;
-
- all = 0;
- if (strcmp(ident, ".") == 0)
- all = 1;
-
- STAILQ_FOREACH(tag, &keyword->keywords, next) {
- if (!all && strcmp(tag->ident, ident) != 0)
- continue;
- tag->enabled = 0;
- if (!all)
- return (0);
- }
-
- if (!all) {
- errno = ENOENT;
- return (-1);
- }
- return (0);
-}
-
-void
-keyword_prepare(struct keyword *keyword)
-{
- struct tag *tag, *temp;
-
- STAILQ_FOREACH_SAFE(tag, &keyword->keywords, next, temp) {
- if (!tag->enabled) {
- STAILQ_REMOVE(&keyword->keywords, tag, tag, next);
- tag_free(tag);
- continue;
- }
- }
-}
-
-/*
- * Expand appropriate RCS keywords. If there's no tag to expand,
- * keyword_expand() returns 0, otherwise it returns 1 and writes a
- * pointer to the new line in *buf and the new len in *len. The
- * new line is allocated with malloc() and needs to be freed by the
- * caller after use.
- */
-int
-keyword_expand(struct keyword *keyword, struct diffinfo *di, char *line,
- size_t size, char **buf, size_t *len)
-{
- struct tag *tag;
- char *dollar, *keystart, *valstart, *vallim, *next;
- char *linestart, *newline, *newval, *cp, *tmp;
- size_t left, newsize, vallen;
-
- if (di->di_expand == EXPAND_OLD || di->di_expand == EXPAND_BINARY)
- return (0);
- newline = NULL;
- newsize = 0;
- left = size;
- linestart = cp = line;
-again:
- dollar = memchr(cp, '$', left);
- if (dollar == NULL) {
- if (newline != NULL) {
- *buf = newline;
- *len = newsize;
- return (1);
- }
- return (0);
- }
- keystart = dollar + 1;
- left -= keystart - cp;
- vallim = memchr(keystart, '$', left);
- if (vallim == NULL) {
- if (newline != NULL) {
- *buf = newline;
- *len = newsize;
- return (1);
- }
- return (0);
- }
- if (vallim == keystart) {
- cp = keystart;
- goto again;
- }
- valstart = memchr(keystart, ':', left);
- if (valstart == keystart) {
- cp = vallim;
- left -= vallim - keystart;
- goto again;
- }
- if (valstart == NULL || valstart > vallim)
- valstart = vallim;
-
- if (valstart < keystart + keyword->minkeylen ||
- valstart > keystart + keyword->maxkeylen) {
- cp = vallim;
- left -= vallim -keystart;
- goto again;
- }
- STAILQ_FOREACH(tag, &keyword->keywords, next) {
- if (strncmp(tag->ident, keystart, valstart - keystart) == 0 &&
- tag->ident[valstart - keystart] == '\0') {
- if (newline != NULL)
- tmp = newline;
- else
- tmp = NULL;
- newval = NULL;
- if (di->di_expand == EXPAND_KEY) {
- newsize = dollar - linestart + 1 +
- valstart - keystart + 1 +
- size - (vallim + 1 - linestart);
- newline = xmalloc(newsize);
- cp = newline;
- memcpy(cp, linestart, dollar - linestart);
- cp += dollar - linestart;
- *cp++ = '$';
- memcpy(cp, keystart, valstart - keystart);
- cp += valstart - keystart;
- *cp++ = '$';
- next = cp;
- memcpy(cp, vallim + 1,
- size - (vallim + 1 - linestart));
- } else if (di->di_expand == EXPAND_VALUE) {
- newval = tag_expand(tag, di);
- if (newval == NULL)
- vallen = 0;
- else
- vallen = strlen(newval);
- newsize = dollar - linestart +
- vallen +
- size - (vallim + 1 - linestart);
- newline = xmalloc(newsize);
- cp = newline;
- memcpy(cp, linestart, dollar - linestart);
- cp += dollar - linestart;
- if (newval != NULL) {
- memcpy(cp, newval, vallen);
- cp += vallen;
- }
- next = cp;
- memcpy(cp, vallim + 1,
- size - (vallim + 1 - linestart));
- } else {
- assert(di->di_expand == EXPAND_DEFAULT ||
- di->di_expand == EXPAND_KEYVALUE ||
- di->di_expand == EXPAND_KEYVALUELOCKER);
- newval = tag_expand(tag, di);
- if (newval == NULL)
- vallen = 0;
- else
- vallen = strlen(newval);
- newsize = dollar - linestart + 1 +
- valstart - keystart + 2 +
- vallen + 2 +
- size - (vallim + 1 - linestart);
- newline = xmalloc(newsize);
- cp = newline;
- memcpy(cp, linestart, dollar - linestart);
- cp += dollar - linestart;
- *cp++ = '$';
- memcpy(cp, keystart, valstart - keystart);
- cp += valstart - keystart;
- *cp++ = ':';
- *cp++ = ' ';
- if (newval != NULL) {
- memcpy(cp, newval, vallen);
- cp += vallen;
- }
- *cp++ = ' ';
- *cp++ = '$';
- next = cp;
- memcpy(cp, vallim + 1,
- size - (vallim + 1 - linestart));
- }
- if (newval != NULL)
- free(newval);
- if (tmp != NULL)
- free(tmp);
- /*
- * Continue looking for tags in the rest of the line.
- */
- cp = next;
- size = newsize;
- left = size - (cp - newline);
- linestart = newline;
- goto again;
- }
- }
- cp = vallim;
- left = size - (cp - linestart);
- goto again;
-}
-
-static struct tag *
-tag_new(const char *ident, rcskey_t key)
-{
- struct tag *new;
-
- new = xmalloc(sizeof(struct tag));
- new->ident = xstrdup(ident);
- new->key = key;
- new->enabled = 1;
- return (new);
-}
-
-static void
-tag_free(struct tag *tag)
-{
-
- free(tag->ident);
- free(tag);
-}
-
-/*
- * Expand a specific tag and return the new value. If NULL
- * is returned, the tag is empty.
- */
-static char *
-tag_expand(struct tag *tag, struct diffinfo *di)
-{
- /*
- * CVS formats dates as "XXXX/XX/XX XX:XX:XX". 32 bytes
- * is big enough until year 10,000,000,000,000,000 :-).
- */
- char cvsdate[32];
- struct tm tm;
- char *filename, *val;
- int error;
-
- error = rcsdatetotm(di->di_revdate, &tm);
- if (error)
- err(1, "strptime");
- if (strftime(cvsdate, sizeof(cvsdate), "%Y/%m/%d %H:%M:%S", &tm) == 0)
- err(1, "strftime");
- filename = strrchr(di->di_rcsfile, '/');
- if (filename == NULL)
- filename = di->di_rcsfile;
- else
- filename++;
-
- switch (tag->key) {
- case RCSKEY_AUTHOR:
- xasprintf(&val, "%s", di->di_author);
- break;
- case RCSKEY_CVSHEADER:
- xasprintf(&val, "%s %s %s %s %s", di->di_rcsfile,
- di->di_revnum, cvsdate, di->di_author, di->di_state);
- break;
- case RCSKEY_DATE:
- xasprintf(&val, "%s", cvsdate);
- break;
- case RCSKEY_HEADER:
- xasprintf(&val, "%s/%s %s %s %s %s", di->di_cvsroot,
- di->di_rcsfile, di->di_revnum, cvsdate, di->di_author,
- di->di_state);
- break;
- case RCSKEY_ID:
- xasprintf(&val, "%s %s %s %s %s", filename, di->di_revnum,
- cvsdate, di->di_author, di->di_state);
- break;
- case RCSKEY_LOCKER:
- /*
- * Unimplemented even in CVSup sources. It seems we don't
- * even have this information sent by the server.
- */
- return (NULL);
- case RCSKEY_LOG:
- /* XXX */
- printf("%s: Implement Log keyword expansion\n", __func__);
- return (NULL);
- case RCSKEY_NAME:
- if (di->di_tag != NULL)
- xasprintf(&val, "%s", di->di_tag);
- else
- return (NULL);
- break;
- case RCSKEY_RCSFILE:
- xasprintf(&val, "%s", filename);
- break;
- case RCSKEY_REVISION:
- xasprintf(&val, "%s", di->di_revnum);
- break;
- case RCSKEY_SOURCE:
- xasprintf(&val, "%s/%s", di->di_cvsroot, di->di_rcsfile);
- break;
- case RCSKEY_STATE:
- xasprintf(&val, "%s", di->di_state);
- break;
- }
- return (val);
-}
diff --git a/contrib/csup/keyword.h b/contrib/csup/keyword.h
deleted file mode 100644
index 033cb0a..0000000
--- a/contrib/csup/keyword.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _KEYWORD_H_
-#define _KEYWORD_H_
-
-/* CVS expansion modes. */
-#define EXPAND_DEFAULT 0
-#define EXPAND_KEYVALUE 1
-#define EXPAND_KEYVALUELOCKER 2
-#define EXPAND_KEY 3
-#define EXPAND_OLD 4
-#define EXPAND_BINARY 5
-#define EXPAND_VALUE 6
-
-struct diffinfo;
-struct keyword;
-
-struct keyword *keyword_new(void);
-int keyword_decode_expand(const char *);
-const char *keyword_encode_expand(int);
-int keyword_alias(struct keyword *, const char *, const char *);
-int keyword_enable(struct keyword *, const char *);
-int keyword_disable(struct keyword *, const char *);
-void keyword_prepare(struct keyword *);
-int keyword_expand(struct keyword *, struct diffinfo *, char *,
- size_t, char **, size_t *);
-void keyword_free(struct keyword *);
-
-#endif /* !_KEYWORD_H_ */
diff --git a/contrib/csup/lex.rcs.c b/contrib/csup/lex.rcs.c
deleted file mode 100644
index 5db7a7b..0000000
--- a/contrib/csup/lex.rcs.c
+++ /dev/null
@@ -1,2094 +0,0 @@
-
-#line 3 "lex.rcs.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE rcsrestart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = yyg->yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via rcsrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
- ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void rcsrestart (FILE *input_file ,yyscan_t yyscanner );
-void rcs_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE rcs_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void rcs_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void rcs_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void rcspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void rcspop_buffer_state (yyscan_t yyscanner );
-
-static void rcsensure_buffer_stack (yyscan_t yyscanner );
-static void rcs_load_buffer_state (yyscan_t yyscanner );
-static void rcs_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER rcs_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE rcs_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE rcs_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE rcs_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *rcsalloc (yy_size_t ,yyscan_t yyscanner );
-void *rcsrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void rcsfree (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer rcs_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- rcsensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- rcsensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define rcswrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
- yyg->yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 10
-#define YY_END_OF_BUFFER 11
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[89] =
- { 0,
- 0, 0, 11, 5, 9, 8, 10, 4, 4, 7,
- 6, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 9, 5, 4, 4, 5,
- 4, 4, 5, 0, 0, 5, 5, 3, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 3, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 2, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 1, 5, 5, 5, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 1, 1, 1, 4, 1, 1, 1, 1,
- 1, 1, 1, 4, 1, 5, 1, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 7, 8, 1,
- 1, 1, 1, 9, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 10, 11, 12, 13,
-
- 14, 1, 15, 16, 17, 1, 18, 19, 20, 21,
- 22, 23, 1, 24, 25, 26, 27, 1, 1, 28,
- 29, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[30] =
- { 0,
- 1, 2, 2, 2, 1, 1, 2, 2, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int16_t yy_base[94] =
- { 0,
- 0, 0, 136, 25, 127, 297, 297, 27, 29, 297,
- 297, 34, 39, 41, 47, 44, 50, 54, 57, 66,
- 68, 70, 76, 80, 82, 91, 84, 86, 90, 93,
- 95, 97, 102, 58, 61, 0, 0, 107, 109, 112,
- 114, 117, 120, 122, 125, 129, 137, 127, 135, 145,
- 148, 74, 152, 155, 157, 162, 167, 174, 164, 178,
- 182, 184, 187, 189, 191, 193, 196, 200, 204, 206,
- 214, 211, 218, 224, 228, 230, 236, 239, 241, 243,
- 245, 248, 250, 254, 260, 265, 267, 297, 76, 56,
- 47, 292, 294
-
- } ;
-
-static yyconst flex_int16_t yy_def[94] =
- { 0,
- 88, 1, 88, 89, 88, 88, 88, 90, 91, 88,
- 88, 92, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 88, 89, 90, 91, 89,
- 91, 91, 92, 93, 93, 33, 33, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 88, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 0, 88, 88,
- 88, 88, 88
-
- } ;
-
-static yyconst flex_int16_t yy_nxt[327] =
- { 0,
- 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 4, 18, 4, 4, 19, 4,
- 20, 4, 4, 4, 21, 22, 4, 4, 4, 24,
- 25, 28, 29, 31, 32, 34, 35, 34, 36, 37,
- 34, 34, 38, 24, 25, 24, 25, 30, 24, 25,
- 39, 24, 25, 43, 24, 25, 27, 44, 24, 25,
- 35, 24, 25, 35, 41, 40, 52, 46, 42, 52,
- 24, 25, 24, 25, 24, 25, 23, 45, 47, 48,
- 24, 25, 34, 51, 24, 25, 24, 25, 24, 25,
- 28, 29, 26, 49, 31, 32, 50, 24, 25, 31,
-
- 32, 31, 32, 34, 35, 34, 36, 37, 34, 34,
- 38, 24, 25, 24, 25, 33, 24, 25, 24, 25,
- 53, 24, 25, 55, 24, 25, 24, 25, 26, 24,
- 25, 24, 25, 24, 25, 88, 56, 54, 60, 24,
- 25, 24, 25, 88, 64, 57, 58, 59, 61, 24,
- 25, 62, 24, 25, 63, 88, 24, 25, 65, 24,
- 25, 24, 25, 88, 66, 68, 24, 25, 24, 25,
- 69, 24, 25, 72, 88, 67, 88, 70, 24, 25,
- 62, 71, 24, 25, 88, 62, 24, 25, 24, 25,
- 62, 24, 25, 24, 25, 24, 25, 24, 25, 73,
-
- 24, 25, 88, 76, 24, 25, 88, 75, 24, 25,
- 24, 25, 62, 88, 74, 24, 25, 79, 24, 25,
- 88, 62, 24, 25, 77, 78, 88, 80, 24, 25,
- 88, 81, 24, 25, 24, 25, 88, 62, 88, 82,
- 24, 25, 62, 24, 25, 24, 25, 24, 25, 24,
- 25, 83, 24, 25, 24, 25, 84, 62, 24, 25,
- 62, 88, 62, 85, 24, 25, 88, 87, 86, 24,
- 25, 24, 25, 62, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 62, 88, 88, 88, 62,
- 88, 62, 33, 33, 34, 34, 3, 88, 88, 88,
-
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88
- } ;
-
-static yyconst flex_int16_t yy_chk[327] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
- 4, 8, 8, 9, 9, 12, 12, 12, 12, 12,
- 12, 12, 12, 13, 13, 14, 14, 91, 16, 16,
- 13, 15, 15, 16, 17, 17, 90, 16, 18, 18,
- 34, 19, 19, 35, 14, 13, 34, 18, 15, 35,
- 20, 20, 21, 21, 22, 22, 89, 17, 19, 20,
- 23, 23, 52, 22, 24, 24, 25, 25, 27, 27,
- 28, 28, 26, 21, 29, 29, 21, 30, 30, 31,
-
- 31, 32, 32, 33, 33, 33, 33, 33, 33, 33,
- 33, 38, 38, 39, 39, 38, 40, 40, 41, 41,
- 39, 42, 42, 41, 43, 43, 44, 44, 5, 45,
- 45, 48, 48, 46, 46, 3, 42, 40, 46, 49,
- 49, 47, 47, 0, 49, 43, 44, 45, 47, 50,
- 50, 47, 51, 51, 48, 0, 53, 53, 49, 54,
- 54, 55, 55, 0, 50, 53, 56, 56, 59, 59,
- 54, 57, 57, 59, 0, 51, 0, 55, 58, 58,
- 57, 56, 60, 60, 0, 58, 61, 61, 62, 62,
- 60, 63, 63, 64, 64, 65, 65, 66, 66, 61,
-
- 67, 67, 0, 66, 68, 68, 0, 65, 69, 69,
- 70, 70, 63, 0, 64, 72, 72, 70, 71, 71,
- 0, 67, 73, 73, 68, 69, 0, 71, 74, 74,
- 0, 72, 75, 75, 76, 76, 0, 74, 0, 75,
- 77, 77, 73, 78, 78, 79, 79, 80, 80, 81,
- 81, 76, 82, 82, 83, 83, 79, 81, 84, 84,
- 77, 0, 78, 80, 85, 85, 0, 84, 83, 86,
- 86, 87, 87, 82, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 85, 0, 0, 0, 86,
- 0, 87, 92, 92, 93, 93, 88, 88, 88, 88,
-
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88
- } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "rcstokenizer.l"
-/*-
- * Copyright (c) 2007-2008, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-/*
- * This tokenizer must be generated by a lexxer with support for reentrancy.
- */
-#line 34 "rcstokenizer.l"
-#include <string.h>
-#include "misc.h"
-#include "rcsparse.h"
-
-#line 567 "lex.rcs.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
- {
-
- /* User-defined. Not touched by flex. */
- YY_EXTRA_TYPE yyextra_r;
-
- /* The rest are the same as the globals declared in the non-reentrant scanner. */
- FILE *yyin_r, *yyout_r;
- size_t yy_buffer_stack_top; /**< index of top of stack. */
- size_t yy_buffer_stack_max; /**< capacity of stack. */
- YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
- char yy_hold_char;
- int yy_n_chars;
- int yyleng_r;
- char *yy_c_buf_p;
- int yy_init;
- int yy_start;
- int yy_did_buffer_switch_on_eof;
- int yy_start_stack_ptr;
- int yy_start_stack_depth;
- int *yy_start_stack;
- yy_state_type yy_last_accepting_state;
- char* yy_last_accepting_cpos;
-
- int yylineno_r;
- int yy_flex_debug_r;
-
- char *yytext_r;
- int yy_more_flag;
- int yy_more_len;
-
- }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
-int rcslex_init (yyscan_t* scanner);
-
-int rcslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int rcslex_destroy (yyscan_t yyscanner );
-
-int rcsget_debug (yyscan_t yyscanner );
-
-void rcsset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE rcsget_extra (yyscan_t yyscanner );
-
-void rcsset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *rcsget_in (yyscan_t yyscanner );
-
-void rcsset_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *rcsget_out (yyscan_t yyscanner );
-
-void rcsset_out (FILE * out_str ,yyscan_t yyscanner );
-
-int rcsget_leng (yyscan_t yyscanner );
-
-char *rcsget_text (yyscan_t yyscanner );
-
-int rcsget_lineno (yyscan_t yyscanner );
-
-void rcsset_lineno (int line_number ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int rcswrap (yyscan_t yyscanner );
-#else
-extern int rcswrap (yyscan_t yyscanner );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- int n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int rcslex (yyscan_t yyscanner);
-
-#define YY_DECL int rcslex (yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 51 "rcstokenizer.l"
-
-
-#line 791 "lex.rcs.c"
-
- if ( !yyg->yy_init )
- {
- yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yyg->yy_start )
- yyg->yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- rcsensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- rcs_load_buffer_state(yyscanner );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = yyg->yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yyg->yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yyg->yy_start;
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 89 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_base[yy_current_state] != 297 );
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- yy_act = yy_accept[yy_current_state];
- }
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yyg->yy_hold_char;
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 53 "rcstokenizer.l"
-{
- return (KEYWORD_TWO);
-}
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 56 "rcstokenizer.l"
-{
- return (KEYWORD);
-}
- YY_BREAK
-case 3:
-/* rule 3 can match eol */
-YY_RULE_SETUP
-#line 59 "rcstokenizer.l"
-{
- return (STRING);
-}
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 62 "rcstokenizer.l"
-{
- return (NUM);
-}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 65 "rcstokenizer.l"
-{
-/* This will use ID as both ID and SYM. Do extra checking elsewhere.*/
- return (ID);
-}
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 69 "rcstokenizer.l"
-{ return (SEMIC); }
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 70 "rcstokenizer.l"
-{ return (COLON); }
- YY_BREAK
-case 8:
-/* rule 8 can match eol */
-YY_RULE_SETUP
-#line 71 "rcstokenizer.l"
-;
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 72 "rcstokenizer.l"
-;
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 73 "rcstokenizer.l"
-ECHO;
- YY_BREAK
-#line 937 "lex.rcs.c"
-case YY_STATE_EOF(INITIAL):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yyg->yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * rcslex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yyg->yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yyg->yy_c_buf_p;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yyg->yy_did_buffer_switch_on_eof = 0;
-
- if ( rcswrap(yyscanner ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p =
- yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yyg->yy_c_buf_p =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of rcslex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- rcsrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- yyg->yy_n_chars, (size_t) num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- if ( yyg->yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- rcsrestart(yyin ,yyscanner);
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
- /* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) rcsrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
- }
-
- yyg->yy_n_chars += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_current_state = yyg->yy_start;
-
- for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 89 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
- register int yy_is_jam;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 89 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 88);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
-{
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_cp = yyg->yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yyg->yy_hold_char;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = yyg->yy_n_chars + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- yyg->yytext_ptr = yy_bp;
- yyg->yy_hold_char = *yy_cp;
- yyg->yy_c_buf_p = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (yyscan_t yyscanner)
-#else
- static int input (yyscan_t yyscanner)
-#endif
-
-{
- int c;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
- if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- /* This was really a NUL. */
- *yyg->yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
- ++yyg->yy_c_buf_p;
-
- switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- rcsrestart(yyin ,yyscanner);
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( rcswrap(yyscanner ) )
- return EOF;
-
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput(yyscanner);
-#else
- return input(yyscanner);
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
- *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
- yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void rcsrestart (FILE * input_file , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! YY_CURRENT_BUFFER ){
- rcsensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- rcs_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- rcs_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- rcs_load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
- void rcs_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* TODO. We should be able to replace this entire function body
- * with
- * rcspop_buffer_state();
- * rcspush_buffer_state(new_buffer);
- */
- rcsensure_buffer_stack (yyscanner);
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- rcs_load_buffer_state(yyscanner );
-
- /* We don't actually know whether we did this switch during
- * EOF (rcswrap()) processing, but the only time this flag
- * is looked at is after rcswrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-static void rcs_load_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- yyg->yy_hold_char = *yyg->yy_c_buf_p;
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE rcs_create_buffer (FILE * file, int size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) rcsalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in rcs_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) rcsalloc(b->yy_buf_size + 2 ,yyscanner );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in rcs_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- rcs_init_buffer(b,file ,yyscanner);
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with rcs_create_buffer()
- * @param yyscanner The scanner object.
- */
- void rcs_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- rcsfree((void *) b->yy_ch_buf ,yyscanner );
-
- rcsfree((void *) b ,yyscanner );
-}
-
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a rcsrestart() or at EOF.
- */
- static void rcs_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
-
-{
- int oerrno = errno;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- rcs_flush_buffer(b ,yyscanner);
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then rcs_init_buffer was _probably_
- * called from rcsrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
- void rcs_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- rcs_load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- * @param yyscanner The scanner object.
- */
-void rcspush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (new_buffer == NULL)
- return;
-
- rcsensure_buffer_stack(yyscanner);
-
- /* This block is copied from rcs_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- yyg->yy_buffer_stack_top++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from rcs_switch_to_buffer. */
- rcs_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- * @param yyscanner The scanner object.
- */
-void rcspop_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (!YY_CURRENT_BUFFER)
- return;
-
- rcs_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if (yyg->yy_buffer_stack_top > 0)
- --yyg->yy_buffer_stack_top;
-
- if (YY_CURRENT_BUFFER) {
- rcs_load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void rcsensure_buffer_stack (yyscan_t yyscanner)
-{
- int num_to_alloc;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (!yyg->yy_buffer_stack) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)rcsalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
- if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in rcsensure_buffer_stack()" );
-
- memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- yyg->yy_buffer_stack_max = num_to_alloc;
- yyg->yy_buffer_stack_top = 0;
- return;
- }
-
- if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)rcsrealloc
- (yyg->yy_buffer_stack,
- num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
- if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in rcsensure_buffer_stack()" );
-
- /* zero only the new slots.*/
- memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
- yyg->yy_buffer_stack_max = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE rcs_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) rcsalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in rcs_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- rcs_switch_to_buffer(b ,yyscanner );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to rcslex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * rcs_scan_bytes() instead.
- */
-YY_BUFFER_STATE rcs_scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-
- return rcs_scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to rcslex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE rcs_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) rcsalloc(n ,yyscanner );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in rcs_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = rcs_scan_buffer(buf,n ,yyscanner);
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in rcs_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = yyg->yy_hold_char; \
- yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
- yyg->yy_hold_char = *yyg->yy_c_buf_p; \
- *yyg->yy_c_buf_p = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE rcsget_extra (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int rcsget_lineno (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int rcsget_column (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *rcsget_in (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *rcsget_out (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int rcsget_leng (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *rcsget_text (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void rcsset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void rcsset_lineno (int line_number , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* lineno is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "rcsset_lineno called with no buffer" , yyscanner);
-
- yylineno = line_number;
-}
-
-/** Set the current column.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void rcsset_column (int column_no , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* column is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "rcsset_column called with no buffer" , yyscanner);
-
- yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see rcs_switch_to_buffer
- */
-void rcsset_in (FILE * in_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
-}
-
-void rcsset_out (FILE * out_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
-}
-
-int rcsget_debug (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yy_flex_debug;
-}
-
-void rcsset_debug (int bdebug , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-/* User-visible API */
-
-/* rcslex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int rcslex_init(yyscan_t* ptr_yy_globals)
-
-{
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) rcsalloc ( sizeof( struct yyguts_t ), NULL );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-/* rcslex_init_extra has the same functionality as rcslex_init, but follows the
- * convention of taking the scanner as the last argument. Note however, that
- * this is a *pointer* to a scanner, as it will be allocated by this call (and
- * is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to rcsalloc in
- * the yyextra field.
- */
-
-int rcslex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
-{
- struct yyguts_t dummy_yyguts;
-
- rcsset_extra (yy_user_defined, &dummy_yyguts);
-
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
- }
-
- *ptr_yy_globals = (yyscan_t) rcsalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in
- yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- rcsset_extra (yy_user_defined, *ptr_yy_globals);
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from rcslex_destroy(), so don't allocate here.
- */
-
- yyg->yy_buffer_stack = 0;
- yyg->yy_buffer_stack_top = 0;
- yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
- yyg->yy_init = 0;
- yyg->yy_start = 0;
-
- yyg->yy_start_stack_ptr = 0;
- yyg->yy_start_stack_depth = 0;
- yyg->yy_start_stack = NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * rcslex_init()
- */
- return 0;
-}
-
-/* rcslex_destroy is for both reentrant and non-reentrant scanners. */
-int rcslex_destroy (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- rcs_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- rcspop_buffer_state(yyscanner);
- }
-
- /* Destroy the stack itself. */
- rcsfree(yyg->yy_buffer_stack ,yyscanner);
- yyg->yy_buffer_stack = NULL;
-
- /* Destroy the start condition stack. */
- rcsfree(yyg->yy_start_stack ,yyscanner );
- yyg->yy_start_stack = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * rcslex() is called, initialization will occur. */
- yy_init_globals( yyscanner);
-
- /* Destroy the main struct (reentrant only). */
- rcsfree ( yyscanner , yyscanner );
- yyscanner = NULL;
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *rcsalloc (yy_size_t size , yyscan_t yyscanner)
-{
- return (void *) malloc( size );
-}
-
-void *rcsrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-void rcsfree (void * ptr , yyscan_t yyscanner)
-{
- free( (char *) ptr ); /* see rcsrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 73 "rcstokenizer.l"
-
-
-
diff --git a/contrib/csup/lister.c b/contrib/csup/lister.c
deleted file mode 100644
index b10dbd3..0000000
--- a/contrib/csup/lister.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "attrstack.h"
-#include "config.h"
-#include "fattr.h"
-#include "globtree.h"
-#include "lister.h"
-#include "misc.h"
-#include "mux.h"
-#include "proto.h"
-#include "status.h"
-#include "stream.h"
-
-/* Internal error codes. */
-#define LISTER_ERR_WRITE (-1) /* Error writing to server. */
-#define LISTER_ERR_STATUS (-2) /* Status file error in lstr->errmsg. */
-
-struct lister {
- struct config *config;
- struct stream *wr;
- char *errmsg;
-};
-
-static int lister_batch(struct lister *);
-static int lister_coll(struct lister *, struct coll *, struct status *);
-static int lister_dodirdown(struct lister *, struct coll *,
- struct statusrec *, struct attrstack *as);
-static int lister_dodirup(struct lister *, struct coll *,
- struct statusrec *, struct attrstack *as);
-static int lister_dofile(struct lister *, struct coll *,
- struct statusrec *);
-static int lister_dodead(struct lister *, struct coll *,
- struct statusrec *);
-static int lister_dorcsfile(struct lister *, struct coll *,
- struct statusrec *);
-static int lister_dorcsdead(struct lister *, struct coll *,
- struct statusrec *);
-
-void *
-lister(void *arg)
-{
- struct thread_args *args;
- struct lister lbuf, *l;
- int error;
-
- args = arg;
- l = &lbuf;
- l->config = args->config;
- l->wr = args->wr;
- l->errmsg = NULL;
- error = lister_batch(l);
- switch (error) {
- case LISTER_ERR_WRITE:
- xasprintf(&args->errmsg,
- "TreeList failed: Network write failure: %s",
- strerror(errno));
- args->status = STATUS_TRANSIENTFAILURE;
- break;
- case LISTER_ERR_STATUS:
- xasprintf(&args->errmsg,
- "TreeList failed: %s. Delete it and try again.",
- l->errmsg);
- free(l->errmsg);
- args->status = STATUS_FAILURE;
- break;
- default:
- assert(error == 0);
- args->status = STATUS_SUCCESS;
- };
- return (NULL);
-}
-
-static int
-lister_batch(struct lister *l)
-{
- struct config *config;
- struct stream *wr;
- struct status *st;
- struct coll *coll;
- int error;
-
- config = l->config;
- wr = l->wr;
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- if (coll->co_options & CO_SKIP)
- continue;
- st = status_open(coll, -1, &l->errmsg);
- if (st == NULL)
- return (LISTER_ERR_STATUS);
- error = proto_printf(wr, "COLL %s %s\n", coll->co_name,
- coll->co_release);
- if (error)
- return (LISTER_ERR_WRITE);
- stream_flush(wr);
- if (coll->co_options & CO_COMPRESS)
- stream_filter_start(wr, STREAM_FILTER_ZLIB, NULL);
- error = lister_coll(l, coll, st);
- status_close(st, NULL);
- if (error)
- return (error);
- if (coll->co_options & CO_COMPRESS)
- stream_filter_stop(wr);
- stream_flush(wr);
- }
- error = proto_printf(wr, ".\n");
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-}
-
-/* List a single collection based on the status file. */
-static int
-lister_coll(struct lister *l, struct coll *coll, struct status *st)
-{
- struct stream *wr;
- struct attrstack *as;
- struct statusrec *sr;
- struct fattr *fa;
- size_t i;
- int depth, error, ret, prunedepth;
-
- wr = l->wr;
- depth = 0;
- prunedepth = INT_MAX;
- as = attrstack_new();
- while ((ret = status_get(st, NULL, 0, 0, &sr)) == 1) {
- switch (sr->sr_type) {
- case SR_DIRDOWN:
- depth++;
- if (depth < prunedepth) {
- error = lister_dodirdown(l, coll, sr, as);
- if (error < 0)
- goto bad;
- if (error)
- prunedepth = depth;
- }
- break;
- case SR_DIRUP:
- if (depth < prunedepth) {
- error = lister_dodirup(l, coll, sr, as);
- if (error)
- goto bad;
- } else if (depth == prunedepth) {
- /* Finished pruning. */
- prunedepth = INT_MAX;
- }
- depth--;
- continue;
- case SR_CHECKOUTLIVE:
- if (depth < prunedepth) {
- error = lister_dofile(l, coll, sr);
- if (error)
- goto bad;
- }
- break;
- case SR_CHECKOUTDEAD:
- if (depth < prunedepth) {
- error = lister_dodead(l, coll, sr);
- if (error)
- goto bad;
- }
- break;
- case SR_FILEDEAD:
- if (depth < prunedepth) {
- if (!(coll->co_options & CO_CHECKOUTMODE)) {
- error = lister_dorcsdead(l, coll, sr);
- if (error)
- goto bad;
- }
- }
- break;
- case SR_FILELIVE:
- if (depth < prunedepth) {
- if (!(coll->co_options & CO_CHECKOUTMODE)) {
- error = lister_dorcsfile(l, coll, sr);
- if (error)
- goto bad;
- }
- }
- break;
- }
- }
- if (ret == -1) {
- l->errmsg = status_errmsg(st);
- error = LISTER_ERR_STATUS;
- goto bad;
- }
- assert(status_eof(st));
- assert(depth == 0);
- error = proto_printf(wr, ".\n");
- attrstack_free(as);
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-bad:
- for (i = 0; i < attrstack_size(as); i++) {
- fa = attrstack_pop(as);
- fattr_free(fa);
- }
- attrstack_free(as);
- return (error);
-}
-
-/* Handle a directory up entry found in the status file. */
-static int
-lister_dodirdown(struct lister *l, struct coll *coll, struct statusrec *sr,
- struct attrstack *as)
-{
- struct config *config;
- struct stream *wr;
- struct fattr *fa, *fa2;
- char *path;
- int error;
-
- config = l->config;
- wr = l->wr;
- if (!globtree_test(coll->co_dirfilter, sr->sr_file))
- return (1);
- if (coll->co_options & CO_TRUSTSTATUSFILE) {
- fa = fattr_new(FT_DIRECTORY, -1);
- } else {
- xasprintf(&path, "%s/%s", coll->co_prefix, sr->sr_file);
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- if (fa == NULL) {
- /* The directory doesn't exist, prune
- * everything below it. */
- free(path);
- return (1);
- }
- if (fattr_type(fa) == FT_SYMLINK) {
- fa2 = fattr_frompath(path, FATTR_FOLLOW);
- if (fa2 != NULL && fattr_type(fa2) == FT_DIRECTORY) {
- /* XXX - When not in checkout mode, CVSup warns
- * here about the file being a symlink to a
- * directory instead of a directory. */
- fattr_free(fa);
- fa = fa2;
- } else {
- fattr_free(fa2);
- }
- }
- free(path);
- }
-
- if (fattr_type(fa) != FT_DIRECTORY) {
- fattr_free(fa);
- /* Report it as something bogus so
- * that it will be replaced. */
- error = proto_printf(wr, "F %s %F\n", pathlast(sr->sr_file),
- fattr_bogus, config->fasupport, coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- return (1);
- }
-
- /* It really is a directory. */
- attrstack_push(as, fa);
- error = proto_printf(wr, "D %s\n", pathlast(sr->sr_file));
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-}
-
-/* Handle a directory up entry found in the status file. */
-static int
-lister_dodirup(struct lister *l, struct coll *coll, struct statusrec *sr,
- struct attrstack *as)
-{
- struct config *config;
- const struct fattr *sendattr;
- struct stream *wr;
- struct fattr *fa, *fa2;
- int error;
-
- config = l->config;
- wr = l->wr;
- fa = attrstack_pop(as);
- if (coll->co_options & CO_TRUSTSTATUSFILE) {
- fattr_free(fa);
- fa = sr->sr_clientattr;
- }
-
- fa2 = sr->sr_clientattr;
- if (fattr_equal(fa, fa2))
- sendattr = fa;
- else
- sendattr = fattr_bogus;
- error = proto_printf(wr, "U %F\n", sendattr, config->fasupport,
- coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- if (!(coll->co_options & CO_TRUSTSTATUSFILE))
- fattr_free(fa);
- /* XXX CVSup flushes here for some reason with a comment saying
- "Be smarter". We don't flush when listing other file types. */
- stream_flush(wr);
- return (0);
-}
-
-/* Handle a checkout live entry found in the status file. */
-static int
-lister_dofile(struct lister *l, struct coll *coll, struct statusrec *sr)
-{
- struct config *config;
- struct stream *wr;
- const struct fattr *sendattr, *fa;
- struct fattr *fa2, *rfa;
- char *path, *spath;
- int error;
-
- if (!globtree_test(coll->co_filefilter, sr->sr_file))
- return (0);
- config = l->config;
- wr = l->wr;
- rfa = NULL;
- sendattr = NULL;
- error = 0;
- if (!(coll->co_options & CO_TRUSTSTATUSFILE)) {
- path = checkoutpath(coll->co_prefix, sr->sr_file);
- if (path == NULL) {
- spath = coll_statuspath(coll);
- xasprintf(&l->errmsg, "Error in \"%s\": "
- "Invalid filename \"%s\"", spath, sr->sr_file);
- free(spath);
- return (LISTER_ERR_STATUS);
- }
- rfa = fattr_frompath(path, FATTR_NOFOLLOW);
- free(path);
- if (rfa == NULL) {
- /*
- * According to the checkouts file we should have
- * this file but we don't. Maybe the user deleted
- * the file, or maybe the checkouts file is wrong.
- * List the file with bogus attributes to cause the
- * server to get things back in sync again.
- */
- sendattr = fattr_bogus;
- goto send;
- }
- fa = rfa;
- } else {
- fa = sr->sr_clientattr;
- }
- fa2 = fattr_forcheckout(sr->sr_serverattr, coll->co_umask);
- if (!fattr_equal(fa, sr->sr_clientattr) || !fattr_equal(fa, fa2) ||
- strcmp(coll->co_tag, sr->sr_tag) != 0 ||
- strcmp(coll->co_date, sr->sr_date) != 0) {
- /*
- * The file corresponds to the information we have
- * recorded about it, and its moded is correct for
- * the requested umask setting.
- */
- sendattr = fattr_bogus;
- } else {
- /*
- * Either the file has been touched, or we are asking
- * for a different revision than the one we recorded
- * information about, or its mode isn't right (because
- * it was last updated using a version of CVSup that
- * wasn't so strict about modes).
- */
- sendattr = sr->sr_serverattr;
- }
- fattr_free(fa2);
- if (rfa != NULL)
- fattr_free(rfa);
-send:
- error = proto_printf(wr, "F %s %F\n", pathlast(sr->sr_file), sendattr,
- config->fasupport, coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-}
-
-/* Handle a rcs file live entry found in the status file. */
-static int
-lister_dorcsfile(struct lister *l, struct coll *coll, struct statusrec *sr)
-{
- struct config *config;
- struct stream *wr;
- const struct fattr *sendattr;
- struct fattr *fa;
- char *path, *spath;
- size_t len;
- int error;
-
- if (!globtree_test(coll->co_filefilter, sr->sr_file))
- return (0);
- config = l->config;
- wr = l->wr;
- if (!(coll->co_options & CO_TRUSTSTATUSFILE)) {
- path = cvspath(coll->co_prefix, sr->sr_file, 0);
- if (path == NULL) {
- spath = coll_statuspath(coll);
- xasprintf(&l->errmsg, "Error in \"%s\": "
- "Invalid filename \"%s\"", spath, sr->sr_file);
- free(spath);
- return (LISTER_ERR_STATUS);
- }
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- free(path);
- } else
- fa = sr->sr_clientattr;
- if (fa != NULL && fattr_equal(fa, sr->sr_clientattr)) {
- /*
- * If the file is an RCS file, we use "loose" equality, so sizes
- * may disagress because of differences in whitespace.
- */
- if (isrcs(sr->sr_file, &len) &&
- !(coll->co_options & CO_NORCS) &&
- !(coll->co_options & CO_STRICTCHECKRCS)) {
- fattr_maskout(fa, FA_SIZE);
- }
- sendattr = fa;
- } else {
- /*
- * If different, the user may have changed it, so we report
- * bogus attributes to force a full comparison.
- */
- sendattr = fattr_bogus;
- }
- error = proto_printf(wr, "F %s %F\n", pathlast(sr->sr_file), sendattr,
- config->fasupport, coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-}
-
-/* Handle a checkout dead entry found in the status file. */
-static int
-lister_dodead(struct lister *l, struct coll *coll, struct statusrec *sr)
-{
- struct config *config;
- struct stream *wr;
- const struct fattr *sendattr;
- struct fattr *fa;
- char *path, *spath;
- int error;
-
- if (!globtree_test(coll->co_filefilter, sr->sr_file))
- return (0);
- config = l->config;
- wr = l->wr;
- if (!(coll->co_options & CO_TRUSTSTATUSFILE)) {
- path = checkoutpath(coll->co_prefix, sr->sr_file);
- if (path == NULL) {
- spath = coll_statuspath(coll);
- xasprintf(&l->errmsg, "Error in \"%s\": "
- "Invalid filename \"%s\"", spath, sr->sr_file);
- free(spath);
- return (LISTER_ERR_STATUS);
- }
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- free(path);
- if (fa != NULL && fattr_type(fa) != FT_DIRECTORY) {
- /*
- * We shouldn't have this file but we do. Report
- * it to the server, which will either send a
- * deletion request, of (if the file has come alive)
- * sent the correct version.
- */
- fattr_free(fa);
- error = proto_printf(wr, "F %s %F\n",
- pathlast(sr->sr_file), fattr_bogus,
- config->fasupport, coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
- }
- fattr_free(fa);
- }
- if (strcmp(coll->co_tag, sr->sr_tag) != 0 ||
- strcmp(coll->co_date, sr->sr_date) != 0)
- sendattr = fattr_bogus;
- else
- sendattr = sr->sr_serverattr;
- error = proto_printf(wr, "f %s %F\n", pathlast(sr->sr_file), sendattr,
- config->fasupport, coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-}
-
-/* Handle a rcs file dead entry found in the status file. */
-static int
-lister_dorcsdead(struct lister *l, struct coll *coll, struct statusrec *sr)
-{
- struct config *config;
- struct stream *wr;
- const struct fattr *sendattr;
- struct fattr *fa;
- char *path, *spath;
- size_t len;
- int error;
-
- if (!globtree_test(coll->co_filefilter, sr->sr_file))
- return (0);
- config = l->config;
- wr = l->wr;
- if (!coll->co_options & CO_TRUSTSTATUSFILE) {
- path = cvspath(coll->co_prefix, sr->sr_file, 1);
- if (path == NULL) {
- spath = coll_statuspath(coll);
- xasprintf(&l->errmsg, "Error in \"%s\": "
- "Invalid filename \"%s\"", spath, sr->sr_file);
- free(spath);
- return (LISTER_ERR_STATUS);
- }
- fa = fattr_frompath(path, FATTR_NOFOLLOW);
- free(path);
- } else
- fa = sr->sr_clientattr;
- if (fattr_equal(fa, sr->sr_clientattr)) {
- /*
- * If the file is an RCS file, we use "loose" equality, so sizes
- * may disagress because of differences in whitespace.
- */
- if (isrcs(sr->sr_file, &len) &&
- !(coll->co_options & CO_NORCS) &&
- !(coll->co_options & CO_STRICTCHECKRCS)) {
- fattr_maskout(fa, FA_SIZE);
- }
- sendattr = fa;
- } else {
- /*
- * If different, the user may have changed it, so we report
- * bogus attributes to force a full comparison.
- */
- sendattr = fattr_bogus;
- }
- error = proto_printf(wr, "f %s %F\n", pathlast(sr->sr_file), sendattr,
- config->fasupport, coll->co_attrignore);
- if (error)
- return (LISTER_ERR_WRITE);
- return (0);
-}
diff --git a/contrib/csup/lister.h b/contrib/csup/lister.h
deleted file mode 100644
index a0a9bbe..0000000
--- a/contrib/csup/lister.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _LISTER_H_
-#define _LISTER_H_
-
-void *lister(void *);
-
-#endif /* !_LISTER_H_ */
diff --git a/contrib/csup/main.c b/contrib/csup/main.c
deleted file mode 100644
index e7711b3..0000000
--- a/contrib/csup/main.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/file.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "fattr.h"
-#include "misc.h"
-#include "proto.h"
-#include "stream.h"
-
-#define USAGE_OPTFMT " %-12s %s\n"
-#define USAGE_OPTFMTSUB " %-14s %s\n", ""
-
-int verbose = 1;
-
-static void
-usage(char *argv0)
-{
-
- lprintf(-1, "Usage: %s [options] supfile\n", basename(argv0));
- lprintf(-1, " Options:\n");
- lprintf(-1, USAGE_OPTFMT, "-1", "Don't retry automatically on failure "
- "(same as \"-r 0\")");
- lprintf(-1, USAGE_OPTFMT, "-4", "Force usage of IPv4 addresses");
- lprintf(-1, USAGE_OPTFMT, "-6", "Force usage of IPv6 addresses");
- lprintf(-1, USAGE_OPTFMT, "-a",
- "Require server to authenticate itself to us");
- lprintf(-1, USAGE_OPTFMT, "-A addr",
- "Bind local socket to a specific address");
- lprintf(-1, USAGE_OPTFMT, "-b base",
- "Override supfile's \"base\" directory");
- lprintf(-1, USAGE_OPTFMT, "-c collDir",
- "Subdirectory of \"base\" for collections (default \"sup\")");
- lprintf(-1, USAGE_OPTFMT, "-d delLimit",
- "Allow at most \"delLimit\" file deletions (default unlimited)");
- lprintf(-1, USAGE_OPTFMT, "-h host",
- "Override supfile's \"host\" name");
- lprintf(-1, USAGE_OPTFMT, "-i pattern",
- "Include only files/directories matching pattern.");
- lprintf(-1, USAGE_OPTFMTSUB,
- "May be repeated for an OR operation. Default is");
- lprintf(-1, USAGE_OPTFMTSUB, "to include each entire collection.");
- lprintf(-1, USAGE_OPTFMT, "-k",
- "Keep bad temporary files when fixups are required");
- lprintf(-1, USAGE_OPTFMT, "-l lockfile",
- "Lock file during update; fail if already locked");
- lprintf(-1, USAGE_OPTFMT, "-L n",
- "Verbosity level (0..2, default 1)");
- lprintf(-1, USAGE_OPTFMT, "-p port",
- "Alternate server port (default 5999)");
- lprintf(-1, USAGE_OPTFMT, "-r n",
- "Maximum retries on transient errors (default unlimited)");
- lprintf(-1, USAGE_OPTFMT, "-s",
- "Don't stat client files; trust the checkouts file");
- lprintf(-1, USAGE_OPTFMT, "-v", "Print version and exit");
- lprintf(-1, USAGE_OPTFMT, "-z", "Enable compression for all "
- "collections");
- lprintf(-1, USAGE_OPTFMT, "-Z", "Disable compression for all "
- "collections");
-}
-
-int
-main(int argc, char *argv[])
-{
- struct tm tm;
- struct backoff_timer *timer;
- struct config *config;
- struct coll *override;
- struct addrinfo *res;
- struct sockaddr *laddr;
- socklen_t laddrlen;
- struct stream *lock;
- char *argv0, *file, *lockfile;
- int family, error, lockfd, lflag, overridemask;
- int c, i, deletelim, port, retries, status, reqauth;
- time_t nexttry;
-
- error = 0;
- family = PF_UNSPEC;
- deletelim = -1;
- port = 0;
- lflag = 0;
- lockfd = 0;
- nexttry = 0;
- retries = -1;
- argv0 = argv[0];
- laddr = NULL;
- laddrlen = 0;
- lockfile = NULL;
- override = coll_new(NULL);
- overridemask = 0;
- reqauth = 0;
-
- while ((c = getopt(argc, argv,
- "146aA:b:c:d:gh:i:kl:L:p:P:r:svzZ")) != -1) {
- switch (c) {
- case '1':
- retries = 0;
- break;
- case '4':
- family = AF_INET;
- break;
- case '6':
- family = AF_INET6;
- break;
- case 'a':
- /* Require server authentication */
- reqauth = 1;
- break;
- case 'A':
- error = getaddrinfo(optarg, NULL, NULL, &res);
- if (error) {
- lprintf(-1, "%s: %s\n", optarg,
- gai_strerror(error));
- return (1);
- }
- laddrlen = res->ai_addrlen;
- laddr = xmalloc(laddrlen);
- memcpy(laddr, res->ai_addr, laddrlen);
- freeaddrinfo(res);
- break;
- case 'b':
- if (override->co_base != NULL)
- free(override->co_base);
- override->co_base = xstrdup(optarg);
- break;
- case 'c':
- override->co_colldir = optarg;
- break;
- case 'd':
- error = asciitoint(optarg, &deletelim, 0);
- if (error || deletelim < 0) {
- lprintf(-1, "Invalid deletion limit\n");
- usage(argv0);
- return (1);
- }
- break;
- case 'g':
- /* For compatibility. */
- break;
- case 'h':
- if (override->co_host != NULL)
- free(override->co_host);
- override->co_host = xstrdup(optarg);
- break;
- case 'i':
- pattlist_add(override->co_accepts, optarg);
- break;
- case 'k':
- override->co_options |= CO_KEEPBADFILES;
- overridemask |= CO_KEEPBADFILES;
- break;
- case 'l':
- lockfile = optarg;
- lflag = 1;
- lockfd = open(lockfile,
- O_CREAT | O_WRONLY | O_TRUNC, 0700);
- if (lockfd != -1) {
- error = flock(lockfd, LOCK_EX | LOCK_NB);
- if (error == -1 && errno == EWOULDBLOCK) {
- if (lockfd != -1)
- close(lockfd);
- lprintf(-1, "\"%s\" is already locked "
- "by another process\n", lockfile);
- return (1);
- }
- }
- if (lockfd == -1 || error == -1) {
- if (lockfd != -1)
- close(lockfd);
- lprintf(-1, "Error locking \"%s\": %s\n",
- lockfile, strerror(errno));
- return (1);
- }
- lock = stream_open_fd(lockfd,
- NULL, stream_write_fd, NULL);
- (void)stream_printf(lock, "%10ld\n", (long)getpid());
- stream_close(lock);
- break;
- case 'L':
- error = asciitoint(optarg, &verbose, 0);
- if (error) {
- lprintf(-1, "Invalid verbosity\n");
- usage(argv0);
- return (1);
- }
- break;
- case 'p':
- /* Use specified server port. */
- error = asciitoint(optarg, &port, 0);
- if (error) {
- lprintf(-1, "Invalid server port\n");
- usage(argv0);
- return (1);
- }
- if (port <= 0 || port >= 65536) {
- lprintf(-1, "Invalid port %d\n", port);
- return (1);
- }
- if (port < 1024) {
- lprintf(-1, "Reserved port %d not permitted\n",
- port);
- return (1);
- }
- break;
- case 'P':
- /* For compatibility. */
- if (strcmp(optarg, "m") != 0) {
- lprintf(-1,
- "Client only supports multiplexed mode\n");
- return (1);
- }
- break;
- case 'r':
- error = asciitoint(optarg, &retries, 0);
- if (error || retries < 0) {
- lprintf(-1, "Invalid retry limit\n");
- usage(argv0);
- return (1);
- }
- break;
- case 's':
- override->co_options |= CO_TRUSTSTATUSFILE;
- overridemask |= CO_TRUSTSTATUSFILE;
- break;
- case 'v':
- lprintf(0, "CVSup client written in C\n");
- lprintf(0, "Software version: %s\n", PROTO_SWVER);
- lprintf(0, "Protocol version: %d.%d\n",
- PROTO_MAJ, PROTO_MIN);
- lprintf(0, "http://mu.org/~mux/csup.html\n");
- return (0);
- break;
- case 'z':
- /* Force compression on all collections. */
- override->co_options |= CO_COMPRESS;
- overridemask |= CO_COMPRESS;
- break;
- case 'Z':
- /* Disables compression on all collections. */
- override->co_options &= ~CO_COMPRESS;
- overridemask &= ~CO_COMPRESS;
- break;
- case '?':
- default:
- usage(argv0);
- return (1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc < 1) {
- usage(argv0);
- return (1);
- }
-
- file = argv[0];
- lprintf(2, "Parsing supfile \"%s\"\n", file);
- config = config_init(file, override, overridemask);
- coll_free(override);
- if (config == NULL)
- return (1);
-
- if (config_checkcolls(config) == 0) {
- lprintf(-1, "No collections selected\n");
- return (1);
- }
-
- if (laddr != NULL) {
- config->laddr = laddr;
- config->laddrlen = laddrlen;
- }
- config->deletelim = deletelim;
- config->reqauth = reqauth;
- lprintf(2, "Connecting to %s\n", config->host);
-
- i = 0;
- fattr_init(); /* Initialize the fattr API. */
- timer = bt_new(300, 7200, 2.0, 0.1);
- for (;;) {
- status = proto_connect(config, family, port);
- if (status == STATUS_SUCCESS) {
- status = proto_run(config);
- if (status != STATUS_TRANSIENTFAILURE)
- break;
- }
- if (retries >= 0 && i >= retries)
- break;
- nexttry = time(0) + bt_get(timer);
- localtime_r(&nexttry, &tm);
- lprintf(1, "Will retry at %02d:%02d:%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- bt_pause(timer);
- lprintf(1, "Retrying\n");
- i++;
- }
- bt_free(timer);
- fattr_fini();
- if (lflag) {
- unlink(lockfile);
- flock(lockfd, LOCK_UN);
- close(lockfd);
- }
- config_free(config);
- if (status != STATUS_SUCCESS)
- return (1);
- return (0);
-}
diff --git a/contrib/csup/main.h b/contrib/csup/main.h
deleted file mode 100644
index 217c7eb..0000000
--- a/contrib/csup/main.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-extern int verbose;
diff --git a/contrib/csup/misc.c b/contrib/csup/misc.c
deleted file mode 100644
index ae16b59..0000000
--- a/contrib/csup/misc.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <openssl/md5.h>
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "fattr.h"
-#include "main.h"
-#include "misc.h"
-
-struct pattlist {
- char **patterns;
- size_t size;
- size_t in;
-};
-
-struct backoff_timer {
- time_t min;
- time_t max;
- time_t interval;
- float backoff;
- float jitter;
-};
-
-static void bt_update(struct backoff_timer *);
-static void bt_addjitter(struct backoff_timer *);
-
-int
-asciitoint(const char *s, int *val, int base)
-{
- char *end;
- long longval;
-
- errno = 0;
- longval = strtol(s, &end, base);
- if (errno || *end != '\0')
- return (-1);
- if (longval > INT_MAX || longval < INT_MIN) {
- errno = ERANGE;
- return (-1);
- }
- *val = longval;
- return (0);
-}
-
-int
-lprintf(int level, const char *fmt, ...)
-{
- FILE *to;
- va_list ap;
- int ret;
-
- if (level > verbose)
- return (0);
- if (level == -1)
- to = stderr;
- else
- to = stdout;
- va_start(ap, fmt);
- ret = vfprintf(to, fmt, ap);
- va_end(ap);
- fflush(to);
- return (ret);
-}
-
-/*
- * Compute the MD5 checksum of a file. The md parameter must
- * point to a buffer containing at least MD5_DIGEST_SIZE bytes.
- *
- * Do not confuse OpenSSL's MD5_DIGEST_LENGTH with our own
- * MD5_DIGEST_SIZE macro.
- */
-int
-MD5_File(char *path, char *md)
-{
- char buf[1024];
- MD5_CTX ctx;
- ssize_t n;
- int fd;
-
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return (-1);
- MD5_Init(&ctx);
- while ((n = read(fd, buf, sizeof(buf))) > 0)
- MD5_Update(&ctx, buf, n);
- close(fd);
- if (n == -1)
- return (-1);
- MD5_End(md, &ctx);
- return (0);
-}
-
-/*
- * Wrapper around MD5_Final() that converts the 128 bits MD5 hash
- * to an ASCII string representing this value in hexadecimal.
- */
-void
-MD5_End(char *md, MD5_CTX *c)
-{
- unsigned char md5[MD5_DIGEST_LENGTH];
- const char hex[] = "0123456789abcdef";
- int i, j;
-
- MD5_Final(md5, c);
- j = 0;
- for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
- md[j++] = hex[md5[i] >> 4];
- md[j++] = hex[md5[i] & 0xf];
- }
- md[j] = '\0';
-}
-
-int
-pathcmp(const char *s1, const char *s2)
-{
- char c1, c2;
-
- do {
- c1 = *s1++;
- if (c1 == '/')
- c1 = 1;
- c2 = *s2++;
- if (c2 == '/')
- c2 = 1;
- } while (c1 == c2 && c1 != '\0');
-
- return (c1 - c2);
-}
-
-size_t
-commonpathlength(const char *a, size_t alen, const char *b, size_t blen)
-{
- size_t i, minlen, lastslash;
-
- minlen = min(alen, blen);
- lastslash = 0;
- for (i = 0; i < minlen; i++) {
- if (a[i] != b[i])
- return (lastslash);
- if (a[i] == '/') {
- if (i == 0) /* Include the leading slash. */
- lastslash = 1;
- else
- lastslash = i;
- }
- }
-
- /* One path is a prefix of the other/ */
- if (alen > minlen) { /* Path "b" is a prefix of "a". */
- if (a[minlen] == '/')
- return (minlen);
- else
- return (lastslash);
- } else if (blen > minlen) { /* Path "a" is a prefix of "b". */
- if (b[minlen] == '/')
- return (minlen);
- else
- return (lastslash);
- }
-
- /* The paths are identical. */
- return (minlen);
-}
-
-const char *
-pathlast(const char *path)
-{
- const char *s;
-
- s = strrchr(path, '/');
- if (s == NULL)
- return (path);
- return (++s);
-}
-
-int
-rcsdatetotm(const char *revdate, struct tm *tm)
-{
- char *cp;
- size_t len;
-
- cp = strchr(revdate, '.');
- if (cp == NULL)
- return (-1);
- len = cp - revdate;
- if (len >= 4)
- cp = strptime(revdate, "%Y.%m.%d.%H.%M.%S", tm);
- else if (len == 2)
- cp = strptime(revdate, "%y.%m.%d.%H.%M.%S", tm);
- else
- return (-1);
- if (cp == NULL || *cp != '\0')
- return (-1);
- return (0);
-}
-
-time_t
-rcsdatetotime(const char *revdate)
-{
- struct tm tm;
- time_t t;
- int error;
-
- error = rcsdatetotm(revdate, &tm);
- if (error)
- return (error);
- t = timegm(&tm);
- return (t);
-}
-
-/*
- * Checks if a file is an RCS file.
- */
-int
-isrcs(const char *file, size_t *len)
-{
- const char *cp;
-
- if (file[0] == '/')
- return (0);
- cp = file;
- while ((cp = strstr(cp, "..")) != NULL) {
- if (cp == file || cp[2] == '\0' ||
- (cp[-1] == '/' && cp[2] == '/'))
- return (0);
- cp += 2;
- }
- *len = strlen(file);
- if (*len < 2 || file[*len - 1] != 'v' || file[*len - 2] != ',') {
- return (0);
- }
-
- return (1);
-}
-
-/*
- * Returns a buffer allocated with malloc() containing the absolute
- * pathname to the checkout file made from the prefix and the path
- * of the corresponding RCS file relatively to the prefix. If the
- * filename is not an RCS filename, NULL will be returned.
- */
-char *
-checkoutpath(const char *prefix, const char *file)
-{
- char *path;
- size_t len;
-
- if (!isrcs(file, &len))
- return (NULL);
- xasprintf(&path, "%s/%.*s", prefix, (int)len - 2, file);
- return (path);
-}
-
-/*
- * Returns a cvs path allocated with malloc() containing absolute pathname to a
- * file in cvs mode which can reside in the attic. XXX: filename has really no
- * restrictions.
- */
-char *
-cvspath(const char *prefix, const char *file, int attic)
-{
- const char *last;
- char *path;
-
- last = pathlast(file);
- if (attic)
- xasprintf(&path, "%s/%.*sAttic/%s", prefix, (int)(last - file),
- file, last);
- else
- xasprintf(&path, "%s/%s", prefix, file);
-
- return (path);
-}
-
-/*
- * Regular or attic path if regular fails.
- * XXX: This should perhaps also check if the Attic file exists too, and return
- * NULL if not.
- */
-char *
-atticpath(const char *prefix, const char *file)
-{
- char *path;
-
- path = cvspath(prefix, file, 0);
- if (access(path, F_OK) != 0) {
- free(path);
- path = cvspath(prefix, file, 1);
- }
- return (path);
-}
-
-int
-mkdirhier(char *path, mode_t mask)
-{
- struct fattr *fa;
- size_t i, last, len;
- int error, finish, rv;
-
- finish = 0;
- last = 0;
- len = strlen(path);
- for (i = len - 1; i > 0; i--) {
- if (path[i] == '/') {
- path[i] = '\0';
- if (access(path, F_OK) == 0) {
- path[i] = '/';
- break;
- }
- if (errno != ENOENT) {
- path[i] = '/';
- if (last == 0)
- return (-1);
- finish = 1;
- break;
- }
- last = i;
- }
- }
- if (last == 0)
- return (0);
-
- i = strlen(path);
- fa = fattr_new(FT_DIRECTORY, -1);
- fattr_mergedefault(fa);
- fattr_umask(fa, mask);
- while (i < len) {
- if (!finish) {
- rv = 0;
- error = fattr_makenode(fa, path);
- if (!error)
- rv = fattr_install(fa, path, NULL);
- if (error || rv == -1)
- finish = 1;
- }
- path[i] = '/';
- i += strlen(path + i);
- }
- assert(i == len);
- if (finish)
- return (-1);
- return (0);
-}
-
-/*
- * Compute temporary pathnames.
- * This can look a bit like overkill but we mimic CVSup's behaviour.
- */
-#define TEMPNAME_PREFIX "#cvs.csup"
-
-static pthread_mutex_t tempname_mtx = PTHREAD_MUTEX_INITIALIZER;
-static pid_t tempname_pid = -1;
-static int tempname_count;
-
-char *
-tempname(const char *path)
-{
- char *cp, *temp;
- int count, error;
-
- error = pthread_mutex_lock(&tempname_mtx);
- assert(!error);
- if (tempname_pid == -1) {
- tempname_pid = getpid();
- tempname_count = 0;
- }
- count = tempname_count++;
- error = pthread_mutex_unlock(&tempname_mtx);
- assert(!error);
- cp = strrchr(path, '/');
- if (cp == NULL)
- xasprintf(&temp, "%s-%ld.%d", TEMPNAME_PREFIX,
- (long)tempname_pid, count);
- else
- xasprintf(&temp, "%.*s%s-%ld.%d", (int)(cp - path + 1), path,
- TEMPNAME_PREFIX, (long)tempname_pid, count);
- return (temp);
-}
-
-void *
-xmalloc(size_t size)
-{
- void *buf;
-
- buf = malloc(size);
- if (buf == NULL)
- err(1, "malloc");
- return (buf);
-}
-
-void *
-xrealloc(void *buf, size_t size)
-{
-
- buf = realloc(buf, size);
- if (buf == NULL)
- err(1, "realloc");
- return (buf);
-}
-
-char *
-xstrdup(const char *str)
-{
- char *buf;
-
- buf = strdup(str);
- if (buf == NULL)
- err(1, "strdup");
- return (buf);
-}
-
-int
-xasprintf(char **ret, const char *format, ...)
-{
- va_list ap;
- int rv;
-
- va_start(ap, format);
- rv = vasprintf(ret, format, ap);
- va_end(ap);
- if (*ret == NULL)
- err(1, "asprintf");
- return (rv);
-}
-
-struct pattlist *
-pattlist_new(void)
-{
- struct pattlist *p;
-
- p = xmalloc(sizeof(struct pattlist));
- p->size = 4; /* Initial size. */
- p->patterns = xmalloc(p->size * sizeof(char *));
- p->in = 0;
- return (p);
-}
-
-void
-pattlist_add(struct pattlist *p, const char *pattern)
-{
-
- if (p->in == p->size) {
- p->size *= 2;
- p->patterns = xrealloc(p->patterns, p->size * sizeof(char *));
- }
- assert(p->in < p->size);
- p->patterns[p->in++] = xstrdup(pattern);
-}
-
-char *
-pattlist_get(struct pattlist *p, size_t i)
-{
-
- assert(i < p->in);
- return (p->patterns[i]);
-}
-
-size_t
-pattlist_size(struct pattlist *p)
-{
-
- return (p->in);
-}
-
-void
-pattlist_free(struct pattlist *p)
-{
- size_t i;
-
- for (i = 0; i < p->in; i++)
- free(p->patterns[i]);
- free(p->patterns);
- free(p);
-}
-
-/* Creates a backoff timer. */
-struct backoff_timer *
-bt_new(time_t min, time_t max, float backoff, float jitter)
-{
- struct backoff_timer *bt;
-
- bt = xmalloc(sizeof(struct backoff_timer));
- bt->min = min;
- bt->max = max;
- bt->backoff = backoff;
- bt->jitter = jitter;
- bt->interval = min;
- bt_addjitter(bt);
- srandom(time(0));
- return (bt);
-}
-
-/* Updates the backoff timer. */
-static void
-bt_update(struct backoff_timer *bt)
-{
-
- bt->interval = (time_t)min(bt->interval * bt->backoff, bt->max);
- bt_addjitter(bt);
-}
-
-/* Adds some jitter. */
-static void
-bt_addjitter(struct backoff_timer *bt)
-{
- long mag;
-
- mag = (long)(bt->jitter * bt->interval);
- /* We want a random number between -mag and mag. */
- bt->interval += (time_t)(random() % (2 * mag) - mag);
-}
-
-/* Returns the current timer value. */
-time_t
-bt_get(struct backoff_timer *bt)
-{
-
- return (bt->interval);
-}
-
-/* Times out for bt->interval seconds. */
-void
-bt_pause(struct backoff_timer *bt)
-{
-
- sleep(bt->interval);
- bt_update(bt);
-}
-
-void
-bt_free(struct backoff_timer *bt)
-{
-
- free(bt);
-}
-
-/* Compare two revisions. */
-int
-rcsnum_cmp(char *revision1, char *revision2)
-{
- char *ptr1, *ptr2, *dot1, *dot2;
- int num1len, num2len, ret;
-
- ptr1 = revision1;
- ptr2 = revision2;
- while (*ptr1 != '\0' && *ptr2 != '\0') {
- dot1 = strchr(ptr1, '.');
- dot2 = strchr(ptr2, '.');
- if (dot1 == NULL)
- dot1 = strchr(ptr1, '\0');
- if (dot2 == NULL)
- dot2 = strchr(ptr2, '\0');
-
- num1len = dot1 - ptr1;
- num2len = dot2 - ptr2;
- /* Check the distance between each, showing how many digits */
- if (num1len > num2len)
- return (1);
- else if (num1len < num2len)
- return (-1);
-
- /* Equal distance means we must check each character. */
- ret = strncmp(ptr1, ptr2, num1len);
- if (ret != 0)
- return (ret);
- ptr1 = (*dot1 == '.') ? (dot1 + 1) : dot1;
- ptr2 = (*dot2 == '.') ? (dot2 + 1) : dot2;
- }
-
- if (*ptr1 != '\0' && *ptr2 == '\0')
- return (1);
- if (*ptr1 == '\0' && *ptr2 != '\0')
- return (-1);
- return (0);
-
-}
-
-/* Returns 0 if a rcsrev is not a trunk revision number. */
-int
-rcsrev_istrunk(char *revnum)
-{
- char *tmp;
-
- tmp = strchr(revnum, '.');
- tmp++;
- if (strchr(tmp, '.') != NULL)
- return (0);
- return (1);
-}
-
-/* Return prefix of rcsfile. */
-char *
-rcsrev_prefix(char *revnum)
-{
- char *modrev, *pos;
-
- modrev = xstrdup(revnum);
- pos = strrchr(modrev, '.');
- if (pos == NULL) {
- free(modrev);
- return (NULL);
- }
- *pos = '\0';
- return (modrev);
-}
diff --git a/contrib/csup/misc.h b/contrib/csup/misc.h
deleted file mode 100644
index a7ca3a6..0000000
--- a/contrib/csup/misc.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _MISC_H_
-#define _MISC_H_
-
-#include <openssl/md5.h>
-
-#include <sys/types.h>
-
-/* If we're not compiling in a C99 environment, define the C99 types. */
-#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901
-
-#ifdef uint32_t
-#undef uint32_t
-#endif
-#define uint32_t u_int32_t
-
-#ifdef uint16_t
-#undef uint16_t
-#endif
-#define uint16_t u_int16_t
-
-#ifdef uint8_t
-#undef uint8_t
-#endif
-#define uint8_t u_int8_t
-
-#else
-#include <stdint.h>
-#endif
-
-/* This is a GCC-specific keyword but some other compilers (namely icc)
- understand it, and the code won't work if we can't disable padding
- anyways. */
-#undef __packed
-#define __packed __attribute__((__packed__))
-
-/* We explicitely don't define this with icc because it defines __GNUC__
- but doesn't support it. */
-#undef __printflike
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && \
- (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC__MINOR__ >= 7)
-#define __printflike(fmtarg, firstvararg) \
- __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
-#else
-#define __printflike(fmtarg, firstvararg)
-#endif
-
-/* Exit codes. */
-#define STATUS_SUCCESS 0
-#define STATUS_FAILURE 1
-#define STATUS_TRANSIENTFAILURE 2
-#define STATUS_INTERRUPTED 3
-
-struct config;
-struct stream;
-
-/* Thread parameters. */
-struct thread_args {
- struct config *config;
- struct stream *rd;
- struct stream *wr;
- int status;
- char *errmsg;
-};
-
-/* Minimum size for MD5_File() and MD5_End() buffers. */
-#define MD5_DIGEST_SIZE 33
-
-#define min(a, b) ((a) > (b) ? (b) : (a))
-#define max(a, b) ((a) < (b) ? (b) : (a))
-
-struct backoff_timer;
-struct pattlist;
-struct tm;
-
-int asciitoint(const char *, int *, int);
-int lprintf(int, const char *, ...) __printflike(2, 3);
-int MD5_File(char *, char *);
-void MD5_End(char *, MD5_CTX *);
-int rcsdatetotm(const char *, struct tm *);
-time_t rcsdatetotime(const char *);
-int pathcmp(const char *, const char *);
-size_t commonpathlength(const char *, size_t, const char *, size_t);
-const char *pathlast(const char *);
-int isrcs(const char *, size_t *);
-char *checkoutpath(const char *, const char *);
-char *cvspath(const char *, const char *, int);
-char *atticpath(const char *, const char *);
-char *path_prefix(char *);
-char *path_first(char *);
-int mkdirhier(char *, mode_t);
-char *tempname(const char *);
-void *xmalloc(size_t);
-void *xrealloc(void *, size_t);
-char *xstrdup(const char *);
-int xasprintf(char **, const char *, ...) __printflike(2, 3);
-int rcsnum_cmp(char *, char *);
-int rcsrev_istrunk(char *);
-char *rcsrev_prefix(char *);
-
-struct pattlist *pattlist_new(void);
-void pattlist_add(struct pattlist *, const char *);
-char *pattlist_get(struct pattlist *, size_t);
-size_t pattlist_size(struct pattlist *);
-void pattlist_free(struct pattlist *);
-
-struct backoff_timer *bt_new(time_t, time_t, float, float);
-time_t bt_get(struct backoff_timer *);
-void bt_pause(struct backoff_timer *);
-void bt_free(struct backoff_timer *);
-
-#endif /* !_MISC_H_ */
diff --git a/contrib/csup/mux.c b/contrib/csup/mux.c
deleted file mode 100644
index b344be1..0000000
--- a/contrib/csup/mux.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <netinet/in.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "misc.h"
-#include "mux.h"
-
-/*
- * Packet types.
- */
-#define MUX_STARTUPREQ 0
-#define MUX_STARTUPREP 1
-#define MUX_CONNECT 2
-#define MUX_ACCEPT 3
-#define MUX_RESET 4
-#define MUX_DATA 5
-#define MUX_WINDOW 6
-#define MUX_CLOSE 7
-
-/*
- * Header sizes.
- */
-#define MUX_STARTUPHDRSZ 3
-#define MUX_CONNECTHDRSZ 8
-#define MUX_ACCEPTHDRSZ 8
-#define MUX_RESETHDRSZ 2
-#define MUX_DATAHDRSZ 4
-#define MUX_WINDOWHDRSZ 6
-#define MUX_CLOSEHDRSZ 2
-
-#define MUX_PROTOVER 0 /* Protocol version. */
-
-struct mux_header {
- uint8_t type;
- union {
- struct {
- uint16_t version;
- } __packed mh_startup;
- struct {
- uint8_t id;
- uint16_t mss;
- uint32_t window;
- } __packed mh_connect;
- struct {
- uint8_t id;
- uint16_t mss;
- uint32_t window;
- } __packed mh_accept;
- struct {
- uint8_t id;
- } __packed mh_reset;
- struct {
- uint8_t id;
- uint16_t len;
- } __packed mh_data;
- struct {
- uint8_t id;
- uint32_t window;
- } __packed mh_window;
- struct {
- uint8_t id;
- } __packed mh_close;
- } mh_u;
-} __packed;
-
-#define mh_startup mh_u.mh_startup
-#define mh_connect mh_u.mh_connect
-#define mh_accept mh_u.mh_accept
-#define mh_reset mh_u.mh_reset
-#define mh_data mh_u.mh_data
-#define mh_window mh_u.mh_window
-#define mh_close mh_u.mh_close
-
-#define MUX_MAXCHAN 2
-
-/* Channel states. */
-#define CS_UNUSED 0
-#define CS_LISTENING 1
-#define CS_CONNECTING 2
-#define CS_ESTABLISHED 3
-#define CS_RDCLOSED 4
-#define CS_WRCLOSED 5
-#define CS_CLOSED 6
-
-/* Channel flags. */
-#define CF_CONNECT 0x01
-#define CF_ACCEPT 0x02
-#define CF_RESET 0x04
-#define CF_WINDOW 0x08
-#define CF_DATA 0x10
-#define CF_CLOSE 0x20
-
-#define CHAN_SBSIZE (16 * 1024) /* Send buffer size. */
-#define CHAN_RBSIZE (16 * 1024) /* Receive buffer size. */
-#define CHAN_MAXSEGSIZE 1024 /* Maximum segment size. */
-
-/* Circular buffer. */
-struct buf {
- uint8_t *data;
- size_t size;
- size_t in;
- size_t out;
-};
-
-struct chan {
- int flags;
- int state;
- pthread_mutex_t lock;
- struct mux *mux;
-
- /* Receiver state variables. */
- struct buf *recvbuf;
- pthread_cond_t rdready;
- uint32_t recvseq;
- uint16_t recvmss;
-
- /* Sender state variables. */
- struct buf *sendbuf;
- pthread_cond_t wrready;
- uint32_t sendseq;
- uint32_t sendwin;
- uint16_t sendmss;
-};
-
-struct mux {
- int closed;
- int status;
- int socket;
- pthread_mutex_t lock;
- pthread_cond_t done;
- struct chan *channels[MUX_MAXCHAN];
- int nchans;
-
- /* Sender thread data. */
- pthread_t sender;
- pthread_cond_t sender_newwork;
- pthread_cond_t sender_started;
- int sender_waiting;
- int sender_ready;
- int sender_lastid;
-
- /* Receiver thread data. */
- pthread_t receiver;
-};
-
-static int sock_writev(int, struct iovec *, int);
-static int sock_write(int, void *, size_t);
-static ssize_t sock_read(int, void *, size_t);
-static int sock_readwait(int, void *, size_t);
-
-static int mux_init(struct mux *);
-static void mux_lock(struct mux *);
-static void mux_unlock(struct mux *);
-
-static struct chan *chan_new(struct mux *);
-static struct chan *chan_get(struct mux *, int);
-static struct chan *chan_connect(struct mux *, int);
-static void chan_lock(struct chan *);
-static void chan_unlock(struct chan *);
-static int chan_insert(struct mux *, struct chan *);
-static void chan_free(struct chan *);
-
-static struct buf *buf_new(size_t);
-static size_t buf_count(struct buf *);
-static size_t buf_avail(struct buf *);
-static void buf_get(struct buf *, void *, size_t);
-static void buf_put(struct buf *, const void *, size_t);
-static void buf_free(struct buf *);
-
-static void sender_wakeup(struct mux *);
-static void *sender_loop(void *);
-static int sender_waitforwork(struct mux *, int *);
-static int sender_scan(struct mux *, int *);
-static void sender_cleanup(void *);
-
-static void *receiver_loop(void *);
-
-static int
-sock_writev(int s, struct iovec *iov, int iovcnt)
-{
- ssize_t nbytes;
-
-again:
- nbytes = writev(s, iov, iovcnt);
- if (nbytes != -1) {
- while (nbytes > 0 && (size_t)nbytes >= iov->iov_len) {
- nbytes -= iov->iov_len;
- iov++;
- iovcnt--;
- }
- if (nbytes == 0)
- return (0);
- iov->iov_len -= nbytes;
- iov->iov_base = (char *)iov->iov_base + nbytes;
- } else if (errno != EINTR) {
- return (-1);
- }
- goto again;
-}
-
-static int
-sock_write(int s, void *buf, size_t size)
-{
- struct iovec iov;
- int ret;
-
- iov.iov_base = buf;
- iov.iov_len = size;
- ret = sock_writev(s, &iov, 1);
- return (ret);
-}
-
-static ssize_t
-sock_read(int s, void *buf, size_t size)
-{
- ssize_t nbytes;
-
-again:
- nbytes = read(s, buf, size);
- if (nbytes == -1 && errno == EINTR)
- goto again;
- return (nbytes);
-}
-
-static int
-sock_readwait(int s, void *buf, size_t size)
-{
- char *cp;
- ssize_t nbytes;
- size_t left;
-
- cp = buf;
- left = size;
- while (left > 0) {
- nbytes = sock_read(s, cp, left);
- if (nbytes == 0) {
- errno = ECONNRESET;
- return (-1);
- }
- if (nbytes < 0)
- return (-1);
- left -= nbytes;
- cp += nbytes;
- }
- return (0);
-}
-
-static void
-mux_lock(struct mux *m)
-{
- int error;
-
- error = pthread_mutex_lock(&m->lock);
- assert(!error);
-}
-
-static void
-mux_unlock(struct mux *m)
-{
- int error;
-
- error = pthread_mutex_unlock(&m->lock);
- assert(!error);
-}
-
-/* Create a TCP multiplexer on the given socket. */
-struct mux *
-mux_open(int sock, struct chan **chan)
-{
- struct mux *m;
- struct chan *chan0;
- int error;
-
- m = xmalloc(sizeof(struct mux));
- memset(m->channels, 0, sizeof(m->channels));
- m->nchans = 0;
- m->closed = 0;
- m->status = -1;
- m->socket = sock;
-
- m->sender_waiting = 0;
- m->sender_lastid = 0;
- m->sender_ready = 0;
- pthread_mutex_init(&m->lock, NULL);
- pthread_cond_init(&m->done, NULL);
- pthread_cond_init(&m->sender_newwork, NULL);
- pthread_cond_init(&m->sender_started, NULL);
-
- error = mux_init(m);
- if (error)
- goto bad;
- chan0 = chan_connect(m, 0);
- if (chan0 == NULL)
- goto bad;
- *chan = chan0;
- return (m);
-bad:
- mux_shutdown(m, NULL, STATUS_FAILURE);
- (void)mux_close(m);
- return (NULL);
-}
-
-int
-mux_close(struct mux *m)
-{
- struct chan *chan;
- int i, status;
-
- assert(m->closed);
- for (i = 0; i < m->nchans; i++) {
- chan = m->channels[i];
- if (chan != NULL)
- chan_free(chan);
- }
- pthread_cond_destroy(&m->sender_started);
- pthread_cond_destroy(&m->sender_newwork);
- pthread_cond_destroy(&m->done);
- pthread_mutex_destroy(&m->lock);
- status = m->status;
- free(m);
- return (status);
-}
-
-/* Close a channel. */
-int
-chan_close(struct chan *chan)
-{
-
- chan_lock(chan);
- if (chan->state == CS_ESTABLISHED) {
- chan->state = CS_WRCLOSED;
- chan->flags |= CF_CLOSE;
- } else if (chan->state == CS_RDCLOSED) {
- chan->state = CS_CLOSED;
- chan->flags |= CF_CLOSE;
- } else if (chan->state == CS_WRCLOSED || chan->state == CS_CLOSED) {
- chan_unlock(chan);
- return (0);
- } else {
- chan_unlock(chan);
- return (-1);
- }
- chan_unlock(chan);
- sender_wakeup(chan->mux);
- return (0);
-}
-
-void
-chan_wait(struct chan *chan)
-{
-
- chan_lock(chan);
- while (chan->state != CS_CLOSED)
- pthread_cond_wait(&chan->rdready, &chan->lock);
- chan_unlock(chan);
-}
-
-/* Returns the ID of an available channel in the listening state. */
-int
-chan_listen(struct mux *m)
-{
- struct chan *chan;
- int i;
-
- mux_lock(m);
- for (i = 0; i < m->nchans; i++) {
- chan = m->channels[i];
- chan_lock(chan);
- if (chan->state == CS_UNUSED) {
- mux_unlock(m);
- chan->state = CS_LISTENING;
- chan_unlock(chan);
- return (i);
- }
- chan_unlock(chan);
- }
- mux_unlock(m);
- chan = chan_new(m);
- chan->state = CS_LISTENING;
- i = chan_insert(m, chan);
- if (i == -1)
- chan_free(chan);
- return (i);
-}
-
-struct chan *
-chan_accept(struct mux *m, int id)
-{
- struct chan *chan;
-
- chan = chan_get(m, id);
- while (chan->state == CS_LISTENING)
- pthread_cond_wait(&chan->rdready, &chan->lock);
- if (chan->state != CS_ESTABLISHED) {
- errno = ECONNRESET;
- chan_unlock(chan);
- return (NULL);
- }
- chan_unlock(chan);
- return (chan);
-}
-
-/* Read bytes from a channel. */
-ssize_t
-chan_read(struct chan *chan, void *buf, size_t size)
-{
- char *cp;
- size_t count, n;
-
- cp = buf;
- chan_lock(chan);
- for (;;) {
- if (chan->state == CS_RDCLOSED || chan->state == CS_CLOSED) {
- chan_unlock(chan);
- return (0);
- }
- if (chan->state != CS_ESTABLISHED &&
- chan->state != CS_WRCLOSED) {
- chan_unlock(chan);
- errno = EBADF;
- return (-1);
- }
- count = buf_count(chan->recvbuf);
- if (count > 0)
- break;
- pthread_cond_wait(&chan->rdready, &chan->lock);
- }
- n = min(count, size);
- buf_get(chan->recvbuf, cp, n);
- chan->recvseq += n;
- chan->flags |= CF_WINDOW;
- chan_unlock(chan);
- /* We need to wake up the sender so that it sends a window update. */
- sender_wakeup(chan->mux);
- return (n);
-}
-
-/* Write bytes to a channel. */
-ssize_t
-chan_write(struct chan *chan, const void *buf, size_t size)
-{
- const char *cp;
- size_t avail, n, pos;
-
- pos = 0;
- cp = buf;
- chan_lock(chan);
- while (pos < size) {
- for (;;) {
- if (chan->state != CS_ESTABLISHED &&
- chan->state != CS_RDCLOSED) {
- chan_unlock(chan);
- errno = EPIPE;
- return (-1);
- }
- avail = buf_avail(chan->sendbuf);
- if (avail > 0)
- break;
- pthread_cond_wait(&chan->wrready, &chan->lock);
- }
- n = min(avail, size - pos);
- buf_put(chan->sendbuf, cp + pos, n);
- pos += n;
- }
- chan_unlock(chan);
- sender_wakeup(chan->mux);
- return (size);
-}
-
-/*
- * Internal channel API.
- */
-
-static struct chan *
-chan_connect(struct mux *m, int id)
-{
- struct chan *chan;
-
- chan = chan_get(m, id);
- if (chan->state != CS_UNUSED) {
- chan_unlock(chan);
- return (NULL);
- }
- chan->state = CS_CONNECTING;
- chan->flags |= CF_CONNECT;
- chan_unlock(chan);
- sender_wakeup(m);
- chan_lock(chan);
- while (chan->state == CS_CONNECTING)
- pthread_cond_wait(&chan->wrready, &chan->lock);
- if (chan->state != CS_ESTABLISHED) {
- chan_unlock(chan);
- return (NULL);
- }
- chan_unlock(chan);
- return (chan);
-}
-
-/*
- * Get a channel from its ID, creating it if necessary.
- * The channel is returned locked.
- */
-static struct chan *
-chan_get(struct mux *m, int id)
-{
- struct chan *chan;
-
- assert(id < MUX_MAXCHAN);
- mux_lock(m);
- chan = m->channels[id];
- if (chan == NULL) {
- chan = chan_new(m);
- m->channels[id] = chan;
- m->nchans++;
- }
- chan_lock(chan);
- mux_unlock(m);
- return (chan);
-}
-
-/* Lock a channel. */
-static void
-chan_lock(struct chan *chan)
-{
- int error;
-
- error = pthread_mutex_lock(&chan->lock);
- assert(!error);
-}
-
-/* Unlock a channel. */
-static void
-chan_unlock(struct chan *chan)
-{
- int error;
-
- error = pthread_mutex_unlock(&chan->lock);
- assert(!error);
-}
-
-/*
- * Create a new channel.
- */
-static struct chan *
-chan_new(struct mux *m)
-{
- struct chan *chan;
-
- chan = xmalloc(sizeof(struct chan));
- chan->state = CS_UNUSED;
- chan->flags = 0;
- chan->mux = m;
- chan->sendbuf = buf_new(CHAN_SBSIZE);
- chan->sendseq = 0;
- chan->sendwin = 0;
- chan->sendmss = 0;
- chan->recvbuf = buf_new(CHAN_RBSIZE);
- chan->recvseq = 0;
- chan->recvmss = CHAN_MAXSEGSIZE;
- pthread_mutex_init(&chan->lock, NULL);
- pthread_cond_init(&chan->rdready, NULL);
- pthread_cond_init(&chan->wrready, NULL);
- return (chan);
-}
-
-/* Free any resources associated with a channel. */
-static void
-chan_free(struct chan *chan)
-{
-
- pthread_cond_destroy(&chan->rdready);
- pthread_cond_destroy(&chan->wrready);
- pthread_mutex_destroy(&chan->lock);
- buf_free(chan->recvbuf);
- buf_free(chan->sendbuf);
- free(chan);
-}
-
-/* Insert the new channel in the channel list. */
-static int
-chan_insert(struct mux *m, struct chan *chan)
-{
- int i;
-
- mux_lock(m);
- for (i = 0; i < MUX_MAXCHAN; i++) {
- if (m->channels[i] == NULL) {
- m->channels[i] = chan;
- m->nchans++;
- mux_unlock(m);
- return (i);
- }
- }
- errno = ENOBUFS;
- return (-1);
-}
-
-/*
- * Initialize the multiplexer protocol.
- *
- * This means negotiating protocol version and starting
- * the receiver and sender threads.
- */
-static int
-mux_init(struct mux *m)
-{
- struct mux_header mh;
- int error;
-
- mh.type = MUX_STARTUPREQ;
- mh.mh_startup.version = htons(MUX_PROTOVER);
- error = sock_write(m->socket, &mh, MUX_STARTUPHDRSZ);
- if (error)
- return (-1);
- error = sock_readwait(m->socket, &mh, MUX_STARTUPHDRSZ);
- if (error)
- return (-1);
- if (mh.type != MUX_STARTUPREP ||
- ntohs(mh.mh_startup.version) != MUX_PROTOVER)
- return (-1);
- mux_lock(m);
- error = pthread_create(&m->sender, NULL, sender_loop, m);
- if (error) {
- mux_unlock(m);
- return (-1);
- }
- /*
- * Make sure the sender thread has run and is waiting for new work
- * before going on. Otherwise, it might lose the race and a
- * request, which will cause a deadlock.
- */
- while (!m->sender_ready)
- pthread_cond_wait(&m->sender_started, &m->lock);
-
- mux_unlock(m);
- error = pthread_create(&m->receiver, NULL, receiver_loop, m);
- if (error)
- return (-1);
- return (0);
-}
-
-/*
- * Close all the channels, terminate the sender and receiver thread.
- * This is an important function because it is used everytime we need
- * to wake up all the worker threads to abort the program.
- *
- * This function accepts an error message that will be printed if the
- * multiplexer wasn't already closed. This is useful because it ensures
- * that only the first error message will be printed, and that it will
- * be printed before doing the actual shutdown work. If this is a
- * normal shutdown, NULL can be passed instead.
- *
- * The "status" parameter of the first mux_shutdown() call is retained
- * and then returned by mux_close(), so that the main thread can know
- * what type of error happened in the end, if any.
- */
-void
-mux_shutdown(struct mux *m, const char *errmsg, int status)
-{
- pthread_t self, sender, receiver;
- struct chan *chan;
- const char *name;
- void *val;
- int i, ret;
-
- mux_lock(m);
- if (m->closed) {
- mux_unlock(m);
- return;
- }
- m->closed = 1;
- m->status = status;
- self = pthread_self();
- sender = m->sender;
- receiver = m->receiver;
- if (errmsg != NULL) {
- if (pthread_equal(self, receiver))
- name = "Receiver";
- else if (pthread_equal(self, sender))
- name = "Sender";
- else
- name = NULL;
- if (name == NULL)
- lprintf(-1, "%s\n", errmsg);
- else
- lprintf(-1, "%s: %s\n", name, errmsg);
- }
-
- for (i = 0; i < MUX_MAXCHAN; i++) {
- if (m->channels[i] != NULL) {
- chan = m->channels[i];
- chan_lock(chan);
- if (chan->state != CS_UNUSED) {
- chan->state = CS_CLOSED;
- chan->flags = 0;
- pthread_cond_broadcast(&chan->rdready);
- pthread_cond_broadcast(&chan->wrready);
- }
- chan_unlock(chan);
- }
- }
- mux_unlock(m);
-
- if (!pthread_equal(self, receiver)) {
- ret = pthread_cancel(receiver);
- assert(!ret);
- pthread_join(receiver, &val);
- assert(val == PTHREAD_CANCELED);
- }
- if (!pthread_equal(self, sender)) {
- ret = pthread_cancel(sender);
- assert(!ret);
- pthread_join(sender, &val);
- assert(val == PTHREAD_CANCELED);
- }
-}
-
-static void
-sender_wakeup(struct mux *m)
-{
- int waiting;
-
- mux_lock(m);
- waiting = m->sender_waiting;
- mux_unlock(m);
- /*
- * We don't care about the race here: if the sender was
- * waiting and is not anymore, we'll just send a useless
- * signal; if he wasn't waiting then he won't go to sleep
- * before having sent what we want him to.
- */
- if (waiting)
- pthread_cond_signal(&m->sender_newwork);
-}
-
-static void *
-sender_loop(void *arg)
-{
- struct iovec iov[3];
- struct mux_header mh;
- struct mux *m;
- struct chan *chan;
- struct buf *buf;
- uint32_t winsize;
- uint16_t hdrsize, size, len;
- int error, id, iovcnt, what = 0;
-
- m = (struct mux *)arg;
- what = 0;
-again:
- id = sender_waitforwork(m, &what);
- chan = chan_get(m, id);
- hdrsize = size = 0;
- switch (what) {
- case CF_CONNECT:
- mh.type = MUX_CONNECT;
- mh.mh_connect.id = id;
- mh.mh_connect.mss = htons(chan->recvmss);
- mh.mh_connect.window = htonl(chan->recvseq +
- chan->recvbuf->size);
- hdrsize = MUX_CONNECTHDRSZ;
- break;
- case CF_ACCEPT:
- mh.type = MUX_ACCEPT;
- mh.mh_accept.id = id;
- mh.mh_accept.mss = htons(chan->recvmss);
- mh.mh_accept.window = htonl(chan->recvseq +
- chan->recvbuf->size);
- hdrsize = MUX_ACCEPTHDRSZ;
- break;
- case CF_RESET:
- mh.type = MUX_RESET;
- mh.mh_reset.id = id;
- hdrsize = MUX_RESETHDRSZ;
- break;
- case CF_WINDOW:
- mh.type = MUX_WINDOW;
- mh.mh_window.id = id;
- mh.mh_window.window = htonl(chan->recvseq +
- chan->recvbuf->size);
- hdrsize = MUX_WINDOWHDRSZ;
- break;
- case CF_DATA:
- mh.type = MUX_DATA;
- mh.mh_data.id = id;
- size = min(buf_count(chan->sendbuf), chan->sendmss);
- winsize = chan->sendwin - chan->sendseq;
- if (winsize < size)
- size = winsize;
- mh.mh_data.len = htons(size);
- hdrsize = MUX_DATAHDRSZ;
- break;
- case CF_CLOSE:
- mh.type = MUX_CLOSE;
- mh.mh_close.id = id;
- hdrsize = MUX_CLOSEHDRSZ;
- break;
- }
- if (size > 0) {
- assert(mh.type == MUX_DATA);
- /*
- * Older FreeBSD versions (and maybe other OSes) have the
- * iov_base field defined as char *. Cast to char * to
- * silence a warning in this case.
- */
- iov[0].iov_base = (char *)&mh;
- iov[0].iov_len = hdrsize;
- iovcnt = 1;
- /* We access the buffer directly to avoid some copying. */
- buf = chan->sendbuf;
- len = min(size, buf->size + 1 - buf->out);
- iov[iovcnt].iov_base = buf->data + buf->out;
- iov[iovcnt].iov_len = len;
- iovcnt++;
- if (size > len) {
- /* Wrapping around. */
- iov[iovcnt].iov_base = buf->data;
- iov[iovcnt].iov_len = size - len;
- iovcnt++;
- }
- /*
- * Since we're the only thread sending bytes from the
- * buffer and modifying buf->out, it's safe to unlock
- * here during I/O. It avoids keeping the channel lock
- * too long, since write() might block.
- */
- chan_unlock(chan);
- error = sock_writev(m->socket, iov, iovcnt);
- if (error)
- goto bad;
- chan_lock(chan);
- chan->sendseq += size;
- buf->out += size;
- if (buf->out > buf->size)
- buf->out -= buf->size + 1;
- pthread_cond_signal(&chan->wrready);
- chan_unlock(chan);
- } else {
- chan_unlock(chan);
- error = sock_write(m->socket, &mh, hdrsize);
- if (error)
- goto bad;
- }
- goto again;
-bad:
- if (error == EPIPE)
- mux_shutdown(m, strerror(errno), STATUS_TRANSIENTFAILURE);
- else
- mux_shutdown(m, strerror(errno), STATUS_FAILURE);
- return (NULL);
-}
-
-static void
-sender_cleanup(void *arg)
-{
- struct mux *m;
-
- m = (struct mux *)arg;
- mux_unlock(m);
-}
-
-static int
-sender_waitforwork(struct mux *m, int *what)
-{
- int id;
-
- mux_lock(m);
- pthread_cleanup_push(sender_cleanup, m);
- if (!m->sender_ready) {
- pthread_cond_signal(&m->sender_started);
- m->sender_ready = 1;
- }
- while ((id = sender_scan(m, what)) == -1) {
- m->sender_waiting = 1;
- pthread_cond_wait(&m->sender_newwork, &m->lock);
- }
- m->sender_waiting = 0;
- pthread_cleanup_pop(1);
- return (id);
-}
-
-/*
- * Scan for work to do for the sender. Has to be called with
- * the multiplexer lock held.
- */
-static int
-sender_scan(struct mux *m, int *what)
-{
- struct chan *chan;
- int id;
-
- if (m->nchans <= 0)
- return (-1);
- id = m->sender_lastid;
- do {
- id++;
- if (id >= m->nchans)
- id = 0;
- chan = m->channels[id];
- chan_lock(chan);
- if (chan->state != CS_UNUSED) {
- if (chan->sendseq != chan->sendwin &&
- buf_count(chan->sendbuf) > 0)
- chan->flags |= CF_DATA;
- if (chan->flags) {
- /* By order of importance. */
- if (chan->flags & CF_CONNECT)
- *what = CF_CONNECT;
- else if (chan->flags & CF_ACCEPT)
- *what = CF_ACCEPT;
- else if (chan->flags & CF_RESET)
- *what = CF_RESET;
- else if (chan->flags & CF_WINDOW)
- *what = CF_WINDOW;
- else if (chan->flags & CF_DATA)
- *what = CF_DATA;
- else if (chan->flags & CF_CLOSE)
- *what = CF_CLOSE;
- chan->flags &= ~*what;
- chan_unlock(chan);
- m->sender_lastid = id;
- return (id);
- }
- }
- chan_unlock(chan);
- } while (id != m->sender_lastid);
- return (-1);
-}
-
-/* Read the rest of a packet header depending on its type. */
-#define SOCK_READREST(s, mh, hsize) \
- sock_readwait(s, (char *)&mh + sizeof(mh.type), (hsize) - sizeof(mh.type))
-
-void *
-receiver_loop(void *arg)
-{
- struct mux_header mh;
- struct mux *m;
- struct chan *chan;
- struct buf *buf;
- uint16_t size, len;
- int error;
-
- m = (struct mux *)arg;
- while ((error = sock_readwait(m->socket, &mh.type,
- sizeof(mh.type))) == 0) {
- switch (mh.type) {
- case MUX_CONNECT:
- error = SOCK_READREST(m->socket, mh, MUX_CONNECTHDRSZ);
- if (error)
- goto bad;
- chan = chan_get(m, mh.mh_connect.id);
- if (chan->state == CS_LISTENING) {
- chan->state = CS_ESTABLISHED;
- chan->sendmss = ntohs(mh.mh_connect.mss);
- chan->sendwin = ntohl(mh.mh_connect.window);
- chan->flags |= CF_ACCEPT;
- pthread_cond_signal(&chan->rdready);
- } else
- chan->flags |= CF_RESET;
- chan_unlock(chan);
- sender_wakeup(m);
- break;
- case MUX_ACCEPT:
- error = SOCK_READREST(m->socket, mh, MUX_ACCEPTHDRSZ);
- if (error)
- goto bad;
- chan = chan_get(m, mh.mh_accept.id);
- if (chan->state == CS_CONNECTING) {
- chan->sendmss = ntohs(mh.mh_accept.mss);
- chan->sendwin = ntohl(mh.mh_accept.window);
- chan->state = CS_ESTABLISHED;
- pthread_cond_signal(&chan->wrready);
- chan_unlock(chan);
- } else {
- chan->flags |= CF_RESET;
- chan_unlock(chan);
- sender_wakeup(m);
- }
- break;
- case MUX_RESET:
- error = SOCK_READREST(m->socket, mh, MUX_RESETHDRSZ);
- if (error)
- goto bad;
- goto badproto;
- case MUX_WINDOW:
- error = SOCK_READREST(m->socket, mh, MUX_WINDOWHDRSZ);
- if (error)
- goto bad;
- chan = chan_get(m, mh.mh_window.id);
- if (chan->state == CS_ESTABLISHED ||
- chan->state == CS_RDCLOSED) {
- chan->sendwin = ntohl(mh.mh_window.window);
- chan_unlock(chan);
- sender_wakeup(m);
- } else {
- chan_unlock(chan);
- }
- break;
- case MUX_DATA:
- error = SOCK_READREST(m->socket, mh, MUX_DATAHDRSZ);
- if (error)
- goto bad;
- chan = chan_get(m, mh.mh_data.id);
- len = ntohs(mh.mh_data.len);
- buf = chan->recvbuf;
- if ((chan->state != CS_ESTABLISHED &&
- chan->state != CS_WRCLOSED) ||
- (len > buf_avail(buf) ||
- len > chan->recvmss)) {
- chan_unlock(chan);
- goto badproto;
- return (NULL);
- }
- /*
- * Similarly to the sender code, it's safe to
- * unlock the channel here.
- */
- chan_unlock(chan);
- size = min(buf->size + 1 - buf->in, len);
- error = sock_readwait(m->socket,
- buf->data + buf->in, size);
- if (error)
- goto bad;
- if (len > size) {
- /* Wrapping around. */
- error = sock_readwait(m->socket,
- buf->data, len - size);
- if (error)
- goto bad;
- }
- chan_lock(chan);
- buf->in += len;
- if (buf->in > buf->size)
- buf->in -= buf->size + 1;
- pthread_cond_signal(&chan->rdready);
- chan_unlock(chan);
- break;
- case MUX_CLOSE:
- error = SOCK_READREST(m->socket, mh, MUX_CLOSEHDRSZ);
- if (error)
- goto bad;
- chan = chan_get(m, mh.mh_close.id);
- if (chan->state == CS_ESTABLISHED)
- chan->state = CS_RDCLOSED;
- else if (chan->state == CS_WRCLOSED)
- chan->state = CS_CLOSED;
- else
- goto badproto;
- pthread_cond_signal(&chan->rdready);
- chan_unlock(chan);
- break;
- default:
- goto badproto;
- }
- }
-bad:
- if (errno == ECONNRESET || errno == ECONNABORTED)
- mux_shutdown(m, strerror(errno), STATUS_TRANSIENTFAILURE);
- else
- mux_shutdown(m, strerror(errno), STATUS_FAILURE);
- return (NULL);
-badproto:
- mux_shutdown(m, "Protocol error", STATUS_FAILURE);
- return (NULL);
-}
-
-/*
- * Circular buffers API.
- */
-
-static struct buf *
-buf_new(size_t size)
-{
- struct buf *buf;
-
- buf = xmalloc(sizeof(struct buf));
- buf->data = xmalloc(size + 1);
- buf->size = size;
- buf->in = 0;
- buf->out = 0;
- return (buf);
-}
-
-static void
-buf_free(struct buf *buf)
-{
-
- free(buf->data);
- free(buf);
-}
-
-/* Number of bytes stored in the buffer. */
-static size_t
-buf_count(struct buf *buf)
-{
- size_t count;
-
- if (buf->in >= buf->out)
- count = buf->in - buf->out;
- else
- count = buf->size + 1 + buf->in - buf->out;
- return (count);
-}
-
-/* Number of bytes available in the buffer. */
-static size_t
-buf_avail(struct buf *buf)
-{
- size_t avail;
-
- if (buf->out > buf->in)
- avail = buf->out - buf->in - 1;
- else
- avail = buf->size + buf->out - buf->in;
- return (avail);
-}
-
-static void
-buf_put(struct buf *buf, const void *data, size_t size)
-{
- const char *cp;
- size_t len;
-
- assert(size > 0);
- assert(buf_avail(buf) >= size);
- cp = data;
- len = buf->size + 1 - buf->in;
- if (len < size) {
- /* Wrapping around. */
- memcpy(buf->data + buf->in, cp, len);
- memcpy(buf->data, cp + len, size - len);
- } else {
- /* Not wrapping around. */
- memcpy(buf->data + buf->in, cp, size);
- }
- buf->in += size;
- if (buf->in > buf->size)
- buf->in -= buf->size + 1;
-}
-
-static void
-buf_get(struct buf *buf, void *data, size_t size)
-{
- char *cp;
- size_t len;
-
- assert(size > 0);
- assert(buf_count(buf) >= size);
- cp = data;
- len = buf->size + 1 - buf->out;
- if (len < size) {
- /* Wrapping around. */
- memcpy(cp, buf->data + buf->out, len);
- memcpy(cp + len, buf->data, size - len);
- } else {
- /* Not wrapping around. */
- memcpy(cp, buf->data + buf->out, size);
- }
- buf->out += size;
- if (buf->out > buf->size)
- buf->out -= buf->size + 1;
-}
diff --git a/contrib/csup/mux.h b/contrib/csup/mux.h
deleted file mode 100644
index ff36083..0000000
--- a/contrib/csup/mux.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _MUX_H_
-#define _MUX_H_
-
-struct mux;
-struct chan;
-
-struct mux *mux_open(int, struct chan **);
-void mux_shutdown(struct mux *, const char *, int);
-int mux_close(struct mux *);
-
-void chan_wait(struct chan *);
-int chan_listen(struct mux *);
-struct chan *chan_accept(struct mux *, int);
-ssize_t chan_read(struct chan *, void *, size_t);
-ssize_t chan_write(struct chan *, const void *, size_t);
-int chan_close(struct chan *);
-
-#endif /* !_MUX_H_ */
diff --git a/contrib/csup/parse.y b/contrib/csup/parse.y
deleted file mode 100644
index 3dcd617..0000000
--- a/contrib/csup/parse.y
+++ /dev/null
@@ -1,91 +0,0 @@
-%{
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-
-#include "config.h"
-#include "token.h"
-
-%}
-
-%union {
- char *str;
- int i;
-}
-
-%token DEFAULT
-%token <i> NAME
-%token <i> BOOLEAN
-%token EQUAL
-%token <str> STRING
-
-%%
-
-config_file
- : config_list
- |
- ;
-
-config_list
- : config
- | config_list config
- ;
-
-config
- : default_line
- | collection
- ;
-
-default_line
- : DEFAULT options
- { coll_setdef(); }
- ;
-
-collection
- : STRING options
- { coll_add($1); }
- ;
-
-options
- :
- | options option
- ;
-
-option
- : BOOLEAN
- { coll_setopt($1, NULL); }
- | value
- ;
-
-value
- : NAME EQUAL STRING
- { coll_setopt($1, $3); }
- ;
-
-%%
diff --git a/contrib/csup/pathcomp.c b/contrib/csup/pathcomp.c
deleted file mode 100644
index 380d042..0000000
--- a/contrib/csup/pathcomp.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "misc.h"
-#include "pathcomp.h"
-
-struct pathcomp {
- char *target;
- size_t targetlen;
- char *trashed;
- char *prev;
- size_t prevlen;
- size_t goal;
- size_t curlen;
-};
-
-struct pathcomp *
-pathcomp_new(void)
-{
- struct pathcomp *pc;
-
- pc = xmalloc(sizeof(struct pathcomp));
- pc->curlen = 0;
- pc->target = NULL;
- pc->targetlen = 0;
- pc->trashed = NULL;
- pc->prev = NULL;
- pc->prevlen = 0;
- return (pc);
-}
-
-int
-pathcomp_put(struct pathcomp *pc, int type, char *path)
-{
- char *cp;
-
- assert(pc->target == NULL);
- if (*path == '/')
- return (-1);
-
- switch (type) {
- case PC_DIRDOWN:
- pc->target = path;
- pc->targetlen = strlen(path);
- break;
- case PC_FILE:
- case PC_DIRUP:
- cp = strrchr(path, '/');
- pc->target = path;
- if (cp != NULL)
- pc->targetlen = cp - path;
- else
- pc->targetlen = 0;
- break;
- }
- if (pc->prev != NULL)
- pc->goal = commonpathlength(pc->prev, pc->prevlen, pc->target,
- pc->targetlen);
- else
- pc->goal = 0;
- if (pc->curlen == pc->goal) /* No need to go up. */
- pc->goal = pc->targetlen;
- return (0);
-}
-
-int
-pathcomp_get(struct pathcomp *pc, int *type, char **name)
-{
- char *cp;
- size_t slashpos, start;
-
- if (pc->curlen > pc->goal) { /* Going up. */
- assert(pc->prev != NULL);
- pc->prev[pc->curlen] = '\0';
- cp = pc->prev + pc->curlen - 1;
- while (cp >= pc->prev) {
- if (*cp == '/')
- break;
- cp--;
- }
- if (cp >= pc->prev)
- slashpos = cp - pc->prev;
- else
- slashpos = 0;
- pc->curlen = slashpos;
- if (pc->curlen <= pc->goal) { /* Done going up. */
- assert(pc->curlen == pc->goal);
- pc->goal = pc->targetlen;
- }
- *type = PC_DIRUP;
- *name = pc->prev;
- return (1);
- } else if (pc->curlen < pc->goal) { /* Going down. */
- /* Restore the previously overwritten '/' character. */
- if (pc->trashed != NULL) {
- *pc->trashed = '/';
- pc->trashed = NULL;
- }
- if (pc->curlen == 0)
- start = pc->curlen;
- else
- start = pc->curlen + 1;
- slashpos = start;
- while (slashpos < pc->goal) {
- if (pc->target[slashpos] == '/')
- break;
- slashpos++;
- }
- if (pc->target[slashpos] != '\0') {
- assert(pc->target[slashpos] == '/');
- pc->trashed = pc->target + slashpos;
- pc->target[slashpos] = '\0';
- }
- pc->curlen = slashpos;
- *type = PC_DIRDOWN;
- *name = pc->target;
- return (1);
- } else { /* Done. */
- if (pc->target != NULL) {
- if (pc->trashed != NULL) {
- *pc->trashed = '/';
- pc->trashed = NULL;
- }
- if (pc->prev != NULL)
- free(pc->prev);
- pc->prev = xmalloc(pc->targetlen + 1);
- memcpy(pc->prev, pc->target, pc->targetlen);
- pc->prev[pc->targetlen] = '\0';
- pc->prevlen = pc->targetlen;
- pc->target = NULL;
- pc->targetlen = 0;
- }
- return (0);
- }
-}
-
-void
-pathcomp_finish(struct pathcomp *pc)
-{
-
- pc->target = NULL;
- pc->targetlen = 0;
- pc->goal = 0;
-}
-
-void
-pathcomp_free(struct pathcomp *pc)
-{
-
- if (pc->prev != NULL)
- free(pc->prev);
- free(pc);
-}
diff --git a/contrib/csup/pathcomp.h b/contrib/csup/pathcomp.h
deleted file mode 100644
index 3cea410..0000000
--- a/contrib/csup/pathcomp.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _PATHCOMP_H
-#define _PATHCOMP_H
-
-/* File types */
-#define PC_DIRDOWN 0
-#define PC_FILE 1
-#define PC_DIRUP 2
-
-struct pathcomp;
-
-struct pathcomp *pathcomp_new(void);
-int pathcomp_put(struct pathcomp *, int, char *);
-int pathcomp_get(struct pathcomp *, int *, char **);
-void pathcomp_finish(struct pathcomp *);
-void pathcomp_free(struct pathcomp *);
-
-#endif /* !_PATHCOMP_H */
diff --git a/contrib/csup/proto.c b/contrib/csup/proto.c
deleted file mode 100644
index 166a134..0000000
--- a/contrib/csup/proto.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "auth.h"
-#include "config.h"
-#include "detailer.h"
-#include "fattr.h"
-#include "fixups.h"
-#include "globtree.h"
-#include "keyword.h"
-#include "lister.h"
-#include "misc.h"
-#include "mux.h"
-#include "proto.h"
-#include "queue.h"
-#include "stream.h"
-#include "threads.h"
-#include "updater.h"
-
-struct killer {
- pthread_t thread;
- sigset_t sigset;
- struct mux *mux;
- int killedby;
-};
-
-static void killer_start(struct killer *, struct mux *);
-static void *killer_run(void *);
-static void killer_stop(struct killer *);
-
-static int proto_waitconnect(int);
-static int proto_greet(struct config *);
-static int proto_negproto(struct config *);
-static int proto_fileattr(struct config *);
-static int proto_xchgcoll(struct config *);
-static struct mux *proto_mux(struct config *);
-
-static int proto_escape(struct stream *, const char *);
-static void proto_unescape(char *);
-
-static int
-proto_waitconnect(int s)
-{
- fd_set readfd;
- socklen_t len;
- int error, rv, soerror;
-
- FD_ZERO(&readfd);
- FD_SET(s, &readfd);
-
- do {
- rv = select(s + 1, &readfd, NULL, NULL, NULL);
- } while (rv == -1 && errno == EINTR);
- if (rv == -1)
- return (-1);
- /* Check that the connection was really successful. */
- len = sizeof(soerror);
- error = getsockopt(s, SOL_SOCKET, SO_ERROR, &soerror, &len);
- if (error) {
- /* We have no choice but faking an error here. */
- errno = ECONNREFUSED;
- return (-1);
- }
- if (soerror) {
- errno = soerror;
- return (-1);
- }
- return (0);
-}
-
-/* Connect to the CVSup server. */
-int
-proto_connect(struct config *config, int family, uint16_t port)
-{
- char addrbuf[NI_MAXHOST];
- /* Enough to hold sizeof("cvsup") or any port number. */
- char servname[8];
- struct addrinfo *res, *ai, hints;
- int error, opt, s;
-
- s = -1;
- if (port != 0)
- snprintf(servname, sizeof(servname), "%d", port);
- else {
- strncpy(servname, "cvsup", sizeof(servname) - 1);
- servname[sizeof(servname) - 1] = '\0';
- }
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- error = getaddrinfo(config->host, servname, &hints, &res);
- /*
- * Try with the hardcoded port number for OSes that don't
- * have cvsup defined in the /etc/services file.
- */
- if (error == EAI_SERVICE) {
- strncpy(servname, "5999", sizeof(servname) - 1);
- servname[sizeof(servname) - 1] = '\0';
- error = getaddrinfo(config->host, servname, &hints, &res);
- }
- if (error) {
- lprintf(0, "Name lookup failure for \"%s\": %s\n", config->host,
- gai_strerror(error));
- return (STATUS_TRANSIENTFAILURE);
- }
- for (ai = res; ai != NULL; ai = ai->ai_next) {
- s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (s != -1) {
- error = 0;
- if (config->laddr != NULL) {
- opt = 1;
- (void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- &opt, sizeof(opt));
- error = bind(s, config->laddr,
- config->laddrlen);
- }
- if (!error) {
- error = connect(s, ai->ai_addr, ai->ai_addrlen);
- if (error && errno == EINTR)
- error = proto_waitconnect(s);
- }
- if (error)
- close(s);
- }
- (void)getnameinfo(ai->ai_addr, ai->ai_addrlen, addrbuf,
- sizeof(addrbuf), NULL, 0, NI_NUMERICHOST);
- if (s == -1 || error) {
- lprintf(0, "Cannot connect to %s: %s\n", addrbuf,
- strerror(errno));
- continue;
- }
- lprintf(1, "Connected to %s\n", addrbuf);
- freeaddrinfo(res);
- config->socket = s;
- return (STATUS_SUCCESS);
- }
- freeaddrinfo(res);
- return (STATUS_TRANSIENTFAILURE);
-}
-
-/* Greet the server. */
-static int
-proto_greet(struct config *config)
-{
- char *line, *cmd, *msg, *swver;
- struct stream *s;
-
- s = config->server;
- line = stream_getln(s, NULL);
- cmd = proto_get_ascii(&line);
- if (cmd == NULL)
- goto bad;
- if (strcmp(cmd, "OK") == 0) {
- (void)proto_get_ascii(&line); /* major number */
- (void)proto_get_ascii(&line); /* minor number */
- swver = proto_get_ascii(&line);
- } else if (strcmp(cmd, "!") == 0) {
- msg = proto_get_rest(&line);
- if (msg == NULL)
- goto bad;
- lprintf(-1, "Rejected by server: %s\n", msg);
- return (STATUS_TRANSIENTFAILURE);
- } else
- goto bad;
- lprintf(2, "Server software version: %s\n",
- swver != NULL ? swver : ".");
- return (STATUS_SUCCESS);
-bad:
- lprintf(-1, "Invalid greeting from server\n");
- return (STATUS_FAILURE);
-}
-
-/* Negotiate protocol version with the server. */
-static int
-proto_negproto(struct config *config)
-{
- struct stream *s;
- char *cmd, *line, *msg;
- int error, maj, min;
-
- s = config->server;
- proto_printf(s, "PROTO %d %d %s\n", PROTO_MAJ, PROTO_MIN, PROTO_SWVER);
- stream_flush(s);
- line = stream_getln(s, NULL);
- cmd = proto_get_ascii(&line);
- if (cmd == NULL || line == NULL)
- goto bad;
- if (strcmp(cmd, "!") == 0) {
- msg = proto_get_rest(&line);
- lprintf(-1, "Protocol negotiation failed: %s\n", msg);
- return (1);
- } else if (strcmp(cmd, "PROTO") != 0)
- goto bad;
- error = proto_get_int(&line, &maj, 10);
- if (!error)
- error = proto_get_int(&line, &min, 10);
- if (error)
- goto bad;
- if (maj != PROTO_MAJ || min != PROTO_MIN) {
- lprintf(-1, "Server protocol version %d.%d not supported "
- "by client\n", maj, min);
- return (STATUS_FAILURE);
- }
- return (STATUS_SUCCESS);
-bad:
- lprintf(-1, "Invalid PROTO command from server\n");
- return (STATUS_FAILURE);
-}
-
-/*
- * File attribute support negotiation.
- */
-static int
-proto_fileattr(struct config *config)
-{
- fattr_support_t support;
- struct stream *s;
- char *line, *cmd;
- int error, i, n, attr;
-
- s = config->server;
- lprintf(2, "Negotiating file attribute support\n");
- proto_printf(s, "ATTR %d\n", FT_NUMBER);
- for (i = 0; i < FT_NUMBER; i++)
- proto_printf(s, "%x\n", fattr_supported(i));
- proto_printf(s, ".\n");
- stream_flush(s);
- line = stream_getln(s, NULL);
- if (line == NULL)
- goto bad;
- cmd = proto_get_ascii(&line);
- error = proto_get_int(&line, &n, 10);
- if (error || line != NULL || strcmp(cmd, "ATTR") != 0 || n > FT_NUMBER)
- goto bad;
- for (i = 0; i < n; i++) {
- line = stream_getln(s, NULL);
- if (line == NULL)
- goto bad;
- error = proto_get_int(&line, &attr, 16);
- if (error)
- goto bad;
- support[i] = fattr_supported(i) & attr;
- }
- for (i = n; i < FT_NUMBER; i++)
- support[i] = 0;
- line = stream_getln(s, NULL);
- if (line == NULL || strcmp(line, ".") != 0)
- goto bad;
- memcpy(config->fasupport, support, sizeof(config->fasupport));
- return (STATUS_SUCCESS);
-bad:
- lprintf(-1, "Protocol error negotiating attribute support\n");
- return (STATUS_FAILURE);
-}
-
-/*
- * Exchange collection information.
- */
-static int
-proto_xchgcoll(struct config *config)
-{
- struct coll *coll;
- struct stream *s;
- struct globtree *diraccept, *dirrefuse;
- struct globtree *fileaccept, *filerefuse;
- char *line, *cmd, *collname, *pat;
- char *msg, *release, *ident, *rcskey, *prefix;
- size_t i, len;
- int error, flags, options;
-
- s = config->server;
- lprintf(2, "Exchanging collection information\n");
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- if (coll->co_options & CO_SKIP)
- continue;
- proto_printf(s, "COLL %s %s %o %d\n", coll->co_name,
- coll->co_release, coll->co_umask, coll->co_options);
- for (i = 0; i < pattlist_size(coll->co_accepts); i++) {
- proto_printf(s, "ACC %s\n",
- pattlist_get(coll->co_accepts, i));
- }
- for (i = 0; i < pattlist_size(coll->co_refusals); i++) {
- proto_printf(s, "REF %s\n",
- pattlist_get(coll->co_refusals, i));
- }
- proto_printf(s, ".\n");
- }
- proto_printf(s, ".\n");
- stream_flush(s);
-
- STAILQ_FOREACH(coll, &config->colls, co_next) {
- if (coll->co_options & CO_SKIP)
- continue;
- coll->co_norsync = globtree_false();
- line = stream_getln(s, NULL);
- if (line == NULL)
- goto bad;
- cmd = proto_get_ascii(&line);
- collname = proto_get_ascii(&line);
- release = proto_get_ascii(&line);
- error = proto_get_int(&line, &options, 10);
- if (error || line != NULL)
- goto bad;
- if (strcmp(cmd, "COLL") != 0 ||
- strcmp(collname, coll->co_name) != 0 ||
- strcmp(release, coll->co_release) != 0)
- goto bad;
- coll->co_options =
- (coll->co_options | (options & CO_SERVMAYSET)) &
- ~(~options & CO_SERVMAYCLEAR);
- while ((line = stream_getln(s, NULL)) != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- cmd = proto_get_ascii(&line);
- if (cmd == NULL)
- goto bad;
- if (strcmp(cmd, "!") == 0) {
- msg = proto_get_rest(&line);
- if (msg == NULL)
- goto bad;
- lprintf(-1, "Server message: %s\n", msg);
- } else if (strcmp(cmd, "PRFX") == 0) {
- prefix = proto_get_ascii(&line);
- if (prefix == NULL || line != NULL)
- goto bad;
- coll->co_cvsroot = xstrdup(prefix);
- } else if (strcmp(cmd, "KEYALIAS") == 0) {
- ident = proto_get_ascii(&line);
- rcskey = proto_get_ascii(&line);
- if (rcskey == NULL || line != NULL)
- goto bad;
- error = keyword_alias(coll->co_keyword, ident,
- rcskey);
- if (error)
- goto bad;
- } else if (strcmp(cmd, "KEYON") == 0) {
- ident = proto_get_ascii(&line);
- if (ident == NULL || line != NULL)
- goto bad;
- error = keyword_enable(coll->co_keyword, ident);
- if (error)
- goto bad;
- } else if (strcmp(cmd, "KEYOFF") == 0) {
- ident = proto_get_ascii(&line);
- if (ident == NULL || line != NULL)
- goto bad;
- error = keyword_disable(coll->co_keyword,
- ident);
- if (error)
- goto bad;
- } else if (strcmp(cmd, "NORS") == 0) {
- pat = proto_get_ascii(&line);
- if (pat == NULL || line != NULL)
- goto bad;
- coll->co_norsync = globtree_or(coll->co_norsync,
- globtree_match(pat, FNM_PATHNAME));
- } else if (strcmp(cmd, "RNORS") == 0) {
- pat = proto_get_ascii(&line);
- if (pat == NULL || line != NULL)
- goto bad;
- coll->co_norsync = globtree_or(coll->co_norsync,
- globtree_match(pat, FNM_PATHNAME |
- FNM_LEADING_DIR));
- } else
- goto bad;
- }
- if (line == NULL)
- goto bad;
- keyword_prepare(coll->co_keyword);
-
- diraccept = globtree_true();
- fileaccept = globtree_true();
- dirrefuse = globtree_false();
- filerefuse = globtree_false();
-
- if (pattlist_size(coll->co_accepts) > 0) {
- globtree_free(diraccept);
- globtree_free(fileaccept);
- diraccept = globtree_false();
- fileaccept = globtree_false();
- flags = FNM_PATHNAME | FNM_LEADING_DIR |
- FNM_PREFIX_DIRS;
- for (i = 0; i < pattlist_size(coll->co_accepts); i++) {
- pat = pattlist_get(coll->co_accepts, i);
- diraccept = globtree_or(diraccept,
- globtree_match(pat, flags));
-
- len = strlen(pat);
- if (coll->co_options & CO_CHECKOUTMODE &&
- (len == 0 || pat[len - 1] != '*')) {
- /* We must modify the pattern so that it
- refers to the RCS file, rather than
- the checked-out file. */
- xasprintf(&pat, "%s,v", pat);
- fileaccept = globtree_or(fileaccept,
- globtree_match(pat, flags));
- free(pat);
- } else {
- fileaccept = globtree_or(fileaccept,
- globtree_match(pat, flags));
- }
- }
- }
-
- for (i = 0; i < pattlist_size(coll->co_refusals); i++) {
- pat = pattlist_get(coll->co_refusals, i);
- dirrefuse = globtree_or(dirrefuse,
- globtree_match(pat, 0));
- len = strlen(pat);
- if (coll->co_options & CO_CHECKOUTMODE &&
- (len == 0 || pat[len - 1] != '*')) {
- /* We must modify the pattern so that it refers
- to the RCS file, rather than the checked-out
- file. */
- xasprintf(&pat, "%s,v", pat);
- filerefuse = globtree_or(filerefuse,
- globtree_match(pat, 0));
- free(pat);
- } else {
- filerefuse = globtree_or(filerefuse,
- globtree_match(pat, 0));
- }
- }
-
- coll->co_dirfilter = globtree_and(diraccept,
- globtree_not(dirrefuse));
- coll->co_filefilter = globtree_and(fileaccept,
- globtree_not(filerefuse));
-
- /* Set up a mask of file attributes that we don't want to sync
- with the server. */
- if (!(coll->co_options & CO_SETOWNER))
- coll->co_attrignore |= FA_OWNER | FA_GROUP;
- if (!(coll->co_options & CO_SETMODE))
- coll->co_attrignore |= FA_MODE;
- if (!(coll->co_options & CO_SETFLAGS))
- coll->co_attrignore |= FA_FLAGS;
- }
- return (STATUS_SUCCESS);
-bad:
- lprintf(-1, "Protocol error during collection exchange\n");
- return (STATUS_FAILURE);
-}
-
-static struct mux *
-proto_mux(struct config *config)
-{
- struct mux *m;
- struct stream *s, *wr;
- struct chan *chan0, *chan1;
- int id;
-
- s = config->server;
- lprintf(2, "Establishing multiplexed-mode data connection\n");
- proto_printf(s, "MUX\n");
- stream_flush(s);
- m = mux_open(config->socket, &chan0);
- if (m == NULL) {
- lprintf(-1, "Cannot open the multiplexer\n");
- return (NULL);
- }
- id = chan_listen(m);
- if (id == -1) {
- lprintf(-1, "ChannelMux.Listen failed: %s\n", strerror(errno));
- mux_close(m);
- return (NULL);
- }
- wr = stream_open(chan0, NULL, (stream_writefn_t *)chan_write, NULL);
- proto_printf(wr, "CHAN %d\n", id);
- stream_close(wr);
- chan1 = chan_accept(m, id);
- if (chan1 == NULL) {
- lprintf(-1, "ChannelMux.Accept failed: %s\n", strerror(errno));
- mux_close(m);
- return (NULL);
- }
- config->chan0 = chan0;
- config->chan1 = chan1;
- return (m);
-}
-
-/*
- * Initializes the connection to the CVSup server, that is handle
- * the protocol negotiation, logging in, exchanging file attributes
- * support and collections information, and finally run the update
- * session.
- */
-int
-proto_run(struct config *config)
-{
- struct thread_args lister_args;
- struct thread_args detailer_args;
- struct thread_args updater_args;
- struct thread_args *args;
- struct killer killer;
- struct threads *workers;
- struct mux *m;
- int i, status;
-
- /*
- * We pass NULL for the close() function because we'll reuse
- * the socket after the stream is closed.
- */
- config->server = stream_open_fd(config->socket, stream_read_fd,
- stream_write_fd, NULL);
- status = proto_greet(config);
- if (status == STATUS_SUCCESS)
- status = proto_negproto(config);
- if (status == STATUS_SUCCESS)
- status = auth_login(config);
- if (status == STATUS_SUCCESS)
- status = proto_fileattr(config);
- if (status == STATUS_SUCCESS)
- status = proto_xchgcoll(config);
- if (status != STATUS_SUCCESS)
- return (status);
-
- /* Multi-threaded action starts here. */
- m = proto_mux(config);
- if (m == NULL)
- return (STATUS_FAILURE);
-
- stream_close(config->server);
- config->server = NULL;
- config->fixups = fixups_new();
- killer_start(&killer, m);
-
- /* Start the worker threads. */
- workers = threads_new();
- args = &lister_args;
- args->config = config;
- args->status = -1;
- args->errmsg = NULL;
- args->rd = NULL;
- args->wr = stream_open(config->chan0,
- NULL, (stream_writefn_t *)chan_write, NULL);
- threads_create(workers, lister, args);
-
- args = &detailer_args;
- args->config = config;
- args->status = -1;
- args->errmsg = NULL;
- args->rd = stream_open(config->chan0,
- (stream_readfn_t *)chan_read, NULL, NULL);
- args->wr = stream_open(config->chan1,
- NULL, (stream_writefn_t *)chan_write, NULL);
- threads_create(workers, detailer, args);
-
- args = &updater_args;
- args->config = config;
- args->status = -1;
- args->errmsg = NULL;
- args->rd = stream_open(config->chan1,
- (stream_readfn_t *)chan_read, NULL, NULL);
- args->wr = NULL;
- threads_create(workers, updater, args);
-
- lprintf(2, "Running\n");
- /* Wait for all the worker threads to finish. */
- status = STATUS_SUCCESS;
- for (i = 0; i < 3; i++) {
- args = threads_wait(workers);
- if (args->rd != NULL)
- stream_close(args->rd);
- if (args->wr != NULL)
- stream_close(args->wr);
- if (args->status != STATUS_SUCCESS) {
- assert(args->errmsg != NULL);
- if (status == STATUS_SUCCESS) {
- status = args->status;
- /* Shutdown the multiplexer to wake up all
- the other threads. */
- mux_shutdown(m, args->errmsg, status);
- }
- free(args->errmsg);
- }
- }
- threads_free(workers);
- if (status == STATUS_SUCCESS) {
- lprintf(2, "Shutting down connection to server\n");
- chan_close(config->chan0);
- chan_close(config->chan1);
- chan_wait(config->chan0);
- chan_wait(config->chan1);
- mux_shutdown(m, NULL, STATUS_SUCCESS);
- }
- killer_stop(&killer);
- fixups_free(config->fixups);
- status = mux_close(m);
- if (status == STATUS_SUCCESS) {
- lprintf(1, "Finished successfully\n");
- } else if (status == STATUS_INTERRUPTED) {
- lprintf(-1, "Interrupted\n");
- if (killer.killedby != -1)
- kill(getpid(), killer.killedby);
- }
- return (status);
-}
-
-/*
- * Write a string into the stream, escaping characters as needed.
- * Characters escaped:
- *
- * SPACE -> "\_"
- * TAB -> "\t"
- * NEWLINE -> "\n"
- * CR -> "\r"
- * \ -> "\\"
- */
-static int
-proto_escape(struct stream *wr, const char *s)
-{
- size_t len;
- ssize_t n;
- char c;
-
- /* Handle characters that need escaping. */
- do {
- len = strcspn(s, " \t\r\n\\");
- n = stream_write(wr, s, len);
- if (n == -1)
- return (-1);
- c = s[len];
- switch (c) {
- case ' ':
- n = stream_write(wr, "\\_", 2);
- break;
- case '\t':
- n = stream_write(wr, "\\t", 2);
- break;
- case '\r':
- n = stream_write(wr, "\\r", 2);
- break;
- case '\n':
- n = stream_write(wr, "\\n", 2);
- break;
- case '\\':
- n = stream_write(wr, "\\\\", 2);
- break;
- }
- if (n == -1)
- return (-1);
- s += len + 1;
- } while (c != '\0');
- return (0);
-}
-
-/*
- * A simple printf() implementation specifically tailored for csup.
- * List of the supported formats:
- *
- * %c Print a char.
- * %d or %i Print an int as decimal.
- * %x Print an int as hexadecimal.
- * %o Print an int as octal.
- * %t Print a time_t as decimal.
- * %s Print a char * escaping some characters as needed.
- * %S Print a char * without escaping.
- * %f Print an encoded struct fattr *.
- * %F Print an encoded struct fattr *, specifying the supported
- * attributes.
- */
-int
-proto_printf(struct stream *wr, const char *format, ...)
-{
- fattr_support_t *support;
- long long longval;
- struct fattr *fa;
- const char *fmt;
- va_list ap;
- char *cp, *s, *attr;
- ssize_t n;
- size_t size;
- off_t off;
- int rv, val, ignore;
- char c;
-
- n = 0;
- rv = 0;
- fmt = format;
- va_start(ap, format);
- while ((cp = strchr(fmt, '%')) != NULL) {
- if (cp > fmt) {
- n = stream_write(wr, fmt, cp - fmt);
- if (n == -1)
- return (-1);
- }
- if (*++cp == '\0')
- goto done;
- switch (*cp) {
- case 'c':
- c = va_arg(ap, int);
- rv = stream_printf(wr, "%c", c);
- break;
- case 'd':
- case 'i':
- val = va_arg(ap, int);
- rv = stream_printf(wr, "%d", val);
- break;
- case 'x':
- val = va_arg(ap, int);
- rv = stream_printf(wr, "%x", val);
- break;
- case 'o':
- val = va_arg(ap, int);
- rv = stream_printf(wr, "%o", val);
- break;
- case 'O':
- off = va_arg(ap, off_t);
- rv = stream_printf(wr, "%llu", off);
- break;
- case 'S':
- s = va_arg(ap, char *);
- assert(s != NULL);
- rv = stream_printf(wr, "%s", s);
- break;
- case 's':
- s = va_arg(ap, char *);
- assert(s != NULL);
- rv = proto_escape(wr, s);
- break;
- case 't':
- longval = (long long)va_arg(ap, time_t);
- rv = stream_printf(wr, "%lld", longval);
- break;
- case 'f':
- fa = va_arg(ap, struct fattr *);
- attr = fattr_encode(fa, NULL, 0);
- rv = proto_escape(wr, attr);
- free(attr);
- break;
- case 'F':
- fa = va_arg(ap, struct fattr *);
- support = va_arg(ap, fattr_support_t *);
- ignore = va_arg(ap, int);
- attr = fattr_encode(fa, *support, ignore);
- rv = proto_escape(wr, attr);
- free(attr);
- break;
- case 'z':
- size = va_arg(ap, size_t);
- rv = stream_printf(wr, "%zu", size);
- break;
-
- case '%':
- n = stream_write(wr, "%", 1);
- if (n == -1)
- return (-1);
- break;
- }
- if (rv == -1)
- return (-1);
- fmt = cp + 1;
- }
- if (*fmt != '\0') {
- rv = stream_printf(wr, "%s", fmt);
- if (rv == -1)
- return (-1);
- }
-done:
- va_end(ap);
- return (0);
-}
-
-/*
- * Unescape the string, see proto_escape().
- */
-static void
-proto_unescape(char *s)
-{
- char *cp, *cp2;
-
- cp = s;
- while ((cp = strchr(cp, '\\')) != NULL) {
- switch (cp[1]) {
- case '_':
- *cp = ' ';
- break;
- case 't':
- *cp = '\t';
- break;
- case 'r':
- *cp = '\r';
- break;
- case 'n':
- *cp = '\n';
- break;
- case '\\':
- *cp = '\\';
- break;
- default:
- *cp = *(cp + 1);
- }
- cp2 = ++cp;
- while (*cp2 != '\0') {
- *cp2 = *(cp2 + 1);
- cp2++;
- }
- }
-}
-
-/*
- * Get an ascii token in the string.
- */
-char *
-proto_get_ascii(char **s)
-{
- char *ret;
-
- ret = strsep(s, " ");
- if (ret == NULL)
- return (NULL);
- /* Make sure we disallow 0-length fields. */
- if (*ret == '\0') {
- *s = NULL;
- return (NULL);
- }
- proto_unescape(ret);
- return (ret);
-}
-
-/*
- * Get the rest of the string.
- */
-char *
-proto_get_rest(char **s)
-{
- char *ret;
-
- if (s == NULL)
- return (NULL);
- ret = *s;
- proto_unescape(ret);
- *s = NULL;
- return (ret);
-}
-
-/*
- * Get an int token.
- */
-int
-proto_get_int(char **s, int *val, int base)
-{
- char *cp;
- int error;
-
- cp = proto_get_ascii(s);
- if (cp == NULL)
- return (-1);
- error = asciitoint(cp, val, base);
- return (error);
-}
-
-/*
- * Get a size_t token.
- */
-int
-proto_get_sizet(char **s, size_t *val, int base)
-{
- unsigned long long tmp;
- char *cp, *end;
-
- cp = proto_get_ascii(s);
- if (cp == NULL)
- return (-1);
- errno = 0;
- tmp = strtoll(cp, &end, base);
- if (errno || *end != '\0')
- return (-1);
- *val = (size_t)tmp;
- return (0);
-}
-
-/*
- * Get a time_t token.
- *
- * Ideally, we would use an intmax_t and strtoimax() here, but strtoll()
- * is more portable and 64bits should be enough for a timestamp.
- */
-int
-proto_get_time(char **s, time_t *val)
-{
- long long tmp;
- char *cp, *end;
-
- cp = proto_get_ascii(s);
- if (cp == NULL)
- return (-1);
- errno = 0;
- tmp = strtoll(cp, &end, 10);
- if (errno || *end != '\0')
- return (-1);
- *val = (time_t)tmp;
- return (0);
-}
-
-/* Start the killer thread. It is used to protect against some signals
- during the multi-threaded run so that we can gracefully fail. */
-static void
-killer_start(struct killer *k, struct mux *m)
-{
- int error;
-
- k->mux = m;
- k->killedby = -1;
- sigemptyset(&k->sigset);
- sigaddset(&k->sigset, SIGINT);
- sigaddset(&k->sigset, SIGHUP);
- sigaddset(&k->sigset, SIGTERM);
- sigaddset(&k->sigset, SIGPIPE);
- pthread_sigmask(SIG_BLOCK, &k->sigset, NULL);
- error = pthread_create(&k->thread, NULL, killer_run, k);
- if (error)
- err(1, "pthread_create");
-}
-
-/* The main loop of the killer thread. */
-static void *
-killer_run(void *arg)
-{
- struct killer *k;
- int error, sig, old;
-
- k = arg;
-again:
- error = sigwait(&k->sigset, &sig);
- assert(!error);
- if (sig == SIGINT || sig == SIGHUP || sig == SIGTERM) {
- if (k->killedby == -1) {
- k->killedby = sig;
- /* Ensure we don't get canceled during the shutdown. */
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old);
- mux_shutdown(k->mux, "Cleaning up ...",
- STATUS_INTERRUPTED);
- pthread_setcancelstate(old, NULL);
- }
- }
- goto again;
-}
-
-/* Stop the killer thread. */
-static void
-killer_stop(struct killer *k)
-{
- void *val;
- int error;
-
- error = pthread_cancel(k->thread);
- assert(!error);
- pthread_join(k->thread, &val);
- assert(val == PTHREAD_CANCELED);
- pthread_sigmask(SIG_UNBLOCK, &k->sigset, NULL);
-}
diff --git a/contrib/csup/proto.h b/contrib/csup/proto.h
deleted file mode 100644
index 0c4a782..0000000
--- a/contrib/csup/proto.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _PROTO_H_
-#define _PROTO_H_
-
-#include <time.h>
-
-#include "misc.h"
-
-#define PROTO_MAJ 17
-#define PROTO_MIN 0
-#define PROTO_SWVER "CSUP_1_0"
-
-struct stream;
-
-int proto_connect(struct config *, int, uint16_t);
-int proto_run(struct config *);
-int proto_printf(struct stream *, const char *, ...);
-char *proto_get_ascii(char **);
-char *proto_get_rest(char **);
-int proto_get_int(char **, int *, int);
-int proto_get_sizet(char **, size_t *, int);
-int proto_get_time(char **, time_t *);
-
-#endif /* !_PROTO_H_ */
diff --git a/contrib/csup/queue.h b/contrib/csup/queue.h
deleted file mode 100644
index aa9cac1..0000000
--- a/contrib/csup/queue.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- * $FreeBSD$
- *
- * $FreeBSD$
- */
-
-#ifndef _QUEUE_H_
-#define _QUEUE_H_
-
-#undef __offsetof
-#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
-
-/*
- * Singly-linked Tail queue declarations.
- */
-#undef STAILQ_HEAD
-#define STAILQ_HEAD(name, type) \
-struct name { \
- struct type *stqh_first;/* first element */ \
- struct type **stqh_last;/* addr of last next element */ \
-}
-
-#undef STAILQ_HEAD_INITIALIZER
-#define STAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).stqh_first }
-
-#undef STAILQ_ENTRY
-#define STAILQ_ENTRY(type) \
-struct { \
- struct type *stqe_next; /* next element */ \
-}
-
-#undef STAILQ_EMPTY
-#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
-
-#undef STAILQ_FIRST
-#define STAILQ_FIRST(head) ((head)->stqh_first)
-
-#undef STAILQ_FOREACH
-#define STAILQ_FOREACH(var, head, field) \
- for((var) = STAILQ_FIRST((head)); \
- (var); \
- (var) = STAILQ_NEXT((var), field))
-
-#undef STAILQ_FOREACH_SAFE
-#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = STAILQ_FIRST((head)); \
- (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
- (var) = (tvar))
-
-#undef STAILQ_INIT
-#define STAILQ_INIT(head) do { \
- STAILQ_FIRST((head)) = NULL; \
- (head)->stqh_last = &STAILQ_FIRST((head)); \
-} while (0)
-
-#undef STAILQ_INSERT_AFTER
-#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
- if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
- STAILQ_NEXT((tqelm), field) = (elm); \
-} while (0)
-
-#undef STAILQ_INSERT_HEAD
-#define STAILQ_INSERT_HEAD(head, elm, field) do { \
- if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
- STAILQ_FIRST((head)) = (elm); \
-} while (0)
-
-#undef STAILQ_INSERT_TAIL
-#define STAILQ_INSERT_TAIL(head, elm, field) do { \
- STAILQ_NEXT((elm), field) = NULL; \
- *(head)->stqh_last = (elm); \
- (head)->stqh_last = &STAILQ_NEXT((elm), field); \
-} while (0)
-
-#undef STAILQ_LAST
-#define STAILQ_LAST(head, type, field) \
- (STAILQ_EMPTY((head)) ? \
- NULL : \
- ((struct type *)(void *) \
- ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
-
-#undef STAILQ_NEXT
-#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
-
-#undef STAILQ_REMOVE
-#define STAILQ_REMOVE(head, elm, type, field) do { \
- if (STAILQ_FIRST((head)) == (elm)) { \
- STAILQ_REMOVE_HEAD((head), field); \
- } \
- else { \
- struct type *curelm = STAILQ_FIRST((head)); \
- while (STAILQ_NEXT(curelm, field) != (elm)) \
- curelm = STAILQ_NEXT(curelm, field); \
- if ((STAILQ_NEXT(curelm, field) = \
- STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
- (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
- } \
-} while (0)
-
-#undef STAILQ_REMOVE_HEAD
-#define STAILQ_REMOVE_HEAD(head, field) do { \
- if ((STAILQ_FIRST((head)) = \
- STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
- (head)->stqh_last = &STAILQ_FIRST((head)); \
-} while (0)
-
-#undef STAILQ_REMOVE_HEAD_UNTIL
-#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
- if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
- (head)->stqh_last = &STAILQ_FIRST((head)); \
-} while (0)
-
-/*
- * List declarations.
- */
-#undef LIST_HEAD
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#undef LIST_HEAD_INITIALIZER
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#undef LIST_ENTRY
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-
-#undef LIST_EMPTY
-#define LIST_EMPTY(head) ((head)->lh_first == NULL)
-
-#undef LIST_FIRST
-#define LIST_FIRST(head) ((head)->lh_first)
-
-#undef LIST_FOREACH
-#define LIST_FOREACH(var, head, field) \
- for ((var) = LIST_FIRST((head)); \
- (var); \
- (var) = LIST_NEXT((var), field))
-
-#undef LIST_FOREACH_SAFE
-#define LIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = LIST_FIRST((head)); \
- (var) && ((tvar) = LIST_NEXT((var), field), 1); \
- (var) = (tvar))
-
-#undef LIST_INIT
-#define LIST_INIT(head) do { \
- LIST_FIRST((head)) = NULL; \
-} while (0)
-
-#undef LIST_INSERT_AFTER
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
- LIST_NEXT((listelm), field)->field.le_prev = \
- &LIST_NEXT((elm), field); \
- LIST_NEXT((listelm), field) = (elm); \
- (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
-} while (0)
-
-#undef LIST_INSERT_BEFORE
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- LIST_NEXT((elm), field) = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
-} while (0)
-
-#undef LIST_INSERT_HEAD
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
- LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
- LIST_FIRST((head)) = (elm); \
- (elm)->field.le_prev = &LIST_FIRST((head)); \
-} while (0)
-
-#undef LIST_NEXT
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#undef LIST_REMOVE
-#define LIST_REMOVE(elm, field) do { \
- if (LIST_NEXT((elm), field) != NULL) \
- LIST_NEXT((elm), field)->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = LIST_NEXT((elm), field); \
-} while (0)
-
-#endif /* !_QUEUE_H_ */
diff --git a/contrib/csup/rcsfile.c b/contrib/csup/rcsfile.c
deleted file mode 100644
index 1f3ede1..0000000
--- a/contrib/csup/rcsfile.c
+++ /dev/null
@@ -1,1412 +0,0 @@
-/*-
- * Copyright (c) 2007-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "diff.h"
-#include "keyword.h"
-#include "misc.h"
-#include "proto.h"
-#include "queue.h"
-#include "rcsfile.h"
-#include "rcsparse.h"
-#include "stream.h"
-
-#define BUF_SIZE_DEFAULT 128
-
-/*
- * RCS parser library. This is the part of the library that handles the
- * importing, editing and exporting of RCS files. It currently supports only the
- * part of the RCS file specification that is needed for csup (for instance,
- * newphrases are not supported), and assumes that you can store the whole RCS
- * file in memory.
- */
-
-/*
- * Linked list for string tokens.
- */
-struct string {
- char *str;
- STAILQ_ENTRY(string) string_next;
-};
-
-/*
- * Linked list of tags and revision numbers, in the RCS file header.
- */
-struct tag {
- char *tag;
- char *revnum;
- STAILQ_ENTRY(tag) tag_next;
-};
-
-/*
- * A RCS delta. The delta is identified by a revision number, and contains the
- * most important RCS attributes that is needed by csup. It also contains
- * pointers to other nodes in the RCS file delta structure.
- */
-struct delta {
- char *revdate;
- char *revnum;
- char *author;
- char *state;
- struct buf *log;
- struct buf *text;
- int placeholder;
- struct delta *diffbase;
- struct delta *prev;
-
- LIST_ENTRY(delta) delta_next;
- STAILQ_ENTRY(delta) delta_prev;
- LIST_ENTRY(delta) table_next;
- STAILQ_ENTRY(delta) stack_next;
- LIST_HEAD(, branch) branchlist;
- LIST_ENTRY(delta) branch_next_date;
-};
-
-/*
- * A branch data structure containing information about deltas in the branch as
- * well as a base revision number.
- */
-struct branch {
- char *revnum;
- LIST_HEAD(, delta) deltalist; /* Next delta in our branch. */
- LIST_ENTRY(branch) branch_next;
-};
-
-/*
- * The rcsfile structure is the "main" structure of the RCS parser library. It
- * contains administrative data as well as pointers to the deltas within the
- * file.
- */
-struct rcsfile {
- char *name;
- char *head;
- char *branch; /* Default branch. */
- char *cvsroot;
- char *colltag;
- STAILQ_HEAD(, string) accesslist;
- STAILQ_HEAD(, tag) taglist;
- int strictlock;
- char *comment;
- int expand;
- int ro;
- struct branch *trunk; /* The tip delta. */
-
- LIST_HEAD(, delta) deltatable;
-
- char *desc;
-};
-
-static void rcsfile_freedelta(struct delta *);
-static void rcsfile_insertdelta(struct branch *, struct delta *,
- int);
-static struct delta *rcsfile_createdelta(char *);
-static int rcsfile_write_deltatext(struct rcsfile *,
- struct stream *);
-static int rcsfile_puttext(struct rcsfile *, struct stream *,
- struct delta *, struct delta *);
-static struct branch *rcsfile_getbranch(struct rcsfile *, char *);
-static void rcsfile_insertsorteddelta(struct rcsfile *,
- struct delta *);
-static struct stream *rcsfile_getdeltatext(struct rcsfile *, struct delta *,
- struct buf **);
-static int rcsdelta_writestring(char *, size_t, struct stream *);
-static void rcsdelta_insertbranch(struct delta *, struct branch *);
-
-/* Space formatting of RCS file. */
-const char *head_space = "\t";
-const char *branch_space = "\t";
-const char *tag_space = "\t";
-const char *date_space = "\t";
-const char *auth_space = "\t";
-const char *state_space = "\t";
-const char *next_space = "\t";
-const char *branches_space = "\t";
-const char *comment_space ="\t";
-const char *expand_space = "\t";
-
-void print_stream(struct stream *);
-
-/* Print the contents of a stream, for debugging. */
-void
-print_stream(struct stream *s)
-{
- char *line;
-
- line = stream_getln(s, NULL);
- while (line != NULL) {
- lprintf(-1, "%s\n", line);
- line = stream_getln(s, NULL);
- }
- lprintf(-1, "\n");
-}
-
-/*
- * Parse rcsfile from path and return a pointer to it.
- */
-struct rcsfile *
-rcsfile_frompath(char *path, char *name, char *cvsroot, char *colltag, int ro)
-{
- struct rcsfile *rf;
- FILE *infp;
- int error;
-
- if (path == NULL || name == NULL || cvsroot == NULL || colltag == NULL)
- return (NULL);
-
- rf = xmalloc(sizeof(struct rcsfile));
- rf->name = xstrdup(name);
- rf->cvsroot = xstrdup(cvsroot);
- rf->colltag = xstrdup(colltag);
-
- /* Initialize head branch. */
- rf->trunk = xmalloc(sizeof(struct branch));
- rf->trunk->revnum = xstrdup("1");
- LIST_INIT(&rf->trunk->deltalist);
- /* Initialize delta list. */
- LIST_INIT(&rf->deltatable);
- /* Initialize tag list. */
- STAILQ_INIT(&rf->taglist);
- /* Initialize accesslist. */
- STAILQ_INIT(&rf->accesslist);
-
- /* Initialize all fields. */
- rf->head = NULL;
- rf->branch = NULL;
- rf->strictlock = 0;
- rf->comment = NULL;
- rf->expand = EXPAND_DEFAULT;
- rf->desc = NULL;
- rf->ro = ro;
-
- infp = fopen(path, "r");
- if (infp == NULL) {
- lprintf(-1, "Cannot open \"%s\": %s\n", path, strerror(errno));
- rcsfile_free(rf);
- return (NULL);
- }
- error = rcsparse_run(rf, infp, ro);
- fclose(infp);
- if (error) {
- lprintf(-1, "Error parsing \"%s\"\n", name);
- rcsfile_free(rf);
- return (NULL);
- }
- return (rf);
-}
-
-/*
- * Write content of rcsfile to server. Assumes we have a complete RCS file
- * loaded.
- */
-int
-rcsfile_send_details(struct rcsfile *rf, struct stream *wr)
-{
- struct delta *d;
- struct tag *t;
- const char *keyword;
- int error;
-
- assert(rf != NULL);
-
- error = proto_printf(wr, "V %s\n", rf->name);
- if (error)
- return(error);
-
- /* Write default branch. */
- if (rf->branch == NULL)
- error = proto_printf(wr, "b\n");
- else
- error = proto_printf(wr, "B %s\n", rf->branch);
- if (error)
- return(error);
-
- /* Write deltas to server. */
- error = proto_printf(wr, "D\n");
- if (error)
- return(error);
-
- LIST_FOREACH(d, &rf->deltatable, table_next) {
- error = proto_printf(wr, "%s %s\n", d->revnum, d->revdate);
- if (error)
- return(error);
- }
- error = proto_printf(wr, ".\n");
-
- if (error)
- return(error);
- /* Write expand. */
- if (rf->expand != EXPAND_DEFAULT) {
- keyword = keyword_encode_expand(rf->expand);
- if (keyword != NULL) {
- error = proto_printf(wr, "E %s\n",
- keyword_encode_expand(rf->expand));
- if (error)
- return(error);
- }
- }
-
- /* Write tags to server. */
- error = proto_printf(wr, "T\n");
- if (error)
- return(error);
- STAILQ_FOREACH(t, &rf->taglist, tag_next) {
- error = proto_printf(wr, "%s %s\n", t->tag, t->revnum);
- if (error)
- return(error);
- }
- error = proto_printf(wr, ".\n");
- if (error)
- return(error);
- error = proto_printf(wr, ".\n");
- return (error);
-}
-
-/*
- * Write a RCS file to disk represented by the destination stream. Keep track of
- * deltas with a stack and an inverted stack.
- */
-int
-rcsfile_write(struct rcsfile *rf, struct stream *dest)
-{
- STAILQ_HEAD(, delta) deltastack;
- STAILQ_HEAD(, delta) deltalist_inverted;
- struct tag *t;
- struct branch *b;
- struct delta *d, *d_tmp, *d_next;
- int error;
-
- /* First write head. */
- d = LIST_FIRST(&rf->trunk->deltalist);
- if (stream_printf(dest, "head%s%s;\n", head_space, d->revnum) < 0)
- return (-1);
-
- /* Write branch, if we have. */
- if (rf->branch != NULL) {
- if (stream_printf(dest, "branch%s%s;\n", branch_space,
- rf->branch) < 0)
- return (-1);
- }
-
- /* Write access. */
- if (stream_printf(dest, "access") < 0)
- return (-1);
-#if 0
- if (!STAILQ_EMPTY(&rf->accesslist)) {
- /*
- * XXX: Write out access. This doesn't seem to be necessary for
- * the time being.
- */
- }
-#endif
- if (stream_printf(dest, ";\n") < 0)
- return (-1);
-
- /* Write out taglist. */
- if (stream_printf(dest, "symbols") < 0)
- return (-1);
- if (!STAILQ_EMPTY(&rf->taglist)) {
- STAILQ_FOREACH(t, &rf->taglist, tag_next) {
- if (stream_printf(dest, "\n%s%s:%s", tag_space, t->tag,
- t->revnum) < 0)
- return (-1);
- }
- }
-
- /* Write out locks and strict. */
- if (stream_printf(dest, ";\nlocks;") < 0)
- return (-1);
- if (rf->strictlock) {
- if (stream_printf(dest, " strict;") < 0)
- return (-1);
- }
- if (stream_printf(dest, "\n") < 0)
- return (-1);
-
- /* Write out the comment. */
- if (rf->comment != NULL) {
- if (stream_printf(dest, "comment%s%s;\n", comment_space,
- rf->comment) < 0)
- return (-1);
- }
- if (rf->expand != EXPAND_DEFAULT) {
- if (stream_printf(dest, "expand%s@%s@;\n", expand_space,
- keyword_encode_expand(rf->expand)) < 0)
- return (-1);
- }
-
- if (stream_printf(dest, "\n\n") < 0)
- return (-1);
-
- /*
- * Write out deltas. We use a stack where we push the appropriate deltas
- * that is to be written out during the loop.
- */
- STAILQ_INIT(&deltastack);
- d = LIST_FIRST(&rf->trunk->deltalist);
- STAILQ_INSERT_HEAD(&deltastack, d, stack_next);
- while (!STAILQ_EMPTY(&deltastack)) {
- d = STAILQ_FIRST(&deltastack);
- STAILQ_REMOVE_HEAD(&deltastack, stack_next);
- /* Do not write out placeholders just to be safe. */
- if (d->placeholder)
- continue;
- if (stream_printf(dest, "%s\n", d->revnum) < 0)
- return (-1);
- if (stream_printf(dest, "date%s%s;%sauthor %s;%sstate",
- date_space, d->revdate, auth_space, d->author,
- state_space) < 0)
- return (-1);
- if (d->state != NULL) {
- if (stream_printf(dest, " %s", d->state) < 0)
- return (-1);
- }
- if (stream_printf(dest, ";\nbranches") < 0)
- return (-1);
- /*
- * Write out our branches. Add them to a reversed list for use
- * later when we write out the text.
- */
- STAILQ_INIT(&deltalist_inverted);
- LIST_FOREACH(b, &d->branchlist, branch_next) {
- d_tmp = LIST_FIRST(&b->deltalist);
- STAILQ_INSERT_HEAD(&deltalist_inverted, d_tmp, delta_prev);
- STAILQ_INSERT_HEAD(&deltastack, d_tmp, stack_next);
- }
-
- /* Push branch heads on stack. */
- STAILQ_FOREACH(d_tmp, &deltalist_inverted, delta_prev) {
- if (d_tmp == NULL) {
- lprintf(2, "Empty branch!\n");
- return (-1);
- }
- if (stream_printf(dest, "\n%s%s", branches_space,
- d_tmp->revnum) < 0)
- return (-1);
- }
-
- if (stream_printf(dest, ";\nnext%s", next_space) < 0)
- return (-1);
- /* Push next delta on stack. */
- d_next = LIST_NEXT(d, delta_next);
- if (d_next != NULL) {
- if (stream_printf(dest, "%s", d_next->revnum) < 0)
- return (-1);
- STAILQ_INSERT_HEAD(&deltastack, d_next, stack_next);
- }
- if (stream_printf(dest, ";\n\n") < 0)
- return (-1);
- }
- /* Write out desc. */
- if (stream_printf(dest, "\ndesc\n@@") < 0)
- return (-1);
- d = LIST_FIRST(&rf->trunk->deltalist);
-
- /* Write out deltatexts. */
- error = rcsfile_write_deltatext(rf, dest);
- if (stream_printf(dest, "\n") < 0)
- return (-1);
- return (error);
-}
-
-/*
- * Write out deltatexts of a delta and it's subbranches recursively.
- */
-int
-rcsfile_write_deltatext(struct rcsfile *rf, struct stream *dest)
-{
- STAILQ_HEAD(, delta) deltastack;
- LIST_HEAD(, delta) branchlist_datesorted;
- struct delta *d, *d_tmp, *d_next, *d_tmp2, *d_tmp3;
- struct stream *in;
- struct branch *b;
- size_t size;
- char *line;
- int error;
-
- error = 0;
- STAILQ_INIT(&deltastack);
- d = LIST_FIRST(&rf->trunk->deltalist);
- d->prev = NULL;
- STAILQ_INSERT_HEAD(&deltastack, d, stack_next);
- while (!STAILQ_EMPTY(&deltastack)) {
- d = STAILQ_FIRST(&deltastack);
- STAILQ_REMOVE_HEAD(&deltastack, stack_next);
- /* Do not write out placeholders just to be safe. */
- if (d->placeholder)
- return (0);
- if (stream_printf(dest, "\n\n\n%s\n", d->revnum) < 0)
- return (-1);
- if (stream_printf(dest, "log\n@") < 0)
- return (-1);
- in = stream_open_buf(d->log);
- line = stream_getln(in, &size);
- while (line != NULL) {
- if (stream_write(dest, line, size) == -1)
- return (-1);
- line = stream_getln(in, &size);
- }
- stream_close(in);
- if (stream_printf(dest, "@\ntext\n@") < 0)
- return (-1);
- error = rcsfile_puttext(rf, dest, d, d->prev);
- if (error)
- return (error);
- if (stream_printf(dest, "@") < 0)
- return (-1);
-
- LIST_INIT(&branchlist_datesorted);
- d_next = LIST_NEXT(d, delta_next);
- if (d_next != NULL) {
- d_next->prev = d;
- /*
- * If it's trunk, treat it like the oldest, if not treat
- * it like a child.
- */
- if (rcsrev_istrunk(d_next->revnum))
- STAILQ_INSERT_HEAD(&deltastack, d_next,
- stack_next);
- else
- LIST_INSERT_HEAD(&branchlist_datesorted, d_next,
- branch_next_date);
- }
-
- /*
- * First, we need to sort our branches based on their date to
- * take into account some self-hacked RCS files.
- */
- LIST_FOREACH(b, &d->branchlist, branch_next) {
- d_tmp = LIST_FIRST(&b->deltalist);
- if (LIST_EMPTY(&branchlist_datesorted)) {
- LIST_INSERT_HEAD(&branchlist_datesorted, d_tmp,
- branch_next_date);
- continue;
- }
-
- d_tmp2 = LIST_FIRST(&branchlist_datesorted);
- if (rcsnum_cmp(d_tmp->revdate, d_tmp2->revdate) <= 0) {
- LIST_INSERT_BEFORE(d_tmp2, d_tmp,
- branch_next_date);
- continue;
- }
- while ((d_tmp3 = LIST_NEXT(d_tmp2, branch_next_date))
- != NULL) {
- if (rcsnum_cmp(d_tmp->revdate, d_tmp3->revdate)
- <= 0)
- break;
- d_tmp2 = d_tmp3;
- }
- LIST_INSERT_AFTER(d_tmp2, d_tmp, branch_next_date);
- }
- /*
- * Invert the deltalist of a branch, since we're writing them
- * the opposite way.
- */
- LIST_FOREACH(d_tmp, &branchlist_datesorted, branch_next_date) {
- d_tmp->prev = d;
- STAILQ_INSERT_HEAD(&deltastack, d_tmp, stack_next);
- }
- }
- return (0);
-}
-
-/*
- * Generates text given a delta and a diffbase.
- */
-static int
-rcsfile_puttext(struct rcsfile *rf, struct stream *dest, struct delta *d,
- struct delta *diffbase)
-{
- struct stream *in, *rd, *orig;
- struct keyword *k;
- struct diffinfo dibuf, *di;
- struct buf *b;
- size_t size;
- char *line;
- int error;
-
- di = &dibuf;
- b = NULL;
- error = 0;
-
- /* Write if the diffbase is the previous */
- if (d->diffbase == diffbase) {
-
- /* Write out the text. */
- in = stream_open_buf(d->text);
- line = stream_getln(in, &size);
- while (line != NULL) {
- if (stream_write(dest, line, size) == -1) {
- error = -1;
- goto cleanup;
- }
- line = stream_getln(in, &size);
- }
- stream_close(in);
- /* We need to apply diff to produce text, this is probably HEAD. */
- } else if (diffbase == NULL) {
- /* Apply diff. */
- orig = rcsfile_getdeltatext(rf, d, &b);
- if (orig == NULL) {
- error = -1;
- goto cleanup;
- }
- line = stream_getln(orig, &size);
- while (line != NULL) {
- if (stream_write(dest, line, size) == -1) {
- error = -1;
- goto cleanup;
- }
- line = stream_getln(orig, &size);
- }
- stream_close(orig);
- /*
- * A new head was probably added, and now the previous HEAD must be
- * changed to include the diff instead.
- */
- } else if (diffbase->diffbase == d) {
- /* Get reverse diff. */
- orig = rcsfile_getdeltatext(rf, d, &b);
- if (orig == NULL) {
- error = -1;
- goto cleanup;
- }
- di->di_rcsfile = rf->name;
- di->di_cvsroot = rf->cvsroot;
- di->di_revnum = d->revnum;
- di->di_revdate = d->revdate;
- di->di_author = d->author;
- di->di_tag = rf->colltag;
- di->di_state = d->state;
- di->di_expand = EXPAND_OLD;
- k = keyword_new();
-
- rd = stream_open_buf(diffbase->text);
- error = diff_reverse(rd, orig, dest, k, di);
- if (error) {
- lprintf(-1, "Error applying reverse diff: %d\n", error);
- goto cleanup;
- }
- keyword_free(k);
- stream_close(rd);
- stream_close(orig);
- }
-cleanup:
- if (b != NULL)
- buf_free(b);
- return (error);
-}
-
-/*
- * Return a stream with an applied diff of a delta.
- * XXX: extra overhead on the last apply. Could write directly to file, but
- * makes things complicated though.
- */
-static struct stream *
-rcsfile_getdeltatext(struct rcsfile *rf, struct delta *d, struct buf **buf_dest)
-{
- struct diffinfo dibuf, *di;
- struct stream *orig, *dest, *rd;
- struct buf *buf_orig;
- struct keyword *k;
- int error;
-
- buf_orig = NULL;
- error = 0;
-
- /*
- * If diffbase is NULL or we are head (the old head), we have a normal
- * complete deltatext.
- */
- if (d->diffbase == NULL && !strcmp(rf->head, d->revnum)) {
- orig = stream_open_buf(d->text);
- return (orig);
- }
-
- di = &dibuf;
- /* If not, we need to apply our diff to that of our diffbase. */
- orig = rcsfile_getdeltatext(rf, d->diffbase, &buf_orig);
- if (orig == NULL)
- return (NULL);
-
- /*
- * Now that we are sure we have a complete deltatext in ret, let's apply
- * our diff to it.
- */
- *buf_dest = buf_new(BUF_SIZE_DEFAULT);
- dest = stream_open_buf(*buf_dest);
-
- di->di_rcsfile = rf->name;
- di->di_cvsroot = rf->cvsroot;
- di->di_revnum = d->revnum;
- di->di_revdate = d->revdate;
- di->di_author = d->author;
- di->di_tag = rf->colltag;
- di->di_state = d->state;
- di->di_expand = EXPAND_OLD;
- rd = stream_open_buf(d->text);
- k = keyword_new();
- error = diff_apply(rd, orig, dest, k, di, 0);
- stream_flush(dest);
- stream_close(rd);
- stream_close(orig);
- stream_close(dest);
- keyword_free(k);
- if (buf_orig != NULL)
- buf_free(buf_orig);
- if (error) {
- lprintf(-1, "Error applying diff: %d\n", error);
- return (NULL);
- }
-
- /* Now reopen the stream for the reading. */
- dest = stream_open_buf(*buf_dest);
- return (dest);
-}
-
-/* Print content of rcsfile. Useful for debugging. */
-void
-rcsfile_print(struct rcsfile *rf)
-{
- struct delta *d;
- struct tag *t;
- struct string *s;
- struct stream *in;
- char *line;
-
- lprintf(1, "\n");
- if (rf->name != NULL)
- lprintf(1, "name: '%s'\n", rf->name);
- if (rf->head != NULL)
- lprintf(1, "head: '%s'\n", rf->head);
- if (rf->branch != NULL)
- lprintf(1, "branch: '%s'\n", rf->branch);
- lprintf(1, "Access: ");
- STAILQ_FOREACH(s, &rf->accesslist, string_next)
- lprintf(1, "'%s' ", s->str);
- lprintf(1, "\n");
-
- /* Print all tags. */
- STAILQ_FOREACH(t, &rf->taglist, tag_next) {
- lprintf(1, "Tag: ");
- if (t->tag != NULL)
- lprintf(1, "name: %s ", t->tag);
- if (t->revnum != NULL)
- lprintf(1, "rev: %s", t->revnum);
- lprintf(1, "\n");
- }
-
- if (rf->strictlock)
- lprintf(1, "Strict!\n");
- if (rf->comment != NULL)
- lprintf(1, "comment: '%s'\n", rf->comment);
- if (rf->expand != EXPAND_DEFAULT)
- lprintf(1, "expand: '%s'\n", keyword_encode_expand(rf->expand));
-
- /* Print all deltas. */
- LIST_FOREACH(d, &rf->deltatable, table_next) {
- lprintf(1, "Delta: ");
- if (d->revdate != NULL)
- lprintf(1, "date: %s ", d->revdate);
- if (d->revnum != NULL)
- lprintf(1, "rev: %s", d->revnum);
- if (d->author != NULL)
- lprintf(1, "author: %s", d->author);
- if (d->state != NULL)
- lprintf(1, "state: %s", d->state);
-
- lprintf(1, "Text:\n");
- in = stream_open_buf(d->text);
- line = stream_getln(in, NULL);
- while (line != NULL) {
- lprintf(1, "TEXT: %s\n", line);
- line = stream_getln(in, NULL);
- }
- stream_close(in);
- lprintf(1, "\n");
- }
-
- if (rf->desc != NULL)
- lprintf(1, "desc: '%s'\n", rf->desc);
-}
-
-/* Free all memory associated with a struct rcsfile. */
-void
-rcsfile_free(struct rcsfile *rf)
-{
- struct delta *d;
- struct tag *t;
- struct string *s;
-
- if (rf->name != NULL)
- free(rf->name);
- if (rf->head != NULL)
- free(rf->head);
- if (rf->branch != NULL)
- free(rf->branch);
- if (rf->cvsroot != NULL)
- free(rf->cvsroot);
- if (rf->colltag != NULL)
- free(rf->colltag);
-
- /* Free all access ids. */
- while (!STAILQ_EMPTY(&rf->accesslist)) {
- s = STAILQ_FIRST(&rf->accesslist);
- STAILQ_REMOVE_HEAD(&rf->accesslist, string_next);
- if (s->str != NULL)
- free(s->str);
- free(s);
- }
-
- /* Free all tags. */
- while (!STAILQ_EMPTY(&rf->taglist)) {
- t = STAILQ_FIRST(&rf->taglist);
- STAILQ_REMOVE_HEAD(&rf->taglist, tag_next);
- if (t->tag != NULL)
- free(t->tag);
- if (t->revnum != NULL)
- free(t->revnum);
- free(t);
- }
-
- if (rf->comment != NULL)
- free(rf->comment);
-
- /* Free all deltas in global list */
- while (!LIST_EMPTY(&rf->deltatable)) {
- d = LIST_FIRST(&rf->deltatable);
- if (!rf->ro)
- LIST_REMOVE(d, delta_next);
- LIST_REMOVE(d, table_next);
- rcsfile_freedelta(d);
- }
-
- /* Free global branch. */
- if (rf->trunk->revnum != NULL)
- free(rf->trunk->revnum);
- free(rf->trunk);
-
- if (rf->desc != NULL)
- free(rf->desc);
-
- free(rf);
-}
-
-/*
- * Free a RCS delta.
- */
-static void
-rcsfile_freedelta(struct delta *d)
-{
- struct branch *b;
-
- if (d->revdate != NULL)
- free(d->revdate);
- if (d->revnum != NULL)
- free(d->revnum);
- if (d->author != NULL)
- free(d->author);
- if (d->state != NULL)
- free(d->state);
- if (d->log != NULL)
- buf_free(d->log);
- if (d->text != NULL)
- buf_free(d->text);
-
- /* Free all subbranches of a delta. */
- while (!LIST_EMPTY(&d->branchlist)) {
- b = LIST_FIRST(&d->branchlist);
- LIST_REMOVE(b, branch_next);
- free(b->revnum);
- free(b);
- }
- free(d);
-}
-
-/*
- * Functions for editing RCS deltas.
- */
-
-/* Add a new entry to the access list. */
-void
-rcsfile_addaccess(struct rcsfile *rf, char *id)
-{
- struct string *s;
-
- s = xmalloc(sizeof(struct string));
- s->str = xstrdup(id);
- STAILQ_INSERT_TAIL(&rf->accesslist, s, string_next);
-}
-
-/* Add a tag to a RCS file. */
-void
-rcsfile_addtag(struct rcsfile *rf, char *tag, char *revnum)
-{
- struct tag *t;
-
- t = xmalloc(sizeof(struct tag));
- t->tag = xstrdup(tag);
- t->revnum = xstrdup(revnum);
-
- STAILQ_INSERT_HEAD(&rf->taglist, t, tag_next);
-}
-
-/* Import a tag to a RCS file. */
-void
-rcsfile_importtag(struct rcsfile *rf, char *tag, char *revnum)
-{
- struct tag *t;
-
- t = xmalloc(sizeof(struct tag));
- t->tag = xstrdup(tag);
- t->revnum = xstrdup(revnum);
-
- STAILQ_INSERT_TAIL(&rf->taglist, t, tag_next);
-}
-
-/*
- * Delete a revision from the global delta list and the branch it is in. Csup
- * will tell us to delete the tags involved.
- */
-void
-rcsfile_deleterev(struct rcsfile *rf, char *revname)
-{
- struct delta *d;
-
- d = rcsfile_getdelta(rf, revname);
- if (!rf->ro)
- LIST_REMOVE(d, delta_next);
- LIST_REMOVE(d, table_next);
- rcsfile_freedelta(d);
-}
-
-/* Delete a tag from the tag list. */
-void
-rcsfile_deletetag(struct rcsfile *rf, char *tag, char *revnum)
-{
- struct tag *t;
-
- STAILQ_FOREACH(t, &rf->taglist, tag_next) {
- if ((strcmp(tag, t->tag) == 0) &&
- (strcmp(revnum, t->revnum) == 0)) {
- STAILQ_REMOVE(&rf->taglist, t, tag, tag_next);
- free(t->tag);
- free(t->revnum);
- free(t);
- return;
- }
- }
-}
-
-/*
- * Searches the global deltalist for a delta.
- */
-struct delta *
-rcsfile_getdelta(struct rcsfile *rf, char *revnum)
-{
- struct delta *d;
-
- LIST_FOREACH(d, &rf->deltatable, table_next) {
- if (strcmp(revnum, d->revnum) == 0)
- return (d);
- }
- return (NULL);
-}
-
-/* Set rcsfile head. */
-void
-rcsfile_setval(struct rcsfile *rf, int field, char *val)
-{
- size_t len;
-
- switch (field) {
- case RCSFILE_HEAD:
- if (rf->head != NULL)
- free(rf->head);
- rf->head = xstrdup(val);
- break;
- case RCSFILE_BRANCH:
- if (rf->branch != NULL)
- free(rf->branch);
- rf->branch = (val == NULL) ? NULL : xstrdup(val);
- break;
- case RCSFILE_STRICT:
- if (val != NULL)
- rf->strictlock = 1;
- break;
- case RCSFILE_COMMENT:
- if (rf->comment != NULL)
- free(rf->comment);
- rf->comment = xstrdup(val);
- break;
- case RCSFILE_EXPAND:
- len = strlen(val) - 1;
- val++;
- val[len - 1] = '\0';
- rf->expand = keyword_decode_expand(val);
- break;
- case RCSFILE_DESC:
- if (rf->desc != NULL)
- free(rf->desc);
- rf->desc = xstrdup(val);
- break;
- default:
- lprintf(-1, "Setting invalid RCSfile value.\n");
- break;
- }
-}
-
-/* Create and initialize a delta. */
-static struct delta *
-rcsfile_createdelta(char *revnum)
-{
- struct delta *d;
-
- d = xmalloc(sizeof(struct delta));
- d->revnum = xstrdup(revnum);
- d->revdate = NULL;
- d->state = NULL;
- d->author = NULL;
- d->log = buf_new(BUF_SIZE_DEFAULT);
- d->text = buf_new(BUF_SIZE_DEFAULT);
- d->diffbase = NULL;
-
- LIST_INIT(&d->branchlist);
- return (d);
-}
-
-/* Add a delta to a imported delta tree. Used by the updater. */
-struct delta *
-rcsfile_addelta(struct rcsfile *rf, char *revnum, char *revdate, char *author,
- char *diffbase)
-{
- struct branch *b;
- struct delta *d, *d_bp, *d_next;
- char *brev, *bprev;
- int trunk;
-
- d_next = NULL;
- d = rcsfile_getdelta(rf, revnum);
- if (d != NULL) {
- lprintf(-1, "Delta %s already exists!\n", revnum);
- return (NULL);
- }
- d = rcsfile_createdelta(revnum);
- d->placeholder = 0;
- d->revdate = xstrdup(revdate);
- d->author = xstrdup(author);
- d->diffbase = rcsfile_getdelta(rf, diffbase);
-
- /* If it's trunk, insert it in the head branch list. */
- b = rcsrev_istrunk(d->revnum) ? rf->trunk :
- rcsfile_getbranch(rf, d->revnum);
-
- /*
- * We didn't find a branch, check if we can find a branchpoint and
- * create a branch there.
- */
- if (b == NULL) {
- brev = rcsrev_prefix(d->revnum);
- bprev = rcsrev_prefix(brev);
-
- d_bp = rcsfile_getdelta(rf, bprev);
- free(bprev);
- if (d_bp == NULL) {
- lprintf(-1, "No branch point for adding delta %s\n",
- d->revnum);
- return (NULL);
- }
-
- /* Create the branch and insert in delta. */
- b = xmalloc(sizeof(struct branch));
- b->revnum = brev;
- LIST_INIT(&b->deltalist);
- rcsdelta_insertbranch(d_bp, b);
- }
-
- /* Insert both into the tree, and into the lookup list. */
- trunk = rcsrev_istrunk(d->revnum);
- rcsfile_insertdelta(b, d, trunk);
- rcsfile_insertsorteddelta(rf, d);
- return (d);
-}
-
-/* Adds a delta to a rcsfile struct. Used by the parser. */
-void
-rcsfile_importdelta(struct rcsfile *rf, char *revnum, char *revdate, char *author,
- char *state, char *next)
-{
- struct branch *b;
- struct delta *d, *d_bp, *d_next;
- char *brev, *bprev;
- int trunk;
-
- d_next = NULL;
- d = rcsfile_getdelta(rf, revnum);
-
- if (d == NULL) {
- /* If not, we'll just create a new entry. */
- d = rcsfile_createdelta(revnum);
- d->placeholder = 0;
- } else {
- if (d->placeholder == 0) {
- lprintf(-1, "Trying to import already existing delta\n");
- return;
- }
- }
- /*
- * If already exists, assume that only revnum is filled out, and set the
- * rest of the fields. This should be an OK assumption given that we can
- * be sure internally that the structure is sufficiently initialized so
- * we won't have any unfreed memory.
- */
- d->revdate = xstrdup(revdate);
- d->author = xstrdup(author);
- if (state != NULL)
- d->state = xstrdup(state);
-
- /* If we have a next, create a placeholder for it. */
- if (next != NULL) {
- d_next = rcsfile_createdelta(next);
- d_next->placeholder = 1;
- /* Diffbase should be the previous. */
- d_next->diffbase = d;
- }
-
- /* If we're opening read-only, do minimal work. */
- if (rf->ro) {
- if (!d->placeholder)
- rcsfile_insertsorteddelta(rf, d);
- else
- d->placeholder = 0;
- if (d_next != NULL)
- rcsfile_insertsorteddelta(rf, d_next);
- return;
- }
-
- /* If it's trunk, insert it in the head branch list. */
- b = rcsrev_istrunk(d->revnum) ? rf->trunk : rcsfile_getbranch(rf,
- d->revnum);
-
- /*
- * We didn't find a branch, check if we can find a branchpoint and
- * create a branch there.
- */
- if (b == NULL) {
- brev = rcsrev_prefix(d->revnum);
- bprev = rcsrev_prefix(brev);
-
- d_bp = rcsfile_getdelta(rf, bprev);
- free(bprev);
- if (d_bp == NULL) {
- lprintf(-1, "No branch point for adding delta %s\n",
- d->revnum);
- return;
- }
-
- /* Create the branch and insert in delta. */
- b = xmalloc(sizeof(struct branch));
- b->revnum = brev;
- LIST_INIT(&b->deltalist);
- rcsdelta_insertbranch(d_bp, b);
- }
-
- /* Insert if not a placeholder. */
- if (!d->placeholder) {
- /* Insert both into the tree, and into the lookup list. */
- if (rcsrev_istrunk(d->revnum))
- rcsfile_insertdelta(b, d, 1);
- else {
- rcsfile_insertdelta(b, d, 0);
- /*
- * On import we need to set the diffbase to our
- * branchpoint for writing out later.
- */
- if (LIST_FIRST(&b->deltalist) == d) {
- brev = rcsrev_prefix(d->revnum);
- bprev = rcsrev_prefix(brev);
- d_bp = rcsfile_getdelta(rf, bprev);
- /* This should really not happen. */
- assert(d_bp != NULL);
- d->diffbase = d_bp;
- free(brev);
- free(bprev);
- }
- }
- rcsfile_insertsorteddelta(rf, d);
- } else /* Not a placeholder anymore. */ {
- d->placeholder = 0;
- /* Put it into the tree. */
- trunk = rcsrev_istrunk(d->revnum);
- rcsfile_insertdelta(b, d, trunk);
- }
-
- /* If we have a next, insert the placeholder into the lookup list. */
- if (d_next != NULL)
- rcsfile_insertsorteddelta(rf, d_next);
-}
-
-/*
- * Find the branch of a revision number.
- */
-static struct branch *
-rcsfile_getbranch(struct rcsfile *rf, char *revnum)
-{
- struct branch *b;
- struct delta *d;
- char *branchrev, *bprev;
-
- branchrev = rcsrev_prefix(revnum);
- bprev = rcsrev_prefix(branchrev);
- d = rcsfile_getdelta(rf, bprev);
- free(bprev);
- LIST_FOREACH(b, &d->branchlist, branch_next) {
- if(rcsnum_cmp(b->revnum, branchrev) == 0) {
- free(branchrev);
- return (b);
- }
- }
- free(branchrev);
- return (NULL);
-}
-
-/* Insert a branch into a delta, sorted by branch revision date. */
-static void
-rcsdelta_insertbranch(struct delta *d, struct branch *b)
-{
- struct branch *b_iter;
-
- /* If it's empty, insert into head. */
- if (LIST_EMPTY(&d->branchlist)) {
- LIST_INSERT_HEAD(&d->branchlist, b, branch_next);
- return;
- }
-
- /* Just put it in before the revdate that is lower. */
- LIST_FOREACH(b_iter, &d->branchlist, branch_next) {
- if (rcsnum_cmp(b->revnum, b_iter->revnum) > 0) {
- LIST_INSERT_BEFORE(b_iter, b, branch_next);
- return;
- }
- if (LIST_NEXT(b_iter, branch_next) == NULL)
- break;
- }
- /* Insert after last element. */
- LIST_INSERT_AFTER(b_iter, b, branch_next);
-}
-
-/* Insert a delta into the correct place in the table of the rcsfile. */
-static void
-rcsfile_insertsorteddelta(struct rcsfile *rf, struct delta *d)
-{
- struct delta *d2;
-
- /* If it's empty, insert into head. */
- if (LIST_EMPTY(&rf->deltatable)) {
- LIST_INSERT_HEAD(&rf->deltatable, d, table_next);
- return;
- }
-
- /* Just put it in before the revdate that is lower. */
- LIST_FOREACH(d2, &rf->deltatable, table_next) {
- if (rcsnum_cmp(d->revnum, d2->revnum) <= 0) {
- LIST_INSERT_BEFORE(d2, d, table_next);
- return;
- }
- if (LIST_NEXT(d2, table_next) == NULL)
- break;
- }
- /* Insert after last element. */
- LIST_INSERT_AFTER(d2, d, table_next);
-}
-
-/*
- * Insert a delta into the correct place in branch. A trunk branch will have
- * different ordering scheme and be sorted by revision number, but a normal
- * branch will be sorted by date to maintain compability with branches that is
- * "hand-hacked".
- */
-static void
-rcsfile_insertdelta(struct branch *b, struct delta *d, int trunk)
-{
- struct delta *d2;
-
- /* If it's empty, insert into head. */
- if (LIST_EMPTY(&b->deltalist)) {
- LIST_INSERT_HEAD(&b->deltalist, d, delta_next);
- return;
- }
-
- /*
- * Just put it in before the revnum that is lower. Sort trunk branch by
- * branchnum but the subbranches after deltadate.
- */
- LIST_FOREACH(d2, &b->deltalist, delta_next) {
- if (trunk) {
- if (rcsnum_cmp(d->revnum, d2->revnum) >= 0) {
- LIST_INSERT_BEFORE(d2, d, delta_next);
- return;
- }
- } else {
- /* XXX: here we depend on the date being set, but it
- * should be before this is called anyway. */
- if (rcsnum_cmp(d->revnum, d2->revnum) < 0) {
- LIST_INSERT_BEFORE(d2, d, delta_next);
- return;
- }
- }
- if (LIST_NEXT(d2, delta_next) == NULL)
- break;
- }
- /* Insert after last element. */
- LIST_INSERT_AFTER(d2, d, delta_next);
-}
-
-
-/* Add logtext to a delta. Assume the delta already exists. */
-int
-rcsdelta_addlog(struct delta *d, char *log, int len)
-{
- struct stream *dest;
- int nbytes;
-
- assert(d != NULL);
- /* Strip away '@' at beginning and end. */
- log++;
- len--;
- log[len - 1] = '\0';
- dest = stream_open_buf(d->log);
- nbytes = stream_write(dest, log, len - 1);
- stream_close(dest);
- return ((nbytes == -1) ? -1 : 0);
-}
-
-/* Add deltatext to a delta. Assume the delta already exists. */
-int
-rcsdelta_addtext(struct delta *d, char *text, int len)
-{
- struct stream *dest;
- int nbytes;
-
- assert(d != NULL);
- /* Strip away '@' at beginning and end. */
- text++;
- len--;
- text[len - 1] = '\0';
-
- dest = stream_open_buf(d->text);
- nbytes = stream_write(dest, text, len - 1);
- stream_close(dest);
- return ((nbytes == -1) ? -1 : 0);
-}
-
-/* Add a deltatext logline to a delta. */
-int
-rcsdelta_appendlog(struct delta *d, char *logline, size_t size)
-{
- struct stream *dest;
- int error;
-
- assert(d != NULL);
- dest = stream_open_buf(d->log);
- error = rcsdelta_writestring(logline, size, dest);
- stream_close(dest);
- return (error);
-}
-
-/* Add a deltatext textline to a delta. */
-int
-rcsdelta_appendtext(struct delta *d, char *textline, size_t size)
-{
- struct stream *dest;
- int error;
-
- assert(d != NULL);
- dest = stream_open_buf(d->text);
- error = rcsdelta_writestring(textline, size, dest);
- stream_close(dest);
- return (error);
-}
-
-static int
-rcsdelta_writestring(char *textline, size_t size, struct stream *dest)
-{
- char buf[3];
- size_t i;
- int count;
-
- for (i = 0; i < size; i++) {
- buf[0] = textline[i];
- buf[1] = '\0';
- count = 1;
- /* Expand @'s */
- if (buf[0] == '@') {
- buf[1] = '@';
- buf[2] = '\0';
- count = 2;
- }
- if (stream_write(dest, buf, count) == -1)
- return (-1);
- }
- return (0);
-}
-
-/* Set delta state. */
-void
-rcsdelta_setstate(struct delta *d, char *state)
-{
-
- if (d->state != NULL)
- free(state);
- if (state != NULL) {
- d->state = xstrdup(state);
- return;
- }
- d->state = NULL;
-}
-
-/* Truncate the deltalog with a certain offset. */
-void
-rcsdelta_truncatelog(struct delta *d, off_t offset)
-{
-
- stream_truncate_buf(d->log, offset);
-}
-
-/* Truncate the deltatext with a certain offset. */
-void
-rcsdelta_truncatetext(struct delta *d, off_t offset)
-{
-
- stream_truncate_buf(d->text, offset);
-}
diff --git a/contrib/csup/rcsfile.h b/contrib/csup/rcsfile.h
deleted file mode 100644
index 5fa9f31..0000000
--- a/contrib/csup/rcsfile.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 2007-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _RCSFILE_H_
-#define _RCSFILE_H_
-
-/* RCSFILE fields. */
-#define RCSFILE_HEAD 0
-#define RCSFILE_BRANCH 1
-#define RCSFILE_STRICT 2
-#define RCSFILE_COMMENT 3
-#define RCSFILE_EXPAND 4
-#define RCSFILE_DESC 5
-
-struct rcsfile;
-struct delta;
-struct stream;
-
-/* Fetching, sending and writing an RCS file. */
-struct rcsfile *rcsfile_frompath(char *, char *, char *, char *, int);
-int rcsfile_send_details(struct rcsfile *, struct stream *);
-int rcsfile_write(struct rcsfile *, struct stream *);
-void rcsfile_print(struct rcsfile *);
-void rcsfile_free(struct rcsfile *);
-
-/* Used for adding and setting rcsfile values. */
-void rcsfile_addaccess(struct rcsfile *, char *);
-void rcsfile_addtag(struct rcsfile *, char *, char *);
-void rcsfile_importtag(struct rcsfile *, char *, char *);
-void rcsfile_deleterev(struct rcsfile *, char *);
-void rcsfile_deletetag(struct rcsfile *, char *, char *);
-struct delta *rcsfile_getdelta(struct rcsfile *, char *);
-void rcsfile_setval(struct rcsfile *, int, char *);
-
-/* Functions used for operating on RCS deltas. */
-struct delta *rcsfile_addelta(struct rcsfile *, char *, char *, char *,
- char *);
-void rcsfile_importdelta(struct rcsfile *, char *, char *, char *,
- char *, char *);
-
-int rcsdelta_addlog(struct delta *, char *, int);
-int rcsdelta_addtext(struct delta *, char *, int);
-int rcsdelta_appendlog(struct delta *, char *, size_t);
-int rcsdelta_appendtext(struct delta *, char *, size_t);
-void rcsdelta_setstate(struct delta *, char *);
-void rcsdelta_truncatetext(struct delta *, off_t);
-void rcsdelta_truncatelog(struct delta *, off_t);
-#endif /* !_RCSFILE_H_ */
diff --git a/contrib/csup/rcsparse.c b/contrib/csup/rcsparse.c
deleted file mode 100644
index 5ea690c..0000000
--- a/contrib/csup/rcsparse.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*-
- * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "misc.h"
-#include "queue.h"
-#include "rcsfile.h"
-#include "rcsparse.h"
-#include "rcstokenizer.h"
-
-/*
- * This is an RCS-parser using lex for tokenizing and makes sure the RCS syntax
- * is correct as it constructs an RCS file that is used by csup.
- */
-
-static void asserttoken(yyscan_t *, int);
-static int parse_admin(struct rcsfile *, yyscan_t *);
-static int parse_deltas(struct rcsfile *, yyscan_t *, int);
-static int parse_deltatexts(struct rcsfile *, yyscan_t *, int);
-static char *duptext(yyscan_t *, int *);
-
-struct string {
- char *str;
- STAILQ_ENTRY(string) next;
-};
-
-static void
-asserttoken(yyscan_t *sp, int token)
-{
- int t;
-
- t = token;
- t = rcslex(*sp);
- assert(t == token);
-}
-
-static char *
-duptext(yyscan_t *sp, int *arglen)
-{
- char *tmp, *val;
- int len;
-
- tmp = rcsget_text(*sp);
- len = rcsget_leng(*sp);
- val = xmalloc(len + 1);
- memcpy(val, tmp, len);
- val[len] = '\0';
- if (arglen != NULL)
- *arglen = len;
- return (val);
-}
-
-/*
- * Start up parser, and use the rcsfile hook to add objects.
- */
-int
-rcsparse_run(struct rcsfile *rf, FILE *infp, int ro)
-{
- yyscan_t scanner;
- char *desc;
- int error, tok;
-
- error = 0;
- rcslex_init(&scanner);
- rcsset_in(infp, scanner);
- tok = parse_admin(rf, &scanner);
- tok = parse_deltas(rf, &scanner, tok);
- assert(tok == KEYWORD);
- asserttoken(&scanner, STRING);
- desc = duptext(&scanner, NULL);
- rcsfile_setval(rf, RCSFILE_DESC, desc);
- free(desc);
- tok = rcslex(scanner);
- /* Parse deltatexts if we need to edit. */
- if (!ro) {
- error = parse_deltatexts(rf, &scanner, tok);
- if (error)
- return (error);
- }
- rcslex_destroy(scanner);
- return (0);
-}
-
-/*
- * Parse the admin part of a RCS file.
- */
-static int
-parse_admin(struct rcsfile *rf, yyscan_t *sp)
-{
- char *branch, *comment, *expand, *head, *id, *revnum, *tag, *tmp;
- int strict, token;
-
- strict = 0;
- branch = NULL;
-
- /* head {num}; */
- asserttoken(sp, KEYWORD);
- asserttoken(sp, NUM);
- head = duptext(sp, NULL);
- rcsfile_setval(rf, RCSFILE_HEAD, head);
- free(head);
- asserttoken(sp, SEMIC);
-
- /* { branch {num}; } */
- token = rcslex(*sp);
- if (token == KEYWORD_TWO) {
- asserttoken(sp, NUM);
- branch = duptext(sp, NULL);
- rcsfile_setval(rf, RCSFILE_BRANCH, branch);
- free(branch);
- asserttoken(sp, SEMIC);
- token = rcslex(*sp);
- }
-
- /* access {id]*; */
- assert(token == KEYWORD);
- token = rcslex(*sp);
- while (token == ID) {
- id = duptext(sp, NULL);
- rcsfile_addaccess(rf, id);
- free(id);
- token = rcslex(*sp);
- }
- assert(token == SEMIC);
-
- /* symbols {sym : num}*; */
- asserttoken(sp, KEYWORD);
- token = rcslex(*sp);
- while (token == ID) {
- tag = duptext(sp, NULL);
- asserttoken(sp, COLON);
- asserttoken(sp, NUM);
- revnum = duptext(sp, NULL);
- rcsfile_importtag(rf, tag, revnum);
- free(tag);
- free(revnum);
- token = rcslex(*sp);
- }
- assert(token == SEMIC);
-
- /* locks {id : num}*; */
- asserttoken(sp, KEYWORD);
- token = rcslex(*sp);
- while (token == ID) {
- /* XXX: locks field is skipped */
- asserttoken(sp, COLON);
- asserttoken(sp, NUM);
- token = rcslex(*sp);
- }
- assert(token == SEMIC);
- token = rcslex(*sp);
- while (token == KEYWORD) {
- tmp = rcsget_text(*sp);
-
- /* {strict ;} */
- if (!strcmp(tmp, "strict")) {
- rcsfile_setval(rf, RCSFILE_STRICT, tmp);
- asserttoken(sp, SEMIC);
- /* { comment {string}; } */
- } else if (!strcmp(tmp, "comment")) {
- token = rcslex(*sp);
- if (token == STRING) {
- comment = duptext(sp, NULL);
- rcsfile_setval(rf, RCSFILE_COMMENT, comment);
- free(comment);
- }
- asserttoken(sp, SEMIC);
- /* { expand {string}; } */
- } else if (!strcmp(tmp, "expand")) {
- token = rcslex(*sp);
- if (token == STRING) {
- expand = duptext(sp, NULL);
- rcsfile_setval(rf, RCSFILE_EXPAND, expand);
- free(expand);
- }
- asserttoken(sp, SEMIC);
- }
- /* {newphrase }* */
- token = rcslex(*sp);
- while (token == ID) {
- token = rcslex(*sp);
- /* XXX: newphrases ignored */
- while (token == ID || token == NUM || token == STRING ||
- token == COLON) {
- token = rcslex(*sp);
- }
- asserttoken(sp, SEMIC);
- token = rcslex(*sp);
- }
- }
- return (token);
-}
-
-/*
- * Parse RCS deltas.
- */
-static int
-parse_deltas(struct rcsfile *rf, yyscan_t *sp, int token)
-{
- STAILQ_HEAD(, string) branchlist;
- char *revnum, *revdate, *author, *state, *next;
-
- /* In case we don't have deltas. */
- if (token != NUM)
- return (token);
- do {
- next = NULL;
- state = NULL;
-
- /* num */
- assert(token == NUM);
- revnum = duptext(sp, NULL);
- /* date num; */
- asserttoken(sp, KEYWORD);
- asserttoken(sp, NUM);
- revdate = duptext(sp, NULL);
- asserttoken(sp, SEMIC);
- /* author id; */
- asserttoken(sp, KEYWORD);
- asserttoken(sp, ID);
- author = duptext(sp, NULL);
- asserttoken(sp, SEMIC);
- /* state {id}; */
- asserttoken(sp, KEYWORD);
- token = rcslex(*sp);
- if (token == ID) {
- state = duptext(sp, NULL);
- token = rcslex(*sp);
- }
- assert(token == SEMIC);
- /* branches {num}*; */
- asserttoken(sp, KEYWORD);
- token = rcslex(*sp);
- STAILQ_INIT(&branchlist);
- while (token == NUM)
- token = rcslex(*sp);
- assert(token == SEMIC);
- /* next {num}; */
- asserttoken(sp, KEYWORD);
- token = rcslex(*sp);
- if (token == NUM) {
- next = duptext(sp, NULL);
- token = rcslex(*sp);
- }
- assert(token == SEMIC);
- /* {newphrase }* */
- token = rcslex(*sp);
- while (token == ID) {
- token = rcslex(*sp);
- /* XXX: newphrases ignored. */
- while (token == ID || token == NUM || token == STRING ||
- token == COLON) {
- token = rcslex(*sp);
- }
- asserttoken(sp, SEMIC);
- token = rcslex(*sp);
- }
- rcsfile_importdelta(rf, revnum, revdate, author, state, next);
- free(revnum);
- free(revdate);
- free(author);
- if (state != NULL)
- free(state);
- if (next != NULL)
- free(next);
- } while (token == NUM);
-
- return (token);
-}
-
-/*
- * Parse RCS deltatexts.
- */
-static int
-parse_deltatexts(struct rcsfile *rf, yyscan_t *sp, int token)
-{
- struct delta *d;
- char *log, *revnum, *text;
- int error, len;
-
- error = 0;
- /* In case we don't have deltatexts. */
- if (token != NUM)
- return (-1);
- do {
- /* num */
- assert(token == NUM);
- revnum = duptext(sp, NULL);
- /* Get delta we're adding text to. */
- d = rcsfile_getdelta(rf, revnum);
- free(revnum);
-
- /* log string */
- asserttoken(sp, KEYWORD);
- asserttoken(sp, STRING);
- log = duptext(sp, &len);
- error = rcsdelta_addlog(d, log, len);
- free(log);
- if (error)
- return (-1);
- /* { newphrase }* */
- token = rcslex(*sp);
- while (token == ID) {
- token = rcslex(*sp);
- /* XXX: newphrases ignored. */
- while (token == ID || token == NUM || token == STRING ||
- token == COLON) {
- token = rcslex(*sp);
- }
- asserttoken(sp, SEMIC);
- token = rcslex(*sp);
- }
- /* text string */
- assert(token == KEYWORD);
- asserttoken(sp, STRING);
- text = duptext(sp, &len);
- error = rcsdelta_addtext(d, text, len);
- /*
- * If this happens, something is wrong with the RCS file, and it
- * should be resent.
- */
- free(text);
- if (error)
- return (-1);
- token = rcslex(*sp);
- } while (token == NUM);
-
- return (0);
-}
diff --git a/contrib/csup/rcsparse.h b/contrib/csup/rcsparse.h
deleted file mode 100644
index 01b0156..0000000
--- a/contrib/csup/rcsparse.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _RCSPARSE_H_
-#define _RCSPARSE_H_
-#define ID 0
-#define NUM 1
-#define KEYWORD 2
-#define KEYWORD_TWO 3
-#define STRING 4
-#define SEMIC 5
-#define COLON 6
-
-struct rcsfile;
-int rcsparse_run(struct rcsfile *, FILE *, int);
-#endif /* !_RCSPARSE_H_ */
diff --git a/contrib/csup/rcstokenizer.h b/contrib/csup/rcstokenizer.h
deleted file mode 100644
index 66ea724..0000000
--- a/contrib/csup/rcstokenizer.h
+++ /dev/null
@@ -1,333 +0,0 @@
-#ifndef rcsHEADER_H
-#define rcsHEADER_H 1
-#define rcsIN_HEADER 1
-
-#line 6 "rcstokenizer.h"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-void rcsrestart (FILE *input_file ,yyscan_t yyscanner );
-void rcs_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE rcs_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void rcs_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void rcs_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void rcspush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void rcspop_buffer_state (yyscan_t yyscanner );
-
-YY_BUFFER_STATE rcs_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE rcs_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE rcs_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *rcsalloc (yy_size_t ,yyscan_t yyscanner );
-void *rcsrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void rcsfree (void * ,yyscan_t yyscanner );
-
-/* Begin user sect3 */
-
-#define rcswrap(n) 1
-#define YY_SKIP_YYWRAP
-
-#define yytext_ptr yytext_r
-
-#ifdef YY_HEADER_EXPORT_START_CONDITIONS
-#define INITIAL 0
-
-#endif
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-int rcslex_init (yyscan_t* scanner);
-
-int rcslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int rcslex_destroy (yyscan_t yyscanner );
-
-int rcsget_debug (yyscan_t yyscanner );
-
-void rcsset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE rcsget_extra (yyscan_t yyscanner );
-
-void rcsset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *rcsget_in (yyscan_t yyscanner );
-
-void rcsset_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *rcsget_out (yyscan_t yyscanner );
-
-void rcsset_out (FILE * out_str ,yyscan_t yyscanner );
-
-int rcsget_leng (yyscan_t yyscanner );
-
-char *rcsget_text (yyscan_t yyscanner );
-
-int rcsget_lineno (yyscan_t yyscanner );
-
-void rcsset_lineno (int line_number ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int rcswrap (yyscan_t yyscanner );
-#else
-extern int rcswrap (yyscan_t yyscanner );
-#endif
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int rcslex (yyscan_t yyscanner);
-
-#define YY_DECL int rcslex (yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-
-#line 73 "rcstokenizer.l"
-
-
-#line 332 "rcstokenizer.h"
-#undef rcsIN_HEADER
-#endif /* rcsHEADER_H */
diff --git a/contrib/csup/rcstokenizer.l b/contrib/csup/rcstokenizer.l
deleted file mode 100644
index 56f0f41..0000000
--- a/contrib/csup/rcstokenizer.l
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- * Copyright (c) 2007-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * This tokenizer must be generated by a lexxer with support for reentrancy.
- */
-%{
-#include <string.h>
-
-#include "misc.h"
-#include "rcsparse.h"
-
-%}
-%option reentrant noyywrap
-%option header-file="rcstokenizer.h"
-
-everything (.|\n)*
-num [0-9\.]+
-whitespace [\t\n ]
-digit [0-9]
-idchar [^$,.:;\t\n ]
-string @([^@]|\n|"@@")*@
-keyword head|access|symbols|locks|comment|expand|strict|date|author|state|branches|next|desc|log|text
-keyword2 branch
-newline \n
-%%
-
-{keyword2} {
- return (KEYWORD_TWO);
-}
-{keyword} {
- return (KEYWORD);
-}
-{string} {
- return (STRING);
-}
-{num} {
- return (NUM);
-}
-{num}?{idchar}({idchar}|{num})* {
-/* This will use ID as both ID and SYM. Do extra checking elsewhere.*/
- return (ID);
-}
-; { return (SEMIC); }
-: { return (COLON); }
-\n ;
-[ \t]+ ;
-%%
diff --git a/contrib/csup/rsyncfile.c b/contrib/csup/rsyncfile.c
deleted file mode 100644
index 7680bcc..0000000
--- a/contrib/csup/rsyncfile.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*-
- * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "misc.h"
-#include "rsyncfile.h"
-
-#define MINBLOCKSIZE 1024
-#define MAXBLOCKSIZE (16 * 1024)
-#define RECEIVEBUFFERSIZE (15 * 1024)
-#define BLOCKINFOSIZE 26
-#define SEARCHREGION 10
-#define MAXBLOCKS (RECEIVEBUFFERSIZE / BLOCKINFOSIZE)
-
-#define CHAR_OFFSET 3
-#define RSUM_SIZE 9
-
-struct rsyncfile {
- char *start;
- char *buf;
- char *end;
- size_t blocksize;
- size_t fsize;
- int fd;
-
- char *blockptr;
- int blocknum;
- char blockmd5[MD5_DIGEST_SIZE];
- char rsumstr[RSUM_SIZE];
- uint32_t rsum;
-};
-
-static size_t rsync_chooseblocksize(size_t);
-static uint32_t rsync_rollsum(char *, size_t);
-
-/* Open a file and initialize variable for rsync operation. */
-struct rsyncfile *
-rsync_open(char *path, size_t blocksize, int rdonly)
-{
- struct rsyncfile *rf;
- struct stat st;
- int error;
-
- rf = xmalloc(sizeof(*rf));
- error = stat(path, &st);
- if (error) {
- free(rf);
- return (NULL);
- }
- rf->fsize = st.st_size;
-
- rf->fd = open(path, rdonly ? O_RDONLY : O_RDWR);
- if (rf->fd < 0) {
- free(rf);
- return (NULL);
- }
- rf->buf = mmap(0, rf->fsize, PROT_READ, MAP_SHARED, rf->fd, 0);
- if (rf->buf == MAP_FAILED) {
- free(rf);
- return (NULL);
- }
- rf->start = rf->buf;
- rf->end = rf->buf + rf->fsize;
- rf->blocksize = (blocksize == 0 ? rsync_chooseblocksize(rf->fsize) :
- blocksize);
- rf->blockptr = rf->buf;
- rf->blocknum = 0;
- return (rf);
-}
-
-/* Close and free all resources related to an rsync file transfer. */
-int
-rsync_close(struct rsyncfile *rf)
-{
- int error;
-
- error = munmap(rf->buf, rf->fsize);
- if (error)
- return (error);
- close(rf->fd);
- free(rf);
- return (0);
-}
-
-/*
- * Choose the most appropriate block size for an rsync transfer. Modeled
- * algorithm after cvsup.
- */
-static size_t
-rsync_chooseblocksize(size_t fsize)
-{
- size_t bestrem, blocksize, bs, hisearch, losearch, rem;
-
- blocksize = fsize / MAXBLOCKS;
- losearch = blocksize - SEARCHREGION;
- hisearch = blocksize + SEARCHREGION;
-
- if (losearch < MINBLOCKSIZE) {
- losearch = MINBLOCKSIZE;
- hisearch = losearch + (2 * SEARCHREGION);
- } else if (hisearch > MAXBLOCKSIZE) {
- hisearch = MAXBLOCKSIZE;
- losearch = hisearch - (2 * SEARCHREGION);
- }
-
- bestrem = MAXBLOCKSIZE;
- for (bs = losearch; bs <= hisearch; bs++) {
- rem = fsize % bs;
- if (rem < bestrem) {
- bestrem = rem;
- blocksize = bs;
- }
- }
- return (bestrem);
-}
-
-/* Get the next rsync block of a file. */
-int
-rsync_nextblock(struct rsyncfile *rf)
-{
- MD5_CTX ctx;
- size_t blocksize;
-
- if (rf->blockptr >= rf->end)
- return (0);
- blocksize = min((size_t)(rf->end - rf->blockptr), rf->blocksize);
- /* Calculate MD5 of the block. */
- MD5_Init(&ctx);
- MD5_Update(&ctx, rf->blockptr, blocksize);
- MD5_End(rf->blockmd5, &ctx);
-
- rf->rsum = rsync_rollsum(rf->blockptr, blocksize);
- snprintf(rf->rsumstr, RSUM_SIZE, "%x", rf->rsum);
- rf->blocknum++;
- rf->blockptr += blocksize;
- return (1);
-}
-
-/* Get the rolling checksum of a file. */
-static uint32_t
-rsync_rollsum(char *buf, size_t len)
-{
- uint32_t a, b;
- char *ptr, *limit;
-
- a = b = 0;
- ptr = buf;
- limit = buf + len;
-
- while (ptr < limit) {
- a += *ptr + CHAR_OFFSET;
- b += a;
- ptr++;
- }
- return ((b << 16) | a);
-}
-
-/* Get running sum so far. */
-char *
-rsync_rsum(struct rsyncfile *rf)
-{
-
- return (rf->rsumstr);
-}
-
-/* Get MD5 of current block. */
-char *
-rsync_blockmd5(struct rsyncfile *rf)
-{
-
- return (rf->blockmd5);
-}
-
-/* Accessor for blocksize. */
-size_t
-rsync_blocksize(struct rsyncfile *rf)
-{
-
- return (rf->blocksize);
-}
-
-/* Accessor for filesize. */
-size_t
-rsync_filesize(struct rsyncfile *rf)
-{
-
- return (rf->fsize);
-}
diff --git a/contrib/csup/rsyncfile.h b/contrib/csup/rsyncfile.h
deleted file mode 100644
index 2c41a28..0000000
--- a/contrib/csup/rsyncfile.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * Copyright (c) 2008-2009, Ulf Lilleengen <lulf@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _RSYNCFILE_H_
-#define _RSYNCFILE_H_
-
-struct rsyncfile;
-struct rsyncfile *rsync_open(char *, size_t, int);
-int rsync_nextblock(struct rsyncfile *);
-char *rsync_rsum(struct rsyncfile *);
-char *rsync_blockmd5(struct rsyncfile *);
-int rsync_close(struct rsyncfile *);
-size_t rsync_blocksize(struct rsyncfile *);
-size_t rsync_filesize(struct rsyncfile *);
-
-#endif /* !_RSYNCFILE_H_ */
diff --git a/contrib/csup/status.c b/contrib/csup/status.c
deleted file mode 100644
index 3482e8e..0000000
--- a/contrib/csup/status.c
+++ /dev/null
@@ -1,874 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "fattr.h"
-#include "misc.h"
-#include "pathcomp.h"
-#include "proto.h"
-#include "queue.h"
-#include "status.h"
-#include "stream.h"
-
-#define STATUS_VERSION 5
-
-/* Internal error codes. */
-#define STATUS_ERR_READ (-1)
-#define STATUS_ERR_WRITE (-2)
-#define STATUS_ERR_PARSE (-3)
-#define STATUS_ERR_UNSORTED (-4)
-#define STATUS_ERR_TRUNC (-5)
-#define STATUS_ERR_BOGUS_DIRUP (-6)
-#define STATUS_ERR_BAD_TYPE (-7)
-#define STATUS_ERR_RENAME (-8)
-
-static struct status *status_new(char *, time_t, struct stream *);
-static struct statusrec *status_rd(struct status *);
-static struct statusrec *status_rdraw(struct status *, char **);
-static int status_wr(struct status *, struct statusrec *);
-static int status_wrraw(struct status *, struct statusrec *,
- char *);
-static struct status *status_fromrd(char *, struct stream *);
-static struct status *status_fromnull(char *);
-static void status_free(struct status *);
-
-static void statusrec_init(struct statusrec *);
-static void statusrec_fini(struct statusrec *);
-static int statusrec_cook(struct statusrec *, char *);
-static int statusrec_cmp(struct statusrec *, struct statusrec *);
-
-struct status {
- char *path;
- char *tempfile;
- int error;
- int suberror;
- struct pathcomp *pc;
- struct statusrec buf;
- struct statusrec *previous;
- struct statusrec *current;
- struct stream *rd;
- struct stream *wr;
- time_t scantime;
- int eof;
- int linenum;
- int depth;
- int dirty;
-};
-
-static void
-statusrec_init(struct statusrec *sr)
-{
-
- memset(sr, 0, sizeof(*sr));
-}
-
-static int
-statusrec_cook(struct statusrec *sr, char *line)
-{
- char *clientattr, *serverattr;
-
- switch (sr->sr_type) {
- case SR_FILEDEAD:
- case SR_FILELIVE:
- clientattr = proto_get_ascii(&line);
- if (clientattr == NULL || line != NULL)
- return (-1);
- sr->sr_clientattr = fattr_decode(clientattr);
- if (sr->sr_clientattr == NULL)
- return (-1);
- break;
- case SR_DIRDOWN:
- /* Nothing to do. */
- if (line != NULL)
- return (-1);
- break;
- case SR_CHECKOUTLIVE:
- sr->sr_tag = proto_get_ascii(&line);
- sr->sr_date = proto_get_ascii(&line);
- serverattr = proto_get_ascii(&line);
- sr->sr_revnum = proto_get_ascii(&line);
- sr->sr_revdate = proto_get_ascii(&line);
- clientattr = proto_get_ascii(&line);
- if (clientattr == NULL || line != NULL)
- return (-1);
- sr->sr_serverattr = fattr_decode(serverattr);
- if (sr->sr_serverattr == NULL)
- return (-1);
- sr->sr_clientattr = fattr_decode(clientattr);
- if (sr->sr_clientattr == NULL) {
- fattr_free(sr->sr_serverattr);
- return (-1);
- }
- break;
- case SR_CHECKOUTDEAD:
- sr->sr_tag = proto_get_ascii(&line);
- sr->sr_date = proto_get_ascii(&line);
- serverattr = proto_get_ascii(&line);
- if (serverattr == NULL || line != NULL)
- return (-1);
- sr->sr_serverattr = fattr_decode(serverattr);
- if (sr->sr_serverattr == NULL)
- return (-1);
- break;
- case SR_DIRUP:
- clientattr = proto_get_ascii(&line);
- if (clientattr == NULL || line != NULL)
- return (-1);
- sr->sr_clientattr = fattr_decode(clientattr);
- if (sr->sr_clientattr == NULL)
- return (-1);
- break;
- default:
- return (-1);
- }
- return (0);
-}
-
-static struct statusrec *
-status_rd(struct status *st)
-{
- struct statusrec *sr;
- char *line;
- int error;
-
- sr = status_rdraw(st, &line);
- if (sr == NULL)
- return (NULL);
- error = statusrec_cook(sr, line);
- if (error) {
- st->error = STATUS_ERR_PARSE;
- return (NULL);
- }
- return (sr);
-}
-
-static struct statusrec *
-status_rdraw(struct status *st, char **linep)
-{
- struct statusrec sr;
- char *cmd, *line, *file;
-
- if (st->rd == NULL || st->eof)
- return (NULL);
- line = stream_getln(st->rd, NULL);
- if (line == NULL) {
- if (stream_eof(st->rd)) {
- if (st->depth != 0) {
- st->error = STATUS_ERR_TRUNC;
- return (NULL);
- }
- st->eof = 1;
- return (NULL);
- }
- st->error = STATUS_ERR_READ;
- st->suberror = errno;
- return (NULL);
- }
- st->linenum++;
- cmd = proto_get_ascii(&line);
- file = proto_get_ascii(&line);
- if (file == NULL || strlen(cmd) != 1) {
- st->error = STATUS_ERR_PARSE;
- return (NULL);
- }
-
- switch (cmd[0]) {
- case 'A':
- sr.sr_type = SR_FILELIVE;
- break;
- case 'D':
- sr.sr_type = SR_DIRDOWN;
- st->depth++;
- break;
- case 'C':
- sr.sr_type = SR_CHECKOUTLIVE;
- break;
- case 'c':
- sr.sr_type = SR_CHECKOUTDEAD;
- break;
- case 'U':
- sr.sr_type = SR_DIRUP;
- if (st->depth <= 0) {
- st->error = STATUS_ERR_BOGUS_DIRUP;
- return (NULL);
- }
- st->depth--;
- break;
- case 'V':
- sr.sr_type = SR_FILELIVE;
- break;
- case 'v':
- sr.sr_type = SR_FILEDEAD;
- break;
- default:
- st->error = STATUS_ERR_BAD_TYPE;
- st->suberror = cmd[0];
- return (NULL);
- }
-
- sr.sr_file = xstrdup(file);
- if (st->previous != NULL &&
- statusrec_cmp(st->previous, &sr) >= 0) {
- st->error = STATUS_ERR_UNSORTED;
- free(sr.sr_file);
- return (NULL);
- }
-
- if (st->previous == NULL) {
- st->previous = &st->buf;
- } else {
- statusrec_fini(st->previous);
- statusrec_init(st->previous);
- }
- st->previous->sr_type = sr.sr_type;
- st->previous->sr_file = sr.sr_file;
- *linep = line;
- return (st->previous);
-}
-
-static int
-status_wr(struct status *st, struct statusrec *sr)
-{
- struct pathcomp *pc;
- const struct fattr *fa;
- char *name;
- int error, type, usedirupattr;
-
- pc = st->pc;
- error = 0;
- usedirupattr = 0;
- if (sr->sr_type == SR_DIRDOWN) {
- pathcomp_put(pc, PC_DIRDOWN, sr->sr_file);
- } else if (sr->sr_type == SR_DIRUP) {
- pathcomp_put(pc, PC_DIRUP, sr->sr_file);
- usedirupattr = 1;
- } else {
- pathcomp_put(pc, PC_FILE, sr->sr_file);
- }
-
- while (pathcomp_get(pc, &type, &name)) {
- if (type == PC_DIRDOWN) {
- error = proto_printf(st->wr, "D %s\n", name);
- } else if (type == PC_DIRUP) {
- if (usedirupattr)
- fa = sr->sr_clientattr;
- else
- fa = fattr_bogus;
- usedirupattr = 0;
- error = proto_printf(st->wr, "U %s %f\n", name, fa);
- }
- if (error)
- goto bad;
- }
-
- switch (sr->sr_type) {
- case SR_DIRDOWN:
- case SR_DIRUP:
- /* Already emitted above. */
- break;
- case SR_CHECKOUTLIVE:
- error = proto_printf(st->wr, "C %s %s %s %f %s %s %f\n",
- sr->sr_file, sr->sr_tag, sr->sr_date, sr->sr_serverattr,
- sr->sr_revnum, sr->sr_revdate, sr->sr_clientattr);
- break;
- case SR_CHECKOUTDEAD:
- error = proto_printf(st->wr, "c %s %s %s %f\n", sr->sr_file,
- sr->sr_tag, sr->sr_date, sr->sr_serverattr);
- break;
- case SR_FILELIVE:
- error = proto_printf(st->wr, "V %s %f\n", sr->sr_file,
- sr->sr_clientattr);
- break;
- case SR_FILEDEAD:
- error = proto_printf(st->wr, "v %s %f\n", sr->sr_file,
- sr->sr_clientattr);
- break;
- }
- if (error)
- goto bad;
- return (0);
-bad:
- st->error = STATUS_ERR_WRITE;
- st->suberror = errno;
- return (-1);
-}
-
-static int
-status_wrraw(struct status *st, struct statusrec *sr, char *line)
-{
- char *name;
- char cmd;
- int error, ret, type;
-
- if (st->wr == NULL)
- return (0);
-
- /*
- * Keep the compressor in sync. At this point, the necessary
- * DirDowns and DirUps should have already been emitted, so the
- * compressor should return exactly one value in the PC_DIRDOWN
- * and PC_DIRUP case and none in the PC_FILE case.
- */
- if (sr->sr_type == SR_DIRDOWN)
- pathcomp_put(st->pc, PC_DIRDOWN, sr->sr_file);
- else if (sr->sr_type == SR_DIRUP)
- pathcomp_put(st->pc, PC_DIRUP, sr->sr_file);
- else
- pathcomp_put(st->pc, PC_FILE, sr->sr_file);
- if (sr->sr_type == SR_DIRDOWN || sr->sr_type == SR_DIRUP) {
- ret = pathcomp_get(st->pc, &type, &name);
- assert(ret);
- if (sr->sr_type == SR_DIRDOWN)
- assert(type == PC_DIRDOWN);
- else
- assert(type == PC_DIRUP);
- }
- ret = pathcomp_get(st->pc, &type, &name);
- assert(!ret);
-
- switch (sr->sr_type) {
- case SR_DIRDOWN:
- cmd = 'D';
- break;
- case SR_DIRUP:
- cmd = 'U';
- break;
- case SR_CHECKOUTLIVE:
- cmd = 'C';
- break;
- case SR_CHECKOUTDEAD:
- cmd = 'c';
- break;
- case SR_FILELIVE:
- cmd = 'V';
- break;
- case SR_FILEDEAD:
- cmd = 'v';
- break;
- default:
- assert(0);
- return (-1);
- }
- if (sr->sr_type == SR_DIRDOWN)
- error = proto_printf(st->wr, "%c %S\n", cmd, sr->sr_file);
- else
- error = proto_printf(st->wr, "%c %s %S\n", cmd, sr->sr_file,
- line);
- if (error) {
- st->error = STATUS_ERR_WRITE;
- st->suberror = errno;
- return (-1);
- }
- return (0);
-}
-
-static void
-statusrec_fini(struct statusrec *sr)
-{
-
- fattr_free(sr->sr_serverattr);
- fattr_free(sr->sr_clientattr);
- free(sr->sr_file);
-}
-
-static int
-statusrec_cmp(struct statusrec *a, struct statusrec *b)
-{
- size_t lena, lenb;
-
- if (a->sr_type == SR_DIRUP || b->sr_type == SR_DIRUP) {
- lena = strlen(a->sr_file);
- lenb = strlen(b->sr_file);
- if (a->sr_type == SR_DIRUP &&
- ((lena < lenb && b->sr_file[lena] == '/') || lena == lenb)
- && strncmp(a->sr_file, b->sr_file, lena) == 0)
- return (1);
- if (b->sr_type == SR_DIRUP &&
- ((lenb < lena && a->sr_file[lenb] == '/') || lenb == lena)
- && strncmp(a->sr_file, b->sr_file, lenb) == 0)
- return (-1);
- }
- return (pathcmp(a->sr_file, b->sr_file));
-}
-
-static struct status *
-status_new(char *path, time_t scantime, struct stream *file)
-{
- struct status *st;
-
- st = xmalloc(sizeof(struct status));
- st->path = path;
- st->error = 0;
- st->suberror = 0;
- st->tempfile = NULL;
- st->scantime = scantime;
- st->rd = file;
- st->wr = NULL;
- st->previous = NULL;
- st->current = NULL;
- st->dirty = 0;
- st->eof = 0;
- st->linenum = 0;
- st->depth = 0;
- st->pc = pathcomp_new();
- statusrec_init(&st->buf);
- return (st);
-}
-
-static void
-status_free(struct status *st)
-{
-
- if (st->previous != NULL)
- statusrec_fini(st->previous);
- if (st->rd != NULL)
- stream_close(st->rd);
- if (st->wr != NULL)
- stream_close(st->wr);
- if (st->tempfile != NULL)
- free(st->tempfile);
- free(st->path);
- pathcomp_free(st->pc);
- free(st);
-}
-
-static struct status *
-status_fromrd(char *path, struct stream *file)
-{
- struct status *st;
- char *id, *line;
- time_t scantime;
- int error, ver;
-
- /* Get the first line of the file and validate it. */
- line = stream_getln(file, NULL);
- if (line == NULL) {
- stream_close(file);
- return (NULL);
- }
- id = proto_get_ascii(&line);
- error = proto_get_int(&line, &ver, 10);
- if (error) {
- stream_close(file);
- return (NULL);
- }
- error = proto_get_time(&line, &scantime);
- if (error || line != NULL) {
- stream_close(file);
- return (NULL);
- }
-
- if (strcmp(id, "F") != 0 || ver != STATUS_VERSION) {
- stream_close(file);
- return (NULL);
- }
-
- st = status_new(path, scantime, file);
- st->linenum = 1;
- return (st);
-}
-
-static struct status *
-status_fromnull(char *path)
-{
- struct status *st;
-
- st = status_new(path, -1, NULL);
- st->eof = 1;
- return (st);
-}
-
-/*
- * Open the status file. If scantime is not -1, the file is opened
- * for updating, otherwise, it is opened read-only. If the status file
- * couldn't be opened, NULL is returned and errmsg is set to the error
- * message.
- */
-struct status *
-status_open(struct coll *coll, time_t scantime, char **errmsg)
-{
- struct status *st;
- struct stream *file;
- struct fattr *fa;
- char *destpath, *path;
- int error, rv;
-
- path = coll_statuspath(coll);
- file = stream_open_file(path, O_RDONLY);
- if (file == NULL) {
- if (errno != ENOENT) {
- xasprintf(errmsg, "Could not open \"%s\": %s\n",
- path, strerror(errno));
- free(path);
- return (NULL);
- }
- st = status_fromnull(path);
- } else {
- st = status_fromrd(path, file);
- if (st == NULL) {
- xasprintf(errmsg, "Error in \"%s\": Bad header line",
- path);
- free(path);
- return (NULL);
- }
- }
-
- if (scantime != -1) {
- /* Open for writing too. */
- xasprintf(&destpath, "%s/%s/%s/", coll->co_base,
- coll->co_colldir, coll->co_name);
- st->tempfile = tempname(destpath);
- if (mkdirhier(destpath, coll->co_umask) != 0) {
- xasprintf(errmsg, "Cannot create directories leading "
- "to \"%s\": %s", destpath, strerror(errno));
- free(destpath);
- status_free(st);
- return (NULL);
- }
- free(destpath);
- st->wr = stream_open_file(st->tempfile,
- O_CREAT | O_TRUNC | O_WRONLY, 0644);
- if (st->wr == NULL) {
- xasprintf(errmsg, "Cannot create \"%s\": %s",
- st->tempfile, strerror(errno));
- status_free(st);
- return (NULL);
- }
- fa = fattr_new(FT_FILE, -1);
- fattr_mergedefault(fa);
- fattr_umask(fa, coll->co_umask);
- rv = fattr_install(fa, st->tempfile, NULL);
- fattr_free(fa);
- if (rv == -1) {
- xasprintf(errmsg,
- "Cannot set attributes for \"%s\": %s",
- st->tempfile, strerror(errno));
- status_free(st);
- return (NULL);
- }
- if (scantime != st->scantime)
- st->dirty = 1;
- error = proto_printf(st->wr, "F %d %t\n", STATUS_VERSION,
- scantime);
- if (error) {
- st->error = STATUS_ERR_WRITE;
- st->suberror = errno;
- *errmsg = status_errmsg(st);
- status_free(st);
- return (NULL);
- }
- }
- return (st);
-}
-
-/*
- * Get an entry from the status file. If name is NULL, the next entry
- * is returned. If name is not NULL, the entry matching this name is
- * returned, or NULL if it couldn't be found. If deleteto is set to 1,
- * all the entries read from the status file while looking for the
- * given name are deleted.
- */
-int
-status_get(struct status *st, char *name, int isdirup, int deleteto,
- struct statusrec **psr)
-{
- struct statusrec key;
- struct statusrec *sr;
- char *line;
- int c, error;
-
- if (st->eof)
- return (0);
-
- if (st->error)
- return (-1);
-
- if (name == NULL) {
- sr = status_rd(st);
- if (sr == NULL) {
- if (st->error)
- return (-1);
- return (0);
- }
- *psr = sr;
- return (1);
- }
-
- if (st->current != NULL) {
- sr = st->current;
- st->current = NULL;
- } else {
- sr = status_rd(st);
- if (sr == NULL) {
- if (st->error)
- return (-1);
- return (0);
- }
- }
-
- key.sr_file = name;
- if (isdirup)
- key.sr_type = SR_DIRUP;
- else
- key.sr_type = SR_CHECKOUTLIVE;
-
- c = statusrec_cmp(sr, &key);
- if (c < 0) {
- if (st->wr != NULL && !deleteto) {
- error = status_wr(st, sr);
- if (error)
- return (-1);
- }
- /* Loop until we find the good entry. */
- for (;;) {
- sr = status_rdraw(st, &line);
- if (sr == NULL) {
- if (st->error)
- return (-1);
- return (0);
- }
- c = statusrec_cmp(sr, &key);
- if (c >= 0)
- break;
- if (st->wr != NULL && !deleteto) {
- error = status_wrraw(st, sr, line);
- if (error)
- return (-1);
- }
- }
- error = statusrec_cook(sr, line);
- if (error) {
- st->error = STATUS_ERR_PARSE;
- return (-1);
- }
- }
- st->current = sr;
- if (c != 0)
- return (0);
- *psr = sr;
- return (1);
-}
-
-/*
- * Put this entry into the status file. If an entry with the same name
- * existed in the status file, it is replaced by this one, otherwise,
- * the entry is added to the status file.
- */
-int
-status_put(struct status *st, struct statusrec *sr)
-{
- struct statusrec *old;
- int error, ret;
-
- ret = status_get(st, sr->sr_file, sr->sr_type == SR_DIRUP, 0, &old);
- if (ret == -1)
- return (-1);
- if (ret) {
- if (old->sr_type == SR_DIRDOWN) {
- /* DirUp should never match DirDown */
- assert(old->sr_type != SR_DIRUP);
- if (sr->sr_type == SR_CHECKOUTLIVE ||
- sr->sr_type == SR_CHECKOUTDEAD) {
- /* We are replacing a directory with a file.
- Delete all entries inside the directory we
- are replacing. */
- ret = status_get(st, sr->sr_file, 1, 1, &old);
- if (ret == -1)
- return (-1);
- assert(ret);
- }
- } else
- st->current = NULL;
- }
- st->dirty = 1;
- error = status_wr(st, sr);
- if (error)
- return (-1);
- return (0);
-}
-
-/*
- * Delete the specified entry from the status file.
- */
-int
-status_delete(struct status *st, char *name, int isdirup)
-{
- struct statusrec *sr;
- int ret;
-
- ret = status_get(st, name, isdirup, 0, &sr);
- if (ret == -1)
- return (-1);
- if (ret) {
- st->current = NULL;
- st->dirty = 1;
- }
- return (0);
-}
-
-/*
- * Check whether we hit the end of file.
- */
-int
-status_eof(struct status *st)
-{
-
- return (st->eof);
-}
-
-/*
- * Returns the error message if there was an error, otherwise returns
- * NULL. The error message is allocated dynamically and needs to be
- * freed by the caller after use.
- */
-char *
-status_errmsg(struct status *st)
-{
- char *errmsg;
-
- if (!st->error)
- return (NULL);
- switch (st->error) {
- case STATUS_ERR_READ:
- xasprintf(&errmsg, "Read failure on \"%s\": %s",
- st->path, strerror(st->suberror));
- break;
- case STATUS_ERR_WRITE:
- xasprintf(&errmsg, "Write failure on \"%s\": %s",
- st->tempfile, strerror(st->suberror));
- break;
- case STATUS_ERR_PARSE:
- xasprintf(&errmsg, "Error in \"%s\": %d: "
- "Could not parse status record", st->path, st->linenum);
- break;
- case STATUS_ERR_UNSORTED:
- xasprintf(&errmsg, "Error in \"%s\": %d: "
- "File is not sorted properly", st->path, st->linenum);
- break;
- case STATUS_ERR_TRUNC:
- xasprintf(&errmsg, "Error in \"%s\": "
- "File is truncated", st->path);
- break;
- case STATUS_ERR_BOGUS_DIRUP:
- xasprintf(&errmsg, "Error in \"%s\": %d: "
- "\"U\" entry has no matching \"D\"", st->path, st->linenum);
- break;
- case STATUS_ERR_BAD_TYPE:
- xasprintf(&errmsg, "Error in \"%s\": %d: "
- "Invalid file type \"%c\"", st->path, st->linenum,
- st->suberror);
- break;
- case STATUS_ERR_RENAME:
- xasprintf(&errmsg, "Cannot rename \"%s\" to \"%s\": %s",
- st->tempfile, st->path, strerror(st->suberror));
- break;
- default:
- assert(0);
- return (NULL);
- }
- return (errmsg);
-}
-
-/*
- * Close the status file and free any resource associated with it.
- * It is OK to pass NULL for errmsg only if the status file was
- * opened read-only. If it wasn't opened read-only, status_close()
- * can produce an error and errmsg is not allowed to be NULL. If
- * there was no errors, errmsg is set to NULL.
- */
-void
-status_close(struct status *st, char **errmsg)
-{
- struct statusrec *sr;
- char *line, *name;
- int error, type;
-
- if (st->wr != NULL) {
- if (st->dirty) {
- if (st->current != NULL) {
- error = status_wr(st, st->current);
- if (error) {
- *errmsg = status_errmsg(st);
- goto bad;
- }
- st->current = NULL;
- }
- /* Copy the rest of the file. */
- while ((sr = status_rdraw(st, &line)) != NULL) {
- error = status_wrraw(st, sr, line);
- if (error) {
- *errmsg = status_errmsg(st);
- goto bad;
- }
- }
- if (st->error) {
- *errmsg = status_errmsg(st);
- goto bad;
- }
-
- /* Close off all the open directories. */
- pathcomp_finish(st->pc);
- while (pathcomp_get(st->pc, &type, &name)) {
- assert(type == PC_DIRUP);
- error = proto_printf(st->wr, "U %s %f\n",
- name, fattr_bogus);
- if (error) {
- st->error = STATUS_ERR_WRITE;
- st->suberror = errno;
- *errmsg = status_errmsg(st);
- goto bad;
- }
- }
-
- /* Rename tempfile. */
- error = rename(st->tempfile, st->path);
- if (error) {
- st->error = STATUS_ERR_RENAME;
- st->suberror = errno;
- *errmsg = status_errmsg(st);
- goto bad;
- }
- } else {
- /* Just discard the tempfile. */
- unlink(st->tempfile);
- }
- *errmsg = NULL;
- }
- status_free(st);
- return;
-bad:
- status_free(st);
-}
diff --git a/contrib/csup/status.h b/contrib/csup/status.h
deleted file mode 100644
index 86efdda..0000000
--- a/contrib/csup/status.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _STATUS_H_
-#define _STATUS_H_
-
-#include <time.h>
-
-struct coll;
-struct fattr;
-struct status;
-
-#define SR_DIRDOWN 0
-#define SR_CHECKOUTLIVE 1
-#define SR_CHECKOUTDEAD 2
-#define SR_FILELIVE 3
-#define SR_FILEDEAD 4
-#define SR_DIRUP 5
-
-struct statusrec {
- int sr_type;
- char *sr_file;
- char *sr_tag;
- char *sr_date;
- char *sr_revnum;
- char *sr_revdate;
-
- /*
- * "clientrttr" contains the attributes of the client's file if there
- * is one. "serverattr" contains the attributes of the corresponding
- * file on the server. In CVS mode, these are identical. But in
- * checkout mode, "clientattr" represents the checked-out file while
- * "serverattr" represents the corresponding RCS file on the server.
- */
- struct fattr *sr_serverattr;
- struct fattr *sr_clientattr;
-};
-
-struct status *status_open(struct coll *, time_t, char **);
-int status_get(struct status *, char *, int, int,
- struct statusrec **);
-int status_put(struct status *, struct statusrec *);
-int status_eof(struct status *);
-char *status_errmsg(struct status *);
-int status_delete(struct status *, char *, int);
-void status_close(struct status *, char **);
-
-#endif /* !_STATUS_H_ */
diff --git a/contrib/csup/stream.c b/contrib/csup/stream.c
deleted file mode 100644
index aa229b4..0000000
--- a/contrib/csup/stream.c
+++ /dev/null
@@ -1,1303 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <zlib.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "misc.h"
-#include "stream.h"
-
-/*
- * Simple stream API to make my life easier. If the fgetln() and
- * funopen() functions were standard and if funopen() wasn't using
- * wrong types for the function pointers, I could have just used
- * stdio, but life sucks.
- *
- * For now, streams are always block-buffered.
- */
-
-/*
- * Try to quiet warnings as much as possible with GCC while staying
- * compatible with other compilers.
- */
-#ifndef __unused
-#if defined(__GNUC__) && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7)
-#define __unused __attribute__((__unused__))
-#else
-#define __unused
-#endif
-#endif
-
-/*
- * Flags passed to the flush methods.
- *
- * STREAM_FLUSH_CLOSING is passed during the last flush call before
- * closing a stream. This allows the zlib filter to emit the EOF
- * marker as appropriate. In all other cases, STREAM_FLUSH_NORMAL
- * should be passed.
- *
- * These flags are completely unused in the default flush method,
- * but they are very important for the flush method of the zlib
- * filter.
- */
-typedef enum {
- STREAM_FLUSH_NORMAL,
- STREAM_FLUSH_CLOSING
-} stream_flush_t;
-
-/*
- * This is because buf_new() will always allocate size + 1 bytes,
- * so our buffer sizes will still be power of 2 values.
- */
-#define STREAM_BUFSIZ 1023
-
-struct buf {
- char *buf;
- size_t size;
- size_t in;
- size_t off;
-};
-
-struct stream {
- void *cookie;
- int fd;
- int buf;
- struct buf *rdbuf;
- struct buf *wrbuf;
- stream_readfn_t *readfn;
- stream_writefn_t *writefn;
- stream_closefn_t *closefn;
- int eof;
- struct stream_filter *filter;
- void *fdata;
-};
-
-typedef int stream_filter_initfn_t(struct stream *, void *);
-typedef void stream_filter_finifn_t(struct stream *);
-typedef int stream_filter_flushfn_t(struct stream *, struct buf *,
- stream_flush_t);
-typedef ssize_t stream_filter_fillfn_t(struct stream *, struct buf *);
-
-struct stream_filter {
- stream_filter_t id;
- stream_filter_initfn_t *initfn;
- stream_filter_finifn_t *finifn;
- stream_filter_fillfn_t *fillfn;
- stream_filter_flushfn_t *flushfn;
-};
-
-/* Low-level buffer API. */
-#define buf_avail(buf) ((buf)->size - (buf)->off - (buf)->in)
-#define buf_count(buf) ((buf)->in)
-#define buf_size(buf) ((buf)->size)
-
-static void buf_more(struct buf *, size_t);
-static void buf_less(struct buf *, size_t);
-static void buf_grow(struct buf *, size_t);
-
-/* Internal stream functions. */
-static ssize_t stream_fill(struct stream *);
-static ssize_t stream_fill_default(struct stream *, struct buf *);
-static int stream_flush_int(struct stream *, stream_flush_t);
-static int stream_flush_default(struct stream *, struct buf *,
- stream_flush_t);
-
-/* Filters specific functions. */
-static struct stream_filter *stream_filter_lookup(stream_filter_t);
-static int stream_filter_init(struct stream *, void *);
-static void stream_filter_fini(struct stream *);
-
-/* The zlib stream filter declarations. */
-#define ZFILTER_EOF 1 /* Got Z_STREAM_END. */
-
-struct zfilter {
- int flags;
- struct buf *rdbuf;
- struct buf *wrbuf;
- z_stream *rdstate;
- z_stream *wrstate;
-};
-
-static int zfilter_init(struct stream *, void *);
-static void zfilter_fini(struct stream *);
-static ssize_t zfilter_fill(struct stream *, struct buf *);
-static int zfilter_flush(struct stream *, struct buf *,
- stream_flush_t);
-
-/* The MD5 stream filter. */
-struct md5filter {
- MD5_CTX ctx;
- char *md5;
- char lastc;
-#define PRINT 1
-#define WS 2
-#define STRING 3
-#define SEEN 4
- int state;
-};
-
-static int md5filter_init(struct stream *, void *);
-static void md5filter_fini(struct stream *);
-static ssize_t md5filter_fill(struct stream *, struct buf *);
-static int md5filter_flush(struct stream *, struct buf *,
- stream_flush_t);
-static int md5rcsfilter_flush(struct stream *, struct buf *,
- stream_flush_t);
-
-/* The available stream filters. */
-struct stream_filter stream_filters[] = {
- {
- STREAM_FILTER_NULL,
- NULL,
- NULL,
- stream_fill_default,
- stream_flush_default
- },
- {
- STREAM_FILTER_ZLIB,
- zfilter_init,
- zfilter_fini,
- zfilter_fill,
- zfilter_flush
- },
- {
- STREAM_FILTER_MD5,
- md5filter_init,
- md5filter_fini,
- md5filter_fill,
- md5filter_flush
- },
- {
- STREAM_FILTER_MD5RCS,
- md5filter_init,
- md5filter_fini,
- md5filter_fill,
- md5rcsfilter_flush
- }
-
-};
-
-
-/* Create a new buffer. */
-struct buf *
-buf_new(size_t size)
-{
- struct buf *buf;
-
- buf = xmalloc(sizeof(struct buf));
- /*
- * We keep one spare byte so that stream_getln() can put a '\0'
- * there in case the stream doesn't have an ending newline.
- */
- buf->buf = xmalloc(size + 1);
- memset(buf->buf, 0, size + 1);
- buf->size = size;
- buf->in = 0;
- buf->off = 0;
- return (buf);
-}
-
-/*
- * Grow the size of the buffer. If "need" is 0, bump its size to the
- * next power of 2 value. Otherwise, bump it to the next power of 2
- * value bigger than "need".
- */
-static void
-buf_grow(struct buf *buf, size_t need)
-{
-
- if (need == 0)
- buf->size = buf->size * 2 + 1; /* Account for the spare byte. */
- else {
- assert(need > buf->size);
- while (buf->size < need)
- buf->size = buf->size * 2 + 1;
- }
- buf->buf = xrealloc(buf->buf, buf->size + 1);
-}
-
-/* Make more room in the buffer if needed. */
-static void
-buf_prewrite(struct buf *buf)
-{
-
- if (buf_count(buf) == buf_size(buf))
- buf_grow(buf, 0);
- if (buf_count(buf) > 0 && buf_avail(buf) == 0) {
- memmove(buf->buf, buf->buf + buf->off, buf_count(buf));
- buf->off = 0;
- }
-}
-
-/* Account for "n" bytes being added in the buffer. */
-static void
-buf_more(struct buf *buf, size_t n)
-{
-
- assert(n <= buf_avail(buf));
- buf->in += n;
-}
-
-/* Account for "n" bytes having been read in the buffer. */
-static void
-buf_less(struct buf *buf, size_t n)
-{
-
- assert(n <= buf_count(buf));
- buf->in -= n;
- if (buf->in == 0)
- buf->off = 0;
- else
- buf->off += n;
-}
-
-/* Free a buffer. */
-void
-buf_free(struct buf *buf)
-{
-
- free(buf->buf);
- free(buf);
-}
-
-static struct stream *
-stream_new(stream_readfn_t *readfn, stream_writefn_t *writefn,
- stream_closefn_t *closefn)
-{
- struct stream *stream;
-
- stream = xmalloc(sizeof(struct stream));
- if (readfn == NULL && writefn == NULL) {
- errno = EINVAL;
- return (NULL);
- }
- if (readfn != NULL)
- stream->rdbuf = buf_new(STREAM_BUFSIZ);
- else
- stream->rdbuf = NULL;
- if (writefn != NULL)
- stream->wrbuf = buf_new(STREAM_BUFSIZ);
- else
- stream->wrbuf = NULL;
- stream->cookie = NULL;
- stream->fd = -1;
- stream->buf = 0;
- stream->readfn = readfn;
- stream->writefn = writefn;
- stream->closefn = closefn;
- stream->filter = stream_filter_lookup(STREAM_FILTER_NULL);
- stream->fdata = NULL;
- stream->eof = 0;
- return (stream);
-}
-
-/* Create a new stream associated with a void *. */
-struct stream *
-stream_open(void *cookie, stream_readfn_t *readfn, stream_writefn_t *writefn,
- stream_closefn_t *closefn)
-{
- struct stream *stream;
-
- stream = stream_new(readfn, writefn, closefn);
- stream->cookie = cookie;
- return (stream);
-}
-
-/* Associate a file descriptor with a stream. */
-struct stream *
-stream_open_fd(int fd, stream_readfn_t *readfn, stream_writefn_t *writefn,
- stream_closefn_t *closefn)
-{
- struct stream *stream;
-
- stream = stream_new(readfn, writefn, closefn);
- stream->cookie = &stream->fd;
- stream->fd = fd;
- return (stream);
-}
-
-/* Associate a buf with a stream. */
-struct stream *
-stream_open_buf(struct buf *b)
-{
- struct stream *stream;
-
- stream = stream_new(stream_read_buf, stream_append_buf, stream_close_buf);
- stream->cookie = b;
- stream->buf = 1;
- b->in = 0;
- return (stream);
-}
-
-/*
- * Truncate a buffer, just decrease offset pointer.
- * XXX: this can be dangerous if not used correctly.
- */
-void
-stream_truncate_buf(struct buf *b, off_t off)
-{
- b->off += off;
-}
-
-/* Like open() but returns a stream. */
-struct stream *
-stream_open_file(const char *path, int flags, ...)
-{
- struct stream *stream;
- stream_readfn_t *readfn;
- stream_writefn_t *writefn;
- va_list ap;
- mode_t mode;
- int fd;
-
- va_start(ap, flags);
- if (flags & O_CREAT) {
- /*
- * GCC says I should not be using mode_t here since it's
- * promoted to an int when passed through `...'.
- */
- mode = va_arg(ap, int);
- fd = open(path, flags, mode);
- } else
- fd = open(path, flags);
- va_end(ap);
- if (fd == -1)
- return (NULL);
-
- flags &= O_ACCMODE;
- if (flags == O_RDONLY) {
- readfn = stream_read_fd;
- writefn = NULL;
- } else if (flags == O_WRONLY) {
- readfn = NULL;
- writefn = stream_write_fd;
- } else if (flags == O_RDWR) {
- assert(flags == O_RDWR);
- readfn = stream_read_fd;
- writefn = stream_write_fd;
- } else {
- errno = EINVAL;
- close(fd);
- return (NULL);
- }
-
- stream = stream_open_fd(fd, readfn, writefn, stream_close_fd);
- if (stream == NULL)
- close(fd);
- return (stream);
-}
-
-/* Return the file descriptor associated with this stream, or -1. */
-int
-stream_fileno(struct stream *stream)
-{
-
- return (stream->fd);
-}
-
-/* Convenience read function for character buffers. */
-ssize_t
-stream_read_buf(void *cookie, void *buf, size_t size)
-{
- struct buf *b;
- size_t avail;
-
- /* Use in to be read offset. */
- b = (struct buf *)cookie;
- /* Just return what we have if the request is to large. */
- avail = b->off - b->in;
- if (avail < size) {
- memcpy(buf, (b->buf + b->in), avail);
- b->in += avail;
- return (avail);
- }
- memcpy(buf, (b->buf + b->in), size);
- b->in += size;
- return (size);
-}
-
-/* Convenience write function for appending character buffers. */
-ssize_t
-stream_append_buf(void *cookie, const void *buf, size_t size)
-{
- struct buf *b;
- size_t avail;
-
- /* Use off to be write offset. */
- b = (struct buf *)cookie;
-
- avail = b->size - b->off;
- if (size > avail)
- buf_grow(b, b->size + size);
- memcpy((b->buf + b->off), buf, size);
- b->off += size;
- b->buf[b->off] = '\0';
- return (size);
-}
-
-/* Convenience close function for freeing character buffers. */
-int
-stream_close_buf(void *cookie)
-{
- void *data;
-
- data = cookie;
- /* Basically a NOP. */
- return (0);
-}
-
-/* Convenience read function for file descriptors. */
-ssize_t
-stream_read_fd(void *cookie, void *buf, size_t size)
-{
- ssize_t nbytes;
- int fd;
-
- fd = *(int *)cookie;
- nbytes = read(fd, buf, size);
- return (nbytes);
-}
-
-/* Convenience write function for file descriptors. */
-ssize_t
-stream_write_fd(void *cookie, const void *buf, size_t size)
-{
- ssize_t nbytes;
- int fd;
-
- fd = *(int *)cookie;
- nbytes = write(fd, buf, size);
- return (nbytes);
-}
-
-/* Convenience close function for file descriptors. */
-int
-stream_close_fd(void *cookie)
-{
- int fd, ret;
-
- fd = *(int *)cookie;
- ret = close(fd);
- return (ret);
-}
-
-/* Read some bytes from the stream. */
-ssize_t
-stream_read(struct stream *stream, void *buf, size_t size)
-{
- struct buf *rdbuf;
- ssize_t ret;
- size_t n;
-
- rdbuf = stream->rdbuf;
- if (buf_count(rdbuf) == 0) {
- ret = stream_fill(stream);
- if (ret <= 0)
- return (-1);
- }
- n = min(size, buf_count(rdbuf));
- memcpy(buf, rdbuf->buf + rdbuf->off, n);
- buf_less(rdbuf, n);
- return (n);
-}
-
-/* A blocking stream_read call. */
-ssize_t
-stream_read_blocking(struct stream *stream, void *buf, size_t size)
-{
- struct buf *rdbuf;
- ssize_t ret;
- size_t n;
-
- rdbuf = stream->rdbuf;
- while (buf_count(rdbuf) <= size) {
- ret = stream_fill(stream);
- if (ret <= 0)
- return (-1);
- }
- /* XXX: Should be at least size bytes in the buffer, right? */
- /* Just do this to make sure. */
- n = min(size, buf_count(rdbuf));
- memcpy(buf, rdbuf->buf + rdbuf->off, n);
- buf_less(rdbuf, n);
- return (n);
-}
-
-/*
- * Read a line from the stream and return a pointer to it.
- *
- * If "len" is non-NULL, the length of the string will be put into it.
- * The pointer is only valid until the next stream API call. The line
- * can be modified by the caller, provided he doesn't write before or
- * after it.
- *
- * This is somewhat similar to the BSD fgetln() function, except that
- * "len" can be NULL here. In that case the string is terminated by
- * overwriting the '\n' character with a NUL character. If it's the
- * last line in the stream and it has no ending newline, we can still
- * add '\0' after it, because we keep one spare byte in the buffers.
- *
- * However, be warned that one can't handle binary lines properly
- * without knowing the size of the string since those can contain
- * NUL characters.
- */
-char *
-stream_getln(struct stream *stream, size_t *len)
-{
- struct buf *buf;
- char *cp, *line;
- ssize_t n;
- size_t done, size;
-
- buf = stream->rdbuf;
- if (buf_count(buf) == 0) {
- n = stream_fill(stream);
- if (n <= 0)
- return (NULL);
- }
- cp = memchr(buf->buf + buf->off, '\n', buf_count(buf));
- for (done = buf_count(buf); cp == NULL; done += n) {
- n = stream_fill(stream);
- if (n < 0)
- return (NULL);
- if (n == 0)
- /* Last line of the stream. */
- cp = buf->buf + buf->off + buf->in - 1;
- else
- cp = memchr(buf->buf + buf->off + done, '\n',
- buf_count(buf) - done);
- }
- line = buf->buf + buf->off;
- assert(cp >= line);
- size = cp - line + 1;
- buf_less(buf, size);
- if (len != NULL) {
- *len = size;
- } else {
- /* Terminate the string when len == NULL. */
- if (line[size - 1] == '\n')
- line[size - 1] = '\0';
- else
- line[size] = '\0';
- }
- return (line);
-}
-
-/* Write some bytes to a stream. */
-ssize_t
-stream_write(struct stream *stream, const void *src, size_t nbytes)
-{
- struct buf *buf;
- int error;
-
- buf = stream->wrbuf;
- if (nbytes > buf_size(buf))
- buf_grow(buf, nbytes);
- if (nbytes > buf_avail(buf)) {
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- if (error)
- return (-1);
- }
- memcpy(buf->buf + buf->off + buf->in, src, nbytes);
- buf_more(buf, nbytes);
- return (nbytes);
-}
-
-/* Formatted output to a stream. */
-int
-stream_printf(struct stream *stream, const char *fmt, ...)
-{
- struct buf *buf;
- va_list ap;
- int error, ret;
-
- buf = stream->wrbuf;
-again:
- va_start(ap, fmt);
- ret = vsnprintf(buf->buf + buf->off + buf->in, buf_avail(buf), fmt, ap);
- va_end(ap);
- if (ret < 0)
- return (ret);
- if ((unsigned)ret >= buf_avail(buf)) {
- if ((unsigned)ret >= buf_size(buf))
- buf_grow(buf, ret + 1);
- if ((unsigned)ret >= buf_avail(buf)) {
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- if (error)
- return (-1);
- }
- goto again;
- }
- buf_more(buf, ret);
- return (ret);
-}
-
-/* Flush the entire write buffer of the stream. */
-int
-stream_flush(struct stream *stream)
-{
- int error;
-
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- return (error);
-}
-
-/* Internal flush API. */
-static int
-stream_flush_int(struct stream *stream, stream_flush_t how)
-{
- struct buf *buf;
- int error;
-
- buf = stream->wrbuf;
- error = (*stream->filter->flushfn)(stream, buf, how);
- assert(buf_count(buf) == 0);
- return (error);
-}
-
-/* The default flush method. */
-static int
-stream_flush_default(struct stream *stream, struct buf *buf,
- stream_flush_t __unused how)
-{
- ssize_t n;
-
- while (buf_count(buf) > 0) {
- do {
- n = (*stream->writefn)(stream->cookie,
- buf->buf + buf->off, buf_count(buf));
- } while (n == -1 && errno == EINTR);
- if (n <= 0)
- return (-1);
- buf_less(buf, n);
- }
- return (0);
-}
-
-/* Flush the write buffer and call fsync() on the file descriptor. */
-int
-stream_sync(struct stream *stream)
-{
- int error;
-
- if (stream->fd == -1) {
- errno = EINVAL;
- return (-1);
- }
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- if (error)
- return (-1);
- error = fsync(stream->fd);
- return (error);
-}
-
-/* Like truncate() but on a stream. */
-int
-stream_truncate(struct stream *stream, off_t size)
-{
- int error;
-
- if (stream->fd == -1) {
- errno = EINVAL;
- return (-1);
- }
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- if (error)
- return (-1);
- error = ftruncate(stream->fd, size);
- return (error);
-}
-
-/* Like stream_truncate() except the off_t parameter is an offset. */
-int
-stream_truncate_rel(struct stream *stream, off_t off)
-{
- struct stat sb;
- int error;
-
- if (stream->buf) {
- stream_truncate_buf(stream->cookie, off);
- return (0);
- }
- if (stream->fd == -1) {
- errno = EINVAL;
- return (-1);
- }
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- if (error)
- return (-1);
- error = fstat(stream->fd, &sb);
- if (error)
- return (-1);
- error = stream_truncate(stream, sb.st_size + off);
- return (error);
-}
-
-/* Rewind the stream. */
-int
-stream_rewind(struct stream *stream)
-{
- int error;
-
- if (stream->fd == -1) {
- errno = EINVAL;
- return (-1);
- }
- if (stream->rdbuf != NULL)
- buf_less(stream->rdbuf, buf_count(stream->rdbuf));
- if (stream->wrbuf != NULL) {
- error = stream_flush_int(stream, STREAM_FLUSH_NORMAL);
- if (error)
- return (error);
- }
- error = lseek(stream->fd, 0, SEEK_SET);
- return (error);
-}
-
-/* Return EOF status. */
-int
-stream_eof(struct stream *stream)
-{
-
- return (stream->eof);
-}
-
-/* Close a stream and free any resources held by it. */
-int
-stream_close(struct stream *stream)
-{
- int error;
-
- if (stream == NULL)
- return (0);
-
- error = 0;
- if (stream->wrbuf != NULL)
- error = stream_flush_int(stream, STREAM_FLUSH_CLOSING);
- stream_filter_fini(stream);
- if (stream->closefn != NULL)
- /*
- * We might overwrite a previous error from stream_flush(),
- * but we have no choice, because wether it had worked or
- * not, we need to close the file descriptor.
- */
- error = (*stream->closefn)(stream->cookie);
- if (stream->rdbuf != NULL)
- buf_free(stream->rdbuf);
- if (stream->wrbuf != NULL)
- buf_free(stream->wrbuf);
- free(stream);
- return (error);
-}
-
-/* The default fill method. */
-static ssize_t
-stream_fill_default(struct stream *stream, struct buf *buf)
-{
- ssize_t n;
-
- if (stream->eof)
- return (0);
- assert(buf_avail(buf) > 0);
- n = (*stream->readfn)(stream->cookie, buf->buf + buf->off + buf->in,
- buf_avail(buf));
- if (n < 0)
- return (-1);
- if (n == 0) {
- stream->eof = 1;
- return (0);
- }
- buf_more(buf, n);
- return (n);
-}
-
-/*
- * Refill the read buffer. This function is not permitted to return
- * without having made more bytes available, unless there was an error.
- * Moreover, stream_fill() returns the number of bytes added.
- */
-static ssize_t
-stream_fill(struct stream *stream)
-{
- struct stream_filter *filter;
- struct buf *buf;
-#ifndef NDEBUG
- size_t oldcount;
-#endif
- ssize_t n;
-
- filter = stream->filter;
- buf = stream->rdbuf;
- buf_prewrite(buf);
-#ifndef NDEBUG
- oldcount = buf_count(buf);
-#endif
- n = (*filter->fillfn)(stream, buf);
- assert((n > 0 && n == (signed)(buf_count(buf) - oldcount)) ||
- (n <= 0 && buf_count(buf) == oldcount));
- return (n);
-}
-
-/*
- * Lookup a stream filter.
- *
- * We are not supposed to get passed an invalid filter id, since
- * filter ids are an enum type and we don't have invalid filter
- * ids in the enum :-). Thus, we are not checking for out of
- * bounds access here. If it happens, it's the caller's fault
- * anyway.
- */
-static struct stream_filter *
-stream_filter_lookup(stream_filter_t id)
-{
- struct stream_filter *filter;
-
- filter = stream_filters;
- while (filter->id != id)
- filter++;
- return (filter);
-}
-
-static int
-stream_filter_init(struct stream *stream, void *data)
-{
- struct stream_filter *filter;
- int error;
-
- filter = stream->filter;
- if (filter->initfn == NULL)
- return (0);
- error = (*filter->initfn)(stream, data);
- return (error);
-}
-
-static void
-stream_filter_fini(struct stream *stream)
-{
- struct stream_filter *filter;
-
- filter = stream->filter;
- if (filter->finifn != NULL)
- (*filter->finifn)(stream);
-}
-
-/*
- * Start a filter on a stream.
- */
-int
-stream_filter_start(struct stream *stream, stream_filter_t id, void *data)
-{
- struct stream_filter *filter;
- int error;
-
- filter = stream->filter;
- if (id == filter->id)
- return (0);
- stream_filter_fini(stream);
- stream->filter = stream_filter_lookup(id);
- stream->fdata = NULL;
- error = stream_filter_init(stream, data);
- return (error);
-}
-
-
-/* Stop a filter, this is equivalent to setting the null filter. */
-void
-stream_filter_stop(struct stream *stream)
-{
-
- stream_filter_start(stream, STREAM_FILTER_NULL, NULL);
-}
-
-/* The zlib stream filter implementation. */
-
-/* Take no chances with zlib... */
-static void *
-zfilter_alloc(void __unused *opaque, unsigned int items, unsigned int size)
-{
-
- return (xmalloc(items * size));
-}
-
-static void
-zfilter_free(void __unused *opaque, void *ptr)
-{
-
- free(ptr);
-}
-
-static int
-zfilter_init(struct stream *stream, void __unused *data)
-{
- struct zfilter *zf;
- struct buf *buf;
- z_stream *state;
- int rv;
-
- zf = xmalloc(sizeof(struct zfilter));
- memset(zf, 0, sizeof(struct zfilter));
- if (stream->rdbuf != NULL) {
- state = xmalloc(sizeof(z_stream));
- state->zalloc = zfilter_alloc;
- state->zfree = zfilter_free;
- state->opaque = Z_NULL;
- rv = inflateInit(state);
- if (rv != Z_OK)
- errx(1, "inflateInit: %s", state->msg);
- buf = buf_new(buf_size(stream->rdbuf));
- zf->rdbuf = stream->rdbuf;
- stream->rdbuf = buf;
- zf->rdstate = state;
- }
- if (stream->wrbuf != NULL) {
- state = xmalloc(sizeof(z_stream));
- state->zalloc = zfilter_alloc;
- state->zfree = zfilter_free;
- state->opaque = Z_NULL;
- rv = deflateInit(state, Z_DEFAULT_COMPRESSION);
- if (rv != Z_OK)
- errx(1, "deflateInit: %s", state->msg);
- buf = buf_new(buf_size(stream->wrbuf));
- zf->wrbuf = stream->wrbuf;
- stream->wrbuf = buf;
- zf->wrstate = state;
- }
- stream->fdata = zf;
- return (0);
-}
-
-static void
-zfilter_fini(struct stream *stream)
-{
- struct zfilter *zf;
- struct buf *zbuf;
- z_stream *state;
- ssize_t n;
-
- zf = stream->fdata;
- if (zf->rdbuf != NULL) {
- state = zf->rdstate;
- zbuf = zf->rdbuf;
- /*
- * Even if it has produced all the bytes, zlib sometimes
- * hasn't seen the EOF marker, so we need to call inflate()
- * again to make sure we have eaten all the zlib'ed bytes.
- */
- if ((zf->flags & ZFILTER_EOF) == 0) {
- n = zfilter_fill(stream, stream->rdbuf);
- assert(n == 0 && zf->flags & ZFILTER_EOF);
- }
- inflateEnd(state);
- free(state);
- buf_free(stream->rdbuf);
- stream->rdbuf = zbuf;
- }
- if (zf->wrbuf != NULL) {
- state = zf->wrstate;
- zbuf = zf->wrbuf;
- /*
- * Compress the remaining bytes in the buffer, if any,
- * and emit an EOF marker as appropriate. We ignore
- * the error because we can't do anything about it at
- * this point, and it can happen if we're getting
- * disconnected.
- */
- (void)zfilter_flush(stream, stream->wrbuf,
- STREAM_FLUSH_CLOSING);
- deflateEnd(state);
- free(state);
- buf_free(stream->wrbuf);
- stream->wrbuf = zbuf;
- }
- free(zf);
-}
-
-static int
-zfilter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
-{
- struct zfilter *zf;
- struct buf *zbuf;
- z_stream *state;
- size_t lastin, lastout, ate, prod;
- int done, error, flags, rv;
-
- zf = stream->fdata;
- state = zf->wrstate;
- zbuf = zf->wrbuf;
-
- if (how == STREAM_FLUSH_NORMAL)
- flags = Z_SYNC_FLUSH;
- else
- flags = Z_FINISH;
-
- done = 0;
- rv = Z_OK;
-
-again:
- /*
- * According to zlib.h, we should have at least 6 bytes
- * available when using deflate() with Z_SYNC_FLUSH.
- */
- if ((buf_avail(zbuf) < 6 && flags == Z_SYNC_FLUSH) ||
- rv == Z_BUF_ERROR || buf_avail(buf) == 0) {
- error = stream_flush_default(stream, zbuf, how);
- if (error)
- return (error);
- }
-
- state->next_in = (Bytef *)(buf->buf + buf->off);
- state->avail_in = buf_count(buf);
- state->next_out = (Bytef *)(zbuf->buf + zbuf->off + zbuf->in);
- state->avail_out = buf_avail(zbuf);
- lastin = state->avail_in;
- lastout = state->avail_out;
- rv = deflate(state, flags);
- if (rv != Z_BUF_ERROR && rv != Z_OK && rv != Z_STREAM_END)
- errx(1, "deflate: %s", state->msg);
- ate = lastin - state->avail_in;
- prod = lastout - state->avail_out;
- buf_less(buf, ate);
- buf_more(zbuf, prod);
- if ((flags == Z_SYNC_FLUSH && buf_count(buf) > 0) ||
- (flags == Z_FINISH && rv != Z_STREAM_END) ||
- (rv == Z_BUF_ERROR))
- goto again;
-
- assert(rv == Z_OK || (rv == Z_STREAM_END && flags == Z_FINISH));
- error = stream_flush_default(stream, zbuf, how);
- return (error);
-}
-
-static ssize_t
-zfilter_fill(struct stream *stream, struct buf *buf)
-{
- struct zfilter *zf;
- struct buf *zbuf;
- z_stream *state;
- size_t lastin, lastout, new;
- ssize_t n;
- int rv;
-
- zf = stream->fdata;
- state = zf->rdstate;
- zbuf = zf->rdbuf;
-
- assert(buf_avail(buf) > 0);
- if (buf_count(zbuf) == 0) {
- n = stream_fill_default(stream, zbuf);
- if (n <= 0)
- return (n);
- }
-again:
- assert(buf_count(zbuf) > 0);
- state->next_in = (Bytef *)(zbuf->buf + zbuf->off);
- state->avail_in = buf_count(zbuf);
- state->next_out = (Bytef *)(buf->buf + buf->off + buf->in);
- state->avail_out = buf_avail(buf);
- lastin = state->avail_in;
- lastout = state->avail_out;
- rv = inflate(state, Z_SYNC_FLUSH);
- buf_less(zbuf, lastin - state->avail_in);
- new = lastout - state->avail_out;
- if (new == 0 && rv != Z_STREAM_END) {
- n = stream_fill_default(stream, zbuf);
- if (n == -1)
- return (-1);
- if (n == 0)
- return (0);
- goto again;
- }
- if (rv != Z_STREAM_END && rv != Z_OK)
- errx(1, "inflate: %s", state->msg);
- if (rv == Z_STREAM_END)
- zf->flags |= ZFILTER_EOF;
- buf_more(buf, new);
- return (new);
-}
-
-/* The MD5 stream filter implementation. */
-static int
-md5filter_init(struct stream *stream, void *data)
-{
- struct md5filter *mf;
-
- mf = xmalloc(sizeof(struct md5filter));
- MD5_Init(&mf->ctx);
- mf->md5 = data;
- mf->lastc = ';';
- mf->state = PRINT;
- stream->fdata = mf;
- return (0);
-}
-
-static void
-md5filter_fini(struct stream *stream)
-{
- struct md5filter *mf;
-
- mf = stream->fdata;
- MD5_End(mf->md5, &mf->ctx);
- free(stream->fdata);
-}
-
-static ssize_t
-md5filter_fill(struct stream *stream, struct buf *buf)
-{
- ssize_t n;
-
- assert(buf_avail(buf) > 0);
- n = stream_fill_default(stream, buf);
- return (n);
-}
-
-static int
-md5filter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
-{
- struct md5filter *mf;
- int error;
-
- mf = stream->fdata;
- MD5_Update(&mf->ctx, buf->buf + buf->off, buf->in);
- error = stream_flush_default(stream, buf, how);
- return (error);
-}
-
-/* MD5 flush for RCS, where whitespaces are omitted. */
-static int
-md5rcsfilter_flush(struct stream *stream, struct buf *buf, stream_flush_t how)
-{
- struct md5filter *mf;
- char *ptr, *end;
- char *start;
- char space[2];
- int error;
-
- mf = stream->fdata;
- space[0] = ' ';
- space[1] = '\0';
- ptr = buf->buf + buf->off;
- end = buf->buf + buf->off + buf->in;
-
-#define IS_WS(var) ((var) == ' ' || (var) == '\n' || (var) == '\t' || \
- (var) == '\010' || (var) == '\013' || (var) == '\f' || \
- (var) == '\r')
-
-#define IS_SPECIAL(var) ((var) == '$' || (var) == ',' || (var) == ':' || \
- (var) == ';' || (var) == '@')
-
-#define IS_PRINT(var) (!IS_WS(var) && (var) != '@')
-
- /* XXX: We can do better than this state machine. */
- while (ptr < end) {
- switch (mf->state) {
- /* Outside RCS statements. */
- case PRINT:
- start = ptr;
- while (ptr < end && IS_PRINT(*ptr)) {
- mf->lastc = *ptr;
- ptr++;
- }
- MD5_Update(&mf->ctx, start, (ptr - start));
- if (ptr < end) {
- if (*ptr == '@') {
- MD5_Update(&mf->ctx, ptr, 1);
- ptr++;
- mf->state = STRING;
- } else {
- mf->state = WS;
- }
- }
- break;
- case WS:
- while (ptr < end && IS_WS(*ptr)) {
- ptr++;
- }
- if (ptr < end) {
- if (*ptr == '@') {
- if (mf->lastc == '@') {
- MD5_Update(&mf->ctx,
- space, 1);
- }
- MD5_Update(&mf->ctx, ptr, 1);
- ptr++;
- mf->state = STRING;
- } else {
- if (!IS_SPECIAL(*ptr) &&
- !IS_SPECIAL(mf->lastc)) {
- MD5_Update(&mf->ctx,
- space, 1);
- }
- mf->state = PRINT;
- }
- }
- break;
- case STRING:
- start = ptr;
- while (ptr < end && *ptr != '@') {
- ptr++;
- }
- MD5_Update(&mf->ctx, start, (ptr - start));
- if (ptr < end) {
- MD5_Update(&mf->ctx, ptr, 1);
- ptr++;
- mf->state = SEEN;
- }
- break;
- case SEEN:
- if (*ptr == '@') {
- MD5_Update(&mf->ctx, ptr, 1);
- ptr++;
- mf->state = STRING;
- } else if(IS_WS(*ptr)) {
- mf->lastc = '@';
- mf->state = WS;
- } else {
- mf->state = PRINT;
- }
- break;
- default:
- err(1, "Invalid state");
- break;
- }
- }
-
- error = stream_flush_default(stream, buf, how);
- return (error);
-}
-
diff --git a/contrib/csup/stream.h b/contrib/csup/stream.h
deleted file mode 100644
index 2128635..0000000
--- a/contrib/csup/stream.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _STREAM_H_
-#define _STREAM_H_
-
-#include "misc.h"
-
-/* Stream filters. */
-typedef enum {
- STREAM_FILTER_NULL,
- STREAM_FILTER_ZLIB,
- STREAM_FILTER_MD5,
- STREAM_FILTER_MD5RCS
-} stream_filter_t;
-
-struct stream;
-struct buf;
-
-typedef ssize_t stream_readfn_t(void *, void *, size_t);
-typedef ssize_t stream_writefn_t(void *, const void *, size_t);
-typedef int stream_closefn_t(void *);
-
-/* Convenience functions for handling file descriptors. */
-stream_readfn_t stream_read_fd;
-stream_writefn_t stream_write_fd;
-stream_closefn_t stream_close_fd;
-
-/* Convenience functions for handling character buffers. */
-stream_readfn_t stream_read_buf;
-stream_writefn_t stream_append_buf;
-stream_closefn_t stream_close_buf;
-
-struct stream *stream_open(void *, stream_readfn_t *, stream_writefn_t *,
- stream_closefn_t *);
-struct stream *stream_open_fd(int, stream_readfn_t *, stream_writefn_t *,
- stream_closefn_t *);
-struct stream *stream_open_buf(struct buf *);
-struct stream *stream_open_file(const char *, int, ...);
-int stream_fileno(struct stream *);
-ssize_t stream_read(struct stream *, void *, size_t);
-ssize_t stream_read_blocking(struct stream *, void *, size_t);
-ssize_t stream_write(struct stream *, const void *, size_t);
-char *stream_getln(struct stream *, size_t *);
-int stream_printf(struct stream *, const char *, ...)
- __printflike(2, 3);
-int stream_flush(struct stream *);
-int stream_sync(struct stream *);
-int stream_truncate(struct stream *, off_t);
-void stream_truncate_buf(struct buf *, off_t);
-int stream_truncate_rel(struct stream *, off_t);
-int stream_rewind(struct stream *);
-int stream_eof(struct stream *);
-int stream_close(struct stream *);
-int stream_filter_start(struct stream *, stream_filter_t, void *);
-void stream_filter_stop(struct stream *);
-
-struct buf *buf_new(size_t);
-void buf_free(struct buf *);
-#endif /* !_STREAM_H_ */
diff --git a/contrib/csup/threads.c b/contrib/csup/threads.c
deleted file mode 100644
index 46a9860..0000000
--- a/contrib/csup/threads.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*-
- * Copyright (c) 2004-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <assert.h>
-#include <err.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#include "misc.h"
-#include "queue.h"
-#include "threads.h"
-
-/*
- * This API is a wrapper around the pthread(3) API, which mainly
- * allows me to wait for multiple threads to exit. We use a
- * condition variable to signal a thread's death. All threads
- * created with this API have a common entry/exit point, so we
- * don't need to add any code in the threads themselves.
- */
-
-/* Structure describing a thread. */
-struct thread {
- pthread_t thread;
- void *(*start)(void *);
- void *data;
- struct threads *threads;
- LIST_ENTRY(thread) runlist;
- STAILQ_ENTRY(thread) deadlist;
-};
-
-/* A set of threads. */
-struct threads {
- pthread_mutex_t threads_mtx;
- pthread_cond_t thread_exited;
- LIST_HEAD(, thread) threads_running;
- STAILQ_HEAD(, thread) threads_dead;
-};
-
-static void *thread_start(void *); /* Common entry point for threads. */
-
-static void threads_lock(struct threads *);
-static void threads_unlock(struct threads *);
-
-static void
-threads_lock(struct threads *tds)
-{
- int error;
-
- error = pthread_mutex_lock(&tds->threads_mtx);
- assert(!error);
-}
-
-static void
-threads_unlock(struct threads *tds)
-{
- int error;
-
- error = pthread_mutex_unlock(&tds->threads_mtx);
- assert(!error);
-}
-
-/* Create a new set of threads. */
-struct threads *
-threads_new(void)
-{
- struct threads *tds;
-
- tds = xmalloc(sizeof(struct threads));
- pthread_mutex_init(&tds->threads_mtx, NULL);
- pthread_cond_init(&tds->thread_exited, NULL);
- LIST_INIT(&tds->threads_running);
- STAILQ_INIT(&tds->threads_dead);
- return (tds);
-}
-
-/* Create a new thread in this set. */
-void
-threads_create(struct threads *tds, void *(*start)(void *), void *data)
-{
- pthread_attr_t attr;
- struct thread *td;
- int error;
-
- td = xmalloc(sizeof(struct thread));
- td->threads = tds;
- td->start = start;
- td->data = data;
- /* We don't use pthread_join() to wait for the threads to finish. */
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- threads_lock(tds);
- error = pthread_create(&td->thread, &attr, thread_start, td);
- if (error)
- err(1, "pthread_create");
- LIST_INSERT_HEAD(&tds->threads_running, td, runlist);
- threads_unlock(tds);
-}
-
-/* Wait for a thread in the set to exit, and return its data pointer. */
-void *
-threads_wait(struct threads *tds)
-{
- struct thread *td;
- void *data;
-
- threads_lock(tds);
- while (STAILQ_EMPTY(&tds->threads_dead)) {
- assert(!LIST_EMPTY(&tds->threads_running));
- pthread_cond_wait(&tds->thread_exited, &tds->threads_mtx);
- }
- td = STAILQ_FIRST(&tds->threads_dead);
- STAILQ_REMOVE_HEAD(&tds->threads_dead, deadlist);
- threads_unlock(tds);
- data = td->data;
- free(td);
- return (data);
-}
-
-/* Free a threads set. */
-void
-threads_free(struct threads *tds)
-{
-
- assert(LIST_EMPTY(&tds->threads_running));
- assert(STAILQ_EMPTY(&tds->threads_dead));
- pthread_cond_destroy(&tds->thread_exited);
- pthread_mutex_destroy(&tds->threads_mtx);
- free(tds);
-}
-
-/*
- * Common entry point for threads. This just calls the real start
- * routine, and then signals the thread's death, after having
- * removed the thread from the list.
- */
-static void *
-thread_start(void *data)
-{
- struct threads *tds;
- struct thread *td;
-
- td = data;
- tds = td->threads;
- td->start(td->data);
- threads_lock(tds);
- LIST_REMOVE(td, runlist);
- STAILQ_INSERT_TAIL(&tds->threads_dead, td, deadlist);
- pthread_cond_signal(&tds->thread_exited);
- threads_unlock(tds);
- return (NULL);
-}
diff --git a/contrib/csup/threads.h b/contrib/csup/threads.h
deleted file mode 100644
index 66153ce..0000000
--- a/contrib/csup/threads.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-
- * Copyright (c) 2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _THREADS_H_
-#define _THREADS_H_
-
-struct threads;
-
-struct threads *threads_new(void);
-void threads_create(struct threads *, void *(*)(void *), void *);
-void *threads_wait(struct threads *);
-void threads_free(struct threads *);
-
-#endif /* !_THREADS_H_ */
diff --git a/contrib/csup/token.h b/contrib/csup/token.h
deleted file mode 100644
index 0dc3ec0..0000000
--- a/contrib/csup/token.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _TOKEN_H_
-#define _TOKEN_H_
-
-void yyerror(const char *);
-int yylex(void);
-int yyparse(void);
-
-/* Parsing tokens. */
-#define PT_BASE 0
-#define PT_DATE 1
-#define PT_HOST 2
-#define PT_PREFIX 3
-#define PT_RELEASE 4
-#define PT_TAG 5
-#define PT_UMASK 6
-#define PT_COMPRESS 7
-#define PT_DELETE 8
-#define PT_USE_REL_SUFFIX 9
-#define PT_LIST 10
-#define PT_NORSYNC 11
-
-#endif /* !_TOKEN_H_ */
diff --git a/contrib/csup/token.l b/contrib/csup/token.l
deleted file mode 100644
index 267e61f..0000000
--- a/contrib/csup/token.l
+++ /dev/null
@@ -1,80 +0,0 @@
-%{
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <err.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "parse.h"
-#include "misc.h"
-#include "token.h"
-
-#define YY_NO_UNPUT
-
-int lineno = 1;
-
-%}
-
-%option noyywrap
-
-%%
-
-[ \t]+ ;
-#.* ;
-\*default { return DEFAULT; }
-base { yylval.i = PT_BASE; return NAME; }
-date { yylval.i = PT_DATE; return NAME; }
-host { yylval.i = PT_HOST; return NAME; }
-prefix { yylval.i = PT_PREFIX; return NAME; }
-release { yylval.i = PT_RELEASE; return NAME; }
-tag { yylval.i = PT_TAG; return NAME; }
-umask { yylval.i = PT_UMASK; return NAME; }
-list { yylval.i = PT_LIST; return NAME; }
-norsync { yylval.i = PT_NORSYNC; return NAME; }
-= { return EQUAL; }
-compress { yylval.i = PT_COMPRESS; return BOOLEAN; }
-delete { yylval.i = PT_DELETE; return BOOLEAN; }
-use-rel-suffix { yylval.i = PT_USE_REL_SUFFIX; return BOOLEAN; }
-[a-zA-Z0-9./_-]+ {
- yylval.str = strdup(yytext);
- if (yylval.str == NULL)
- err(1, "strdup");
- return STRING;
- }
-\n lineno++;
-
-%%
-
-void
-yyerror(const char *s)
-{
-
- lprintf(-1, "Parse error line %d: %s: %s\n", lineno, s, yytext);
- exit(1);
-}
diff --git a/contrib/csup/updater.c b/contrib/csup/updater.c
deleted file mode 100644
index d9f4210..0000000
--- a/contrib/csup/updater.c
+++ /dev/null
@@ -1,2044 +0,0 @@
-/*-
- * Copyright (c) 2003-2006, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "diff.h"
-#include "fattr.h"
-#include "fixups.h"
-#include "keyword.h"
-#include "updater.h"
-#include "misc.h"
-#include "mux.h"
-#include "proto.h"
-#include "rcsfile.h"
-#include "status.h"
-#include "stream.h"
-
-/* Internal error codes. */
-#define UPDATER_ERR_PROTO (-1) /* Protocol error. */
-#define UPDATER_ERR_MSG (-2) /* Error is in updater->errmsg. */
-#define UPDATER_ERR_READ (-3) /* Error reading from server. */
-#define UPDATER_ERR_DELETELIM (-4) /* File deletion limit exceeded. */
-
-#define BUFSIZE 4096
-
-/* Everything needed to update a file. */
-struct file_update {
- struct statusrec srbuf;
- char *destpath;
- char *temppath;
- char *origpath;
- char *coname; /* Points somewhere in destpath. */
- char *wantmd5;
- struct coll *coll;
- struct status *st;
- /* Those are only used for diff updating. */
- char *author;
- struct stream *orig;
- struct stream *to;
- int attic;
- int expand;
-};
-
-struct updater {
- struct config *config;
- struct stream *rd;
- char *errmsg;
- int deletecount;
-};
-
-static struct file_update *fup_new(struct coll *, struct status *);
-static int fup_prepare(struct file_update *, char *, int);
-static void fup_cleanup(struct file_update *);
-static void fup_free(struct file_update *);
-
-static void updater_prunedirs(char *, char *);
-static int updater_batch(struct updater *, int);
-static int updater_docoll(struct updater *, struct file_update *, int);
-static int updater_delete(struct updater *, struct file_update *);
-static void updater_deletefile(const char *);
-static int updater_checkout(struct updater *, struct file_update *, int);
-static int updater_addfile(struct updater *, struct file_update *,
- char *, int);
-int updater_addelta(struct rcsfile *, struct stream *, char *);
-static int updater_setattrs(struct updater *, struct file_update *,
- char *, char *, char *, char *, char *, struct fattr *);
-static int updater_setdirattrs(struct updater *, struct coll *,
- struct file_update *, char *, char *);
-static int updater_updatefile(struct updater *, struct file_update *fup,
- const char *, int);
-static int updater_updatenode(struct updater *, struct coll *,
- struct file_update *, char *, char *);
-static int updater_diff(struct updater *, struct file_update *);
-static int updater_diff_batch(struct updater *, struct file_update *);
-static int updater_diff_apply(struct updater *, struct file_update *,
- char *);
-static int updater_rcsedit(struct updater *, struct file_update *, char *,
- char *);
-int updater_append_file(struct updater *, struct file_update *,
- off_t);
-static int updater_rsync(struct updater *, struct file_update *, size_t);
-static int updater_read_checkout(struct stream *, struct stream *);
-
-static struct file_update *
-fup_new(struct coll *coll, struct status *st)
-{
- struct file_update *fup;
-
- fup = xmalloc(sizeof(struct file_update));
- memset(fup, 0, sizeof(*fup));
- fup->coll = coll;
- fup->st = st;
- return (fup);
-}
-
-static int
-fup_prepare(struct file_update *fup, char *name, int attic)
-{
- struct coll *coll;
-
- coll = fup->coll;
- fup->attic = 0;
- fup->origpath = NULL;
-
- if (coll->co_options & CO_CHECKOUTMODE)
- fup->destpath = checkoutpath(coll->co_prefix, name);
- else {
- fup->destpath = cvspath(coll->co_prefix, name, attic);
- fup->origpath = atticpath(coll->co_prefix, name);
- /* If they're equal, we don't need special care. */
- if (fup->origpath != NULL &&
- strcmp(fup->origpath, fup->destpath) == 0) {
- free(fup->origpath);
- fup->origpath = NULL;
- }
- fup->attic = attic;
- }
- if (fup->destpath == NULL)
- return (-1);
- fup->coname = fup->destpath + coll->co_prefixlen + 1;
- return (0);
-}
-
-/* Called after each file update to reinit the structure. */
-static void
-fup_cleanup(struct file_update *fup)
-{
- struct statusrec *sr;
-
- sr = &fup->srbuf;
-
- if (fup->destpath != NULL) {
- free(fup->destpath);
- fup->destpath = NULL;
- }
- if (fup->temppath != NULL) {
- free(fup->temppath);
- fup->temppath = NULL;
- }
- if (fup->origpath != NULL) {
- free(fup->origpath);
- fup->origpath = NULL;
- }
- fup->coname = NULL;
- if (fup->author != NULL) {
- free(fup->author);
- fup->author = NULL;
- }
- fup->expand = 0;
- if (fup->wantmd5 != NULL) {
- free(fup->wantmd5);
- fup->wantmd5 = NULL;
- }
- if (fup->orig != NULL) {
- stream_close(fup->orig);
- fup->orig = NULL;
- }
- if (fup->to != NULL) {
- stream_close(fup->to);
- fup->to = NULL;
- }
- if (sr->sr_file != NULL)
- free(sr->sr_file);
- if (sr->sr_tag != NULL)
- free(sr->sr_tag);
- if (sr->sr_date != NULL)
- free(sr->sr_date);
- if (sr->sr_revnum != NULL)
- free(sr->sr_revnum);
- if (sr->sr_revdate != NULL)
- free(sr->sr_revdate);
- fattr_free(sr->sr_clientattr);
- fattr_free(sr->sr_serverattr);
- memset(sr, 0, sizeof(*sr));
-}
-
-static void
-fup_free(struct file_update *fup)
-{
-
- fup_cleanup(fup);
- free(fup);
-}
-
-void *
-updater(void *arg)
-{
- struct thread_args *args;
- struct updater upbuf, *up;
- int error;
-
- args = arg;
-
- up = &upbuf;
- up->config = args->config;
- up->rd = args->rd;
- up->errmsg = NULL;
- up->deletecount = 0;
-
- error = updater_batch(up, 0);
-
- /*
- * Make sure to close the fixups even in case of an error,
- * so that the lister thread doesn't block indefinitely.
- */
- fixups_close(up->config->fixups);
- if (!error)
- error = updater_batch(up, 1);
- switch (error) {
- case UPDATER_ERR_PROTO:
- xasprintf(&args->errmsg, "Updater failed: Protocol error");
- args->status = STATUS_FAILURE;
- break;
- case UPDATER_ERR_MSG:
- xasprintf(&args->errmsg, "Updater failed: %s", up->errmsg);
- free(up->errmsg);
- args->status = STATUS_FAILURE;
- break;
- case UPDATER_ERR_READ:
- if (stream_eof(up->rd)) {
- xasprintf(&args->errmsg, "Updater failed: "
- "Premature EOF from server");
- } else {
- xasprintf(&args->errmsg, "Updater failed: "
- "Network read failure: %s", strerror(errno));
- }
- args->status = STATUS_TRANSIENTFAILURE;
- break;
- case UPDATER_ERR_DELETELIM:
- xasprintf(&args->errmsg, "Updater failed: "
- "File deletion limit exceeded");
- args->status = STATUS_FAILURE;
- break;
- default:
- assert(error == 0);
- args->status = STATUS_SUCCESS;
- };
- return (NULL);
-}
-
-static int
-updater_batch(struct updater *up, int isfixups)
-{
- struct stream *rd;
- struct coll *coll;
- struct status *st;
- struct file_update *fup;
- char *line, *cmd, *errmsg, *collname, *release;
- int error;
-
- rd = up->rd;
- STAILQ_FOREACH(coll, &up->config->colls, co_next) {
- if (coll->co_options & CO_SKIP)
- continue;
- umask(coll->co_umask);
- line = stream_getln(rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_READ);
- cmd = proto_get_ascii(&line);
- collname = proto_get_ascii(&line);
- release = proto_get_ascii(&line);
- if (release == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- if (strcmp(cmd, "COLL") != 0 ||
- strcmp(collname, coll->co_name) != 0 ||
- strcmp(release, coll->co_release) != 0)
- return (UPDATER_ERR_PROTO);
-
- if (!isfixups)
- lprintf(1, "Updating collection %s/%s\n", coll->co_name,
- coll->co_release);
-
- if (coll->co_options & CO_COMPRESS)
- stream_filter_start(rd, STREAM_FILTER_ZLIB, NULL);
-
- st = status_open(coll, coll->co_scantime, &errmsg);
- if (st == NULL) {
- up->errmsg = errmsg;
- return (UPDATER_ERR_MSG);
- }
- fup = fup_new(coll, st);
- error = updater_docoll(up, fup, isfixups);
- status_close(st, &errmsg);
- fup_free(fup);
- if (errmsg != NULL) {
- /* Discard previous error. */
- if (up->errmsg != NULL)
- free(up->errmsg);
- up->errmsg = errmsg;
- return (UPDATER_ERR_MSG);
- }
- if (error)
- return (error);
-
- if (coll->co_options & CO_COMPRESS)
- stream_filter_stop(rd);
- }
- line = stream_getln(rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_READ);
- if (strcmp(line, ".") != 0)
- return (UPDATER_ERR_PROTO);
- return (0);
-}
-
-static int
-updater_docoll(struct updater *up, struct file_update *fup, int isfixups)
-{
- struct stream *rd;
- struct coll *coll;
- struct statusrec srbuf, *sr;
- struct fattr *rcsattr, *tmp;
- char *attr, *cmd, *blocksize, *line, *msg;
- char *name, *tag, *date, *revdate;
- char *expand, *wantmd5, *revnum;
- char *optstr, *rcsopt, *pos;
- time_t t;
- off_t position;
- int attic, error, needfixupmsg;
-
- error = 0;
- rd = up->rd;
- coll = fup->coll;
- needfixupmsg = isfixups;
- while ((line = stream_getln(rd, NULL)) != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- memset(&srbuf, 0, sizeof(srbuf));
- if (needfixupmsg) {
- lprintf(1, "Applying fixups for collection %s/%s\n",
- coll->co_name, coll->co_release);
- needfixupmsg = 0;
- }
- cmd = proto_get_ascii(&line);
- if (cmd == NULL || strlen(cmd) != 1)
- return (UPDATER_ERR_PROTO);
- switch (cmd[0]) {
- case 'T':
- /* Update recorded information for checked-out file. */
- name = proto_get_ascii(&line);
- tag = proto_get_ascii(&line);
- date = proto_get_ascii(&line);
- revnum = proto_get_ascii(&line);
- revdate = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
-
- rcsattr = fattr_decode(attr);
- if (rcsattr == NULL)
- return (UPDATER_ERR_PROTO);
-
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- error = updater_setattrs(up, fup, name, tag, date,
- revnum, revdate, rcsattr);
- fattr_free(rcsattr);
- if (error)
- return (error);
- break;
- case 'c':
- /* Checkout dead file. */
- name = proto_get_ascii(&line);
- tag = proto_get_ascii(&line);
- date = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
-
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- /* Theoritically, the file does not exist on the client.
- Just to make sure, we'll delete it here, if it
- exists. */
- if (access(fup->destpath, F_OK) == 0) {
- error = updater_delete(up, fup);
- if (error)
- return (error);
- }
-
- sr = &srbuf;
- sr->sr_type = SR_CHECKOUTDEAD;
- sr->sr_file = name;
- sr->sr_tag = tag;
- sr->sr_date = date;
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
-
- error = status_put(fup->st, sr);
- fattr_free(sr->sr_serverattr);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'U':
- /* Update live checked-out file. */
- name = proto_get_ascii(&line);
- tag = proto_get_ascii(&line);
- date = proto_get_ascii(&line);
- proto_get_ascii(&line); /* XXX - oldRevNum */
- proto_get_ascii(&line); /* XXX - fromAttic */
- proto_get_ascii(&line); /* XXX - logLines */
- expand = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- wantmd5 = proto_get_ascii(&line);
- if (wantmd5 == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
-
- sr = &fup->srbuf;
- sr->sr_type = SR_CHECKOUTLIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_date = xstrdup(date);
- sr->sr_tag = xstrdup(tag);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
-
- fup->expand = keyword_decode_expand(expand);
- if (fup->expand == -1)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
-
- fup->wantmd5 = xstrdup(wantmd5);
- fup->temppath = tempname(fup->destpath);
- error = updater_diff(up, fup);
- if (error)
- return (error);
- break;
- case 'u':
- /* Update dead checked-out file. */
- name = proto_get_ascii(&line);
- tag = proto_get_ascii(&line);
- date = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
-
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- error = updater_delete(up, fup);
- if (error)
- return (error);
- sr = &srbuf;
- sr->sr_type = SR_CHECKOUTDEAD;
- sr->sr_file = name;
- sr->sr_tag = tag;
- sr->sr_date = date;
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
- error = status_put(fup->st, sr);
- fattr_free(sr->sr_serverattr);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'C':
- case 'Y':
- /* Checkout file. */
- name = proto_get_ascii(&line);
- tag = proto_get_ascii(&line);
- date = proto_get_ascii(&line);
- revnum = proto_get_ascii(&line);
- revdate = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
-
- sr = &fup->srbuf;
- sr->sr_type = SR_CHECKOUTLIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_tag = xstrdup(tag);
- sr->sr_date = xstrdup(date);
- sr->sr_revnum = xstrdup(revnum);
- sr->sr_revdate = xstrdup(revdate);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
-
- t = rcsdatetotime(revdate);
- if (t == -1)
- return (UPDATER_ERR_PROTO);
-
- sr->sr_clientattr = fattr_new(FT_FILE, t);
- tmp = fattr_forcheckout(sr->sr_serverattr,
- coll->co_umask);
- fattr_override(sr->sr_clientattr, tmp, FA_MASK);
- fattr_free(tmp);
- fattr_mergedefault(sr->sr_clientattr);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- fup->temppath = tempname(fup->destpath);
- if (*cmd == 'Y')
- error = updater_checkout(up, fup, 1);
- else
- error = updater_checkout(up, fup, 0);
- if (error)
- return (error);
- break;
- case 'D':
- /* Delete file. */
- name = proto_get_ascii(&line);
- if (name == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- error = updater_delete(up, fup);
- if (error)
- return (error);
- error = status_delete(fup->st, name, 0);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'A':
- case 'a':
- case 'R':
- name = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (name == NULL || attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- attic = (cmd[0] == 'a');
- error = fup_prepare(fup, name, attic);
- if (error)
- return (UPDATER_ERR_PROTO);
-
- fup->temppath = tempname(fup->destpath);
- sr = &fup->srbuf;
- sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
- if (attic)
- lprintf(1, " Create %s -> Attic\n", name);
- else
- lprintf(1, " Create %s\n", name);
- error = updater_addfile(up, fup, attr, 0);
- if (error)
- return (error);
- break;
- case 'r':
- name = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- blocksize = proto_get_ascii(&line);
- wantmd5 = proto_get_ascii(&line);
- if (name == NULL || attr == NULL || blocksize == NULL ||
- wantmd5 == NULL) {
- return (UPDATER_ERR_PROTO);
- }
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- fup->wantmd5 = xstrdup(wantmd5);
- fup->temppath = tempname(fup->destpath);
- sr = &fup->srbuf;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- sr->sr_type = SR_FILELIVE;
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
- error = updater_rsync(up, fup, strtol(blocksize, NULL,
- 10));
- if (error)
- return (error);
- break;
- case 'I':
- /*
- * Create directory and add DirDown entry in status
- * file.
- */
- name = proto_get_ascii(&line);
- if (name == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- sr = &fup->srbuf;
- sr->sr_type = SR_DIRDOWN;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = NULL;
- sr->sr_clientattr = fattr_new(FT_DIRECTORY, -1);
- fattr_mergedefault(sr->sr_clientattr);
-
- error = mkdirhier(fup->destpath, coll->co_umask);
- if (error)
- return (UPDATER_ERR_PROTO);
- if (access(fup->destpath, F_OK) != 0) {
- lprintf(1, " Mkdir %s\n", name);
- error = fattr_makenode(sr->sr_clientattr,
- fup->destpath);
- if (error)
- return (UPDATER_ERR_PROTO);
- }
- error = status_put(fup->st, sr);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'i':
- /* Remove DirDown entry in status file. */
- name = proto_get_ascii(&line);
- if (name == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- error = status_delete(fup->st, name, 0);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'J':
- /*
- * Set attributes of directory and update DirUp entry in
- * status file.
- */
- name = proto_get_ascii(&line);
- if (name == NULL)
- return (UPDATER_ERR_PROTO);
- attr = proto_get_ascii(&line);
- if (attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- error = updater_setdirattrs(up, coll, fup, name, attr);
- if (error)
- return (error);
- break;
- case 'j':
- /*
- * Remove directory and delete its DirUp entry in status
- * file.
- */
- name = proto_get_ascii(&line);
- if (name == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- if (error)
- return (UPDATER_ERR_PROTO);
- lprintf(1, " Rmdir %s\n", name);
- updater_deletefile(fup->destpath);
- error = status_delete(fup->st, name, 0);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'L':
- case 'l':
- name = proto_get_ascii(&line);
- if (name == NULL)
- return (UPDATER_ERR_PROTO);
- attr = proto_get_ascii(&line);
- if (attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- attic = (cmd[0] == 'l');
- sr = &fup->srbuf;
- sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- sr->sr_clientattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL ||
- sr->sr_clientattr == NULL)
- return (UPDATER_ERR_PROTO);
-
- /* Save space. Described in detail in updatefile. */
- if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT)
- || fattr_getlinkcount(sr->sr_clientattr) <= 1)
- fattr_maskout(sr->sr_clientattr,
- FA_DEV | FA_INODE);
- fattr_maskout(sr->sr_clientattr, FA_FLAGS);
- error = status_put(fup->st, sr);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
- break;
- case 'N':
- case 'n':
- name = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (name == NULL || attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- attic = (cmd[0] == 'n');
- error = fup_prepare(fup, name, attic);
- if (error)
- return (UPDATER_ERR_PROTO);
- sr = &fup->srbuf;
- sr->sr_type = (attic ? SR_FILEDEAD : SR_FILELIVE);
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- sr->sr_clientattr = fattr_new(FT_SYMLINK, -1);
- fattr_mergedefault(sr->sr_clientattr);
- fattr_maskout(sr->sr_clientattr, FA_FLAGS);
- error = updater_updatenode(up, coll, fup, name, attr);
- if (error)
- return (error);
- break;
- case 'V':
- case 'v':
- name = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- optstr = proto_get_ascii(&line);
- wantmd5 = proto_get_ascii(&line);
- rcsopt = NULL; /* XXX: Not supported. */
- if (attr == NULL || line != NULL || wantmd5 == NULL)
- return (UPDATER_ERR_PROTO);
- attic = (cmd[0] == 'v');
- error = fup_prepare(fup, name, attic);
- if (error)
- return (UPDATER_ERR_PROTO);
- fup->temppath = tempname(fup->destpath);
- fup->wantmd5 = xstrdup(wantmd5);
- sr = &fup->srbuf;
- sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
-
- error = 0;
- error = updater_rcsedit(up, fup, name, rcsopt);
- if (error)
- return (error);
- break;
- case 'X':
- case 'x':
- name = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- if (name == NULL || attr == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- attic = (cmd[0] == 'x');
- error = fup_prepare(fup, name, attic);
- if (error)
- return (UPDATER_ERR_PROTO);
-
- fup->temppath = tempname(fup->destpath);
- sr = &fup->srbuf;
- sr->sr_type = attic ? SR_FILEDEAD : SR_FILELIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
- lprintf(1, " Fixup %s\n", name);
- error = updater_addfile(up, fup, attr, 1);
- if (error)
- return (error);
- break;
- case 'Z':
- name = proto_get_ascii(&line);
- attr = proto_get_ascii(&line);
- pos = proto_get_ascii(&line);
- if (name == NULL || attr == NULL || pos == NULL ||
- line != NULL)
- return (UPDATER_ERR_PROTO);
- error = fup_prepare(fup, name, 0);
- fup->temppath = tempname(fup->destpath);
- sr = &fup->srbuf;
- sr->sr_type = SR_FILELIVE;
- sr->sr_file = xstrdup(name);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
- position = strtol(pos, NULL, 10);
- lprintf(1, " Append to %s\n", name);
- error = updater_append_file(up, fup, position);
- if (error)
- return (error);
- break;
- case '!':
- /* Warning from server. */
- msg = proto_get_rest(&line);
- if (msg == NULL)
- return (UPDATER_ERR_PROTO);
- lprintf(-1, "Server warning: %s\n", msg);
- break;
- default:
- return (UPDATER_ERR_PROTO);
- }
- fup_cleanup(fup);
- }
- if (line == NULL)
- return (UPDATER_ERR_READ);
- return (0);
-}
-
-/* Delete file. */
-static int
-updater_delete(struct updater *up, struct file_update *fup)
-{
- struct config *config;
- struct coll *coll;
-
- config = up->config;
- coll = fup->coll;
- if (coll->co_options & CO_DELETE) {
- lprintf(1, " Delete %s\n", fup->coname);
- if (config->deletelim >= 0 &&
- up->deletecount >= config->deletelim)
- return (UPDATER_ERR_DELETELIM);
- up->deletecount++;
- updater_deletefile(fup->destpath);
- if (coll->co_options & CO_CHECKOUTMODE)
- updater_prunedirs(coll->co_prefix, fup->destpath);
- } else {
- lprintf(1," NoDelete %s\n", fup->coname);
- }
- return (0);
-}
-
-static void
-updater_deletefile(const char *path)
-{
- int error;
-
- error = fattr_delete(path);
- if (error && errno != ENOENT) {
- lprintf(-1, "Cannot delete \"%s\": %s\n",
- path, strerror(errno));
- }
-}
-
-static int
-updater_setattrs(struct updater *up, struct file_update *fup, char *name,
- char *tag, char *date, char *revnum, char *revdate, struct fattr *rcsattr)
-{
- struct statusrec sr;
- struct status *st;
- struct coll *coll;
- struct fattr *fileattr, *fa;
- char *path;
- int error, rv;
-
- coll = fup->coll;
- st = fup->st;
- path = fup->destpath;
-
- fileattr = fattr_frompath(path, FATTR_NOFOLLOW);
- if (fileattr == NULL) {
- /* The file has vanished. */
- error = status_delete(st, name, 0);
- if (error) {
- up->errmsg = status_errmsg(st);
- return (UPDATER_ERR_MSG);
- }
- return (0);
- }
- fa = fattr_forcheckout(rcsattr, coll->co_umask);
- fattr_override(fileattr, fa, FA_MASK);
- fattr_free(fa);
-
- rv = fattr_install(fileattr, path, NULL);
- if (rv == -1) {
- lprintf(1, " SetAttrs %s\n", fup->coname);
- fattr_free(fileattr);
- xasprintf(&up->errmsg, "Cannot set attributes for \"%s\": %s",
- path, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- if (rv == 1) {
- lprintf(1, " SetAttrs %s\n", fup->coname);
- fattr_free(fileattr);
- fileattr = fattr_frompath(path, FATTR_NOFOLLOW);
- if (fileattr == NULL) {
- /* We're being very unlucky. */
- error = status_delete(st, name, 0);
- if (error) {
- up->errmsg = status_errmsg(st);
- return (UPDATER_ERR_MSG);
- }
- return (0);
- }
- }
-
- fattr_maskout(fileattr, FA_COIGNORE);
-
- sr.sr_type = SR_CHECKOUTLIVE;
- sr.sr_file = name;
- sr.sr_tag = tag;
- sr.sr_date = date;
- sr.sr_revnum = revnum;
- sr.sr_revdate = revdate;
- sr.sr_clientattr = fileattr;
- sr.sr_serverattr = rcsattr;
-
- error = status_put(st, &sr);
- fattr_free(fileattr);
- if (error) {
- up->errmsg = status_errmsg(st);
- return (UPDATER_ERR_MSG);
- }
- return (0);
-}
-
-static int
-updater_updatefile(struct updater *up, struct file_update *fup,
- const char *md5, int isfixup)
-{
- struct coll *coll;
- struct status *st;
- struct statusrec *sr;
- struct fattr *fileattr;
- int error, rv;
-
- coll = fup->coll;
- sr = &fup->srbuf;
- st = fup->st;
-
- if (strcmp(fup->wantmd5, md5) != 0) {
- if (isfixup) {
- lprintf(-1, "%s: Checksum mismatch -- "
- "file not updated\n", fup->destpath);
- } else {
- lprintf(-1, "%s: Checksum mismatch -- "
- "will transfer entire file\n", fup->destpath);
- fixups_put(up->config->fixups, fup->coll, sr->sr_file);
- }
- if (coll->co_options & CO_KEEPBADFILES)
- lprintf(-1, "Bad version saved in %s\n", fup->temppath);
- else
- updater_deletefile(fup->temppath);
- return (0);
- }
-
- fattr_umask(sr->sr_clientattr, coll->co_umask);
- rv = fattr_install(sr->sr_clientattr, fup->destpath, fup->temppath);
- if (rv == -1) {
- xasprintf(&up->errmsg, "Cannot install \"%s\" to \"%s\": %s",
- fup->temppath, fup->destpath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
-
- /* XXX Executes */
- /*
- * We weren't necessarily able to set all the file attributes to the
- * desired values, and any executes may have altered the attributes.
- * To make sure we record the actual attribute values, we fetch
- * them from the file.
- *
- * However, we preserve the link count as received from the
- * server. This is important for preserving hard links in mirror
- * mode.
- */
- fileattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
- if (fileattr == NULL) {
- xasprintf(&up->errmsg, "Cannot stat \"%s\": %s", fup->destpath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- fattr_override(fileattr, sr->sr_clientattr, FA_LINKCOUNT);
- fattr_free(sr->sr_clientattr);
- sr->sr_clientattr = fileattr;
-
- /*
- * To save space, don't write out the device and inode unless
- * the link count is greater than 1. These attributes are used
- * only for detecting hard links. If the link count is 1 then we
- * know there aren't any hard links.
- */
- if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT) ||
- fattr_getlinkcount(sr->sr_clientattr) <= 1)
- fattr_maskout(sr->sr_clientattr, FA_DEV | FA_INODE);
-
- if (coll->co_options & CO_CHECKOUTMODE)
- fattr_maskout(sr->sr_clientattr, FA_COIGNORE);
-
- error = status_put(st, sr);
- if (error) {
- up->errmsg = status_errmsg(st);
- return (UPDATER_ERR_MSG);
- }
- return (0);
-}
-
-/*
- * Update attributes of a directory.
- */
-static int
-updater_setdirattrs(struct updater *up, struct coll *coll,
- struct file_update *fup, char *name, char *attr)
-{
- struct statusrec *sr;
- struct fattr *fa;
- int error, rv;
-
- sr = &fup->srbuf;
- sr->sr_type = SR_DIRUP;
- sr->sr_file = xstrdup(name);
- sr->sr_clientattr = fattr_decode(attr);
- sr->sr_serverattr = fattr_decode(attr);
- if (sr->sr_clientattr == NULL || sr->sr_serverattr == NULL)
- return (UPDATER_ERR_PROTO);
- fattr_mergedefault(sr->sr_clientattr);
- fattr_umask(sr->sr_clientattr, coll->co_umask);
- rv = fattr_install(sr->sr_clientattr, fup->destpath, NULL);
- lprintf(1, " SetAttrs %s\n", name);
- if (rv == -1) {
- xasprintf(&up->errmsg, "Cannot install \"%s\" to \"%s\": %s",
- fup->temppath, fup->destpath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- /*
- * Now, make sure they were set and record what was set in the status
- * file.
- */
- fa = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
- if (fa == NULL) {
- xasprintf(&up->errmsg, "Cannot open \%s\": %s", fup->destpath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- fattr_free(sr->sr_clientattr);
- fattr_maskout(fa, FA_FLAGS);
- sr->sr_clientattr = fa;
- error = status_put(fup->st, sr);
- if (error) {
- up->errmsg = status_errmsg(fup->st);
- return (UPDATER_ERR_MSG);
- }
-
- return (0);
-}
-
-static int
-updater_diff(struct updater *up, struct file_update *fup)
-{
- char md5[MD5_DIGEST_SIZE];
- struct coll *coll;
- struct statusrec *sr;
- struct fattr *fa, *tmp;
- char *author, *path, *revnum, *revdate;
- char *line, *cmd;
- int error;
-
- coll = fup->coll;
- sr = &fup->srbuf;
- path = fup->destpath;
-
- lprintf(1, " Edit %s\n", fup->coname);
- while ((line = stream_getln(up->rd, NULL)) != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- cmd = proto_get_ascii(&line);
- if (cmd == NULL || strcmp(cmd, "D") != 0)
- return (UPDATER_ERR_PROTO);
- revnum = proto_get_ascii(&line);
- proto_get_ascii(&line); /* XXX - diffbase */
- revdate = proto_get_ascii(&line);
- author = proto_get_ascii(&line);
- if (author == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- if (sr->sr_revnum != NULL)
- free(sr->sr_revnum);
- if (sr->sr_revdate != NULL)
- free(sr->sr_revdate);
- if (fup->author != NULL)
- free(fup->author);
- sr->sr_revnum = xstrdup(revnum);
- sr->sr_revdate = xstrdup(revdate);
- fup->author = xstrdup(author);
- if (fup->orig == NULL) {
- /* First patch, the "origin" file is the one we have. */
- fup->orig = stream_open_file(path, O_RDONLY);
- if (fup->orig == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot open: %s",
- path, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- } else {
- /* Subsequent patches. */
- stream_close(fup->orig);
- fup->orig = fup->to;
- stream_rewind(fup->orig);
- unlink(fup->temppath);
- free(fup->temppath);
- fup->temppath = tempname(path);
- }
- fup->to = stream_open_file(fup->temppath,
- O_RDWR | O_CREAT | O_TRUNC, 0600);
- if (fup->to == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot open: %s",
- fup->temppath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- lprintf(2, " Add delta %s %s %s\n", sr->sr_revnum,
- sr->sr_revdate, fup->author);
- error = updater_diff_batch(up, fup);
- if (error)
- return (error);
- }
- if (line == NULL)
- return (UPDATER_ERR_READ);
-
- fa = fattr_frompath(path, FATTR_FOLLOW);
- tmp = fattr_forcheckout(sr->sr_serverattr, coll->co_umask);
- fattr_override(fa, tmp, FA_MASK);
- fattr_free(tmp);
- fattr_maskout(fa, FA_MODTIME);
- sr->sr_clientattr = fa;
-
- if (MD5_File(fup->temppath, md5) == -1) {
- xasprintf(&up->errmsg,
- "Cannot calculate checksum for \"%s\": %s",
- path, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- error = updater_updatefile(up, fup, md5, 0);
- return (error);
-}
-
-/*
- * Edit a file and add delta.
- */
-static int
-updater_diff_batch(struct updater *up, struct file_update *fup)
-{
- struct stream *rd;
- char *cmd, *line, *state, *tok;
- int error;
-
- state = NULL;
- rd = up->rd;
- while ((line = stream_getln(rd, NULL)) != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- cmd = proto_get_ascii(&line);
- if (cmd == NULL || strlen(cmd) != 1) {
- error = UPDATER_ERR_PROTO;
- goto bad;
- }
- switch (cmd[0]) {
- case 'L':
- line = stream_getln(rd, NULL);
- /* XXX - We're just eating the log for now. */
- while (line != NULL && strcmp(line, ".") != 0 &&
- strcmp(line, ".+") != 0)
- line = stream_getln(rd, NULL);
- if (line == NULL) {
- error = UPDATER_ERR_READ;
- goto bad;
- }
- break;
- case 'S':
- tok = proto_get_ascii(&line);
- if (tok == NULL || line != NULL) {
- error = UPDATER_ERR_PROTO;
- goto bad;
- }
- if (state != NULL)
- free(state);
- state = xstrdup(tok);
- break;
- case 'T':
- error = updater_diff_apply(up, fup, state);
- if (error)
- goto bad;
- break;
- default:
- error = UPDATER_ERR_PROTO;
- goto bad;
- }
- }
- if (line == NULL) {
- error = UPDATER_ERR_READ;
- goto bad;
- }
- if (state != NULL)
- free(state);
- return (0);
-bad:
- if (state != NULL)
- free(state);
- return (error);
-}
-
-int
-updater_diff_apply(struct updater *up, struct file_update *fup, char *state)
-{
- struct diffinfo dibuf, *di;
- struct coll *coll;
- struct statusrec *sr;
- int error;
-
- coll = fup->coll;
- sr = &fup->srbuf;
- di = &dibuf;
-
- di->di_rcsfile = sr->sr_file;
- di->di_cvsroot = coll->co_cvsroot;
- di->di_revnum = sr->sr_revnum;
- di->di_revdate = sr->sr_revdate;
- di->di_author = fup->author;
- di->di_tag = sr->sr_tag;
- di->di_state = state;
- di->di_expand = fup->expand;
-
- error = diff_apply(up->rd, fup->orig, fup->to, coll->co_keyword, di, 1);
- if (error) {
- /* XXX Bad error message */
- xasprintf(&up->errmsg, "Bad diff from server");
- return (UPDATER_ERR_MSG);
- }
- return (0);
-}
-
-/* Update or create a node. */
-static int
-updater_updatenode(struct updater *up, struct coll *coll,
- struct file_update *fup, char *name, char *attr)
-{
- struct fattr *fa, *fileattr;
- struct status *st;
- struct statusrec *sr;
- int error, rv;
-
- sr = &fup->srbuf;
- st = fup->st;
- fa = fattr_decode(attr);
-
- if (fattr_type(fa) == FT_SYMLINK) {
- lprintf(1, " Symlink %s -> %s\n", name,
- fattr_getlinktarget(fa));
- } else {
- lprintf(1, " Mknod %s\n", name);
- }
-
- /* Create directory. */
- error = mkdirhier(fup->destpath, coll->co_umask);
- if (error)
- return (UPDATER_ERR_PROTO);
-
- /* If it does not exist, create it. */
- if (access(fup->destpath, F_OK) != 0)
- fattr_makenode(fa, fup->destpath);
-
- /*
- * Coming from attic? I don't think this is a problem since we have
- * determined attic before we call this function (Look at UpdateNode in
- * cvsup).
- */
- fattr_umask(fa, coll->co_umask);
- rv = fattr_install(fa, fup->destpath, fup->temppath);
- if (rv == -1) {
- xasprintf(&up->errmsg, "Cannot update attributes on "
- "\"%s\": %s", fup->destpath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- /*
- * XXX: Executes not implemented. Have not encountered much use for it
- * yet.
- */
- /*
- * We weren't necessarily able to set all the file attributes to the
- * desired values, and any executes may have altered the attributes.
- * To make sure we record the actual attribute values, we fetch
- * them from the file.
- *
- * However, we preserve the link count as received from the
- * server. This is important for preserving hard links in mirror
- * mode.
- */
- fileattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
- if (fileattr == NULL) {
- xasprintf(&up->errmsg, "Cannot stat \"%s\": %s", fup->destpath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- fattr_override(fileattr, sr->sr_clientattr, FA_LINKCOUNT);
- fattr_free(sr->sr_clientattr);
- sr->sr_clientattr = fileattr;
-
- /*
- * To save space, don't write out the device and inode unless
- * the link count is greater than 1. These attributes are used
- * only for detecting hard links. If the link count is 1 then we
- * know there aren't any hard links.
- */
- if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT) ||
- fattr_getlinkcount(sr->sr_clientattr) <= 1)
- fattr_maskout(sr->sr_clientattr, FA_DEV | FA_INODE);
-
- /* If it is a symlink, write only out it's path. */
- if (fattr_type(fa) == FT_SYMLINK) {
- fattr_maskout(sr->sr_clientattr, ~(FA_FILETYPE |
- FA_LINKTARGET));
- }
- fattr_maskout(sr->sr_clientattr, FA_FLAGS);
- error = status_put(st, sr);
- if (error) {
- up->errmsg = status_errmsg(st);
- return (UPDATER_ERR_MSG);
- }
- fattr_free(fa);
-
- return (0);
-}
-
-/*
- * Fetches a new file in CVS mode.
- */
-static int
-updater_addfile(struct updater *up, struct file_update *fup, char *attr,
- int isfixup)
-{
- struct coll *coll;
- struct stream *to;
- struct statusrec *sr;
- struct fattr *fa;
- char buf[BUFSIZE];
- char md5[MD5_DIGEST_SIZE];
- ssize_t nread;
- off_t fsize, remains;
- char *cmd, *line, *path;
- int error;
-
- coll = fup->coll;
- path = fup->destpath;
- sr = &fup->srbuf;
- fa = fattr_decode(attr);
- fsize = fattr_filesize(fa);
-
- error = mkdirhier(path, coll->co_umask);
- if (error)
- return (UPDATER_ERR_PROTO);
- to = stream_open_file(fup->temppath, O_WRONLY | O_CREAT | O_TRUNC, 0755);
- if (to == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot create: %s",
- fup->temppath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- stream_filter_start(to, STREAM_FILTER_MD5, md5);
- remains = fsize;
- do {
- nread = stream_read(up->rd, buf, (BUFSIZE > remains ?
- remains : BUFSIZE));
- if (nread == -1)
- return (UPDATER_ERR_PROTO);
- remains -= nread;
- if (stream_write(to, buf, nread) == -1)
- goto bad;
- } while (remains > 0);
- stream_close(to);
- line = stream_getln(up->rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_PROTO);
- /* Check for EOF. */
- if (!(*line == '.' || (strncmp(line, ".<", 2) != 0)))
- return (UPDATER_ERR_PROTO);
- line = stream_getln(up->rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_PROTO);
-
- cmd = proto_get_ascii(&line);
- fup->wantmd5 = proto_get_ascii(&line);
- if (fup->wantmd5 == NULL || line != NULL || strcmp(cmd, "5") != 0)
- return (UPDATER_ERR_PROTO);
-
- sr->sr_clientattr = fattr_frompath(fup->temppath, FATTR_NOFOLLOW);
- if (sr->sr_clientattr == NULL)
- return (UPDATER_ERR_PROTO);
- fattr_override(sr->sr_clientattr, sr->sr_serverattr,
- FA_MODTIME | FA_MASK);
- error = updater_updatefile(up, fup, md5, isfixup);
- fup->wantmd5 = NULL; /* So that it doesn't get freed. */
- return (error);
-bad:
- xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
-}
-
-static int
-updater_checkout(struct updater *up, struct file_update *fup, int isfixup)
-{
- char md5[MD5_DIGEST_SIZE];
- struct statusrec *sr;
- struct coll *coll;
- struct stream *to;
- ssize_t nbytes;
- size_t size;
- char *cmd, *path, *line;
- int error, first;
-
- coll = fup->coll;
- sr = &fup->srbuf;
- path = fup->destpath;
-
- if (isfixup)
- lprintf(1, " Fixup %s\n", fup->coname);
- else
- lprintf(1, " Checkout %s\n", fup->coname);
- error = mkdirhier(path, coll->co_umask);
- if (error) {
- xasprintf(&up->errmsg,
- "Cannot create directories leading to \"%s\": %s",
- path, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
-
- to = stream_open_file(fup->temppath,
- O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (to == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot create: %s",
- fup->temppath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- stream_filter_start(to, STREAM_FILTER_MD5, md5);
- line = stream_getln(up->rd, &size);
- first = 1;
- while (line != NULL) {
- if (line[size - 1] == '\n')
- size--;
- if ((size == 1 && *line == '.') ||
- (size == 2 && memcmp(line, ".+", 2) == 0))
- break;
- if (size >= 2 && memcmp(line, "..", 2) == 0) {
- size--;
- line++;
- }
- if (!first) {
- nbytes = stream_write(to, "\n", 1);
- if (nbytes == -1)
- goto bad;
- }
- nbytes = stream_write(to, line, size);
- if (nbytes == -1)
- goto bad;
- line = stream_getln(up->rd, &size);
- first = 0;
- }
- if (line == NULL) {
- stream_close(to);
- return (UPDATER_ERR_READ);
- }
- if (size == 1 && *line == '.') {
- nbytes = stream_write(to, "\n", 1);
- if (nbytes == -1)
- goto bad;
- }
- stream_close(to);
- /* Get the checksum line. */
- line = stream_getln(up->rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_READ);
- cmd = proto_get_ascii(&line);
- fup->wantmd5 = proto_get_ascii(&line);
- if (fup->wantmd5 == NULL || line != NULL || strcmp(cmd, "5") != 0)
- return (UPDATER_ERR_PROTO);
- error = updater_updatefile(up, fup, md5, isfixup);
- fup->wantmd5 = NULL; /* So that it doesn't get freed. */
- if (error)
- return (error);
- return (0);
-bad:
- xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
-}
-
-/*
- * Remove all empty directories below file.
- * This function will trash the path passed to it.
- */
-static void
-updater_prunedirs(char *base, char *file)
-{
- char *cp;
- int error;
-
- while ((cp = strrchr(file, '/')) != NULL) {
- *cp = '\0';
- if (strcmp(base, file) == 0)
- return;
- error = rmdir(file);
- if (error)
- return;
- }
-}
-
-/*
- * Edit an RCS file.
- */
-static int
-updater_rcsedit(struct updater *up, struct file_update *fup, char *name,
- char *rcsopt)
-{
- struct coll *coll;
- struct stream *dest;
- struct statusrec *sr;
- struct status *st;
- struct rcsfile *rf;
- struct fattr *oldfattr;
- char md5[MD5_DIGEST_SIZE];
- char *branch, *cmd, *expand, *line, *path, *revnum, *tag, *temppath;
- int error;
-
- coll = fup->coll;
- sr = &fup->srbuf;
- st = fup->st;
- temppath = fup->temppath;
- path = fup->origpath != NULL ? fup->origpath : fup->destpath;
- error = 0;
-
- /* If the path is new, we must create the Attic dir if needed. */
- if (fup->origpath != NULL) {
- error = mkdirhier(fup->destpath, coll->co_umask);
- if (error) {
- xasprintf(&up->errmsg, "Unable to create Attic dir for "
- "%s\n", fup->origpath);
- return (UPDATER_ERR_MSG);
- }
- }
- /*
- * XXX: we could avoid parsing overhead if we're reading ahead before we
- * parse the file.
- */
- oldfattr = fattr_frompath(path, FATTR_NOFOLLOW);
- if (oldfattr == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot get attributes: %s", path,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- fattr_merge(sr->sr_serverattr, oldfattr);
- rf = NULL;
-
- /* Macro for making touching an RCS file faster. */
-#define UPDATER_OPENRCS(rf, up, path, name, cvsroot, tag) do { \
- if ((rf) == NULL) { \
- lprintf(1, " Edit %s", fup->coname); \
- if (fup->attic) \
- lprintf(1, " -> Attic"); \
- lprintf(1, "\n"); \
- (rf) = rcsfile_frompath((path), (name), (cvsroot), \
- (tag), 0); \
- if ((rf) == NULL) { \
- xasprintf(&(up)->errmsg, \
- "Error reading rcsfile %s\n", (name)); \
- return (UPDATER_ERR_MSG); \
- } \
- } \
-} while (0)
-
- while ((line = stream_getln(up->rd, NULL)) != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- cmd = proto_get_ascii(&line);
- if (cmd == NULL) {
- lprintf(-1, "Error editing %s\n", name);
- return (UPDATER_ERR_PROTO);
- }
- switch(cmd[0]) {
- case 'B':
- branch = proto_get_ascii(&line);
- if (branch == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- break;
- case 'b':
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- rcsfile_setval(rf, RCSFILE_BRANCH, NULL);
- break;
- case 'D':
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- error = updater_addelta(rf, up->rd, line);
- if (error)
- return (error);
- break;
- case 'd':
- revnum = proto_get_ascii(&line);
- if (revnum == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- rcsfile_deleterev(rf, revnum);
- break;
- case 'E':
- expand = proto_get_ascii(&line);
- if (expand == NULL || line != NULL)
- return (UPDATER_ERR_PROTO);
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- rcsfile_setval(rf, RCSFILE_EXPAND, expand);
- break;
- case 'T':
- tag = proto_get_ascii(&line);
- revnum = proto_get_ascii(&line);
- if (tag == NULL || revnum == NULL ||
- line != NULL)
- return (UPDATER_ERR_PROTO);
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- rcsfile_addtag(rf, tag, revnum);
- break;
- case 't':
- tag = proto_get_ascii(&line);
- revnum = proto_get_ascii(&line);
- if (tag == NULL || revnum == NULL ||
- line != NULL)
- return (UPDATER_ERR_PROTO);
- UPDATER_OPENRCS(rf, up, path, name,
- coll->co_cvsroot, coll->co_tag);
- rcsfile_deletetag(rf, tag, revnum);
- break;
- default:
- return (UPDATER_ERR_PROTO);
- }
- }
-
- if (rf == NULL) {
- fattr_maskout(oldfattr, ~FA_MODTIME);
- if (fattr_equal(oldfattr, sr->sr_serverattr))
- lprintf(1, " SetAttrs %s", fup->coname);
- else
- lprintf(1, " Touch %s", fup->coname);
- /* Install new attributes. */
- fattr_umask(sr->sr_serverattr, coll->co_umask);
- fattr_install(sr->sr_serverattr, fup->destpath, NULL);
- if (fup->attic)
- lprintf(1, " -> Attic");
- lprintf(1, "\n");
- fattr_free(oldfattr);
- goto finish;
- }
-
- /* Write and rename temp file. */
- dest = stream_open_file(fup->temppath,
- O_RDWR | O_CREAT | O_TRUNC, 0600);
- if (dest == NULL) {
- xasprintf(&up->errmsg, "Error opening file %s for writing: %s\n",
- fup->temppath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- stream_filter_start(dest, STREAM_FILTER_MD5RCS, md5);
- error = rcsfile_write(rf, dest);
- stream_close(dest);
- rcsfile_free(rf);
- if (error) {
- xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
-
-finish:
- sr->sr_clientattr = fattr_frompath(path, FATTR_NOFOLLOW);
- if (sr->sr_clientattr == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot get attributes: %s",
- fup->destpath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- fattr_override(sr->sr_clientattr, sr->sr_serverattr,
- FA_MODTIME | FA_MASK);
- if (rf != NULL) {
- error = updater_updatefile(up, fup, md5, 0);
- fup->wantmd5 = NULL; /* So that it doesn't get freed. */
- if (error)
- return (error);
- } else {
- /* Record its attributes since we touched it. */
- if (!(fattr_getmask(sr->sr_clientattr) & FA_LINKCOUNT) ||
- fattr_getlinkcount(sr->sr_clientattr) <= 1)
- fattr_maskout(sr->sr_clientattr, FA_DEV | FA_INODE);
- error = status_put(st, sr);
- if (error) {
- up->errmsg = status_errmsg(st);
- return (UPDATER_ERR_MSG);
- }
- }
-
- /* In this case, we need to remove the old file afterwards. */
- /* XXX: Can we be sure that a file not edited is moved? I don't think
- * this is a problem, since if a file is moved, it should be edited to
- * show if it's dead or not.
- */
- if (fup->origpath != NULL)
- updater_deletefile(fup->origpath);
- return (0);
-}
-
-/*
- * Add a delta to a RCS file.
- */
-int
-updater_addelta(struct rcsfile *rf, struct stream *rd, char *cmdline)
-{
- struct delta *d;
- size_t size;
- char *author, *cmd, *diffbase, *line, *logline;
- char *revdate, *revnum, *state, *textline;
-
- revnum = proto_get_ascii(&cmdline);
- diffbase = proto_get_ascii(&cmdline);
- revdate = proto_get_ascii(&cmdline);
- author = proto_get_ascii(&cmdline);
- size = 0;
-
- if (revnum == NULL || revdate == NULL || author == NULL)
- return (UPDATER_ERR_PROTO);
-
- /* First add the delta so we have it. */
- d = rcsfile_addelta(rf, revnum, revdate, author, diffbase);
- if (d == NULL) {
- lprintf(-1, "Error adding delta %s\n", revnum);
- return (UPDATER_ERR_READ);
- }
- while ((line = stream_getln(rd, NULL)) != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- cmd = proto_get_ascii(&line);
- switch (cmd[0]) {
- case 'L':
- /* Do the same as in 'C' command. */
- logline = stream_getln(rd, &size);
- while (logline != NULL) {
- if (size == 2 && *logline == '.')
- break;
- if (size == 3 &&
- memcmp(logline, ".+", 2) == 0) {
- rcsdelta_truncatelog(d, -1);
- break;
- }
- if (size >= 3 &&
- memcmp(logline, "..", 2) == 0) {
- size--;
- logline++;
- }
- if (rcsdelta_appendlog(d, logline, size)
- < 0)
- return (-1);
- logline = stream_getln(rd, &size);
- }
- break;
- case 'N':
- case 'n':
- /* XXX: Not supported. */
- break;
- case 'S':
- state = proto_get_ascii(&line);
- if (state == NULL)
- return (UPDATER_ERR_PROTO);
- rcsdelta_setstate(d, state);
- break;
- case 'T':
- /* Do the same as in 'C' command. */
- textline = stream_getln(rd, &size);
- while (textline != NULL) {
- if (size == 2 && *textline == '.')
- break;
- if (size == 3 &&
- memcmp(textline, ".+", 2) == 0) {
- /* Truncate newline. */
- rcsdelta_truncatetext(d, -1);
- break;
- }
- if (size >= 3 &&
- memcmp(textline, "..", 2) == 0) {
- size--;
- textline++;
- }
- if (rcsdelta_appendtext(d, textline,
- size) < 0)
- return (-1);
- textline = stream_getln(rd, &size);
- }
- break;
- }
- }
-
- return (0);
-}
-
-int
-updater_append_file(struct updater *up, struct file_update *fup, off_t pos)
-{
- struct fattr *fa;
- struct stream *to;
- struct statusrec *sr;
- ssize_t nread;
- off_t bytes;
- char buf[BUFSIZE], md5[MD5_DIGEST_SIZE];
- char *line, *cmd;
- int error, fd;
-
- sr = &fup->srbuf;
- fa = sr->sr_serverattr;
- to = stream_open_file(fup->temppath, O_WRONLY | O_CREAT | O_TRUNC,
- 0755);
- if (to == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot open: %s", fup->temppath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- fd = open(fup->destpath, O_RDONLY);
- if (fd < 0) {
- xasprintf(&up->errmsg, "%s: Cannot open: %s", fup->destpath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
-
- stream_filter_start(to, STREAM_FILTER_MD5, md5);
- /* First write the existing content. */
- while ((nread = read(fd, buf, BUFSIZE)) > 0) {
- if (stream_write(to, buf, nread) == -1)
- goto bad;
- }
- if (nread == -1) {
- xasprintf(&up->errmsg, "%s: Error reading: %s", fup->destpath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- close(fd);
-
- bytes = fattr_filesize(fa) - pos;
- /* Append the new data. */
- do {
- nread = stream_read(up->rd, buf,
- (BUFSIZE > bytes) ? bytes : BUFSIZE);
- if (nread == -1)
- return (UPDATER_ERR_PROTO);
- bytes -= nread;
- if (stream_write(to, buf, nread) == -1)
- goto bad;
- } while (bytes > 0);
- stream_close(to);
-
- line = stream_getln(up->rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_PROTO);
- /* Check for EOF. */
- if (!(*line == '.' || (strncmp(line, ".<", 2) != 0)))
- return (UPDATER_ERR_PROTO);
- line = stream_getln(up->rd, NULL);
- if (line == NULL)
- return (UPDATER_ERR_PROTO);
-
- cmd = proto_get_ascii(&line);
- fup->wantmd5 = proto_get_ascii(&line);
- if (fup->wantmd5 == NULL || line != NULL || strcmp(cmd, "5") != 0)
- return (UPDATER_ERR_PROTO);
-
- sr->sr_clientattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
- if (sr->sr_clientattr == NULL)
- return (UPDATER_ERR_PROTO);
- fattr_override(sr->sr_clientattr, sr->sr_serverattr,
- FA_MODTIME | FA_MASK);
- error = updater_updatefile(up, fup, md5, 0);
- fup->wantmd5 = NULL; /* So that it doesn't get freed. */
- return (error);
-bad:
- xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath,
- strerror(errno));
- return (UPDATER_ERR_MSG);
-}
-
-/*
- * Read file data from stream of checkout commands, and write it to the
- * destination.
- */
-static int
-updater_read_checkout(struct stream *src, struct stream *dest)
-{
- ssize_t nbytes;
- size_t size;
- char *line;
- int first;
-
- first = 1;
- line = stream_getln(src, &size);
- while (line != NULL) {
- if (line[size - 1] == '\n')
- size--;
- if ((size == 1 && *line == '.') ||
- (size == 2 && strncmp(line, ".+", 2) == 0))
- break;
- if (size >= 2 && strncmp(line, "..", 2) == 0) {
- size--;
- line++;
- }
- if (!first) {
- nbytes = stream_write(dest, "\n", 1);
- if (nbytes == -1)
- return (UPDATER_ERR_MSG);
- }
- nbytes = stream_write(dest, line, size);
- if (nbytes == -1)
- return (UPDATER_ERR_MSG);
- line = stream_getln(src, &size);
- first = 0;
- }
- if (line == NULL)
- return (UPDATER_ERR_READ);
- if (size == 1 && *line == '.') {
- nbytes = stream_write(dest, "\n", 1);
- if (nbytes == -1)
- return (UPDATER_ERR_MSG);
- }
- return (0);
-}
-
-/* Update file using the rsync protocol. */
-static int
-updater_rsync(struct updater *up, struct file_update *fup, size_t blocksize)
-{
- struct statusrec *sr;
- struct stream *to;
- char md5[MD5_DIGEST_SIZE];
- ssize_t nbytes;
- size_t blocknum, blockstart, blockcount;
- char *buf, *line;
- int error, orig;
-
- sr = &fup->srbuf;
-
- lprintf(1, " Rsync %s\n", fup->coname);
- /* First open all files that we are going to work on. */
- to = stream_open_file(fup->temppath, O_WRONLY | O_CREAT | O_TRUNC,
- 0600);
- if (to == NULL) {
- xasprintf(&up->errmsg, "%s: Cannot create: %s",
- fup->temppath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- orig = open(fup->destpath, O_RDONLY);
- if (orig < 0) {
- xasprintf(&up->errmsg, "%s: Cannot open: %s",
- fup->destpath, strerror(errno));
- return (UPDATER_ERR_MSG);
- }
- stream_filter_start(to, STREAM_FILTER_MD5, md5);
-
- error = updater_read_checkout(up->rd, to);
- if (error) {
- xasprintf(&up->errmsg, "%s: Cannot write: %s", fup->temppath,
- strerror(errno));
- return (error);
- }
-
- /* Buffer must contain blocksize bytes. */
- buf = xmalloc(blocksize);
- /* Done with the initial text, read and write chunks. */
- line = stream_getln(up->rd, NULL);
- while (line != NULL) {
- if (strcmp(line, ".") == 0)
- break;
- error = UPDATER_ERR_PROTO;
- if (proto_get_sizet(&line, &blockstart, 10) != 0)
- goto bad;
- if (proto_get_sizet(&line, &blockcount, 10) != 0)
- goto bad;
- /* Read blocks from original file. */
- lseek(orig, (blocksize * blockstart), SEEK_SET);
- error = UPDATER_ERR_MSG;
- for (blocknum = 0; blocknum < blockcount; blocknum++) {
- nbytes = read(orig, buf, blocksize);
- if (nbytes < 0) {
- xasprintf(&up->errmsg, "%s: Cannot read: %s",
- fup->destpath, strerror(errno));
- goto bad;
- }
- nbytes = stream_write(to, buf, nbytes);
- if (nbytes == -1) {
- xasprintf(&up->errmsg, "%s: Cannot write: %s",
- fup->temppath, strerror(errno));
- goto bad;
- }
- }
- /* Get the remaining text from the server. */
- error = updater_read_checkout(up->rd, to);
- if (error) {
- xasprintf(&up->errmsg, "%s: Cannot write: %s",
- fup->temppath, strerror(errno));
- goto bad;
- }
- line = stream_getln(up->rd, NULL);
- }
- stream_close(to);
- close(orig);
-
- sr->sr_clientattr = fattr_frompath(fup->destpath, FATTR_NOFOLLOW);
- if (sr->sr_clientattr == NULL)
- return (UPDATER_ERR_PROTO);
- fattr_override(sr->sr_clientattr, sr->sr_serverattr,
- FA_MODTIME | FA_MASK);
-
- error = updater_updatefile(up, fup, md5, 0);
- fup->wantmd5 = NULL; /* So that it doesn't get freed. */
-bad:
- free(buf);
- return (error);
-}
diff --git a/contrib/csup/updater.h b/contrib/csup/updater.h
deleted file mode 100644
index 9ec9ed7..0000000
--- a/contrib/csup/updater.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * Copyright (c) 2003-2004, Maxime Henrion <mux@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#ifndef _UPDATER_H_
-#define _UPDATER_H
-
-void *updater(void *);
-
-#endif /* !_UPDATER_H_ */
OpenPOWER on IntegriCloud