FILE * curlfopen(struct repoinfo *cinfo, const char *file, int uncompress, const unsigned char *chksum, Id chksumtype, int markincomplete) { FILE *fp; pid_t pid; int fd; int status; char url[4096]; const char *baseurl = cinfo->baseurl; if (!baseurl) { if (!cinfo->metalink && !cinfo->mirrorlist) return 0; if (file != cinfo->metalink && file != cinfo->mirrorlist) { unsigned char mlchksum[32]; Id mlchksumtype = 0; fp = curlfopen(cinfo, cinfo->metalink ? cinfo->metalink : cinfo->mirrorlist, 0, 0, 0, 0); if (!fp) return 0; if (cinfo->metalink) cinfo->baseurl = findmetalinkurl(fp, mlchksum, &mlchksumtype); else cinfo->baseurl = findmirrorlisturl(fp); fclose(fp); if (!cinfo->baseurl) return 0; #if defined(FEDORA) || defined(MAGEIA) if (strchr(cinfo->baseurl, '$')) { char *b = yum_substitute(cinfo->repo->pool, cinfo->baseurl); free(cinfo->baseurl); cinfo->baseurl = strdup(b); } #endif if (!chksumtype && mlchksumtype && !strcmp(file, "repodata/repomd.xml")) { chksumtype = mlchksumtype; chksum = mlchksum; } return curlfopen(cinfo, file, uncompress, chksum, chksumtype, markincomplete); } snprintf(url, sizeof(url), "%s", file); } else { const char *path = cinfo->path && strcmp(cinfo->path, "/") != 0 ? cinfo->path : ""; int l = strlen(baseurl); int pl = strlen(path); const char *sep = l && baseurl[l - 1] == '/' ? "" : "/"; const char *psep = pl && cinfo->path[pl - 1] == '/' ? "" : "/"; snprintf(url, sizeof(url), "%s%s%s%s%s", baseurl, sep, path, psep, file); } fd = opentmpfile(); // printf("url: %s\n", url); if ((pid = fork()) == (pid_t)-1) { perror("fork"); exit(1); } if (pid == 0) { if (fd != 1) { dup2(fd, 1); close(fd); } execlp("curl", "curl", "-f", "-s", "-L", url, (char *)0); perror("curl"); _exit(0); } status = 0; while (waitpid(pid, &status, 0) != pid) ; if (lseek(fd, 0, SEEK_END) == 0 && (!status || !chksumtype)) { /* empty file */ close(fd); return 0; } lseek(fd, 0, SEEK_SET); if (status) { printf("%s: download error %d\n", file, status >> 8 ? status >> 8 : status); if (markincomplete) cinfo->incomplete = 1; close(fd); return 0; } if (chksumtype && !verify_checksum(fd, file, chksum, chksumtype)) { if (markincomplete) cinfo->incomplete = 1; close(fd); return 0; } fcntl(fd, F_SETFD, FD_CLOEXEC); if (uncompress) { if (solv_xfopen_iscompressed(file) < 0) { printf("%s: unsupported compression\n", file); if (markincomplete) cinfo->incomplete = 1; close(fd); return 0; } fp = solv_xfopen_fd(file, fd, "r"); } else fp = fdopen(fd, "r"); if (!fp) close(fd); return fp; }
Id repo_add_arch_pkg(Repo *repo, const char *fn, int flags) { Pool *pool = repo->pool; Repodata *data; FILE *fp; struct tarhead th; char line[4096]; int ignoreline; Solvable *s; int l, fd; struct stat stb; void *pkgidhandle = 0; data = repo_add_repodata(repo, flags); if ((fd = open(flags & REPO_USE_ROOTDIR ? pool_prepend_rootdir_tmp(pool, fn) : fn, O_RDONLY, 0)) < 0) { pool_error(pool, -1, "%s: %s", fn, strerror(errno)); return 0; } if (fstat(fd, &stb)) { pool_error(pool, -1, "%s: fstat: %s", fn, strerror(errno)); close(fd); return 0; } if (!(fp = solv_xfopen_fd(fn, fd, "r"))) { pool_error(pool, -1, "%s: fdopen failed", fn); close(fd); return 0; } s = 0; inittarhead(&th, fp); while (gettarhead(&th) > 0) { if (th.type != 1 || strcmp(th.path, ".PKGINFO") != 0) { skipentry(&th); continue; } ignoreline = 0; s = pool_id2solvable(pool, repo_add_solvable(repo)); if (flags & ARCH_ADD_WITH_PKGID) pkgidhandle = solv_chksum_create(REPOKEY_TYPE_MD5); while (getsentry(&th, line, sizeof(line))) { l = strlen(line); if (l == 0) continue; if (pkgidhandle) solv_chksum_add(pkgidhandle, line, l); if (line[l - 1] != '\n') { ignoreline = 1; continue; } if (ignoreline) { ignoreline = 0; continue; } line[--l] = 0; if (l == 0 || line[0] == '#') continue; if (!strncmp(line, "pkgname = ", 10)) s->name = pool_str2id(pool, line + 10, 1); else if (!strncmp(line, "pkgver = ", 9)) s->evr = pool_str2id(pool, line + 9, 1); else if (!strncmp(line, "pkgdesc = ", 10)) { repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line + 10); repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line + 10); } else if (!strncmp(line, "url = ", 6)) repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line + 6); else if (!strncmp(line, "builddate = ", 12)) repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line + 12, 0, 10)); else if (!strncmp(line, "packager = ", 11)) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line + 11); else if (!strncmp(line, "size = ", 7)) repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line + 7, 0, 10)); else if (!strncmp(line, "arch = ", 7)) s->arch = pool_str2id(pool, line + 7, 1); else if (!strncmp(line, "license = ", 10)) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_LICENSE, line + 10); else if (!strncmp(line, "replaces = ", 11)) s->obsoletes = adddep(repo, s->obsoletes, line + 11); else if (!strncmp(line, "group = ", 8)) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line + 8); else if (!strncmp(line, "depend = ", 9)) s->requires = adddep(repo, s->requires, line + 9); else if (!strncmp(line, "optdepend = ", 12)) { char *p = strchr(line, ':'); if (p) *p = 0; s->suggests = adddep(repo, s->suggests, line + 12); } else if (!strncmp(line, "conflict = ", 11)) s->conflicts = adddep(repo, s->conflicts, line + 11); else if (!strncmp(line, "provides = ", 11)) s->provides = adddep(repo, s->provides, line + 11); } break; } freetarhead(&th); fclose(fp); if (!s) { pool_error(pool, -1, "%s: not an arch package", fn); if (pkgidhandle) solv_chksum_free(pkgidhandle, 0); return 0; } if (s && !s->name) { pool_error(pool, -1, "%s: package has no name", fn); repo_free_solvable(repo, s - pool->solvables, 1); s = 0; } if (s) { if (!s->arch) s->arch = ARCH_ANY; if (!s->evr) s->evr = ID_EMPTY; s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); if (!(flags & REPO_NO_LOCATION)) repodata_set_location(data, s - pool->solvables, 0, 0, fn); if (S_ISREG(stb.st_mode)) repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size); if (pkgidhandle) { unsigned char pkgid[16]; solv_chksum_free(pkgidhandle, pkgid); repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid); pkgidhandle = 0; } } if (pkgidhandle) solv_chksum_free(pkgidhandle, 0); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return s ? s - pool->solvables : 0; }