XBPS Library API 20250531
The X Binary Package System
plist_fetch.c
1/*-
2 * Copyright (c) 2009-2014 Juan Romero Pardines.
3 * Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg (at) NetBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *-
26 * From: $NetBSD: pkg_io.c,v 1.9 2009/08/16 21:10:15 joerg Exp $
27 */
28
29#include <errno.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include <archive.h>
35#include <archive_entry.h>
36
37#include "xbps_api_impl.h"
38#include "fetch.h"
39
40/**
41 * @file lib/plist_fetch.c
42 * @brief Package URL metadata files handling
43 * @defgroup plist_fetch Package URL metadata files handling
44 */
45
46static struct archive *
47open_archive(const char *url)
48{
49 struct archive *ar;
50 int r;
51
52 ar = xbps_archive_read_new();
53 if (!ar) {
54 r = -errno;
55 xbps_error_printf("failed to open archive: %s: %s\n", url, strerror(-r));
56 errno = -r;
57 return NULL;
58 }
59
61 r = xbps_archive_read_open_remote(ar, url);
62 } else {
63 r = xbps_archive_read_open(ar, url);
64 }
65 if (r < 0) {
66 xbps_error_printf("failed to open archive: %s: %s\n", url, strerror(-r));
67 archive_read_free(ar);
68 errno = -r;
69 return NULL;
70 }
71
72 return ar;
73}
74
75char *
76xbps_archive_fetch_file(const char *url, const char *fname)
77{
78 struct archive *a;
79 struct archive_entry *entry;
80 char *buf = NULL;
81
82 assert(url);
83 assert(fname);
84
85 if ((a = open_archive(url)) == NULL)
86 return NULL;
87
88 while ((archive_read_next_header(a, &entry)) == ARCHIVE_OK) {
89 const char *bfile;
90
91 bfile = archive_entry_pathname(entry);
92 if (bfile[0] == '.')
93 bfile++; /* skip first dot */
94
95 if (strcmp(bfile, fname) == 0) {
96 buf = xbps_archive_get_file(a, entry);
97 break;
98 }
99 archive_read_data_skip(a);
100 }
101 archive_read_free(a);
102
103 return buf;
104}
105
106int
107xbps_archive_fetch_file_into_fd(const char *url, const char *fname, int fd)
108{
109 struct archive *a;
110 struct archive_entry *entry;
111 int rv = 0;
112
113 assert(url);
114 assert(fname);
115 assert(fd != -1);
116
117 if ((a = open_archive(url)) == NULL)
118 return EINVAL;
119
120 for (;;) {
121 const char *bfile;
122 rv = archive_read_next_header(a, &entry);
123 if (rv == ARCHIVE_EOF) {
124 rv = 0;
125 break;
126 }
127 if (rv == ARCHIVE_FATAL) {
128 const char *error = archive_error_string(a);
129 if (error != NULL) {
130 xbps_error_printf(
131 "Reading archive entry from: %s: %s\n",
132 url, error);
133 } else {
134 xbps_error_printf(
135 "Reading archive entry from: %s: %s\n",
136 url, strerror(archive_errno(a)));
137 }
138 rv = archive_errno(a);
139 break;
140 }
141 bfile = archive_entry_pathname(entry);
142 if (bfile[0] == '.')
143 bfile++; /* skip first dot */
144
145 if (strcmp(bfile, fname) == 0) {
146 rv = archive_read_data_into_fd(a, fd);
147 if (rv != ARCHIVE_OK)
148 rv = archive_errno(a);
149 break;
150 }
151 archive_read_data_skip(a);
152 }
153 archive_read_free(a);
154
155 return rv;
156}
157
158xbps_dictionary_t
159xbps_archive_fetch_plist(const char *url, const char *plistf)
160{
161 xbps_dictionary_t d;
162 char *buf;
163
164 if ((buf = xbps_archive_fetch_file(url, plistf)) == NULL)
165 return NULL;
166
167 d = xbps_dictionary_internalize(buf);
168 free(buf);
169 return d;
170}
char * xbps_archive_fetch_file(const char *url, const char *fname)
Definition plist_fetch.c:76
xbps_dictionary_t xbps_archive_fetch_plist(const char *url, const char *plistf)
int xbps_archive_fetch_file_into_fd(const char *url, const char *fname, int fd)
bool xbps_repository_is_remote(const char *uri)
Definition util.c:66