XBPS Library API 20240111
The X Binary Package System
package_script.c
1/*-
2 * Copyright (c) 2012-2015 Juan Romero Pardines.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/stat.h>
27
28#include <errno.h>
29#include <stdbool.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35#include "xbps_api_impl.h"
36
37
38int
40 const void *blob,
41 const size_t blobsiz,
42 const char *pkgver,
43 const char *action,
44 bool update)
45{
46 int i;
47 ssize_t ret;
48 const char *tmpdir, *version;
49 const char *shells[] = {
50 "/bin/sh",
51 "/bin/dash",
52 "/bin/bash",
53 NULL
54 };
55 char pkgname[XBPS_NAME_SIZE], *fpath;
56 int fd, rv;
57
58 assert(blob);
59 assert(pkgver);
60 assert(action);
61
62 if (xhp->target_arch) {
63 xbps_dbg_printf("%s: not executing %s "
64 "install/remove action.\n", pkgver, action);
65 return 0;
66 }
67
68 if (strcmp(xhp->rootdir, "/") == 0) {
69 tmpdir = getenv("TMPDIR");
70 if (tmpdir == NULL)
71 tmpdir = P_tmpdir;
72
73 fpath = xbps_xasprintf("%s/.xbps-script-XXXXXX", tmpdir);
74 } else {
75 fpath = strdup(".xbps-script-XXXXXX");
76 }
77
78 /* change cwd to rootdir to exec the script */
79 if (chdir(xhp->rootdir) == -1) {
80 rv = errno;
81 goto out;
82 }
83
84 /* Create temp file to run script */
85 if ((fd = mkstemp(fpath)) == -1) {
86 rv = errno;
87 xbps_dbg_printf("%s: mkstemp %s\n",
88 __func__, strerror(errno));
89 goto out;
90 }
91 /* write blob to our temp fd */
92 ret = write(fd, blob, blobsiz);
93 if (ret == -1) {
94 rv = errno;
95 xbps_dbg_printf("%s: write %s\n",
96 __func__, strerror(errno));
97 close(fd);
98 goto out;
99 }
100 fchmod(fd, 0750);
101#ifdef HAVE_FDATASYNC
102 fdatasync(fd);
103#else
104 fsync(fd);
105#endif
106 close(fd);
107
108 /* exec script */
109 if (!xbps_pkg_name(pkgname, sizeof(pkgname), pkgver)) {
110 abort();
111 }
112 version = xbps_pkg_version(pkgver);
113 assert(version);
114
115 // find a shell that can be used to execute the script.
116 for (i = 0; shells[i] != NULL; i++) {
117 if (access(shells[i], X_OK) == 0) {
118 break;
119 }
120 }
121 if (shells[i] != NULL) {
122 rv = xbps_file_exec(xhp, shells[i], fpath, action, pkgname, version,
123 update ? "yes" : "no",
124 "no", xhp->native_arch, NULL);
125 } else if (access("/bin/busybox", X_OK) == 0) {
126 rv = xbps_file_exec(xhp, "/bin/busybox", "sh", fpath, action, pkgname, version,
127 update ? "yes" : "no",
128 "no", xhp->native_arch, NULL);
129 } else if (access("/bin/busybox.static", X_OK) == 0) {
130 rv = xbps_file_exec(xhp, "/bin/busybox.static", "sh", fpath, action, pkgname, version,
131 update ? "yes" : "no",
132 "no", xhp->native_arch, NULL);
133 } else {
134 rv = -1;
135 }
136
137out:
138 remove(fpath);
139 free(fpath);
140 return rv;
141}
142
143int
145 xbps_dictionary_t d,
146 const char *script,
147 const char *action,
148 bool update)
149{
150 xbps_data_t data;
151 const void *buf;
152 size_t buflen;
153 const char *pkgver = NULL;
154 int rv;
155
156 assert(xhp);
157 assert(d);
158 assert(script);
159 assert(action);
160
161 data = xbps_dictionary_get(d, script);
162 if (data == NULL)
163 return 0;
164
165 xbps_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
166
167 buf = xbps_data_data_nocopy(data);
168 buflen = xbps_data_size(data);
169 rv = xbps_pkg_exec_buffer(xhp, buf, buflen, pkgver, action, update);
170
171 return rv;
172}
const char * target_arch
Definition xbps.h:631
char rootdir[XBPS_MAXPATH]
Definition xbps.h:650
char native_arch[64]
Definition xbps.h:671
Generic XBPS structure handler for initialization.
Definition xbps.h:550
int xbps_pkg_exec_buffer(struct xbps_handle *xhp, const void *blob, const size_t blobsiz, const char *pkgver, const char *action, bool update)
int xbps_pkg_exec_script(struct xbps_handle *xhp, xbps_dictionary_t d, const char *script, const char *action, bool update)
char * xbps_xasprintf(const char *fmt,...) __attribute__((format(printf
bool xbps_pkg_name(char *dst, size_t len, const char *pkg)
Definition util.c:253
const char * xbps_pkg_version(const char *pkg)
Definition util.c:124