summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2021-02-14 10:01:02 -0500
committerTimo Teräs <timo.teras@iki.fi>2021-03-19 12:26:15 +0000
commit646c834492a419a96b4032c230e842d27f87e997 (patch)
treef3b78584924624dc73c8ec909f7dc8d685a84db0
parent4fe5ac83287678a5f870def74ed28f45ab22815f (diff)
downloadapk-tools-646c834492a419a96b4032c230e842d27f87e997.tar.gz
apk-tools-646c834492a419a96b4032c230e842d27f87e997.tar.bz2
apk-tools-646c834492a419a96b4032c230e842d27f87e997.tar.xz
apk-tools-646c834492a419a96b4032c230e842d27f87e997.zip
Log to /var/log/apk.log
This adds a log file at /var/log/apk.log. On each run, apk's version information and the current date & time are written to this file, followed by any normal apk output.
-rw-r--r--doc/apk.8.scd2
-rw-r--r--src/apk.c13
-rw-r--r--src/apk_print.h7
-rw-r--r--src/context.c16
-rw-r--r--src/print.c33
5 files changed, 61 insertions, 10 deletions
diff --git a/doc/apk.8.scd b/doc/apk.8.scd
index 0ca26b1..caf8382 100644
--- a/doc/apk.8.scd
+++ b/doc/apk.8.scd
@@ -15,6 +15,8 @@ to install is called the _world_ (see *apk-world*(5)). *apk* supports various
sub-commands to query and manipulate _world_ and local & remote package
repositories.
+All apk commands which modify the database are logged to /var/log/apk.log.
+
# COMMANDS
Each command is documented in detail on its manual page.
diff --git a/src/apk.c b/src/apk.c
index 1141180..3de5ca4 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -46,11 +46,11 @@ time_t time(time_t *tloc)
}
#endif
-static void version(struct apk_out *out)
+static void version(struct apk_out *out, const char *prefix)
{
- apk_out(out, "apk-tools " APK_VERSION ", compiled for " APK_DEFAULT_ARCH ".");
+ apk_out_fmt(out, prefix, "apk-tools " APK_VERSION ", compiled for " APK_DEFAULT_ARCH ".");
#ifdef TEST_MODE
- apk_out(out, "TEST MODE BUILD. NOT FOR PRODUCTION USE.");
+ apk_out_fmt(out, prefix, "TEST MODE BUILD. NOT FOR PRODUCTION USE.");
#endif
}
@@ -122,7 +122,7 @@ static int option_parse_global(void *ctx, struct apk_ctx *ac, int opt, const cha
ac->out.verbosity++;
break;
case OPT_GLOBAL_version:
- version(out);
+ version(out, NULL);
return -ESHUTDOWN;
case OPT_GLOBAL_force:
ac->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK
@@ -260,7 +260,7 @@ const struct apk_option_group optgroup_commit = {
static int usage(struct apk_out *out, struct apk_applet *applet)
{
- version(out);
+ version(out, NULL);
apk_applet_help(applet, out);
return 1;
}
@@ -460,6 +460,9 @@ int main(int argc, char **argv)
r = apk_ctx_prepare(&ctx);
if (r != 0) goto err;
+ apk_out_log_argv(&ctx.out, apk_argv);
+ version(&ctx.out, APK_OUT_LOG_ONLY);
+
if (ctx.open_flags) {
r = apk_db_open(&db, &ctx);
if (r != 0) {
diff --git a/src/apk_print.h b/src/apk_print.h
index ec766ed..132fd8c 100644
--- a/src/apk_print.h
+++ b/src/apk_print.h
@@ -30,11 +30,15 @@ void apk_url_parse(struct apk_url_print *, const char *);
struct apk_out {
int verbosity;
unsigned int width, last_change;
- FILE *out, *err;
+ FILE *out, *err, *log;
};
static inline int apk_out_verbosity(struct apk_out *out) { return out->verbosity; }
+// Pass this as the prefix to skip logging to the console (but still write to
+// the log file).
+#define APK_OUT_LOG_ONLY ((const char*)-1)
+
#define apk_err(out, args...) do { apk_out_fmt(out, "ERROR: ", args); } while (0)
#define apk_out(out, args...) do { apk_out_fmt(out, NULL, args); } while (0)
#define apk_warn(out, args...) do { if (apk_out_verbosity(out) >= 0) { apk_out_fmt(out, "WARNING: ", args); } } while (0)
@@ -44,6 +48,7 @@ static inline int apk_out_verbosity(struct apk_out *out) { return out->verbosity
void apk_out_reset(struct apk_out *);
void apk_out_fmt(struct apk_out *, const char *prefix, const char *format, ...);
+void apk_out_log_argv(struct apk_out *, char **argv);
struct apk_progress {
struct apk_out *out;
diff --git a/src/context.c b/src/context.c
index a6d7e5d..32a284e 100644
--- a/src/context.c
+++ b/src/context.c
@@ -29,6 +29,7 @@ void apk_ctx_free(struct apk_ctx *ac)
apk_trust_free(&ac->trust);
apk_string_array_free(&ac->repository_list);
apk_string_array_free(&ac->private_keys);
+ if (ac->out.log) fclose(ac->out.log);
}
int apk_ctx_prepare(struct apk_ctx *ac)
@@ -53,6 +54,21 @@ int apk_ctx_prepare(struct apk_ctx *ac)
apk_err(&ac->out, "Unable to open root: %s", apk_error_str(errno));
return -errno;
}
+
+ if (ac->open_flags & APK_OPENF_WRITE) {
+ const char *log_path = "var/log/apk.log", *log_dir = "var/log";
+ const int lflags = O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC;
+ int fd = openat(ac->root_fd, log_path, lflags, 0644);
+ if (fd < 0 && (ac->open_flags & APK_OPENF_CREATE)) {
+ mkdirat(ac->root_fd, log_dir, 0755);
+ fd = openat(ac->root_fd, log_path, lflags, 0644);
+ }
+ if (fd < 0) {
+ apk_err(&ac->out, "Unable to open log: %s", apk_error_str(errno));
+ return -errno;
+ }
+ ac->out.log = fdopen(fd, "a");
+ }
return 0;
}
diff --git a/src/print.c b/src/print.c
index e9e1dfb..cc82c49 100644
--- a/src/print.c
+++ b/src/print.c
@@ -136,10 +136,35 @@ static void log_internal(FILE *dest, const char *prefix, const char *format, va_
void apk_out_fmt(struct apk_out *out, const char *prefix, const char *format, ...)
{
va_list va;
- va_start(va, format);
- log_internal(prefix ? out->err : out->out, prefix, format, va);
- out->last_change++;
- va_end(va);
+ if (prefix != APK_OUT_LOG_ONLY) {
+ va_start(va, format);
+ log_internal(prefix ? out->err : out->out, prefix, format, va);
+ out->last_change++;
+ va_end(va);
+ }
+
+ if (out->log) {
+ va_start(va, format);
+ log_internal(out->log, prefix, format, va);
+ va_end(va);
+ }
+}
+
+void apk_out_log_argv(struct apk_out *out, char **argv)
+{
+ char when[32];
+ struct tm tm;
+ time_t now = time(NULL);
+
+ if (!out->log) return;
+ fprintf(out->log, "\nRunning `");
+ for (int i = 0; argv[i]; ++i) {
+ fprintf(out->log, "%s%s", argv[i], argv[i+1] ? " " : "");
+ }
+
+ gmtime_r(&now, &tm);
+ strftime(when, sizeof(when), "%Y-%m-%d %H:%M:%S", &tm);
+ fprintf(out->log, "` at %s\n", when);
}
void apk_print_progress(struct apk_progress *p, size_t done, size_t total)