Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/src/add.c
2065 views
1
/*-
2
* Copyright (c) 2011-2012 Baptiste Daroussin <[email protected]>
3
* Copyright (c) 2011-2012 Julien Laffaye <[email protected]>
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer
11
* in this position and unchanged.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*/
27
28
#include <sys/param.h>
29
30
#include <err.h>
31
#include <errno.h>
32
#include <stdio.h>
33
#include <stdlib.h>
34
#include <string.h>
35
#include <unistd.h>
36
#include <getopt.h>
37
#include <xstring.h>
38
39
#include <pkg.h>
40
41
#include "pkgcli.h"
42
43
static int
44
is_url(const char * const pattern)
45
{
46
if (strncmp(pattern, "http://", 7) == 0 ||
47
strncmp(pattern, "https://", 8) == 0 ||
48
strncmp(pattern, "file://", 7) == 0)
49
return (EPKG_OK);
50
51
return (EPKG_FATAL);
52
}
53
54
void
55
usage_add(void)
56
{
57
fprintf(stderr, "Usage: pkg add [-IAfqM] <pkg-name> ...\n");
58
fprintf(stderr, " pkg add [-IAfqM] <protocol>://<path>/<pkg-name> ...\n\n");
59
fprintf(stderr, "For more information see 'pkg help add'.\n");
60
}
61
62
int
63
exec_add(int argc, char **argv)
64
{
65
struct pkgdb *db = NULL;
66
xstring *failedpkgs = NULL;
67
char path[MAXPATHLEN];
68
char *env, *file;
69
int retcode;
70
int ch;
71
int i;
72
int failedpkgcount = 0;
73
int scriptnoexec = 0;
74
pkg_flags f = PKG_FLAG_NONE;
75
const char *location = NULL;
76
77
/* options descriptor */
78
struct option longopts[] = {
79
{ "no-scripts", no_argument, NULL, 'I' },
80
{ "script-no-exec", no_argument, &scriptnoexec, 1 },
81
{ "automatic", no_argument, NULL, 'A' },
82
{ "force", no_argument, NULL, 'f' },
83
{ "accept-missing", no_argument, NULL, 'M' },
84
{ "quiet", no_argument, NULL, 'q' },
85
{ "relocate", required_argument, NULL, 1 },
86
{ NULL, 0, NULL, 0 }
87
};
88
89
while ((ch = getopt_long(argc, argv, "+IAfqM", longopts, NULL)) != -1) {
90
switch (ch) {
91
case 'I':
92
f |= PKG_ADD_NOSCRIPT;
93
break;
94
case 'A':
95
f |= PKG_ADD_AUTOMATIC;
96
break;
97
case 'f':
98
f |= PKG_ADD_FORCE;
99
force = true;
100
break;
101
case 'M':
102
f |= PKG_ADD_FORCE_MISSING;
103
break;
104
case 'q':
105
quiet = true;
106
break;
107
case 1:
108
location = optarg;
109
break;
110
case 0:
111
if (scriptnoexec == 1)
112
f |= PKG_ADD_NOEXEC;
113
break;
114
default:
115
usage_add();
116
return (EXIT_FAILURE);
117
}
118
}
119
argc -= optind;
120
argv += optind;
121
122
if (argc < 1) {
123
usage_add();
124
return (EXIT_FAILURE);
125
}
126
127
retcode = pkgdb_access(PKGDB_MODE_READ |
128
PKGDB_MODE_WRITE |
129
PKGDB_MODE_CREATE,
130
PKGDB_DB_LOCAL);
131
if (retcode == EPKG_ENOACCESS) {
132
warnx("Insufficient privileges to add packages");
133
return (EXIT_FAILURE);
134
} else if (retcode != EPKG_OK)
135
return (EXIT_FAILURE);
136
137
if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
138
return (EXIT_FAILURE);
139
140
if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
141
pkgdb_close(db);
142
warnx("Cannot get an exclusive lock on a database, it is locked by another process");
143
return (EXIT_FAILURE);
144
}
145
146
failedpkgs = xstring_new();
147
for (i = 0; i < argc; i++) {
148
if (is_url(argv[i]) == EPKG_OK) {
149
const char *name = strrchr(argv[i], '/');
150
if (name == NULL)
151
name = argv[i];
152
else
153
name++;
154
155
if ((env = getenv("TMPDIR")) == NULL)
156
env = "/tmp";
157
snprintf(path, sizeof(path), "%s/%s.XXXXX", env, name);
158
if ((retcode = pkg_fetch_file(NULL, argv[i], path, 0, 0, 0)) != EPKG_OK)
159
break;
160
161
file = path;
162
} else {
163
file = argv[i];
164
165
/* Special case: treat a filename of "-" as
166
meaning 'read from stdin.' It doesn't make
167
sense to have a filename of "-" more than
168
once per command line, but we aren't
169
testing for that at the moment */
170
171
if (!STREQ(file, "-") && access(file, F_OK) != 0) {
172
warn("%s", file);
173
if (errno == ENOENT)
174
warnx("Was 'pkg install %s' meant?", file);
175
fprintf(failedpkgs->fp, "%s", argv[i]);
176
if (i != argc - 1)
177
fprintf(failedpkgs->fp, ", ");
178
failedpkgcount++;
179
continue;
180
}
181
182
}
183
184
if ((retcode = pkg_add(db, file, f, location)) != EPKG_OK) {
185
fprintf(failedpkgs->fp, "%s", argv[i]);
186
if (i != argc - 1)
187
fprintf(failedpkgs->fp, ", ");
188
failedpkgcount++;
189
}
190
191
if (is_url(argv[i]) == EPKG_OK)
192
unlink(file);
193
194
}
195
pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
196
pkgdb_close(db);
197
198
if(failedpkgcount > 0) {
199
fflush(failedpkgs->fp);
200
printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, failedpkgs->buf);
201
retcode = EPKG_FATAL;
202
}
203
xstring_free(failedpkgs);
204
205
pkg_add_triggers();
206
if (messages != NULL) {
207
fflush(messages->fp);
208
printf("%s", messages->buf);
209
}
210
211
return (retcode == EPKG_OK ? EXIT_SUCCESS : EXIT_FAILURE);
212
}
213
214
215