add.c 5.3 KB
Newer Older
1 2 3 4 5 6
/* add.c - Alpine Package Keeper (APK)
 *
 * Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
 * Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
 * All rights reserved.
 *
Timo Teräs's avatar
Timo Teräs committed
7
 * This program is free software; you can redistribute it and/or modify it
8 9 10 11
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation. See http://www.gnu.org/ for details.
 */

12
#include <errno.h>
13
#include <stdio.h>
14
#include <zlib.h>
15 16
#include "apk_applet.h"
#include "apk_database.h"
17
#include "apk_state.h"
18

19
struct add_ctx {
20
	unsigned int open_flags;
21
	const char *virtpkg;
22 23 24 25 26 27 28 29
};

static int add_parse(void *ctx, int optch, int optindex, const char *optarg)
{
	struct add_ctx *actx = (struct add_ctx *) ctx;

	switch (optch) {
	case 0x10000:
30
		actx->open_flags |= APK_OPENF_CREATE;
31
		break;
32
	case 'u':
33
		apk_flags |= APK_UPGRADE;
34
		break;
35 36 37
	case 't':
		actx->virtpkg = optarg;
		break;
38 39 40 41 42 43
	default:
		return -1;
	}
	return 0;
}

44 45
static int cup(void)
{
Timo Teräs's avatar
Timo Teräs committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
	/* compressed/uncompressed size is 259/1213 */
	static unsigned char z[] = {
		0x78,0x9c,0x9d,0x94,0x3d,0x8e,0xc4,0x20,0x0c,0x85,0xfb,0x9c,
		0xc2,0x72,0x43,0x46,0x8a,0x4d,0x3f,0x67,0x89,0x64,0x77,0x2b,
		0x6d,0xbb,0x6d,0x0e,0x3f,0xc6,0x84,0x4d,0x08,0x84,0x55,0xd6,
		0xa2,0xe0,0xef,0x7b,0x36,0xe1,0x11,0x80,0x6e,0xcc,0x53,0x7f,
		0x3e,0xc5,0xeb,0xcf,0x1d,0x20,0x22,0xcc,0x3c,0x53,0x8e,0x17,
		0xd9,0x80,0x6d,0xee,0x0e,0x61,0x42,0x3c,0x8b,0xcf,0xc7,0x12,
		0x22,0x71,0x8b,0x31,0x05,0xd5,0xb0,0x11,0x4b,0xa7,0x32,0x2f,
		0x80,0x69,0x6b,0xb0,0x98,0x40,0xe2,0xcd,0xba,0x6a,0xba,0xe4,
		0x65,0xed,0x61,0x23,0x44,0xb5,0x95,0x06,0x8b,0xde,0x6c,0x61,
		0x70,0xde,0x0e,0xb6,0xed,0xc4,0x43,0x0c,0x56,0x6f,0x8f,0x31,
		0xd0,0x35,0xb5,0xc7,0x58,0x06,0xff,0x81,0x49,0x84,0xb8,0x0e,
		0xb1,0xd8,0xc1,0x66,0x31,0x0e,0x46,0x5c,0x43,0xc9,0xef,0xe5,
		0xdc,0x63,0xb1,0xdc,0x67,0x6d,0x31,0xb3,0xc9,0x69,0x74,0x87,
		0xc7,0xa3,0x1b,0x6a,0xb3,0xbd,0x2f,0x3b,0xd5,0x0c,0x57,0x3b,
		0xce,0x7c,0x5e,0xe5,0x48,0xd0,0x48,0x01,0x92,0x49,0x8b,0xf7,
		0xfc,0x58,0x67,0xb3,0xf7,0x14,0x20,0x5c,0x4c,0x9e,0xcc,0xeb,
		0x78,0x7e,0x64,0xa6,0xa1,0xf5,0xb2,0x70,0x38,0x09,0x7c,0x7f,
		0xfd,0xc0,0x8a,0x4e,0xc8,0x55,0xe8,0x12,0xe2,0x9f,0x1a,0xb1,
		0xb9,0x82,0x52,0x02,0x7a,0xe5,0xf9,0xd9,0x88,0x47,0x79,0x3b,
		0x46,0x61,0x27,0xf9,0x51,0xb1,0x17,0xb0,0x2c,0x0e,0xd5,0x39,
		0x2d,0x96,0x25,0x27,0xd6,0xd1,0x3f,0xa5,0x08,0xe1,0x9e,0x4e,
		0xa7,0xe9,0x03,0xb1,0x0a,0xb6,0x75
	};
71
	unsigned char buf[1213];
Timo Teräs's avatar
Timo Teräs committed
72 73
	unsigned long len = sizeof(buf);

74 75
	uncompress(buf, &len, z, sizeof(z));
	write(STDOUT_FILENO, buf, len);
Timo Teräs's avatar
Timo Teräs committed
76

77 78 79
	return 0;
}

Timo Teräs's avatar
Timo Teräs committed
80

Timo Teräs's avatar
Timo Teräs committed
81
static int add_main(void *ctx, int argc, char **argv)
82
{
83
	struct add_ctx *actx = (struct add_ctx *) ctx;
84
	struct apk_database db;
85
	struct apk_state *state = NULL;
86 87
	struct apk_dependency_array *pkgs = NULL;
	struct apk_package *virtpkg = NULL;
88
	struct apk_dependency virtdep;
89
	int i, r;
90

Timo Teräs's avatar
Timo Teräs committed
91
	if ((argc > 0) && (apk_verbosity > 1) &&
92 93
	    (strcmp(argv[0], "coffee") == 0))
		return cup();
94

95 96 97
	r = apk_db_open(&db, apk_root, actx->open_flags | APK_OPENF_WRITE);
	if (r != 0)
		return r;
Timo Teräs's avatar
Timo Teräs committed
98

99 100 101 102 103 104
	if (actx->virtpkg) {
		virtpkg = apk_pkg_new();
		if (virtpkg == NULL) {
			apk_error("Failed to allocate virtual meta package");
			goto err;
		}
Timo Teräs's avatar
Timo Teräs committed
105
		virtpkg->name = apk_db_get_name(&db, APK_BLOB_STR(actx->virtpkg));
Timo Teräs's avatar
Timo Teräs committed
106
		csum_blob(APK_BLOB_STR(virtpkg->name->name), virtpkg->csum);
107 108
		virtpkg->version = strdup("0");
		virtpkg->description = strdup("virtual meta package");
109
		virtdep = apk_dep_from_pkg(&db, virtpkg);
110
		virtdep.name->flags |= APK_NAME_TOPLEVEL | APK_NAME_VIRTUAL;
111 112
		virtpkg = apk_db_pkg_add(&db, virtpkg);
	}
113

114
	for (i = 0; i < argc; i++) {
115 116 117 118 119 120 121 122 123 124 125
		struct apk_dependency dep;

		if (strstr(argv[i], ".apk") != NULL) {
			struct apk_package *pkg;

			pkg = apk_db_pkg_add_file(&db, argv[i]);
			if (pkg == NULL) {
				apk_error("Unable to read '%s'", argv[i]);
				goto err;
			}

126 127 128 129
			dep = apk_dep_from_pkg(&db, pkg);
		} else
			dep = apk_dep_from_str(&db, argv[i]);

130 131 132 133 134
		if (virtpkg) {
			apk_deps_add(&virtpkg->depends, &dep);
		} else {
			dep.name->flags |= APK_NAME_TOPLEVEL;
		}
135
		apk_deps_add(&pkgs, &dep);
136
	}
137

138
	if (virtpkg) {
139
		apk_deps_add(&pkgs, &virtdep);
140 141
		apk_deps_add(&db.world, &virtdep);
	}
142

143
	state = apk_state_new(&db);
144
	for (i = 0; (pkgs != NULL) && i < pkgs->num; i++) {
145
		r = apk_state_lock_dependency(state, &pkgs->item[i]);
146
		if (r != 0) {
147
			apk_error("Unable to install '%s'", pkgs->item[i].name->name);
148 149
			if (!(apk_flags & APK_FORCE))
				goto err;
150
		}
151 152
		if (!virtpkg)
			apk_deps_add(&db.world, &pkgs->item[i]);
153
	}
154
	r = apk_state_commit(state, &db);
155
err:
156 157
	if (state != NULL)
		apk_state_unref(state);
158
	apk_db_close(&db);
159
	return r;
160 161
}

Timo Teräs's avatar
Timo Teräs committed
162 163 164 165 166 167 168 169
static struct apk_option add_options[] = {
	{ 0x10000,	"initdb",	"Initialize database" },
	{ 'u',		"upgrade",	"Prefer to upgrade package" },
	{ 't',		"virtual",
	  "Instead of adding all the packages to 'world', create a new virtual "
	  "package with the listed dependencies and add that to 'world'. The "
	  "actions of the command are easily reverted by deleting the virtual "
	  "package.", required_argument, "NAME" },
170 171
};

172 173
static struct apk_applet apk_add = {
	.name = "add",
Timo Teräs's avatar
Timo Teräs committed
174 175 176
	.help = "Add (or update) PACKAGEs to main dependencies and install "
		"them, while ensuring that all dependencies are met.",
	.arguments = "PACKAGE...",
177 178 179 180
	.context_size = sizeof(struct add_ctx),
	.num_options = ARRAY_SIZE(add_options),
	.options = add_options,
	.parse = add_parse,
181 182 183 184 185
	.main = add_main,
};

APK_DEFINE_APPLET(apk_add);