XBPS Library API  0.19
The X Binary Package System
package_register.c
1 /*-
2  * Copyright (c) 2008-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 #include <time.h>
31 
32 #include "xbps_api_impl.h"
33 
34 /**
35  * @file lib/package_register.c
36  * @brief Package registration routines
37  * @defgroup pkg_register Package registration functions
38  *
39  * Register and unregister packages into/from the installed
40  * packages database.
41  */
42 
43 int
44 xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
45 {
46  prop_dictionary_t pkgd;
47  prop_array_t provides, rundeps;
48  char outstr[64];
49  time_t t;
50  struct tm *tmp;
51  const char *pkgname, *version, *desc, *pkgver;
52  char *buf, *sha256;
53  int rv = 0;
54  bool autoinst = false;
55 
56  assert(prop_object_type(pkgrd) == PROP_TYPE_DICTIONARY);
57 
58  prop_dictionary_get_cstring_nocopy(pkgrd, "pkgname", &pkgname);
59  prop_dictionary_get_cstring_nocopy(pkgrd, "version", &version);
60  prop_dictionary_get_cstring_nocopy(pkgrd, "short_desc", &desc);
61  prop_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver);
62  prop_dictionary_get_bool(pkgrd, "automatic-install", &autoinst);
63  provides = prop_dictionary_get(pkgrd, "provides");
64  rundeps = prop_dictionary_get(pkgrd, "run_depends");
65 
66  xbps_set_cb_state(xhp, XBPS_STATE_REGISTER, 0, pkgname, version, NULL);
67 
68  assert(pkgname != NULL);
69  assert(version != NULL);
70  assert(desc != NULL);
71  assert(pkgver != NULL);
72 
73  pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
74  if (pkgd == NULL) {
75  rv = ENOENT;
76  goto out;
77  }
78  if (!prop_dictionary_set_cstring_nocopy(pkgd,
79  "version", version)) {
80  xbps_dbg_printf(xhp, "%s: invalid version for %s\n",
81  __func__, pkgname);
82  rv = EINVAL;
83  goto out;
84  }
85  if (!prop_dictionary_set_cstring_nocopy(pkgd,
86  "pkgver", pkgver)) {
87  xbps_dbg_printf(xhp, "%s: invalid pkgver for %s\n",
88  __func__, pkgname);
89  rv = EINVAL;
90  goto out;
91  }
92  if (!prop_dictionary_set_cstring_nocopy(pkgd,
93  "short_desc", desc)) {
94  xbps_dbg_printf(xhp, "%s: invalid short_desc for %s\n",
95  __func__, pkgname);
96  rv = EINVAL;
97  goto out;
98  }
99  prop_dictionary_get_bool(pkgd, "automatic-install", &autoinst);
100  if (xhp->flags & XBPS_FLAG_INSTALL_AUTO)
101  autoinst = true;
102  else if (xhp->flags & XBPS_FLAG_INSTALL_MANUAL)
103  autoinst = false;
104 
105  if (!prop_dictionary_set_bool(pkgd,
106  "automatic-install", autoinst)) {
107  xbps_dbg_printf(xhp, "%s: invalid autoinst for %s\n",
108  __func__, pkgname);
109  rv = EINVAL;
110  goto out;
111  }
112  /*
113  * Set the "install-date" object to know the pkg installation date.
114  */
115  t = time(NULL);
116  if ((tmp = localtime(&t)) == NULL) {
117  xbps_dbg_printf(xhp, "%s: localtime failed: %s\n",
118  pkgname, strerror(errno));
119  rv = EINVAL;
120  goto out;
121  }
122  if (strftime(outstr, sizeof(outstr)-1, "%F %R %Z", tmp) == 0) {
123  xbps_dbg_printf(xhp, "%s: strftime failed: %s\n",
124  pkgname, strerror(errno));
125  rv = EINVAL;
126  goto out;
127  }
128  if (!prop_dictionary_set_cstring(pkgd, "install-date", outstr)) {
129  xbps_dbg_printf(xhp, "%s: install-date set failed!\n", pkgname);
130  rv = EINVAL;
131  goto out;
132  }
133 
134  if (provides && !prop_dictionary_set(pkgd, "provides", provides)) {
135  xbps_dbg_printf(xhp, "%s: failed to set provides for %s\n",
136  __func__, pkgname);
137  rv = EINVAL;
138  goto out;
139  }
140  if (rundeps == NULL)
141  rundeps = prop_array_create();
142 
143  if (!prop_dictionary_set(pkgd, "run_depends", rundeps)) {
144  xbps_dbg_printf(xhp, "%s: failed to set rundeps for %s\n",
145  __func__, pkgname);
146  rv = EINVAL;
147  goto out;
148  }
149 
150  /*
151  * Create a hash for the pkg's metafile.
152  */
153  buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
154  sha256 = xbps_file_hash(buf);
155  assert(sha256);
156  prop_dictionary_set_cstring(pkgd, "metafile-sha256", sha256);
157  free(sha256);
158  free(buf);
159  /*
160  * Remove unneeded objs from pkg dictionary.
161  */
162  prop_dictionary_remove(pkgd, "remove-and-update");
163  prop_dictionary_remove(pkgd, "transaction");
164 
165  if (!xbps_pkgdb_replace_pkg(xhp, pkgd, pkgname, flush)) {
166  xbps_dbg_printf(xhp,
167  "%s: failed to replace pkgd dict for %s\n",
168  __func__, pkgname);
169  goto out;
170  }
171 out:
172  if (rv != 0) {
173  xbps_set_cb_state(xhp, XBPS_STATE_REGISTER_FAIL,
174  rv, pkgname, version,
175  "%s: failed to register package: %s",
176  pkgver, strerror(rv));
177  }
178 
179  return rv;
180 }
181 
182 int
183 xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver, bool flush)
184 {
185  assert(xhp);
186  assert(pkgver);
187 
188  xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER, 0, pkgver, NULL, NULL);
189 
190  if (!xbps_pkgdb_remove_pkg(xhp, pkgver, flush)) {
191  xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER_FAIL,
192  errno, pkgver, NULL,
193  "%s: failed to unregister package: %s",
194  pkgver, strerror(errno));
195  return errno;
196  }
197  return 0;
198 }