summaryrefslogtreecommitdiffabout
path: root/src/triplet.c
Side-by-side diff
Diffstat (limited to 'src/triplet.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/triplet.c104
1 files changed, 97 insertions, 7 deletions
diff --git a/src/triplet.c b/src/triplet.c
index 79ca8c2..05b7536 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -29,13 +29,13 @@ hash_triplet_hasher (void *data, unsigned long n_buckets)
/* Compare two strings for equality. */
static int
hash_triplet_compare (void const *data1, void const *data2)
{
struct file_triplet const *t1 = data1;
struct file_triplet const *t2 = data2;
- return strcmp (t1->name, t2->name);
+ return t1->spool == t2->spool && strcmp (t1->name, t2->name);
}
/* Reclaim memory storage associated with a table entry */
void
hash_triplet_free (void *data)
{
@@ -95,12 +95,13 @@ register_file (struct file_info *finfo, const struct spool *spool)
grecs_alloc_die ();
}
key.name = grecs_malloc (finfo->root_len + 1);
memcpy (key.name, finfo->name, finfo->root_len);
key.name[finfo->root_len] = 0;
+ key.spool = spool;
ret = grecs_symtab_lookup_or_install (triplet_table, &key, &install);
if (!ret)
grecs_alloc_die ();
free (key.name);
if (install)
@@ -108,12 +109,34 @@ register_file (struct file_info *finfo, const struct spool *spool)
ret->spool = spool;
ret->acc = txtacc_create ();
}
ret->file[finfo->type] = *finfo;
}
+struct file_triplet *
+triplet_lookup (struct spool *spool, const char *name)
+{
+ struct file_triplet key, *ret;
+ struct file_info finfo;
+
+ if (!triplet_table)
+ return NULL;
+
+ parse_file_name (name, &finfo);
+
+ key.name = grecs_malloc (finfo.root_len + 1);
+ memcpy (key.name, finfo.name, finfo.root_len);
+ key.name[finfo.root_len] = 0;
+ key.spool = spool;
+
+ ret = grecs_symtab_lookup_or_install (triplet_table, &key, NULL);
+ file_info_cleanup (&finfo);
+
+ return ret;
+}
+
/* Return true if any part of the triplet TRP was modified more than
TTL seconds ago */
static int
triplet_expired_p (struct file_triplet *trp, time_t ttl)
{
int i;
@@ -144,27 +167,26 @@ enum triplet_state
triplet_incomplete, /* Incomplete triplet: some files are missing */
triplet_bad, /* Bad triplet. Should be removed immediately. */
};
static enum triplet_state
-check_triplet_state (struct file_triplet *trp)
+check_triplet_state (struct file_triplet *trp, int noauth)
{
if (trp->file[file_directive].name)
{
- if (verify_directive_file (trp))
+ if (verify_directive_file (trp, noauth))
return triplet_bad;
if (trp->file[file_dist].name == 0
&& trp->file[file_signature].name == 0)
{
if (directive_get_value (trp, "filename", NULL))
return triplet_directive;
}
- else if (trp->file[file_dist].name
- && trp->file[file_signature].name)
+ else if (trp->file[file_dist].name && trp->file[file_signature].name)
{
if (trp->file[file_dist].sb.st_uid ==
trp->file[file_signature].sb.st_uid
&& trp->file[file_dist].sb.st_uid ==
trp->file[file_directive].sb.st_uid)
return triplet_complete;
@@ -209,13 +231,13 @@ triplet_processor (void *data, void *proc_data)
logmsg (LOG_DEBUG, "FILE %s, DIST=%s, SIG=%s, DIRECTIVE=%s",
trp->name,
SP (trp->file[file_dist].name),
SP (trp->file[file_signature].name),
SP (trp->file[file_directive].name));
- switch (check_triplet_state (trp))
+ switch (check_triplet_state (trp, 0))
{
case triplet_directive:
case triplet_complete:
if (debug_level)
logmsg (LOG_DEBUG, _("processing triplet `%s'"), trp->name);
if (process_directives (trp))
@@ -243,17 +265,19 @@ triplet_processor (void *data, void *proc_data)
return 0;
}
/* Process all triplets from the table according to the SPOOL */
void
-enumerate_triplets (const struct spool *spool)
+spool_commit_triplets (struct spool *spool)
{
if (debug_level)
logmsg (LOG_DEBUG, _("processing spool %s (%s)"),
spool->tag, mu_url_to_string (spool->dest_url));
+ if (spool_open_dictionaries (spool))
+ return;
if (triplet_table)
{
grecs_symtab_enumerate (triplet_table, triplet_processor, NULL);
grecs_symtab_clear (triplet_table);
}
}
@@ -261,12 +285,78 @@ enumerate_triplets (const struct spool *spool)
size_t
count_collected_triplets ()
{
return triplet_table ? grecs_symtab_count_entries (triplet_table) : 0;
}
+static int
+triplet_counter (void *data, void *proc_data)
+{
+ struct file_triplet *trp = data;
+ size_t *cp = proc_data;
+
+ if (debug_level)
+ logmsg (LOG_DEBUG, "FILE %s, DIST=%s, SIG=%s, DIRECTIVE=%s",
+ trp->name,
+ SP (trp->file[file_dist].name),
+ SP (trp->file[file_signature].name),
+ SP (trp->file[file_directive].name));
+
+ switch (check_triplet_state (trp, 1))
+ {
+ case triplet_directive:
+ case triplet_complete:
+ case triplet_bad:
+ ++*cp;
+ case triplet_incomplete:
+ return 0;
+ }
+
+ if (triplet_expired_p (trp, trp->spool->file_sweep_time))
+ ++*cp;//FIXME
+
+ return 0;
+}
+
+size_t
+count_processable_triplets ()
+{
+ size_t count = 0;
+ if (triplet_table)
+ grecs_symtab_enumerate (triplet_table, triplet_counter, &count);
+ return count;
+}
+
+void
+triplet_remove_file (struct spool *spool, const char *name)
+{
+ struct file_triplet *tp = triplet_lookup (spool, name);
+ int i, n = 0;
+
+ if (!tp)
+ return;
+
+ for (i = 0; i < FILE_TYPE_COUNT; i++)
+ {
+ if (!tp->file[i].name)
+ /* nothing */;
+ else if (strcmp (tp->file[i].name, name) == 0)
+ file_info_cleanup (&tp->file[i]);
+ else
+ n++;
+ }
+
+ if (!n)
+ {
+ if (debug_level > 0)
+ logmsg (LOG_DEBUG, "deleting empty triplet (%s/%s)",
+ spool->source_dir, name);
+ grecs_symtab_remove (triplet_table, tp);
+ }
+}
+
static const char *
expand_project_base (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->project;

Return to:

Send suggestions and report system problems to the System administrator.