summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/csup/lister.c99
1 files changed, 79 insertions, 20 deletions
diff --git a/contrib/csup/lister.c b/contrib/csup/lister.c
index 65439c1..5597c8e 100644
--- a/contrib/csup/lister.c
+++ b/contrib/csup/lister.c
@@ -64,10 +64,10 @@ static int lister_dofile(struct lister *, struct coll *,
struct statusrec *);
static int lister_dodead(struct lister *, struct coll *,
struct statusrec *);
-#if 0
static int lister_dorcsfile(struct lister *, struct coll *,
- struct statusrec *, int);
-#endif
+ struct statusrec *);
+static int lister_dorcsdead(struct lister *, struct coll *,
+ struct statusrec *);
void *
lister(void *arg)
@@ -150,14 +150,13 @@ lister_coll(struct lister *l, struct coll *coll, struct status *st)
struct statusrec *sr;
struct fattr *fa;
size_t i;
- int depth, error, ret, prunedepth, attic;
+ 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) {
- attic = 0;
switch (sr->sr_type) {
case SR_DIRDOWN:
depth++;
@@ -194,20 +193,24 @@ lister_coll(struct lister *l, struct coll *coll, struct status *st)
goto bad;
}
break;
-#if 0
case SR_FILEDEAD:
- attic = 1;
+ 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,
- attic);
+ error = lister_dorcsfile(l, coll, sr);
if (error)
goto bad;
}
}
break;
-#endif
}
}
if (ret == -1) {
@@ -402,18 +405,15 @@ send:
return (0);
}
-#if 0
-/* Handle a file live or file dead entry found in the status file. */
+/* Handle a rcs file live entry found in the status file. */
static int
-lister_dorcsfile(struct lister *l, struct coll *coll, struct statusrec *sr,
- int attic)
+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;
- char cmd;
size_t len;
int error;
@@ -422,7 +422,7 @@ lister_dorcsfile(struct lister *l, struct coll *coll, struct statusrec *sr,
config = l->config;
wr = l->wr;
if (!coll->co_options & CO_TRUSTSTATUSFILE) {
- path = cvspath(coll->co_prefix, sr->sr_file, attic);
+ path = cvspath(coll->co_prefix, sr->sr_file, 0);
if (path == NULL) {
spath = coll_statuspath(coll);
xasprintf(&l->errmsg, "Error in \"%s\": "
@@ -434,9 +434,11 @@ lister_dorcsfile(struct lister *l, struct coll *coll, struct statusrec *sr,
free(path);
} else
fa = sr->sr_clientattr;
- /* XXX: Perhaps check attic path name here. */
- cmd = attic ? 'F' : 'f';
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)) {
@@ -444,15 +446,18 @@ lister_dorcsfile(struct lister *l, struct coll *coll, struct statusrec *sr,
}
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, "%c %s %F\n", cmd, pathlast(sr->sr_file), fa,
+ 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);
}
-#endif
/* Handle a checkout dead entry found in the status file. */
static int
@@ -508,3 +513,57 @@ lister_dodead(struct lister *l, struct coll *coll, struct statusrec *sr)
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);
+}
OpenPOWER on IntegriCloud