summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2008-04-21 16:30:10 +0000
committerTimo Teras <timo.teras@iki.fi>2008-04-21 16:30:10 +0000
commit823283edca0d8403742999917a4ff0698ad641cb (patch)
treec023160837e616ca5ff5e85cc754cd3e17bd1d2e
parent951602e551bc56b433f7c6d908998b6289890b09 (diff)
Argument parsing. Some other stuff too.
-rw-r--r--Makefile8
-rw-r--r--TODO4
-rw-r--r--src/Makefile2
-rw-r--r--src/add.c7
-rw-r--r--src/apk.c74
-rw-r--r--src/apk_applet.h3
-rw-r--r--src/apk_database.h8
-rw-r--r--src/archive.c2
-rw-r--r--src/blob.c3
-rw-r--r--src/create.c28
-rw-r--r--src/database.c142
-rw-r--r--src/del.c6
-rw-r--r--src/index.c4
-rw-r--r--src/package.c20
-rw-r--r--src/ver.c6
15 files changed, 202 insertions, 115 deletions
diff --git a/Makefile b/Makefile
index 783b7ce..ee4ca1e 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,13 @@ INSTALLDIR=$(INSTALL) -d
CFLAGS=-O2 -g -D_GNU_SOURCE -Werror -Wall -Wstrict-prototypes -std=gnu99 \
-DAPK_VERSION=\"$(FULL_VERSION)\"
-LDFLAGS=-g -lpthread -nopie
+LDFLAGS=-g -nopie
+LIBS=-lpthread
+
+ifeq ($(STATIC),yes)
+CFLAGS+=-fno-stack-protector
+LDFLAGS+=-static
+endif
DESTDIR=
SBINDIR=/usr/sbin
diff --git a/TODO b/TODO
index 5c67bdb..72e1bc1 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,5 @@
-- Command line parsing
-- Get repositories/root from command line
+- Handle properly gunzip failure
+
- Repository index/package fetching from URLs
- Installation of local files
diff --git a/src/Makefile b/src/Makefile
index 0964012..15eeb00 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,6 +18,7 @@ apk_OBJS = \
blob.o \
hash.o \
md5.o \
+ create.o \
add.o \
del.o \
ver.o \
@@ -29,6 +30,7 @@ ALL_OBJS = $(apk_OBJS)
all: $(TARGETS)
apk: $(apk_OBJS)
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
clean::
@rm -f $(TARGETS) $(ALL_OBJS)
diff --git a/src/add.c b/src/add.c
index 28dcb9b..be8012b 100644
--- a/src/add.c
+++ b/src/add.c
@@ -18,8 +18,9 @@ static int add_main(int argc, char **argv)
struct apk_database db;
int i;
- apk_db_init(&db, "/home/fabled/tmproot/");
- apk_db_read_config(&db);
+ if (apk_db_open(&db, apk_root) < 0)
+ return -1;
+
for (i = 0; i < argc; i++) {
struct apk_dependency dep = {
.name = apk_db_get_name(&db, argv[i]),
@@ -27,7 +28,7 @@ static int add_main(int argc, char **argv)
apk_deps_add(&db.world, &dep);
}
apk_db_recalculate_and_commit(&db);
- apk_db_free(&db);
+ apk_db_close(&db);
return 0;
}
diff --git a/src/apk.c b/src/apk.c
index f8f13dd..e59074a 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -11,11 +11,17 @@
#include <stdio.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <string.h>
+#include <getopt.h>
+#include <sys/stat.h>
#include "apk_defines.h"
#include "apk_applet.h"
+const char *apk_root = "/";
+const char *apk_repository = NULL;
+
void apk_log(const char *prefix, const char *format, ...)
{
va_list va;
@@ -46,10 +52,30 @@ int usage(void)
return 1;
}
+static struct apk_applet *find_applet(const char *name)
+{
+ struct apk_applet **a;
+
+ for (a = &__start_apkapplets; a < &__stop_apkapplets; a++) {
+ if (strcmp(name, (*a)->name) == 0)
+ return *a;
+ }
+
+ return NULL;
+}
+
int main(int argc, char **argv)
{
- struct apk_applet **a, *applet;
- char *prog;
+ static struct option generic_options[] = {
+ {"root", required_argument, NULL, 'Q' },
+ {"repository", required_argument, NULL, 'X' },
+ {0, 0, 0, 0},
+ };
+ struct apk_applet *applet = NULL;
+ const char *prog;
+ int r;
+
+ umask(0);
prog = strrchr(argv[0], '/');
if (prog == NULL)
@@ -57,25 +83,35 @@ int main(int argc, char **argv)
else
prog++;
- if (strcmp(prog, "apk") == 0) {
- if (argc < 2)
- return usage();
- prog = argv[1];
- argv++;
- argc--;
- } else if (strncmp(prog, "apk_", 4) == 0) {
- prog += 4;
- } else
- return usage();
+ if (strncmp(prog, "apk_", 4) == 0)
+ applet = find_applet(prog + 4);
- for (a = &__start_apkapplets; a < &__stop_apkapplets; a++) {
- applet = *a;
- if (strcmp(prog, applet->name) == 0) {
- argv++;
- argc--;
- return applet->main(argc, argv);
+ while ((r = getopt_long(argc, argv, "",
+ generic_options, NULL)) != -1) {
+ switch (r) {
+ case 'Q':
+ apk_root = optarg;
+ break;
+ case 'X':
+ apk_repository = optarg;
+ break;
+ default:
+ return usage();
}
}
- return usage();
+ argc -= optind;
+ argv += optind;
+
+ if (applet == NULL) {
+ if (argc > 0)
+ applet = find_applet(argv[0]);
+ if (applet == NULL)
+ return usage();
+
+ argc--;
+ argv++;
+ }
+
+ return applet->main(argc, argv);
}
diff --git a/src/apk_applet.h b/src/apk_applet.h
index 4107135..e4c2e1d 100644
--- a/src/apk_applet.h
+++ b/src/apk_applet.h
@@ -12,6 +12,9 @@
#ifndef APK_APPLET_H
#define APK_APPLET_H
+extern const char *apk_root;
+extern const char *apk_repository;
+
struct apk_applet {
const char *name;
const char *usage;
diff --git a/src/apk_database.h b/src/apk_database.h
index 96ff361..fcb9c54 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -52,6 +52,7 @@ struct apk_repository {
struct apk_database {
char *root;
+ int root_fd;
unsigned pkg_id, num_repos;
struct apk_dependency_array *world;
@@ -76,10 +77,9 @@ struct apk_database {
struct apk_name *apk_db_get_name(struct apk_database *db, const char *name);
void apk_name_free(struct apk_name *pkgname);
-void apk_db_init(struct apk_database *db, const char *root);
-void apk_db_free(struct apk_database *db);
-int apk_db_read_config(struct apk_database *db);
-int apk_db_write_config(struct apk_database *db);
+int apk_db_create(const char *root);
+int apk_db_open(struct apk_database *db, const char *root);
+void apk_db_close(struct apk_database *db);
int apk_db_pkg_add_file(struct apk_database *db, const char *file);
struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum);
diff --git a/src/archive.c b/src/archive.c
index e5092dc..6b91a1e 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -57,7 +57,6 @@ static int get_dev_null(void)
err(EX_OSFILE, "/dev/null");
}
return fd_null;
-
}
pid_t apk_open_gz(int *fd)
@@ -243,6 +242,7 @@ int apk_archive_entry_extract(struct apk_archive_entry *ae, const char *fn)
/* BIG HONKING FIXME */
unlink(fn);
+ apk_message("Extracting %s...", ae->mode);
switch (ae->mode & S_IFMT) {
case S_IFDIR:
diff --git a/src/blob.c b/src/blob.c
index eecf642..f7c14b5 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -18,6 +18,9 @@ char *apk_blob_cstr(apk_blob_t blob)
{
char *cstr;
+ if (blob.ptr == NULL)
+ return strdup("");
+
if (blob.ptr[blob.len-1] == 0)
return strdup(blob.ptr);
diff --git a/src/create.c b/src/create.c
new file mode 100644
index 0000000..a033170
--- /dev/null
+++ b/src/create.c
@@ -0,0 +1,28 @@
+/* create.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.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+#include <stdio.h>
+#include "apk_applet.h"
+#include "apk_database.h"
+
+static int create_main(int argc, char **argv)
+{
+ return apk_db_create(apk_root);
+}
+
+static struct apk_applet apk_create = {
+ .name = "create",
+ .usage = "",
+ .main = create_main,
+};
+
+APK_DEFINE_APPLET(apk_create);
+
diff --git a/src/database.c b/src/database.c
index f98be64..fa3f8c6 100644
--- a/src/database.c
+++ b/src/database.c
@@ -20,6 +20,7 @@
#include "apk_package.h"
#include "apk_database.h"
#include "apk_state.h"
+#include "apk_applet.h"
struct install_ctx {
struct apk_database *db;
@@ -107,7 +108,7 @@ static struct apk_db_dir *apk_db_dir_ref(struct apk_database *db,
if (dir->parent != NULL)
apk_db_dir_ref(db, dir->parent, create_dir);
db->installed.stats.dirs++;
- if (create_dir)
+ if (create_dir && dir->mode)
mkdir(dir->dirname, dir->mode);
}
dir->refs++;
@@ -135,7 +136,7 @@ static struct apk_db_dir *apk_db_dir_get(struct apk_database *db,
apk_blob_t bparent;
char *cstr;
- if (name.ptr[name.len-1] == '/')
+ if (name.len && name.ptr[name.len-1] == '/')
name.len--;
cstr = apk_blob_cstr(name);
@@ -149,8 +150,12 @@ static struct apk_db_dir *apk_db_dir_get(struct apk_database *db,
dir->dirname[name.len] = 0;
apk_hash_insert(&db->installed.dirs, dir);
- if (apk_blob_rsplit(name, '/', &bparent, NULL))
+ if (name.len == 0)
+ dir->parent = NULL;
+ else if (apk_blob_rsplit(name, '/', &bparent, NULL))
dir->parent = apk_db_dir_get(db, bparent);
+ else
+ dir->parent = apk_db_dir_get(db, APK_BLOB_NULL);
return dir;
}
@@ -194,22 +199,21 @@ static struct apk_db_file *apk_db_file_get(struct apk_database *db,
struct hlist_node *cur;
apk_blob_t bdir, bfile;
- if (!apk_blob_rsplit(name, '/', &bdir, &bfile))
- return NULL;
-
dir = NULL;
- if (ctx != NULL && ctx->dircache != NULL) {
+ if (!apk_blob_rsplit(name, '/', &bdir, &bfile)) {
+ dir = apk_db_dir_get(db, APK_BLOB_NULL);
+ bfile = name;
+ } else if (ctx != NULL && ctx->dircache != NULL) {
dir = ctx->dircache;
if (strncmp(dir->dirname, bdir.ptr, bdir.len) != 0 ||
dir->dirname[bdir.len] != 0)
dir = NULL;
}
- if (dir == NULL) {
+ if (dir == NULL)
dir = apk_db_dir_get(db, bdir);
- if (ctx != NULL) {
- ctx->dircache = dir;
- ctx->file_dir_node = &dir->files.first;
- }
+ if (ctx != NULL && dir != ctx->dircache) {
+ ctx->dircache = dir;
+ ctx->file_dir_node = &dir->files.first;
}
hlist_for_each_entry(file, cur, &dir->files, dir_files_list) {
@@ -382,39 +386,45 @@ static int apk_db_read_scriptdb(struct apk_database *db, int fd)
return 0;
}
-static const char *get_db_path(struct apk_database *db, const char *f)
+static const char *get_db_path(const char *root, const char *f)
{
static char fn[1024];
- snprintf(fn, sizeof(fn), "%s%s", db->root, f);
+ snprintf(fn, sizeof(fn), "%s/%s", root, f);
return fn;
}
-void apk_db_init(struct apk_database *db, const char *root)
+int apk_db_create(const char *root)
{
- memset(db, 0, sizeof(*db));
- apk_hash_init(&db->available.names, &pkg_name_hash_ops, 1000);
- apk_hash_init(&db->available.packages, &pkg_info_hash_ops, 4000);
- apk_hash_init(&db->installed.dirs, &dir_hash_ops, 1000);
+ apk_blob_t deps = APK_BLOB_STR("busybox, alpine-baselayout, "
+ "apk-tools, alpine-conf");
+ int fd;
- if (root != NULL) {
- db->root = strdup(root);
- apk_db_add_repository(db, "/home/fabled/foo/");
- mkdir(get_db_path(db, "tmp"), 01777);
- mkdir(get_db_path(db, "dev"), 0755);
- mknod(get_db_path(db, "dev/null"), 0666, makedev(1, 3));
- }
+ mkdir(get_db_path(root, "tmp"), 01777);
+ mkdir(get_db_path(root, "dev"), 0755);
+ mknod(get_db_path(root, "dev/null"), 0666, makedev(1, 3));
+ mkdir(get_db_path(root, "var"), 0755);
+ mkdir(get_db_path(root, "var/lib"), 0755);
+ mkdir(get_db_path(root, "var/lib/apk"), 0755);
+
+ fd = creat(get_db_path(root, "var/lib/apk/world"), 0600);
+ if (fd < 0)
+ return -1;
+ write(fd, deps.ptr, deps.len);
+ close(fd);
+
+ return 0;
}
-int apk_db_read_config(struct apk_database *db)
+static int apk_db_read_config(struct apk_database *db)
{
struct stat st;
char *buf;
int fd;
if (db->root == NULL)
- return -1;
+ return 0;
/* Read:
* 1. installed repository
@@ -424,27 +434,24 @@ int apk_db_read_config(struct apk_database *db)
* 5. files db
* 6. script db
*/
- fd = open(get_db_path(db, "var/lib/apk/world"), O_RDONLY);
- if (fd >= 0) {
- fstat(fd, &st);
- buf = malloc(st.st_size);
- read(fd, buf, st.st_size);
- apk_deps_parse(db, &db->world,
- APK_BLOB_PTR_LEN(buf, st.st_size));
- close(fd);
- } else {
- apk_deps_parse(db, &db->world,
- APK_BLOB_STR("busybox, alpine-baselayout, "
- "apk-tools, alpine-conf"));
- }
+ fd = open(get_db_path(db->root, "var/lib/apk/world"), O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ fstat(fd, &st);
+ buf = malloc(st.st_size);
+ read(fd, buf, st.st_size);
+ apk_deps_parse(db, &db->world,
+ APK_BLOB_PTR_LEN(buf, st.st_size));
+ close(fd);
- fd = open(get_db_path(db, "var/lib/apk/files"), O_RDONLY);
+ fd = open(get_db_path(db->root, "var/lib/apk/files"), O_RDONLY);
if (fd >= 0) {
apk_db_read_fdb(db, fd);
close(fd);
}
- fd = open(get_db_path(db, "var/lib/apk/scripts"), O_RDONLY);
+ fd = open(get_db_path(db->root, "var/lib/apk/scripts"), O_RDONLY);
if (fd >= 0) {
apk_db_read_scriptdb(db, fd);
close(fd);
@@ -453,37 +460,54 @@ int apk_db_read_config(struct apk_database *db)
return 0;
}
+int apk_db_open(struct apk_database *db, const char *root)
+{
+ memset(db, 0, sizeof(*db));
+ apk_hash_init(&db->available.names, &pkg_name_hash_ops, 1000);
+ apk_hash_init(&db->available.packages, &pkg_info_hash_ops, 4000);
+ apk_hash_init(&db->installed.dirs, &dir_hash_ops, 1000);
+
+ if (root != NULL) {
+ db->root = strdup(root);
+ db->root_fd = open(root, O_RDONLY);
+ if (db->root_fd < 0) {
+ free(db->root);
+ return -1;
+ }
+
+ apk_db_add_repository(db, apk_repository);
+ }
+
+ return apk_db_read_config(db);
+}
+
struct write_ctx {
struct apk_database *db;
int fd;
};
-int apk_db_write_config(struct apk_database *db)
+static int apk_db_write_config(struct apk_database *db)
{
char buf[1024];
int n, fd;
if (db->root == NULL)
- return -1;
-
- mkdir(get_db_path(db, "var"), 0755);
- mkdir(get_db_path(db, "var/lib"), 0755);
- mkdir(get_db_path(db, "var/lib/apk"), 0755);
+ return 0;
- fd = creat(get_db_path(db, "var/lib/apk/world"), 0600);
+ fd = creat(get_db_path(db->root, "var/lib/apk/world"), 0600);
if (fd < 0)
return -1;
n = apk_deps_format(buf, sizeof(buf), db->world);
write(fd, buf, n);
close(fd);
- fd = creat(get_db_path(db, "var/lib/apk/files"), 0600);
+ fd = creat(get_db_path(db->root, "var/lib/apk/files"), 0600);
if (fd < 0)
return -1;
apk_db_write_fdb(db, fd);
close(fd);
- fd = creat(get_db_path(db, "var/lib/apk/scripts"), 0600);
+ fd = creat(get_db_path(db->root, "var/lib/apk/scripts"), 0600);
if (fd < 0)
return -1;
apk_db_write_scriptdb(db, fd);
@@ -492,13 +516,17 @@ int apk_db_write_config(struct apk_database *db)
return 0;
}
-void apk_db_free(struct apk_database *db)
+void apk_db_close(struct apk_database *db)
{
+ apk_db_write_config(db);
+
apk_hash_free(&db->available.names);
apk_hash_free(&db->available.packages);
apk_hash_free(&db->installed.dirs);
- if (db->root != NULL)
+ if (db->root != NULL) {
+ close(db->root_fd);
free(db->root);
+ }
}
static void apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg)
@@ -593,7 +621,7 @@ int apk_db_add_repository(struct apk_database *db, const char *repo)
.url = strdup(repo)
};
- snprintf(tmp, sizeof(tmp), "%sAPK_INDEX", repo);
+ snprintf(tmp, sizeof(tmp), "%s/APK_INDEX", repo);
fd = open(tmp, O_RDONLY);
if (fd < 0) {
apk_error("Failed to open index file %s", tmp);
@@ -732,7 +760,7 @@ int apk_db_install_pkg(struct apk_database *db,
pthread_t tid = 0;
int fd, r;
- if (chdir(db->root) < 0)
+ if (fchdir(db->root_fd) < 0)
return errno;
/* Purge the old package if there */
@@ -753,7 +781,7 @@ int apk_db_install_pkg(struct apk_database *db,
/* Install the new stuff */
snprintf(file, sizeof(file),
- "%s%s-%s.apk",
+ "%s/%s-%s.apk",
db->repos[0].url, newpkg->name->name, newpkg->version);
fd = open(file, O_RDONLY);
diff --git a/src/del.c b/src/del.c
index c4d7539..2fc6048 100644
--- a/src/del.c
+++ b/src/del.c
@@ -18,8 +18,8 @@ static int del_main(int argc, char **argv)
struct apk_database db;
int i, j;
- apk_db_init(&db, "/home/fabled/tmproot/");
- apk_db_read_config(&db);
+ if (apk_db_open(&db, apk_root) < 0)
+ return -1;
if (db.world == NULL)
goto out;
@@ -38,7 +38,7 @@ static int del_main(int argc, char **argv)
apk_db_recalculate_and_commit(&db);
out:
- apk_db_free(&db);
+ apk_db_close(&db);
return 0;
}
diff --git a/src/index.c b/src/index.c
index 4234002..eeaa337 100644
--- a/src/index.c
+++ b/src/index.c
@@ -44,12 +44,12 @@ static int index_main(int argc, char **argv)
struct counts counts = {0,0};
int i;
- apk_db_init(&db, NULL);
+ apk_db_open(&db, NULL);
for (i = 0; i < argc; i++)
apk_db_pkg_add_file(&db, argv[i]);
apk_db_index_write(&db, STDOUT_FILENO);
apk_hash_foreach(&db.available.names, warn_if_no_providers, &counts);
- apk_db_free(&db);
+ apk_db_close(&db);
if (counts.unsatisfied != 0)
apk_warning("Total of %d unsatisfiable package "
diff --git a/src/package.c b/src/package.c
index 88aef70..04ec2be 100644
--- a/src/package.c
+++ b/src/package.c
@@ -362,26 +362,6 @@ int apk_pkg_run_script(struct apk_package *pkg, const char *root,
return -1;
}
- /* FIXME: Remove this ugly kludge */
- if (strcmp(pkg->name->name, "busybox") == 0 &&
- type == APK_SCRIPT_POST_INSTALL) {
- apk_message("Create busybox links");
-
- pid = fork();
- if (pid == -1)
- return -1;
- if (pid == 0) {
- chroot(root);
- execl("/bin/busybox", "busybox", "--install", "-s", NULL);
- exit(1);
- }
- waitpid(pid, &status, 0);
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- return -1;
-
- }
-
return 0;
}
diff --git a/src/ver.c b/src/ver.c
index c8b2e2b..8d62f3a 100644
--- a/src/ver.c
+++ b/src/ver.c
@@ -44,8 +44,8 @@ static int ver_main(int argc, char **argv)
return 0;
}
- apk_db_init(&db, "/home/fabled/tmproot/");
- apk_db_read_config(&db);
+ if (apk_db_open(&db, apk_root) < 0)
+ return -1;
hlist_for_each_entry(pkg, c, &db.installed.packages, installed_pkgs_list) {
name = pkg->name;
@@ -61,7 +61,7 @@ static int ver_main(int argc, char **argv)
}
printf("%-40s%c\n", name->name, pkg != upg ? '<' : '=');
}
- apk_db_free(&db);
+ apk_db_close(&db);
return 0;
}