summaryrefslogtreecommitdiffstats
path: root/aports-cache.c
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2017-04-27 15:38:59 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2017-04-27 15:38:59 +0200
commite4a21ab9165074353d265a183063333892ca2ccc (patch)
tree7d9a53ec10b4c2d79fa2c35cf82c2b7f244011dc /aports-cache.c
downloadaports-cache-e4a21ab9165074353d265a183063333892ca2ccc.tar.bz2
aports-cache-e4a21ab9165074353d265a183063333892ca2ccc.tar.xz
initial commit
Diffstat (limited to 'aports-cache.c')
-rw-r--r--aports-cache.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/aports-cache.c b/aports-cache.c
new file mode 100644
index 0000000..b0dfdf0
--- /dev/null
+++ b/aports-cache.c
@@ -0,0 +1,109 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <dirent.h>
+#include <err.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef DEBUG
+#define debug_printf(args...) fprintf(stderr, ## args)
+#else
+#define debug_printf(args...)
+#endif
+
+int is_newer(struct timespec a, struct timespec b)
+{
+ return (a.tv_sec == b.tv_sec) ? a.tv_nsec > b.tv_nsec : a.tv_sec > b.tv_sec;
+}
+
+int cache_invalid(int dirfd, const char *filename)
+{
+ struct stat cache;
+ DIR *dir;
+ struct dirent *ent;
+ int r = 0;
+
+ if (fstatat(dirfd, filename, &cache, 0) == -1)
+ return 1;
+
+ dir = fdopendir(dirfd);
+ if (dir == NULL)
+ err(1, "fdopendir");
+
+ while(1) {
+ char buf[PATH_MAX];
+ struct stat apkbuild;
+
+ errno = 0;
+ ent = readdir(dir);
+ if (ent == NULL) {
+ if (errno != 0)
+ err(1, "readdir");
+ break;
+ }
+
+ if (ent->d_name[0] == '.')
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s/APKBUILD", ent->d_name);
+ if (fstatat(dirfd, buf, &apkbuild, 0) == -1) {
+ warn("%s", buf);
+ continue;
+ }
+
+ if (is_newer(apkbuild.st_mtim, cache.st_mtim)) {
+ debug_printf("%s\n", buf);
+ r = 1;
+ break;
+ }
+ }
+
+ closedir(dir);
+ return r;
+}
+
+int main(int argc, char *argv[])
+{
+ static struct option opts[] = {
+ {"verbose", no_argument, 0, 'v' },
+ {"force", no_argument, 0, 'f' },
+ { 0, 0, 0, 0}
+ };
+ int i, c, verbose=0;
+ const char *cachefile = ".aports.cache.json";
+ char dirpath_buf[PATH_MAX];
+ char *dirpath = dirpath_buf;
+ int dirfd;
+
+ while ((c = getopt_long(argc, argv, "fv", opts, &i)) != -1) {
+ switch(c) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ if (verbose)
+ printf("optind=%i, argc=%i\n", optind, argc);
+
+ if (optind < argc) {
+ dirpath = argv[optind];
+ } else {
+ dirpath = getcwd(dirpath_buf, sizeof(dirpath_buf));
+ }
+
+ dirfd = open(dirpath, O_DIRECTORY);
+ if (dirfd < 0)
+ err(1, "%s", dirpath);
+
+ if (cache_invalid(dirfd, cachefile))
+ printf("refresh\n");
+
+ return 0;
+}
+