XBPS Library API  0.19
The X Binary Package System
package_configure.c
1 /*-
2  * Copyright (c) 2009-2012 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 <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 
31 #include "xbps_api_impl.h"
32 
33 /**
34  * @file lib/package_configure.c
35  * @brief Package configuration routines
36  * @defgroup configure Package configuration functions
37  *
38  * Configure a package or all packages. Only packages in XBPS_PKG_STATE_UNPACKED
39  * state will be processed (unless overriden). Package configuration steps:
40  * - Its <b>post-install</b> target in the INSTALL script will be executed.
41  * - Its state will be changed to XBPS_PKG_STATE_INSTALLED if previous step
42  * ran successful.
43  *
44  * @note
45  * If the \a XBPS_FLAG_FORCE_CONFIGURE is set through xbps_init() in the flags
46  * member, the package (or packages) will be reconfigured even if its
47  * state is XBPS_PKG_STATE_INSTALLED.
48  */
49 int
50 xbps_configure_packages(struct xbps_handle *xhp, bool flush)
51 {
52  prop_object_t obj;
53  prop_object_iterator_t iter;
54  const char *pkgname;
55  int rv;
56 
57  if ((rv = xbps_pkgdb_init(xhp)) != 0)
58  return rv;
59 
60  iter = prop_array_iterator(xhp->pkgdb);
61  assert(iter);
62  while ((obj = prop_object_iterator_next(iter))) {
63  prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
64  rv = xbps_configure_pkg(xhp, pkgname, true, false, false);
65  if (rv != 0) {
66  xbps_dbg_printf(xhp, "%s: failed to configure %s: %s\n",
67  __func__, pkgname, strerror(rv));
68  break;
69  }
70  }
71  prop_object_iterator_release(iter);
72 
73  if (flush)
74  rv = xbps_pkgdb_update(xhp, true);
75 
76  return rv;
77 }
78 
79 int
81  const char *pkgname,
82  bool check_state,
83  bool update,
84  bool flush)
85 {
86  prop_dictionary_t pkgd, pkgmetad;
87  const char *version, *pkgver;
88  char *plist;
89  int rv = 0;
90  pkg_state_t state = 0;
91 
92  assert(pkgname != NULL);
93 
94  pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
95  if (pkgd == NULL)
96  return ENOENT;
97 
98  prop_dictionary_get_cstring_nocopy(pkgd, "version", &version);
99  prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
100 
101  rv = xbps_pkg_state_dictionary(pkgd, &state);
102  xbps_dbg_printf(xhp, "%s: state %d rv %d\n", pkgname, state, rv);
103  if (rv != 0) {
104  xbps_dbg_printf(xhp, "%s: [configure] failed to get "
105  "pkg state: %s\n", pkgname, strerror(rv));
106  prop_object_release(pkgd);
107  return EINVAL;
108  }
109 
110  if (check_state) {
111  if (state == XBPS_PKG_STATE_INSTALLED) {
112  if ((xhp->flags & XBPS_FLAG_FORCE_CONFIGURE) == 0)
113  return 0;
114  } else if (state != XBPS_PKG_STATE_UNPACKED)
115  return EINVAL;
116  }
117 
118  xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE, 0, pkgname, version, NULL);
119 
120  /* internalize pkg dictionary from metadir */
121  plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
122  pkgmetad = prop_dictionary_internalize_from_file(plist);
123  free(plist);
124  assert(pkgmetad);
125 
126  rv = xbps_pkg_exec_script(xhp, pkgmetad, "install-script", "post", update);
127  if (rv != 0) {
128  xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL,
129  errno, pkgname, version,
130  "%s: [configure] INSTALL script failed to execute "
131  "the post ACTION: %s", pkgver, strerror(rv));
132  return rv;
133  }
134  if (state == XBPS_PKG_STATE_INSTALLED) {
135  prop_object_release(pkgmetad);
136  return rv;
137  }
138 
139  rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_INSTALLED);
140  if (rv != 0) {
141  xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv,
142  pkgname, version,
143  "%s: [configure] failed to set state to installed: %s",
144  pkgver, strerror(rv));
145  }
146  if (flush) {
147  if ((rv = xbps_pkgdb_update(xhp, true)) != 0) {
148  xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv,
149  pkgname, version,
150  "%s: [configure] failed to update pkgdb: %s\n",
151  pkgver, strerror(rv));
152  }
153  }
154  prop_object_release(pkgmetad);
155 
156  return rv;
157 }