bool magnet_set_exact_topic(struct magnet_resource *res, const char *topic) { struct sha1 sha1; struct tth tth; if (urn_get_bitprint(topic, strlen(topic), &sha1, &tth)) { if (!res->sha1) { magnet_set_sha1(res, &sha1); } if (!res->tth) { magnet_set_tth(res, &tth); } return TRUE; } else if (urn_get_sha1(topic, &sha1)) { if (!res->sha1) { magnet_set_sha1(res, &sha1); } return TRUE; } else if (urn_get_tth(topic, strlen(topic), &tth)) { if (!res->tth) { magnet_set_tth(res, &tth); } return TRUE; } else { return FALSE; } }
static struct magnet_source * magnet_parse_path(const char *path, const char **error_str) { static const struct magnet_source zero_ms; struct magnet_source ms; const char *p, *endptr; clear_error_str(&error_str); g_return_val_if_fail(path, NULL); ms = zero_ms; p = path; if ('/' != *p) { *error_str = "Expected path starting with '/'"; /* Skip this parameter */ return NULL; } g_assert(*p == '/'); endptr = is_strprefix(p, "/uri-res/N2R?"); if (endptr) { struct sha1 sha1; p = endptr; if (!urn_get_sha1(p, &sha1)) { *error_str = "Bad SHA1 in MAGNET URI"; return NULL; } ms.sha1 = atom_sha1_get(&sha1); } else { ms.path = atom_str_get(p); } return wcopy(&ms, sizeof ms); }
/** * This function is used to read the disk cache into memory. * * It must be passed one line from the cache (ending with '\n'). It * performs all the syntactic processing to extract the fields from * the line and calls add_volatile_cache_entry() to append the record * to the in-memory cache. */ static G_GNUC_COLD void parse_and_append_cache_entry(char *line) { const char *p, *end; /* pointers to scan the line */ int c, error; filesize_t size; time_t mtime; struct sha1 sha1; struct tth tth; bool has_tth; /* Skip comments and blank lines */ if (file_line_is_skipable(line)) return; /* Scan until file size */ p = line; while ((c = *p) != '\0' && c != '\t') { p++; } if (urn_get_bitprint(line, p - line, &sha1, &tth)) { has_tth = TRUE; } else if (urn_get_sha1(line, &sha1)) { has_tth = FALSE; } else { const char *sha1_digest_ascii; has_tth = FALSE; sha1_digest_ascii = line; /* SHA1 digest is the first field. */ if ( *p != '\t' || (p - sha1_digest_ascii) != SHA1_BASE32_SIZE || SHA1_RAW_SIZE != base32_decode(sha1.data, sizeof sha1.data, sha1_digest_ascii, SHA1_BASE32_SIZE) ) { goto failure; } } p++; /* Skip \t */ /* p is now supposed to point to the beginning of the file size */ size = parse_uint64(p, &end, 10, &error); if (error || *end != '\t') { goto failure; } p = ++end; /* * p is now supposed to point to the beginning of the file last * modification time. */ mtime = parse_uint64(p, &end, 10, &error); if (error || *end != '\t') { goto failure; } p = ++end; /* p is now supposed to point to the file name */ if (strchr(p, '\t') != NULL) goto failure; add_volatile_cache_entry(p, size, mtime, &sha1, has_tth ? &tth : NULL, FALSE); return; failure: g_warning("malformed line in SHA1 cache file: %s", line); }