aboutsummaryrefslogtreecommitdiff
path: root/src/directive.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-04-27 09:28:38 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-04-27 09:28:38 +0300
commite19cf8e1303700b5b2e4f3e525285f63a3c7b51f (patch)
tree3d104c781bdc181fac49d38402e10f0bca9f1610 /src/directive.c
parent563d555bc14424066973a4dbc92123d308344a49 (diff)
downloadwydawca-e19cf8e1303700b5b2e4f3e525285f63a3c7b51f.tar.gz
wydawca-e19cf8e1303700b5b2e4f3e525285f63a3c7b51f.tar.bz2
Minor improvement
* src/directive.c (directive_parse): Optimize two sequential directives referring for filename and filename.sig
Diffstat (limited to 'src/directive.c')
-rw-r--r--src/directive.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/directive.c b/src/directive.c
index f6c9a83..8e7afeb 100644
--- a/src/directive.c
+++ b/src/directive.c
@@ -18,6 +18,74 @@
/* Directive file support */
+#define ISSPACE(c) ((c)==' '||(c)=='\t')
+
+/*
+ * An auxiliary function to compare two directive lines.
+ * If A and B have the same directive name portion, analyze the directive
+ * argument (or arguments, in case of "symlink". If each argument of B
+ * is the corresponding argument of A plus the ".sig" suffix, return 1.
+ * If the relation is the reverse (arg(A) = arg(B) + ".sig"), return -1.
+ * Otherwise, return 0.
+ */
+static int
+str_dirname_sig(char const *a, char const *b)
+{
+ char const *p = a;
+ int arg2;
+
+ while (1) {
+ if (*a != *b)
+ return 0;
+ if (*a == 0 || *a == ':')
+ break;
+ a++;
+ b++;
+ }
+
+ arg2 = (a-p+1 == sizeof("symlink") && memcmp(p, "symlink", a-p) == 0);
+
+ do {
+ if (!*++a)
+ return 0;
+ } while (ISSPACE(*a));
+
+ do {
+ if (!*++b)
+ return 0;
+ } while (ISSPACE(*b));
+
+ while (*a && *b) {
+ if (*a != *b) {
+ if (arg2) {
+ if (ISSPACE(*a) && strncmp(b, ".sig", 4) == 0) {
+ arg2 = 1;
+ b += 4;
+ } else if (ISSPACE(*b) && strncmp(a, ".sig", 4) == 0) {
+ arg2 = -1;
+ a += 4;
+ } else
+ return 0;
+ while (*a && ISSPACE(*a))
+ a++;
+ while (*b && ISSPACE(*b))
+ b++;
+ } else
+ return 0;
+ }
+ a++;
+ b++;
+ }
+
+ if (*a == 0 && strcmp(b, ".sig") == 0)
+ return (arg2 == 0 || arg2 == 1) ? 1 : 0;
+
+ if (*b == 0 && strcmp(a, ".sig") == 0)
+ return (arg2 == 0 || arg2 == -1) ? -1 : 0;
+
+ return 0;
+}
+
/* Parse directives from TRP->blurb. Fill TRP->directive */
int
directive_parse(struct wy_triplet *trp)
@@ -49,6 +117,29 @@ directive_parse(struct wy_triplet *trp)
trp->directive = NULL;
return 1;
}
+ if (j > 1) {
+ /*
+ * The gnupload script (as of version 2018-05-19.18) when given the
+ * --symlink-regex option generates two symlink directives in
+ * sequence: the first one for the filename, and second one
+ * for filename.sig. This contradicts The Automated FTP Uploads
+ * specification, which says that:
+ *
+ * "The .sig file should not be explicitly mentioned in a
+ * directive. When you specify a directive to operate on
+ * a file, its corresponding .sig file will be handled
+ * automatically."
+ *
+ * The following optimizes this case.
+ */
+ switch (str_dirname_sig(trp->directive[j-1], trp->directive[j])) {
+ case 1:
+ continue;
+ case -1:
+ trp->directive[j-1] = trp->directive[j];
+ continue;
+ }
+ }
j++;
if (!p)
break;

Return to:

Send suggestions and report system problems to the System administrator.