Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2014 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
5 : : * Copyright (c) 2013-2014 Matthew Seaman <matthew@FreeBSD.org>
6 : : * All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer
13 : : * in this position and unchanged.
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in the
16 : : * documentation and/or other materials provided with the distribution.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
19 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
22 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : : */
29 : :
30 : : #include <sys/param.h>
31 : :
32 : : #include <err.h>
33 : : #include <stdio.h>
34 : : #include <pkg.h>
35 : : #include <unistd.h>
36 : : #include <stdlib.h>
37 : : #include <stdbool.h>
38 : : #include <getopt.h>
39 : :
40 : : #include "pkgcli.h"
41 : :
42 : : void
43 : 0 : usage_register(void)
44 : : {
45 : 0 : fprintf(stderr, "Usage: pkg register [-dtN] [-i <input-path>]"
46 : : " [-f <plist-file>] -m <metadatadir>\n");
47 : 0 : fprintf(stderr, " pkg register [-dtN] [-i <input_path>]"
48 : : " -M <manifest>\n\n");
49 : 0 : fprintf(stderr, "For more information see 'pkg help register'.\n");
50 : 0 : }
51 : :
52 : : int
53 : 78 : exec_register(int argc, char **argv)
54 : : {
55 : 78 : struct pkg *pkg = NULL;
56 : 78 : struct pkgdb *db = NULL;
57 : :
58 : 78 : const char *plist = NULL;
59 : 78 : const char *mdir = NULL;
60 : 78 : const char *mfile = NULL;
61 : 78 : const char *input_path = NULL;
62 : 78 : const char *location = NULL;
63 : :
64 : 78 : bool testing_mode = false;
65 : 78 : bool reg_in_db = true;
66 : :
67 : : int ch;
68 : 78 : int ret = EPKG_OK;
69 : 78 : int retcode = EXIT_SUCCESS;
70 : :
71 : : /* options descriptor */
72 : 78 : struct option longopts[] = {
73 : : { "automatic", no_argument, NULL, 'A' },
74 : : { "debug", no_argument, NULL, 'd' },
75 : : { "manifest", required_argument, NULL, 'M' },
76 : : { "metadata", required_argument, NULL, 'm' },
77 : : { "no-registration", no_argument, NULL, 'N' },
78 : : { "plist", required_argument, NULL, 'f' },
79 : : { "relocate", required_argument, NULL, 1 },
80 : : { "root", required_argument, NULL, 'i' },
81 : : { "test", no_argument, NULL, 't' },
82 : : { NULL, 0, NULL, 0},
83 : : };
84 : :
85 [ + - ]: 78 : if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK)
86 : 0 : err(EXIT_FAILURE, "malloc");
87 : :
88 [ + + ]: 180 : while ((ch = getopt_long(argc, argv, "+Adf:i:M:m:Nt", longopts, NULL)) != -1) {
89 [ + - + + : 102 : switch (ch) {
+ + + + -
- ]
90 : : case 'A':
91 : : case 'd':
92 : 3 : pkg_set(pkg, PKG_ATTR_AUTOMATIC, (bool)true);
93 : 3 : break;
94 : : case 'f':
95 : 3 : plist = optarg;
96 : 3 : break;
97 : : case 'i':
98 : 5 : input_path = optarg;
99 : 5 : break;
100 : : case 'M':
101 : 76 : mfile = optarg;
102 : 76 : break;
103 : : case 'm':
104 : 2 : mdir = optarg;
105 : 2 : break;
106 : : case 'N':
107 : 1 : reg_in_db = false;
108 : 1 : break;
109 : : case 't':
110 : 12 : testing_mode = true;
111 : 12 : break;
112 : : case 1:
113 : 0 : location = optarg;
114 : 0 : break;
115 : : default:
116 : 0 : warnx("Unrecognised option -%c\n", ch);
117 : 0 : usage_register();
118 : 0 : pkg_free(pkg);
119 : 0 : return (EXIT_FAILURE);
120 : : }
121 : : }
122 : :
123 : 78 : retcode = pkgdb_access(PKGDB_MODE_READ |
124 : : PKGDB_MODE_WRITE |
125 : : PKGDB_MODE_CREATE,
126 : : PKGDB_DB_LOCAL);
127 [ - + ]: 78 : if (retcode == EPKG_ENOACCESS) {
128 : 0 : warnx("Insufficient privileges to register packages");
129 : 0 : pkg_free(pkg);
130 : 0 : return (EXIT_FAILURE);
131 [ - + ]: 78 : } else if (retcode != EPKG_OK) {
132 : 0 : pkg_free(pkg);
133 : 0 : return (EXIT_FAILURE);
134 : : }
135 : :
136 : : /*
137 : : * Ideally, the +MANIFEST should be all that is necessary,
138 : : * since it can contain all of the meta-data supplied by the
139 : : * other files mentioned below. These are here for backwards
140 : : * compatibility with the way the ports tree works with
141 : : * pkg_tools.
142 : : *
143 : : * The -M option specifies one manifest file to read the
144 : : * meta-data from, and overrides the use of legacy meta-data
145 : : * inputs.
146 : : *
147 : : * Dependencies, shlibs, files etc. may be derived by
148 : : * analysing the package files (maybe discovered as the
149 : : * content of the staging directory) unless -t (testing_mode)
150 : : * is used.
151 : : */
152 : :
153 [ + + - + ]: 78 : if (mfile != NULL && mdir != NULL) {
154 : 0 : warnx("Cannot use both -m and -M together");
155 : 0 : usage_register();
156 : 0 : pkg_free(pkg);
157 : 0 : return (EXIT_FAILURE);
158 : : }
159 : :
160 : :
161 [ + + + - ]: 78 : if (mfile == NULL && mdir == NULL) {
162 : 0 : warnx("One of either -m or -M flags is required");
163 : 0 : usage_register();
164 : 0 : pkg_free(pkg);
165 : 0 : return (EXIT_FAILURE);
166 : : }
167 : :
168 [ + + + - ]: 78 : if (testing_mode && input_path != NULL) {
169 : 0 : warnx("-i incompatible with -t option");
170 : 0 : usage_register();
171 : 0 : pkg_free(pkg);
172 : 0 : return (EXIT_FAILURE);
173 : : }
174 : :
175 : 78 : ret = pkg_load_metadata(pkg, mfile, mdir, plist, input_path, testing_mode);
176 [ + + ]: 78 : if (ret != EPKG_OK) {
177 : 1 : pkg_free(pkg);
178 : 1 : return (EXIT_FAILURE);
179 : : }
180 : :
181 : :
182 [ + + + - ]: 77 : if (reg_in_db && pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
183 : 0 : pkg_free(pkg);
184 : 0 : return (EXIT_FAILURE);
185 : : }
186 : :
187 [ + + - + ]: 77 : if (db != NULL && pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
188 : 0 : pkgdb_close(db);
189 : 0 : pkg_free(pkg);
190 : 0 : warnx("Cannot get an exclusive lock on a database, it is locked by another process");
191 : 0 : return (EXIT_FAILURE);
192 : : }
193 : :
194 : 77 : retcode = pkg_add_port(db, pkg, input_path, location, testing_mode);
195 : :
196 [ + + + + ]: 77 : if (retcode == EPKG_OK && messages != NULL) {
197 : 11 : fflush(messages->fp);
198 : 11 : printf("%s\n", messages->buf);
199 : 11 : }
200 : :
201 : 77 : pkg_free(pkg);
202 [ + + ]: 77 : if (db != NULL)
203 : 76 : pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
204 : :
205 : 77 : return (retcode != EPKG_OK ? EXIT_FAILURE : EXIT_SUCCESS);
206 : 78 : }
|