Move cache validation logic into ctpv.c

This commit is contained in:
Nikita Ivanov 2022-05-28 19:07:59 +05:00
parent 770d92769e
commit d2b86ba8b3
No known key found for this signature in database
GPG Key ID: 6E656AC5B97B5133
7 changed files with 107 additions and 27 deletions

View File

@ -8,7 +8,7 @@ PRE := $(wildcard prev/*.sh)
GEN := gen/prev/scripts.h gen/server.h
CFLAGS += -Os -MD -Wall -Wextra -Wno-unused-parameter
LDFLAGS += -lmagic
LDFLAGS += -lmagic -lcrypto
all: ctpv

81
ctpv.c
View File

@ -5,6 +5,7 @@
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <openssl/md5.h>
#include "error.h"
#include "server.h"
@ -25,9 +26,11 @@ static struct {
MODE_END,
MODE_LIST,
MODE_MIME,
MODE_NEWER,
MODE_CHECK_CACHE,
} mode;
char *server_id_s;
char *check_file;
char *ctpv_path;
} ctpv = { .mode = MODE_PREVIEW };
static void cleanup(void) {
@ -98,6 +101,11 @@ static int check_file(char const *f)
static int preview(int argc, char *argv[])
{
if (!ctpv.ctpv_path) {
print_error("argument 0 is null");
return ERR;
}
char *f, *w, *h, *x, *y;
GET_PARG(f, 0);
GET_PARG(w, 1);
@ -114,7 +122,10 @@ static int preview(int argc, char *argv[])
const char *mimetype;
ERRCHK_RET(!(mimetype = get_mimetype(f)));
PreviewArgs args = { .f = f, .w = w, .h = h, .x = x, .y = y };
PreviewArgs args = {
.ctpv = ctpv.ctpv_path,
.f = f, .w = w, .h = h, .x = x, .y = y
};
return run_preview(get_ext(f), mimetype, &args);
}
@ -190,17 +201,8 @@ static int mime(int argc, char *argv[])
return OK;
}
static int newer(int argc, char *argv[])
static int is_newer(char *f1, char *f2)
{
char *f1, *f2;
GET_PARG(f1, 0);
GET_PARG(f2, 1);
if (!f1 || !f2) {
print_error("2 file should be given");
return ERR;
}
struct stat stat1, stat2;
ERRCHK_RET(stat(f1, &stat1) == -1, FUNCFAILED("stat"), ERRNOS);
ERRCHK_RET(stat(f2, &stat2) == -1, FUNCFAILED("stat"), ERRNOS);
@ -214,12 +216,54 @@ static int newer(int argc, char *argv[])
return OK;
}
static void md5_string(char *buf, size_t len, char *s)
{
unsigned char out[MD5_DIGEST_LENGTH];
char b[16];
MD5((const unsigned char *)s, strlen(s), out);
buf[0] = '\0';
for(unsigned int i = 0; i < LEN(out); i++) {
snprintf(b, LEN(b)-1, "%02x", out[i]);
strncat(buf, b, len);
}
}
static int check_cache(void)
{
ERRCHK_RET_OK(check_file(ctpv.check_file));
char cache_file[FILENAME_MAX];
ERRCHK_RET_OK(
get_cache_dir(cache_file, LEN(cache_file) - 1, "ctpv//"));
{
char cache_file_cpy[FILENAME_MAX];
strncpy(cache_file_cpy, cache_file, LEN(cache_file_cpy) - 1);
ERRCHK_RET(mkpath(cache_file_cpy, 0700) == -1, FUNCFAILED("mkpath"),
ERRNOS);
}
char name[64];
md5_string(name, LEN(name)-1, ctpv.check_file);
strncat(cache_file, name, LEN(cache_file)-1);
puts(cache_file);
if (access(cache_file, F_OK) != 0)
return ERR;
return is_newer(cache_file, ctpv.check_file);
}
int main(int argc, char *argv[])
{
program = argc > 0 ? argv[0] : "ctpv";
ctpv.ctpv_path = argc > 0 ? argv[0] : NULL;
program = ctpv.ctpv_path ? ctpv.ctpv_path : "ctpv";
int c;
while ((c = getopt(argc, argv, "s:ce:lmn")) != -1) {
while ((c = getopt(argc, argv, "s:ce:lmC:")) != -1) {
switch (c) {
case 's':
ctpv.mode = MODE_SERVER;
@ -238,8 +282,9 @@ int main(int argc, char *argv[])
case 'm':
ctpv.mode = MODE_MIME;
break;
case 'n':
ctpv.mode = MODE_NEWER;
case 'C':
ctpv.mode = MODE_CHECK_CACHE;
ctpv.check_file = optarg;
break;
default:
return EXIT_FAILURE;
@ -269,8 +314,8 @@ int main(int argc, char *argv[])
case MODE_MIME:
ret = mime(argc, argv);
break;
case MODE_NEWER:
ret = newer(argc, argv);
case MODE_CHECK_CACHE:
ret = check_cache();
break;
default:
PRINTINTERR("unknowm mode: %d", ctpv.mode);

View File

@ -20,11 +20,7 @@ check_exist() {
}
cache() {
cache_d="${XDG_CACHE_HOME:-$HOME/.cache}/ctpv"
mkdir -p "$cache_d"
cache_f="$cache_d/$(printf '%s' "$f" | md5sum - | cut -d' ' -f1)"
test -e "$cache_f" || return
ctpv -n "$cache_f" "$f"
cache_f="$("$ctpv" -C "$f")"
}
show_image() {

View File

@ -155,6 +155,7 @@ static int run(Preview *p, int *exitcode)
int run_preview(const char *ext, const char *mimetype, PreviewArgs *pa)
{
SET_PENV("ctpv", pa->ctpv);
SET_PENV("f", pa->f);
SET_PENV("w", pa->w);
SET_PENV("h", pa->h);

View File

@ -9,7 +9,7 @@ typedef struct {
} Preview;
typedef struct {
char *f, *w, *h, *x, *y;
char *ctpv, *f, *w, *h, *x, *y;
} PreviewArgs;
void init_previews(Preview *ps, size_t len);

40
utils.c
View File

@ -1,12 +1,14 @@
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include "error.h"
#include "utils.h"
char *program;
char *program = NULL;
int spawn_redirect(const void *arg)
{
@ -80,6 +82,40 @@ int strcmpnull(char const *s1, char const *s2)
return strcmp(s1, s2);
}
int get_cache_dir(char *buf, size_t len, char *name)
{
char *home, *cache_d, cache_d_buf[FILENAME_MAX];
if (!(cache_d = getenv("XDG_CACHE_HOME"))) {
home = getenv("HOME");
ERRCHK_RET(!home, "HOME env var does not exist");
snprintf(cache_d_buf, LEN(cache_d_buf)-1, "%s/.cache", home);
cache_d = cache_d_buf;
}
snprintf(buf, len, "%s/%s", cache_d, name);
return OK;
}
int mkpath(char* file_path, mode_t mode)
{
for (char* p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) {
*p = '\0';
if (mkdir(file_path, mode) == -1) {
if (errno != EEXIST) {
*p = '/';
return -1;
}
}
*p = '/';
}
return 0;
}
CharVec char_v_new(size_t cap)
{
CharVec v;

View File

@ -34,6 +34,8 @@ int spawn(char *args[], pid_t *cpid, int *exitcode, int (*cfunc)(const void *),
const void *carg);
int strcmpnull(char const *s1, char const *s2);
int get_cache_dir(char *buf, size_t len, char *name);
int mkpath(char* file_path, mode_t mode);
CharVec char_v_new(size_t cap);
void char_v_append(CharVec *v, char c);