diff --git a/TODO b/TODO index 72e1bc1..085c9e0 100644 --- a/TODO +++ b/TODO @@ -8,7 +8,6 @@ - Error handling and rollback - Dependency manipulation API: deletion, overwrite, check compatibility -- File ownership chowning - New user/group creation - Non-trivial solution finder diff --git a/src/apk.c b/src/apk.c index e59074a..588112b 100644 --- a/src/apk.c +++ b/src/apk.c @@ -21,6 +21,7 @@ const char *apk_root = "/"; const char *apk_repository = NULL; +int apk_quiet = 0; void apk_log(const char *prefix, const char *format, ...) { @@ -69,6 +70,7 @@ int main(int argc, char **argv) static struct option generic_options[] = { {"root", required_argument, NULL, 'Q' }, {"repository", required_argument, NULL, 'X' }, + {"quiet", no_argument, NULL, 'q' }, {0, 0, 0, 0}, }; struct apk_applet *applet = NULL; @@ -95,6 +97,9 @@ int main(int argc, char **argv) case 'X': apk_repository = optarg; break; + case 'q': + apk_quiet = 1; + break; default: return usage(); } diff --git a/src/apk_database.h b/src/apk_database.h index fcb9c54..d687bce 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -36,6 +36,8 @@ struct apk_db_dir { unsigned refs; mode_t mode; + uid_t uid; + gid_t gid; char dirname[]; }; diff --git a/src/apk_defines.h b/src/apk_defines.h index ecd08e3..c9c64f5 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -44,9 +44,11 @@ typedef struct md5_ctx csum_ctx_t; #define csum_finish(ctx, buf) md5_finish(ctx, buf) #endif -#define apk_error(args...) apk_log("ERROR: ", args) -#define apk_warning(args...) apk_log("WARNING: ", args) -#define apk_message(args...) apk_log(NULL, args) +extern int apk_quiet; + +#define apk_error(args...) if (!apk_quiet) { apk_log("ERROR: ", args); } +#define apk_warning(args...) if (!apk_quiet) { apk_log("WARNING: ", args); } +#define apk_message(args...) if (!apk_quiet) { apk_log(NULL, args); } void apk_log(const char *prefix, const char *format, ...); diff --git a/src/archive.c b/src/archive.c index 6b91a1e..18031a0 100644 --- a/src/archive.c +++ b/src/archive.c @@ -124,7 +124,7 @@ int apk_parse_tar(int fd, apk_archive_entry_parser parser, void *ctx) .size = GET_OCTAL(buf.size), .uid = GET_OCTAL(buf.uid), .gid = GET_OCTAL(buf.gid), - .mode = GET_OCTAL(buf.mode) & 0777, + .mode = GET_OCTAL(buf.mode) & 07777, .mtime = GET_OCTAL(buf.mtime), .name = entry.name, .uname = buf.uname, @@ -242,17 +242,16 @@ 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: - r = mkdir(fn, ae->mode & 0777); + r = mkdir(fn, ae->mode & 07777); if (r < 0 && errno == EEXIST) r = 0; break; case S_IFREG: if (ae->link_target == NULL) { - r = open(fn, O_WRONLY | O_CREAT, ae->mode & 0777); + r = open(fn, O_WRONLY | O_CREAT, ae->mode & 07777); if (r < 0) break; ae->size -= do_splice(ae->read_fd, r, ae->size); @@ -269,11 +268,17 @@ int apk_archive_entry_extract(struct apk_archive_entry *ae, const char *fn) case S_IFBLK: case S_IFCHR: case S_IFIFO: - r = mknod(fn, ae->mode, ae->device); + r = mknod(fn, ae->mode & 07777, ae->device); break; } - if (r != 0) + if (r == 0) { + if (!S_ISLNK(ae->mode)) + r = chown(fn, ae->uid, ae->gid); + else + r = lchown(fn, ae->uid, ae->gid); + } else { apk_error("Failed to extract %s\n", ae->name); + } return r; } diff --git a/src/database.c b/src/database.c index fa3f8c6..174b6f6 100644 --- a/src/database.c +++ b/src/database.c @@ -108,8 +108,10 @@ 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 && dir->mode) + if (create_dir && dir->mode) { mkdir(dir->dirname, dir->mode); + chown(dir->dirname, dir->uid, dir->gid); + } } dir->refs++; @@ -666,6 +668,7 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae, struct apk_database *db = ctx->db; struct apk_package *pkg = ctx->pkg; apk_blob_t name = APK_BLOB_STR(ae->name); + struct apk_db_dir *dir; struct apk_db_file *file; const char *p; int r = 0, type; @@ -722,7 +725,10 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae, } else { if (name.ptr[name.len-1] == '/') name.len--; - apk_db_dir_get(db, name)->mode = 0777 & ae->mode; + dir = apk_db_dir_get(db, name); + dir->mode = ae->mode & 07777; + dir->uid = ae->uid; + dir->gid = ae->gid; } return r; @@ -817,9 +823,12 @@ int apk_db_install_pkg(struct apk_database *db, r = apk_pkg_run_script(newpkg, db->root, (oldpkg == NULL) ? APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE); - if (r != 0) + if (r != 0) { apk_error("%s-%s: Failed to execute post-install/upgrade script", newpkg->name->name, newpkg->version); + } else if (apk_quiet) { + write(STDOUT_FILENO, ".", 1); + } return r; err_close: diff --git a/src/index.c b/src/index.c index eeaa337..45b7cf1 100644 --- a/src/index.c +++ b/src/index.c @@ -26,12 +26,13 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx) struct apk_name *name = (struct apk_name *) item; if (name->pkgs == NULL) { - if (++counts->unsatisfied < 10) + if (++counts->unsatisfied < 10) { apk_warning("No provider for dependency '%s'", name->name); - else if (counts->unsatisfied == 10) + } else if (counts->unsatisfied == 10) { apk_warning("Too many unsatisfiable dependencies, " "not reporting the rest."); + } } counts->total++;