svn commit: r184054 - in projects/csup_cvsmode: contrib/csup
usr.bin/csup
Ulf Lilleengen
lulf at FreeBSD.org
Sun Oct 19 09:09:00 UTC 2008
Author: lulf
Date: Sun Oct 19 09:08:59 2008
New Revision: 184054
URL: http://svn.freebsd.org/changeset/base/184054
Log:
- Import csup work from p4.
Added:
projects/csup_cvsmode/contrib/csup/lex.rcs.c (contents, props changed)
projects/csup_cvsmode/contrib/csup/rcsfile.c (contents, props changed)
projects/csup_cvsmode/contrib/csup/rcsfile.h (contents, props changed)
projects/csup_cvsmode/contrib/csup/rcsparse.c (contents, props changed)
projects/csup_cvsmode/contrib/csup/rcsparse.h (contents, props changed)
projects/csup_cvsmode/contrib/csup/rcstokenizer.h (contents, props changed)
projects/csup_cvsmode/contrib/csup/rcstokenizer.l
Modified:
projects/csup_cvsmode/contrib/csup/Makefile
projects/csup_cvsmode/contrib/csup/config.c
projects/csup_cvsmode/contrib/csup/detailer.c
projects/csup_cvsmode/contrib/csup/diff.c
projects/csup_cvsmode/contrib/csup/diff.h
projects/csup_cvsmode/contrib/csup/fattr.c
projects/csup_cvsmode/contrib/csup/fattr.h
projects/csup_cvsmode/contrib/csup/keyword.c
projects/csup_cvsmode/contrib/csup/keyword.h
projects/csup_cvsmode/contrib/csup/lister.c
projects/csup_cvsmode/contrib/csup/misc.c
projects/csup_cvsmode/contrib/csup/misc.h
projects/csup_cvsmode/contrib/csup/mux.c
projects/csup_cvsmode/contrib/csup/proto.c
projects/csup_cvsmode/contrib/csup/status.c
projects/csup_cvsmode/contrib/csup/stream.c
projects/csup_cvsmode/contrib/csup/stream.h
projects/csup_cvsmode/contrib/csup/updater.c
projects/csup_cvsmode/usr.bin/csup/Makefile
Modified: projects/csup_cvsmode/contrib/csup/Makefile
==============================================================================
--- projects/csup_cvsmode/contrib/csup/Makefile Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/Makefile Sun Oct 19 09:08:59 2008 (r184054)
@@ -9,10 +9,11 @@ UNAME!= /usr/bin/uname -s
PROG= csup
SRCS= attrstack.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
+ pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
+ rcsfile.c rcsparse.c lex.rcs.c
CFLAGS+= -I. -I${.CURDIR} -g -pthread -DHAVE_FFLAGS -DNDEBUG
-WARNS?= 6
+WARNS?= 1
# A bit of tweaking is needed to get this Makefile working
# with the bsd.prog.mk of all the *BSD OSes...
Modified: projects/csup_cvsmode/contrib/csup/config.c
==============================================================================
--- projects/csup_cvsmode/contrib/csup/config.c Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/config.c Sun Oct 19 09:08:59 2008 (r184054)
@@ -444,10 +444,10 @@ coll_add(char *name)
"\"%s\"\n", cur_coll->co_name);
exit(1);
}
- if (!(cur_coll->co_options & CO_CHECKOUTMODE)) {
+/* if (!(cur_coll->co_options & CO_CHECKOUTMODE)) {
lprintf(-1, "Client only supports checkout mode\n");
exit(1);
- }
+ }*/
if (!STAILQ_EMPTY(&colls)) {
coll = STAILQ_LAST(&colls, coll, co_next);
if (strcmp(coll->co_host, cur_coll->co_host) != 0) {
Modified: projects/csup_cvsmode/contrib/csup/detailer.c
==============================================================================
--- projects/csup_cvsmode/contrib/csup/detailer.c Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/detailer.c Sun Oct 19 09:08:59 2008 (r184054)
@@ -30,6 +30,11 @@
#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"
@@ -37,6 +42,7 @@
#include "misc.h"
#include "mux.h"
#include "proto.h"
+#include "rcsfile.h"
#include "status.h"
#include "stream.h"
@@ -56,8 +62,15 @@ struct detailer {
static int detailer_batch(struct detailer *);
static int detailer_coll(struct detailer *, struct coll *,
struct status *);
-static int detailer_dofile(struct detailer *, struct coll *,
+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_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)
@@ -93,6 +106,7 @@ detailer(void *arg)
xasprintf(&args->errmsg, "Detailer failed: "
"Network read failure: %s", strerror(errno));
}
+ lprintf(-1, "Error is '%s'\n", args->errmsg);
args->status = STATUS_TRANSIENTFAILURE;
break;
case DETAILER_ERR_WRITE:
@@ -131,8 +145,9 @@ detailer_batch(struct detailer *d)
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)
+ 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)
@@ -147,8 +162,9 @@ detailer_batch(struct detailer *d)
return (DETAILER_ERR_MSG);
error = detailer_coll(d, coll, st);
status_close(st, NULL);
- if (error)
+ if (error) {
return (error);
+ }
if (coll->co_options & CO_COMPRESS) {
stream_filter_stop(rd);
stream_filter_stop(wr);
@@ -156,10 +172,12 @@ detailer_batch(struct detailer *d)
stream_flush(wr);
}
line = stream_getln(rd, NULL);
- if (line == NULL)
+ if (line == NULL) {
return (DETAILER_ERR_READ);
- if (strcmp(line, ".") != 0)
+ }
+ if (strcmp(line, ".") != 0) {
return (DETAILER_ERR_PROTO);
+ }
error = proto_printf(wr, ".\n");
if (error)
return (DETAILER_ERR_WRITE);
@@ -186,8 +204,13 @@ detailer_batch(struct detailer *d)
}
if (fixup->f_coll != coll)
break;
- error = proto_printf(wr, "Y %s %s %s\n", fixup->f_name,
- coll->co_tag, coll->co_date);
+ 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;
@@ -208,35 +231,107 @@ detailer_batch(struct detailer *d)
static int
detailer_coll(struct detailer *d, struct coll *coll, struct status *st)
{
+ struct fattr *rcsattr;
struct stream *rd, *wr;
- char *cmd, *file, *line, *msg;
- int error;
+ char *attr, *cmd, *file, *line, *msg, *target, *path;
+ int error, attic;
rd = d->rd;
wr = d->wr;
+ attic = 0;
line = stream_getln(rd, NULL);
- if (line == NULL)
+ if (line == NULL) {
return (DETAILER_ERR_READ);
+ }
while (strcmp(line, ".") != 0) {
cmd = proto_get_ascii(&line);
- if (cmd == NULL || strlen(cmd) != 1)
+ 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, "D %s\n", file);
+ 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);
- error = detailer_dofile(d, coll, st, file);
+ 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;
@@ -248,6 +343,7 @@ detailer_coll(struct detailer *d, struct
lprintf(-1, "Server warning: %s\n", msg);
break;
default:
+ lprintf(-1, "Line: %s, cmd %s\n", line, cmd);
return (DETAILER_ERR_PROTO);
}
stream_flush(wr);
@@ -261,8 +357,81 @@ detailer_coll(struct detailer *d, struct
return (0);
}
+/*
+ * Tell the server to update a regular file.
+ */
static int
-detailer_dofile(struct detailer *d, struct coll *coll, struct status *st,
+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 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);
+ free(path);
+ if (rf == NULL) {
+ lprintf(-1, "Error parsing, resend file.\n");
+ 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)
{
char md5[MD5_DIGEST_SIZE];
@@ -274,8 +443,9 @@ detailer_dofile(struct detailer *d, stru
wr = d->wr;
path = checkoutpath(coll->co_prefix, file);
- if (path == NULL)
+ 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
@@ -337,3 +507,78 @@ detailer_dofile(struct detailer *d, stru
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 {
+ detailer_dofile_regular(d, name, path);
+ }
+ } else {
+ error = proto_printf(d->wr, "N %s\n", name);
+ if (error)
+ return (DETAILER_ERR_WRITE);
+ }
+ return (0);
+}
Modified: projects/csup_cvsmode/contrib/csup/diff.c
==============================================================================
--- projects/csup_cvsmode/contrib/csup/diff.c Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/diff.c Sun Oct 19 09:08:59 2008 (r184054)
@@ -26,25 +26,33 @@
* $FreeBSD$
*/
+#include <sys/limits.h>
+
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <stdio.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;
@@ -55,15 +63,23 @@ struct editcmd {
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 int diff_free(struct diffstart *);
int
diff_apply(struct stream *rd, struct stream *orig, struct stream *dest,
- struct keyword *keyword, struct diffinfo *di)
+ struct keyword *keyword, struct diffinfo *di, int comode)
{
struct editcmd ec;
lineno_t i;
@@ -104,7 +120,7 @@ diff_apply(struct stream *rd, struct str
line = stream_getln(rd, &size);
if (line == NULL)
return (-1);
- if (line[0] == '.') {
+ if (comode && line[0] == '.') {
line++;
size--;
}
@@ -143,6 +159,213 @@ diff_apply(struct stream *rd, struct str
return (0);
}
+static int
+diff_write_reverse(struct stream *dest, struct diffstart *ds)
+{
+ long firstoutputlinedeleted, endline, startline, editline, num_deleted,
+ num_added;
+ int num;
+ struct editcmd *ec, *nextec;
+
+ 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. */
+ /* XXX: check if this gets too slow. */
+ 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 int
+diff_free(struct diffstart *ds)
+{
+ struct editcmd *ec;
+ int freecount = 0;
+
+ while(!LIST_EMPTY(&ds->dhead)) {
+ ec = LIST_FIRST(&ds->dhead);
+ LIST_REMOVE(ec, next);
+ free(ec);
+ freecount++;
+ }
+ return freecount;
+}
+
+/*
+ * 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;
+ int malloccount = 0, freecount = 0;
+
+ 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);
+ /*fprintf(stderr, "Diff line '%s'\n", line);*/
+ if (error)
+ break;
+ if (ec.cmd == EC_ADD) {
+ addec = xmalloc(sizeof(struct editcmd));
+ malloccount++;
+ *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);
+ /*fprintf(stderr, "Diff line '%s'\n", line);*/
+ 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);
+ freecount++;
+ 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));
+ malloccount++;
+ *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) {
+ /*fprintf(stderr, "Diff line '%s'\n", line);*/
+ line = stream_getln(rd, NULL);
+ }
+ /*fprintf(stderr, "Done with diff\n");*/
+ if (delec != NULL) {
+ diff_insert_edit(&ds, delec);
+ delec = NULL;
+ }
+
+ addec = xmalloc(sizeof(struct editcmd));
+ malloccount++;
+ /* 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;
+
+ /*fprintf(stderr, "Done with last diff\n");*/
+ diff_write_reverse(dest, &ds);
+ freecount += diff_free(&ds);
+ /*fprintf(stderr, "Diff did a total of %d mallocs\n", malloccount);
+ fprintf(stderr, "Diff did a total of %d frees\n", freecount);*/
+ stream_flush(dest);
+ return (0);
+}
+
/* Get an editing command from the diff. */
static int
diff_geteditcmd(struct editcmd *ec, char *line)
@@ -194,6 +417,22 @@ diff_copyln(struct editcmd *ec, lineno_t
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)
+{
+ char *line;
+ size_t size;
+
+ 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)
Modified: projects/csup_cvsmode/contrib/csup/diff.h
==============================================================================
--- projects/csup_cvsmode/contrib/csup/diff.h Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/diff.h Sun Oct 19 09:08:59 2008 (r184054)
@@ -45,6 +45,8 @@ struct diffinfo {
};
int diff_apply(struct stream *, struct stream *, struct stream *,
- struct keyword *, struct diffinfo *);
+ struct keyword *, struct diffinfo *, int);
+int diff_reverse(struct stream *, struct stream *,
+ struct stream *, struct keyword *, struct diffinfo *);
#endif /* !_DIFF_H_ */
Modified: projects/csup_cvsmode/contrib/csup/fattr.c
==============================================================================
--- projects/csup_cvsmode/contrib/csup/fattr.c Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/fattr.c Sun Oct 19 09:08:59 2008 (r184054)
@@ -44,7 +44,7 @@
/*
* 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 à la chflags() and fattr_posix.h for
+ * support the extended file flags ? la chflags() and fattr_posix.h for
* bare POSIX systems that don't.
*/
#ifdef HAVE_FFLAGS
@@ -449,7 +449,7 @@ fattr_encode(const struct fattr *fa, fat
piece++;
}
if (mask & FA_DEV) {
- vallen = snprintf(piece->val, sizeof(piece->val), "%lld",
+ 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;
@@ -534,6 +534,13 @@ fattr_getlinkcount(const struct fattr *f
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
@@ -732,23 +739,32 @@ fattr_makenode(const struct fattr *fa, c
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. */
- assert(fa->type == FT_DIRECTORY);
if (fa->mask & FA_MODE)
mode = fa->mode & modemask;
else
mode = 0700;
- error = mkdir(path, mode);
+
+ 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)
+int fattr_delete(const char *path)
{
struct fattr *fa;
int error;
@@ -830,8 +846,9 @@ fattr_install(struct fattr *fa, const ch
error = rmdir(topath);
else
error = unlink(topath);
- if (error)
+ if (error) {
goto bad;
+ }
}
}
@@ -842,8 +859,9 @@ fattr_install(struct fattr *fa, const ch
tv[1].tv_sec = fa->modtime; /* Modification time. */
tv[1].tv_usec = 0;
error = utimes(frompath, tv);
- if (error)
+ if (error) {
goto bad;
+ }
}
if (mask & FA_OWNER || mask & FA_GROUP) {
uid = -1;
@@ -853,8 +871,9 @@ fattr_install(struct fattr *fa, const ch
if (mask & FA_GROUP)
gid = fa->gid;
error = chown(frompath, uid, gid);
- if (error)
+ if (error) {
goto bad;
+ }
}
if (mask & FA_MODE) {
newmode = fa->mode & modemask;
@@ -936,3 +955,12 @@ fattr_equal(const struct fattr *fa1, con
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);
+}
Modified: projects/csup_cvsmode/contrib/csup/fattr.h
==============================================================================
--- projects/csup_cvsmode/contrib/csup/fattr.h Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/fattr.h Sun Oct 19 09:08:59 2008 (r184054)
@@ -101,6 +101,7 @@ 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 *);
@@ -111,5 +112,7 @@ int fattr_install(struct fattr *, cons
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_ */
Modified: projects/csup_cvsmode/contrib/csup/keyword.c
==============================================================================
--- projects/csup_cvsmode/contrib/csup/keyword.c Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/keyword.c Sun Oct 19 09:08:59 2008 (r184054)
@@ -152,6 +152,29 @@ keyword_decode_expand(const char *expand
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)
{
Modified: projects/csup_cvsmode/contrib/csup/keyword.h
==============================================================================
--- projects/csup_cvsmode/contrib/csup/keyword.h Sun Oct 19 08:43:16 2008 (r184053)
+++ projects/csup_cvsmode/contrib/csup/keyword.h Sun Oct 19 09:08:59 2008 (r184054)
@@ -42,6 +42,7 @@ 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 *);
Added: projects/csup_cvsmode/contrib/csup/lex.rcs.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/csup_cvsmode/contrib/csup/lex.rcs.c Sun Oct 19 09:08:59 2008 (r184054)
@@ -0,0 +1,2094 @@
+
+#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)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list