Commit 384c2f1d authored by Timo Teräs's avatar Timo Teräs
Browse files

Preserve uid and gid. Quiet flag to print dots on progress.

parent 823283ed
......@@ -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
......
......@@ -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();
}
......
......@@ -36,6 +36,8 @@ struct apk_db_dir {
unsigned refs;
mode_t mode;
uid_t uid;
gid_t gid;
char dirname[];
};
......
......@@ -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, ...);
......
......@@ -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;
}
......
......@@ -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:
......
......@@ -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++;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment