Preserve uid and gid. Quiet flag to print dots on progress.
parent
823283edca
commit
384c2f1d94
1
TODO
1
TODO
|
@ -8,7 +8,6 @@
|
||||||
- Error handling and rollback
|
- Error handling and rollback
|
||||||
- Dependency manipulation API: deletion, overwrite, check compatibility
|
- Dependency manipulation API: deletion, overwrite, check compatibility
|
||||||
|
|
||||||
- File ownership chowning
|
|
||||||
- New user/group creation
|
- New user/group creation
|
||||||
|
|
||||||
- Non-trivial solution finder
|
- Non-trivial solution finder
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
const char *apk_root = "/";
|
const char *apk_root = "/";
|
||||||
const char *apk_repository = NULL;
|
const char *apk_repository = NULL;
|
||||||
|
int apk_quiet = 0;
|
||||||
|
|
||||||
void apk_log(const char *prefix, const char *format, ...)
|
void apk_log(const char *prefix, const char *format, ...)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +70,7 @@ int main(int argc, char **argv)
|
||||||
static struct option generic_options[] = {
|
static struct option generic_options[] = {
|
||||||
{"root", required_argument, NULL, 'Q' },
|
{"root", required_argument, NULL, 'Q' },
|
||||||
{"repository", required_argument, NULL, 'X' },
|
{"repository", required_argument, NULL, 'X' },
|
||||||
|
{"quiet", no_argument, NULL, 'q' },
|
||||||
{0, 0, 0, 0},
|
{0, 0, 0, 0},
|
||||||
};
|
};
|
||||||
struct apk_applet *applet = NULL;
|
struct apk_applet *applet = NULL;
|
||||||
|
@ -95,6 +97,9 @@ int main(int argc, char **argv)
|
||||||
case 'X':
|
case 'X':
|
||||||
apk_repository = optarg;
|
apk_repository = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'q':
|
||||||
|
apk_quiet = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return usage();
|
return usage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ struct apk_db_dir {
|
||||||
|
|
||||||
unsigned refs;
|
unsigned refs;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
char dirname[];
|
char dirname[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,11 @@ typedef struct md5_ctx csum_ctx_t;
|
||||||
#define csum_finish(ctx, buf) md5_finish(ctx, buf)
|
#define csum_finish(ctx, buf) md5_finish(ctx, buf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define apk_error(args...) apk_log("ERROR: ", args)
|
extern int apk_quiet;
|
||||||
#define apk_warning(args...) apk_log("WARNING: ", args)
|
|
||||||
#define apk_message(args...) apk_log(NULL, args)
|
#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, ...);
|
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),
|
.size = GET_OCTAL(buf.size),
|
||||||
.uid = GET_OCTAL(buf.uid),
|
.uid = GET_OCTAL(buf.uid),
|
||||||
.gid = GET_OCTAL(buf.gid),
|
.gid = GET_OCTAL(buf.gid),
|
||||||
.mode = GET_OCTAL(buf.mode) & 0777,
|
.mode = GET_OCTAL(buf.mode) & 07777,
|
||||||
.mtime = GET_OCTAL(buf.mtime),
|
.mtime = GET_OCTAL(buf.mtime),
|
||||||
.name = entry.name,
|
.name = entry.name,
|
||||||
.uname = buf.uname,
|
.uname = buf.uname,
|
||||||
|
@ -242,17 +242,16 @@ int apk_archive_entry_extract(struct apk_archive_entry *ae, const char *fn)
|
||||||
|
|
||||||
/* BIG HONKING FIXME */
|
/* BIG HONKING FIXME */
|
||||||
unlink(fn);
|
unlink(fn);
|
||||||
apk_message("Extracting %s...", ae->mode);
|
|
||||||
|
|
||||||
switch (ae->mode & S_IFMT) {
|
switch (ae->mode & S_IFMT) {
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
r = mkdir(fn, ae->mode & 0777);
|
r = mkdir(fn, ae->mode & 07777);
|
||||||
if (r < 0 && errno == EEXIST)
|
if (r < 0 && errno == EEXIST)
|
||||||
r = 0;
|
r = 0;
|
||||||
break;
|
break;
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
if (ae->link_target == NULL) {
|
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)
|
if (r < 0)
|
||||||
break;
|
break;
|
||||||
ae->size -= do_splice(ae->read_fd, r, ae->size);
|
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_IFBLK:
|
||||||
case S_IFCHR:
|
case S_IFCHR:
|
||||||
case S_IFIFO:
|
case S_IFIFO:
|
||||||
r = mknod(fn, ae->mode, ae->device);
|
r = mknod(fn, ae->mode & 07777, ae->device);
|
||||||
break;
|
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);
|
apk_error("Failed to extract %s\n", ae->name);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,10 @@ static struct apk_db_dir *apk_db_dir_ref(struct apk_database *db,
|
||||||
if (dir->parent != NULL)
|
if (dir->parent != NULL)
|
||||||
apk_db_dir_ref(db, dir->parent, create_dir);
|
apk_db_dir_ref(db, dir->parent, create_dir);
|
||||||
db->installed.stats.dirs++;
|
db->installed.stats.dirs++;
|
||||||
if (create_dir && dir->mode)
|
if (create_dir && dir->mode) {
|
||||||
mkdir(dir->dirname, dir->mode);
|
mkdir(dir->dirname, dir->mode);
|
||||||
|
chown(dir->dirname, dir->uid, dir->gid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dir->refs++;
|
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_database *db = ctx->db;
|
||||||
struct apk_package *pkg = ctx->pkg;
|
struct apk_package *pkg = ctx->pkg;
|
||||||
apk_blob_t name = APK_BLOB_STR(ae->name);
|
apk_blob_t name = APK_BLOB_STR(ae->name);
|
||||||
|
struct apk_db_dir *dir;
|
||||||
struct apk_db_file *file;
|
struct apk_db_file *file;
|
||||||
const char *p;
|
const char *p;
|
||||||
int r = 0, type;
|
int r = 0, type;
|
||||||
|
@ -722,7 +725,10 @@ static int apk_db_install_archive_entry(struct apk_archive_entry *ae,
|
||||||
} else {
|
} else {
|
||||||
if (name.ptr[name.len-1] == '/')
|
if (name.ptr[name.len-1] == '/')
|
||||||
name.len--;
|
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;
|
return r;
|
||||||
|
@ -817,9 +823,12 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
r = apk_pkg_run_script(newpkg, db->root,
|
r = apk_pkg_run_script(newpkg, db->root,
|
||||||
(oldpkg == NULL) ?
|
(oldpkg == NULL) ?
|
||||||
APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE);
|
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",
|
apk_error("%s-%s: Failed to execute post-install/upgrade script",
|
||||||
newpkg->name->name, newpkg->version);
|
newpkg->name->name, newpkg->version);
|
||||||
|
} else if (apk_quiet) {
|
||||||
|
write(STDOUT_FILENO, ".", 1);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
err_close:
|
err_close:
|
||||||
|
|
|
@ -26,13 +26,14 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
|
||||||
struct apk_name *name = (struct apk_name *) item;
|
struct apk_name *name = (struct apk_name *) item;
|
||||||
|
|
||||||
if (name->pkgs == NULL) {
|
if (name->pkgs == NULL) {
|
||||||
if (++counts->unsatisfied < 10)
|
if (++counts->unsatisfied < 10) {
|
||||||
apk_warning("No provider for dependency '%s'",
|
apk_warning("No provider for dependency '%s'",
|
||||||
name->name);
|
name->name);
|
||||||
else if (counts->unsatisfied == 10)
|
} else if (counts->unsatisfied == 10) {
|
||||||
apk_warning("Too many unsatisfiable dependencies, "
|
apk_warning("Too many unsatisfiable dependencies, "
|
||||||
"not reporting the rest.");
|
"not reporting the rest.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
counts->total++;
|
counts->total++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue