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 [-ldtN] [-i <input-path>]"
46 : : " [-f <plist-file>] -m <metadatadir>\n");
47 : 0 : fprintf(stderr, " pkg register [-ldtN] [-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 : 386 : exec_register(int argc, char **argv)
54 : : {
55 : 386 : struct pkg *pkg = NULL;
56 : 386 : struct pkgdb *db = NULL;
57 : :
58 : 386 : const char *plist = NULL;
59 : 386 : const char *mdir = NULL;
60 : 386 : const char *mfile = NULL;
61 : 386 : const char *input_path = NULL;
62 : 386 : const char *location = NULL;
63 : :
64 : 386 : bool legacy = false;
65 : 386 : bool testing_mode = false;
66 : 386 : bool reg_in_db = true;
67 : :
68 : : int ch;
69 : 386 : int ret = EPKG_OK;
70 : 386 : int retcode = EXIT_SUCCESS;
71 : :
72 : : /* options descriptor */
73 : 386 : struct option longopts[] = {
74 : : { "automatic", no_argument, NULL, 'A' },
75 : : { "debug", no_argument, NULL, 'd' },
76 : : { "legacy", no_argument, NULL, 'l' },
77 : : { "manifest", required_argument, NULL, 'M' },
78 : : { "metadata", required_argument, NULL, 'm' },
79 : : { "no-registration", no_argument, NULL, 'N' },
80 : : { "plist", required_argument, NULL, 'f' },
81 : : { "relocate", required_argument, NULL, 1 },
82 : : { "root", required_argument, NULL, 'i' },
83 : : { "test", no_argument, NULL, 't' },
84 : : { NULL, 0, NULL, 0},
85 : : };
86 : :
87 [ - + ]: 386 : if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK)
88 : 0 : err(EXIT_FAILURE, "malloc");
89 : :
90 [ + + ]: 905 : while ((ch = getopt_long(argc, argv, "+Adf:i:lM:m:Nt", longopts, NULL)) != -1) {
91 [ + + + - : 519 : switch (ch) {
+ + + + -
- ]
92 : : case 'A':
93 : : case 'd':
94 : 39 : pkg_set(pkg, PKG_AUTOMATIC, (bool)true);
95 : 39 : break;
96 : : case 'f':
97 : 12 : plist = optarg;
98 : 12 : break;
99 : : case 'i':
100 : 20 : input_path = optarg;
101 : 20 : break;
102 : : case 'l':
103 : 0 : legacy = true;
104 : 0 : break;
105 : : case 'M':
106 : 378 : mfile = optarg;
107 : 378 : break;
108 : : case 'm':
109 : 8 : mdir = optarg;
110 : 8 : break;
111 : : case 'N':
112 : 4 : reg_in_db = false;
113 : 4 : break;
114 : : case 't':
115 : 58 : testing_mode = true;
116 : 58 : break;
117 : : case 1:
118 : 0 : location = optarg;
119 : 0 : break;
120 : : default:
121 : 0 : warnx("Unrecognised option -%c\n", ch);
122 : 0 : usage_register();
123 : 0 : pkg_free(pkg);
124 : 0 : return (EXIT_FAILURE);
125 : : }
126 : : }
127 : :
128 : 386 : retcode = pkgdb_access(PKGDB_MODE_READ |
129 : : PKGDB_MODE_WRITE |
130 : : PKGDB_MODE_CREATE,
131 : : PKGDB_DB_LOCAL);
132 [ - + ]: 386 : if (retcode == EPKG_ENOACCESS) {
133 : 0 : warnx("Insufficient privileges to register packages");
134 : 0 : pkg_free(pkg);
135 : 0 : return (EXIT_FAILURE);
136 [ - + ]: 386 : } else if (retcode != EPKG_OK) {
137 : 0 : pkg_free(pkg);
138 : 0 : return (EXIT_FAILURE);
139 : : }
140 : :
141 : : /*
142 : : * Ideally, the +MANIFEST should be all that is necessary,
143 : : * since it can contain all of the meta-data supplied by the
144 : : * other files mentioned below. These are here for backwards
145 : : * compatibility with the way the ports tree works with
146 : : * pkg_tools.
147 : : *
148 : : * The -M option specifies one manifest file to read the
149 : : * meta-data from, and overrides the use of legacy meta-data
150 : : * inputs.
151 : : *
152 : : * Dependencies, shlibs, files etc. may be derived by
153 : : * analysing the package files (maybe discovered as the
154 : : * content of the staging directory) unless -t (testing_mode)
155 : : * is used.
156 : : */
157 : :
158 [ + + + - ]: 386 : if (mfile != NULL && mdir != NULL) {
159 : 0 : warnx("Cannot use both -m and -M together");
160 : 0 : usage_register();
161 : 0 : pkg_free(pkg);
162 : 0 : return (EXIT_FAILURE);
163 : : }
164 : :
165 : :
166 [ + + + - ]: 386 : if (mfile == NULL && mdir == NULL) {
167 : 0 : warnx("One of either -m or -M flags is required");
168 : 0 : usage_register();
169 : 0 : pkg_free(pkg);
170 : 0 : return (EXIT_FAILURE);
171 : : }
172 : :
173 [ + + + - ]: 386 : if (testing_mode && input_path != NULL) {
174 : 0 : warnx("-i incompatible with -t option");
175 : 0 : usage_register();
176 : 0 : pkg_free(pkg);
177 : 0 : return (EXIT_FAILURE);
178 : : }
179 : :
180 : 386 : ret = pkg_load_metadata(pkg, mfile, mdir, plist, input_path, testing_mode);
181 [ + + ]: 386 : if (ret != EPKG_OK) {
182 : 4 : pkg_free(pkg);
183 : 4 : return (EXIT_FAILURE);
184 : : }
185 : :
186 : :
187 [ + + + - ]: 382 : if (reg_in_db && pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
188 : 0 : pkg_free(pkg);
189 : 0 : return (EXIT_FAILURE);
190 : : }
191 : :
192 [ + + + - ]: 382 : if (db != NULL && pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
193 : 0 : pkgdb_close(db);
194 : 0 : pkg_free(pkg);
195 : 0 : warnx("Cannot get an exclusive lock on a database, it is locked by another process");
196 : 0 : return (EXIT_FAILURE);
197 : : }
198 : :
199 : 382 : retcode = pkg_add_port(db, pkg, input_path, location, testing_mode);
200 : :
201 [ + - + + : 382 : if (!legacy && retcode == EPKG_OK && messages != NULL) {
+ + ]
202 : 44 : fflush(messages->fp);
203 : 44 : printf("%s\n", messages->buf);
204 : 44 : }
205 : :
206 : 382 : pkg_free(pkg);
207 [ + + ]: 382 : if (db != NULL)
208 : 378 : pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
209 : :
210 : 382 : return (retcode != EPKG_OK ? EXIT_FAILURE : EXIT_SUCCESS);
211 : 386 : }
|