static void lr_lrmirror_free(void *data) { LrInternalMirror *mirror = data; lr_free(mirror->url); lr_free(mirror); }
void lr_free_metalinkhash(lr_MetalinkHash metalinkhash) { if (!metalinkhash) return; lr_free(metalinkhash->type); lr_free(metalinkhash->value); lr_free(metalinkhash); }
void lr_free_metalinkurl(lr_MetalinkUrl metalinkurl) { if (!metalinkurl) return; lr_free(metalinkurl->protocol); lr_free(metalinkurl->type); lr_free(metalinkurl->location); lr_free(metalinkurl->url); lr_free(metalinkurl); }
void lr_internalmirrorlist_free(lr_InternalMirrorlist ml) { if (!ml) return; for (int x=0; x < ml->nom; x++) { lr_free(ml->mirrors[x]->url); lr_free(ml->mirrors[x]); } lr_free(ml->mirrors); lr_free(ml); }
void lr_handle_free(LrHandle *handle) { if (!handle) return; if (handle->curl_handle) curl_easy_cleanup(handle->curl_handle); if (handle->mirrorlist_fd != -1) close(handle->mirrorlist_fd); if (handle->metalink_fd != -1) close(handle->metalink_fd); lr_handle_free_list(&handle->urls); lr_free(handle->fastestmirrorcache); lr_free(handle->mirrorlist); lr_free(handle->mirrorlisturl); lr_free(handle->metalinkurl); lr_free(handle->used_mirror); lr_free(handle->destdir); lr_free(handle->useragent); lr_lrmirrorlist_free(handle->internal_mirrorlist); lr_lrmirrorlist_free(handle->urls_mirrors); lr_lrmirrorlist_free(handle->mirrorlist_mirrors); lr_lrmirrorlist_free(handle->metalink_mirrors); lr_lrmirrorlist_free(handle->mirrors); lr_metalink_free(handle->metalink); lr_handle_free_list(&handle->yumdlist); lr_handle_free_list(&handle->yumblist); lr_urlvars_free(handle->urlvars); lr_free(handle); }
void lr_metalink_free(lr_Metalink metalink) { if (!metalink) return; lr_free(metalink->filename); for (int x = 0; x < metalink->noh; x++) lr_free_metalinkhash(metalink->hashes[x]); lr_free(metalink->hashes); for (int x = 0; x < metalink->nou; x++) lr_free_metalinkurl(metalink->urls[x]); lr_free(metalink->urls); lr_free(metalink); }
void lr_handle_free_list(char ***list) { int x; if (!list || *list == NULL) return; x = 0; while ((*list)[x]) { lr_free((*list)[x]); x++; } lr_free(*list); *list = NULL; }
/* * Read a file line by line. * http://rosettacode.org/wiki/Read_a_file_line_by_line */ int main() { struct line_reader lr; FILE *f; size_t len; char *line; f = fopen("foobar.txt", "r"); if (f == NULL) { perror("foobar.txt"); exit(1); } /* * This loop reads each line. * Remember that line is not a C string. * There is no terminating '\0'. */ lr_init(&lr, f); while (line = next_line(&lr, &len)) { /* * Do something with line. */ fputs("LINE: ", stdout); fwrite(line, len, 1, stdout); } if (!feof(f)) { perror("next_line"); exit(1); } lr_free(&lr); return 0; }
END_TEST START_TEST(test_free) { // No SIGSEGV should be raised lr_free(NULL); }
int lr_yum_download_repo(lr_Handle handle, lr_YumRepo repo, lr_YumRepoMd repomd) { int ret = LRE_OK; char *destdir; /* Destination dir */ lr_CurlTargetList targets = lr_curltargetlist_new(); destdir = handle->destdir; DEBUGASSERT(destdir); DEBUGASSERT(strlen(destdir)); for (int x = 0; x < repomd->nor; x++) { int fd; char *path; lr_CurlTarget target; lr_YumRepoMdRecord record = repomd->records[x]; if (!lr_yum_repomd_record_enabled(handle, record->type)) continue; path = lr_pathconcat(destdir, record->location_href, NULL); fd = open(path, O_CREAT|O_TRUNC|O_RDWR, 0660); if (fd < 0) { DPRINTF("%s: Cannot create/open %s (%s)\n", __func__, path, strerror(errno)); lr_free(path); return LRE_IO; } target = lr_curltarget_new(); target->path = lr_strdup(record->location_href); target->fd = fd; target->checksum_type = lr_checksum_type(record->checksum_type); target->checksum = lr_strdup(record->checksum); lr_curltargetlist_append(targets, target); /* Becouse path may already exists in repo (while update) */ lr_yum_repo_update(repo, record->type, path); lr_free(path); } if (lr_curltargetlist_len(targets) > 0) ret = lr_curl_multi_download(handle, targets); lr_curltargetlist_free(targets); return ret; }
void lr_yum_repo_free(lr_YumRepo repo) { if (!repo) return; lr_yum_repo_clear(repo); lr_free(repo); }
static void lr_yum_repomdrecord_free(LrYumRepoMdRecord *rec) { if (!rec) return; g_string_chunk_free(rec->chunk); lr_free(rec); }
void lr_result_free(lr_Result result) { if (!result) return; lr_result_clear(result); lr_free(result); }
void lr_mirrorlist_free(LrMirrorlist *mirrorlist) { if (!mirrorlist) return; g_slist_free_full(mirrorlist->urls, (GDestroyNotify)lr_free); lr_free(mirrorlist); }
END_TEST START_TEST(test_gettmpdir) { char *tmp_dir = lr_gettmpdir(); fail_if(tmp_dir == NULL); fail_if(rmdir(tmp_dir) != 0); lr_free(tmp_dir); }
END_TEST START_TEST(test_malloc0) { long long *num = NULL; num = lr_malloc0(sizeof(long long)); fail_if(num == NULL); fail_if(*num != 0LL); lr_free(num); }
void lr_downloadtarget_free(LrDownloadTarget *target) { if (!target) return; g_slist_free_full(target->checksums, (GDestroyNotify) lr_downloadtargetchecksum_free); g_string_chunk_free(target->chunk); lr_free(target); }
int read_data_1d_cols(FILE *fp, int ncols, int *cols, int *nlines, double **data){ struct line_reader lr; size_t len = 0; char *line = NULL; int j; int nlinefields = 64; double *linefields = (double*)malloc(sizeof(double) * nlinefields); *nlines = 0; lr_init(&lr, fp); int nlines_alloc = 0; while(NULL != (line = next_line(&lr, &len))){ if(line[0] == '#'){ continue; } line[len] = '\0'; if(*nlines >= nlines_alloc){ nlines_alloc *= 2; if(0 == nlines_alloc){ nlines_alloc = 64; } *data = (double*)realloc(*data, sizeof(double) * (ncols) * nlines_alloc); } int nf = 0; char *saveptr = NULL; char *field; field = STRTOK(line, " \t", &saveptr); while(NULL != field){ if(nf >= nlinefields){ nlinefields *= 2; linefields = (double*)realloc(linefields, sizeof(double) * nlinefields); } linefields[nf] = atof(field); ++nf; field = STRTOK(NULL, " \t", &saveptr); } for(j = 0; j < ncols; ++j){ if(cols[j] < nf){ (*data)[j+(*nlines)*ncols] = linefields[cols[j]]; }else{ (*data)[j+(*nlines)*ncols] = 0; } } (*nlines)++; } if(!feof(fp)){ return -1; } lr_free(&lr); free(linefields); return 0; }
END_TEST START_TEST(test_remove_dir) { char *tmp_dir; char *tmp_file; int fd, rc; tmp_dir = lr_gettmpdir(); fail_if(tmp_dir == NULL); tmp_file = lr_pathconcat(tmp_dir, "file_a", NULL); fd = open(tmp_file, O_CREAT|O_TRUNC|O_RDWR, 0660); fail_if(fd < 0); close(fd); rc = lr_remove_dir(tmp_dir); fail_if(rc != 0); fail_if(unlink(tmp_file) == 0); fail_if(rmdir(tmp_dir) == 0); lr_free(tmp_dir); lr_free(tmp_file); }
END_TEST START_TEST(test_pathconcat) { char *path = NULL; path = lr_pathconcat(NULL, NULL); fail_if(path != NULL); path = lr_pathconcat("", NULL); fail_if(path == NULL); fail_if(strcmp(path, "")); lr_free(path); path = NULL; path = lr_pathconcat("/tmp", "foo///", "bar", NULL); fail_if(path == NULL); fail_if(strcmp(path, "/tmp/foo/bar")); lr_free(path); path = NULL; path = lr_pathconcat("foo", "bar/", NULL); fail_if(path == NULL); fail_if(strcmp(path, "foo/bar")); lr_free(path); path = NULL; path = lr_pathconcat("foo", "/bar/", NULL); fail_if(path == NULL); fail_if(strcmp(path, "foo/bar")); lr_free(path); path = NULL; path = lr_pathconcat("foo", "bar", "", NULL); fail_if(path == NULL); fail_if(strcmp(path, "foo/bar/")); lr_free(path); path = NULL; }
gboolean lr_repoutil_yum_parse_repomd(const char *in_path, LrYumRepoMd *repomd, GError **err) { int fd; gboolean ret; struct stat st; char *path; assert(in_path); assert(!err || *err == NULL); if (stat(in_path, &st) != 0) { g_set_error(err, LR_REPOUTIL_YUM_ERROR, LRE_IO, "stat(%s,) error: %s", in_path, strerror(errno)); return FALSE; } if (st.st_mode & S_IFDIR) path = lr_pathconcat(in_path, "repodata/repomd.xml", NULL); else path = g_strdup(in_path); fd = open(path, O_RDONLY); if (fd < 0) { g_set_error(err, LR_REPOUTIL_YUM_ERROR, LRE_IO, "open(%s, O_RDONLY) error: %s", path, strerror(errno)); lr_free(path); return FALSE; } lr_free(path); ret = lr_yum_repomd_parse_file(repomd, fd, NULL, NULL, err); close(fd); return ret; }
static void test_checksum(const char *filename, lr_ChecksumType ch_type, char *expected) { int fd; char *checksum; fail_if((fd = open(filename, O_RDONLY)) < 0); fail_if((checksum = lr_checksum_fd(ch_type, fd)) == NULL); fail_if(strcmp(checksum, expected), "Checksum is %s instead of %s", checksum, expected); lr_free(checksum); close(fd); }
void lr_yum_repo_free(LrYumRepo *repo) { if (!repo) return; for (GSList *elem = repo->paths; elem; elem = g_slist_next(elem)) { LrYumRepoPath *yumrepopath = elem->data; assert(yumrepopath); lr_free(yumrepopath->type); lr_free(yumrepopath->path); lr_free(yumrepopath); } g_slist_free(repo->paths); lr_free(repo->repomd); lr_free(repo->url); lr_free(repo->destdir); lr_free(repo->signature); lr_free(repo->mirrorlist); lr_free(repo->metalink); lr_free(repo); }
void lr_yum_repo_update(lr_YumRepo repo, const char *type, const char *path) { assert(repo); assert(type); assert(path); for (int x = 0; x < repo->nop; x++) if (!strcmp(repo->paths[x]->type, type)) { lr_free(repo->paths[x]->path); repo->paths[x]->path = lr_strdup(path); return; } lr_yum_repo_append(repo, type, path); }
LrInternalMirrorlist * lr_lrmirrorlist_append_metalink(LrInternalMirrorlist *list, LrMetalink *metalink, const char *suffix, LrUrlVars *urlvars) { size_t suffix_len = 0; if (!metalink || !metalink->urls) return list; if (suffix) suffix_len = strlen(suffix); for (GSList *elem = metalink->urls; elem; elem = g_slist_next(elem)) { LrMetalinkUrl *metalinkurl = elem->data; assert(metalinkurl); char *url = metalinkurl->url; if (!url) continue; // No url present size_t url_len = strlen(url); if (!url_len) continue; // No url present char *url_copy = NULL; if (suffix_len) { /* Remove suffix if necessary */ if (url_len >= suffix_len && !strcmp(url+(url_len-suffix_len), suffix)) url_copy = g_strndup(url, url_len-suffix_len); } if (!url_copy) url_copy = g_strdup(url); LrInternalMirror *mirror = lr_lrmirror_new(url_copy, urlvars); mirror->preference = metalinkurl->preference; mirror->protocol = lr_detect_protocol(mirror->url); lr_free(url_copy); list = g_slist_append(list, mirror); //g_debug("%s: Appending URL: %s", __func__, mirror->url); } return list; }
int read_data_1d(FILE *fp, int *ncols, int *nlines, double **data){ struct line_reader lr; size_t len; char *line; int got_first_line = 0; *ncols = 0; *nlines = 0; lr_init(&lr, fp); int nlines_alloc = 0; while(NULL != (line = next_line(&lr, &len))){ if(line[0] == '#'){ continue; } line[len] = '\0'; if(!got_first_line){ char *saveptr; char *field; field = STRTOK(line, " \t", &saveptr); while(NULL != field){ (*ncols)++; field = STRTOK(NULL, " \t", &saveptr); } nlines_alloc = 256; *data = (double*)realloc(*data, sizeof(double) * (*ncols) * nlines_alloc); got_first_line = 1; } if(*nlines >= nlines_alloc){ nlines_alloc *= 2; *data = (double*)realloc(*data, sizeof(double) * (*ncols) * nlines_alloc); } int nf = 0; char *saveptr; char *field; field = STRTOK(line, " \t", &saveptr); while(NULL != field && nf < *ncols){ (*data)[nf+(*nlines)*(*ncols)] = atof(field); ++nf; field = STRTOK(NULL, " \t", &saveptr); } (*nlines)++; } if(!feof(fp)){ return -1; } lr_free(&lr); return 0; }
void lr_yum_repo_clear(lr_YumRepo repo) { if (!repo) return; for (int x = 0; x < repo->nop; x++) { lr_free(repo->paths[x]->type); lr_free(repo->paths[x]->path); lr_free(repo->paths[x]); } lr_free(repo->paths); lr_free(repo->repomd); lr_free(repo->url); lr_free(repo->destdir); lr_free(repo->signature); memset(repo, 0, sizeof(struct _lr_YumRepo)); }
static void lr_yum_repo_update(LrYumRepo *repo, const char *type, const char *path) { assert(repo); assert(type); assert(path); for (GSList *elem = repo->paths; elem; elem = g_slist_next(elem)) { LrYumRepoPath *yumrepopath = elem->data; assert(yumrepopath); if (!strcmp(yumrepopath->type, type)) { lr_free(yumrepopath->path); yumrepopath->path = g_strdup(path); return; } } lr_yum_repo_append(repo, type, path); }
static gboolean lr_yum_download_remote(LrHandle *handle, LrResult *result, GError **err) { int rc; gboolean ret = TRUE; int fd; int create_repodata_dir = 1; char *path_to_repodata; LrYumRepo *repo; LrYumRepoMd *repomd; GError *tmp_err = NULL; assert(!err || *err == NULL); repo = result->yum_repo; repomd = result->yum_repomd; g_debug("%s: Downloading/Copying repo..", __func__); path_to_repodata = lr_pathconcat(handle->destdir, "repodata", NULL); if (handle->update) { /* Check if should create repodata/ subdir */ struct stat buf; if (stat(path_to_repodata, &buf) != -1) if (S_ISDIR(buf.st_mode)) create_repodata_dir = 0; } if (create_repodata_dir) { /* Prepare repodata/ subdir */ rc = mkdir(path_to_repodata, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH); if (rc == -1) { g_debug("%s: Cannot create dir: %s (%s)", __func__, path_to_repodata, g_strerror(errno)); g_set_error(err, LR_YUM_ERROR, LRE_CANNOTCREATEDIR, "Cannot create directory: %s: %s", path_to_repodata, g_strerror(errno)); lr_free(path_to_repodata); return FALSE; } } lr_free(path_to_repodata); if (!handle->update) { char *path; /* Store mirrorlist file(s) */ if (handle->mirrorlist_fd != -1) { char *ml_file_path = lr_pathconcat(handle->destdir, "mirrorlist", NULL); fd = open(ml_file_path, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd < 0) { g_debug("%s: Cannot create: %s", __func__, ml_file_path); g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot create %s: %s", ml_file_path, g_strerror(errno)); lr_free(ml_file_path); return FALSE; } rc = lr_copy_content(handle->mirrorlist_fd, fd); close(fd); if (rc != 0) { g_debug("%s: Cannot copy content of mirrorlist file", __func__); g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot copy content of mirrorlist file %s: %s", ml_file_path, g_strerror(errno)); lr_free(ml_file_path); return FALSE; } repo->mirrorlist = ml_file_path; } if (handle->metalink_fd != -1) { char *ml_file_path = lr_pathconcat(handle->destdir, "metalink.xml", NULL); fd = open(ml_file_path, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd < 0) { g_debug("%s: Cannot create: %s", __func__, ml_file_path); g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot create %s: %s", ml_file_path, g_strerror(errno)); lr_free(ml_file_path); return FALSE; } rc = lr_copy_content(handle->metalink_fd, fd); close(fd); if (rc != 0) { g_debug("%s: Cannot copy content of metalink file", __func__); g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot copy content of metalink file %s: %s", ml_file_path, g_strerror(errno)); lr_free(ml_file_path); return FALSE; } repo->metalink = ml_file_path; } /* Prepare repomd.xml file */ path = lr_pathconcat(handle->destdir, "/repodata/repomd.xml", NULL); fd = open(path, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd == -1) { g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot open %s: %s", path, g_strerror(errno)); lr_free(path); return FALSE; } /* Download repomd.xml */ ret = lr_yum_download_repomd(handle, handle->metalink, fd, err); if (!ret) { close(fd); lr_free(path); return FALSE; } /* Check repomd.xml.asc if available. * Try to download and verify GPG signature (repomd.xml.asc). * Try to download only from the mirror where repomd.xml iself was * downloaded. It is because most of yum repositories are not signed * and try every mirror for signature is non effective. * Every mirror would be tried because mirrorded_download function have * no clue if 404 for repomd.xml.asc means that no signature exists or * it is just error on the mirror and should try the next one. **/ if (handle->checks & LR_CHECK_GPG) { int fd_sig; char *url, *signature; signature = lr_pathconcat(handle->destdir, "repodata/repomd.xml.asc", NULL); fd_sig = open(signature, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd_sig == -1) { g_debug("%s: Cannot open: %s", __func__, signature); g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot open %s: %s", signature, g_strerror(errno)); close(fd); lr_free(path); lr_free(signature); return FALSE; } url = lr_pathconcat(handle->used_mirror, "repodata/repomd.xml.asc", NULL); ret = lr_download_url(handle, url, fd_sig, &tmp_err); lr_free(url); close(fd_sig); if (!ret) { // Signature doesn't exist g_debug("%s: GPG signature doesn't exists: %s", __func__, tmp_err->message); g_set_error(err, LR_YUM_ERROR, LRE_BADGPG, "GPG verification is enabled, but GPG signature " "repomd.xml.asc is not available: %s", tmp_err->message); g_clear_error(&tmp_err); unlink(signature); lr_free(signature); return FALSE; } else { // Signature downloaded repo->signature = g_strdup(signature); ret = lr_gpg_check_signature(signature, path, handle->gnupghomedir, &tmp_err); if (!ret) { g_debug("%s: GPG signature verification failed: %s", __func__, tmp_err->message); g_propagate_prefixed_error(err, tmp_err, "repomd.xml GPG signature verification error: "); close(fd); lr_free(path); lr_free(signature); return FALSE; } g_debug("%s: GPG signature successfully verified", __func__); } } lseek(fd, 0, SEEK_SET); /* Parse repomd */ g_debug("%s: Parsing repomd.xml", __func__); ret = lr_yum_repomd_parse_file(repomd, fd, lr_xml_parser_warning_logger, "Repomd xml parser", &tmp_err); close(fd); if (!ret) { g_debug("%s: Parsing unsuccessful: %s", __func__, tmp_err->message); g_propagate_prefixed_error(err, tmp_err, "repomd.xml parser error: "); lr_free(path); return FALSE; } /* Fill result object */ result->destdir = g_strdup(handle->destdir); repo->destdir = g_strdup(handle->destdir); repo->repomd = path; if (handle->used_mirror) repo->url = g_strdup(handle->used_mirror); else repo->url = g_strdup(handle->urls[0]); g_debug("%s: Repomd revision: %s", repomd->revision, __func__); } /* Download rest of metadata files */ ret = lr_yum_download_repo(handle, repo, repomd, &tmp_err); assert((ret && !tmp_err) || (!ret && tmp_err)); if (!ret) { g_debug("%s: Repository download error: %s", __func__, tmp_err->message); g_propagate_prefixed_error(err, tmp_err, "Yum repo downloading error: "); return FALSE; } return TRUE; }
static gboolean lr_yum_use_local_load_base(LrHandle *handle, LrResult *result, LrYumRepo *repo, LrYumRepoMd *repomd, const gchar *baseurl, GError **err) { gboolean ret; GError *tmp_err = NULL; _cleanup_free_ gchar *path = NULL; _cleanup_free_ gchar *sig = NULL; _cleanup_file_close_ int fd = -1; if (handle->mirrorlist_fd != -1) { // Locate mirrorlist if available. gchar *mrl_fn = lr_pathconcat(baseurl, "mirrorlist", NULL); if (g_file_test(mrl_fn, G_FILE_TEST_IS_REGULAR)) { g_debug("%s: Found local mirrorlist: %s", __func__, mrl_fn); repo->mirrorlist = mrl_fn; } else { repo->mirrorlist = NULL; lr_free(mrl_fn); } } if (handle->metalink_fd != -1) { // Locate metalink.xml if available. gchar *mtl_fn = lr_pathconcat(baseurl, "metalink.xml", NULL); if (g_file_test(mtl_fn, G_FILE_TEST_IS_REGULAR)) { g_debug("%s: Found local metalink: %s", __func__, mtl_fn); repo->metalink = mtl_fn; } else { repo->metalink = NULL; lr_free(mtl_fn); } } // Open repomd.xml path = lr_pathconcat(baseurl, "repodata/repomd.xml", NULL); fd = open(path, O_RDONLY); if (fd < 0) { g_debug("%s: open(%s): %s", __func__, path, g_strerror(errno)); g_set_error(err, LR_YUM_ERROR, LRE_IO, "Cannot open %s: %s", path, g_strerror(errno)); return FALSE; } // Parse repomd.xml g_debug("%s: Parsing repomd.xml", __func__); ret = lr_yum_repomd_parse_file(repomd, fd, lr_xml_parser_warning_logger, "Repomd xml parser", &tmp_err); if (!ret) { g_debug("%s: Parsing unsuccessful: %s", __func__, tmp_err->message); g_propagate_prefixed_error(err, tmp_err, "repomd.xml parser error: "); return FALSE; } // Fill result object result->destdir = g_strdup(baseurl); repo->destdir = g_strdup(baseurl); repo->repomd = g_strdup(path); // Check if signature file exists sig = lr_pathconcat(baseurl, "repodata/repomd.xml.asc", NULL); if (access(sig, F_OK) == 0) repo->signature = g_strdup(sig); // Signature checking if (handle->checks & LR_CHECK_GPG) { if (!repo->signature) { // Signature doesn't exist g_debug("%s: GPG signature doesn't exists", __func__); g_set_error(err, LR_YUM_ERROR, LRE_BADGPG, "GPG verification is enabled, but GPG signature " "repomd.xml.asc is not available"); return FALSE; } ret = lr_gpg_check_signature(repo->signature, repo->repomd, handle->gnupghomedir, &tmp_err); if (!ret) { g_debug("%s: repomd.xml GPG signature verification failed: %s", __func__, tmp_err->message); g_propagate_prefixed_error(err, tmp_err, "repomd.xml GPG signature verification failed: "); return FALSE; } } // Done - repomd is loaded and checked g_debug("%s: Repomd revision: %s", __func__, repomd->revision); return TRUE; }