X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Freqstat.c;h=18349529fa35681bf6c245a8f2ebeac62a7f4cdf;hb=4e564b59c7c565387c4907017dfacce2ef761f8a;hp=838f6116695eb72072620a2c63579f766b4c01af;hpb=713581e52521b150428ff5cd46b75a8736877799;p=doldaconnect.git diff --git a/daemon/reqstat.c b/daemon/reqstat.c index 838f611..1834952 100644 --- a/daemon/reqstat.c +++ b/daemon/reqstat.c @@ -30,6 +30,10 @@ #include "module.h" #include "log.h" +#ifdef HAVE_XATTR +#include +#endif + struct trdata { size_t startpos; }; @@ -61,19 +65,62 @@ void filelog(char *format, ...) fclose(out); } +#ifdef HAVE_XATTR +void xainc(wchar_t *file, char *an, off_t inc) +{ + char buf[32]; + ssize_t al; + off_t val; + char *fn; + + if(file[0] != L'/') + return; + if((fn = icswcstombs(file, NULL, NULL)) == NULL) { + flog(LOG_WARNING, "could not convert filename %ls into local charset: %s", file, strerror(errno)); + return; + } + if((al = getxattr(fn, an, buf, sizeof(buf) - 1)) < 0) { + if(errno != ENOATTR) { + flog(LOG_WARNING, "could not get xattr %s on %s: %s", an, fn, strerror(errno)); + return; + } + val = 0; + } else { + buf[al] = 0; + val = strtoll(buf, NULL, 10); + } + val += inc; + al = snprintf(buf, sizeof(buf), "%ji", (intmax_t)val); + if(setxattr(fn, an, buf, al, 0) < 0) + flog(LOG_WARNING, "could not set xattr %s on %s: %s", an, fn, strerror(errno)); +} +#endif + void request(struct transfer *transfer, struct trdata *data) { filelog("request %ls", transfer->path); +#ifdef HAVE_XATTR + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-req", 1); +#endif } void start(struct transfer *transfer, struct trdata *data) { filelog("start %ls at %zi", transfer->path, data->startpos); +#ifdef HAVE_XATTR + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-started", 1); +#endif } void finish(struct transfer *transfer, struct trdata *data) { filelog("finish %ls at %zi, total %zi", transfer->path, transfer->curpos, transfer->curpos - data->startpos); +#ifdef HAVE_XATTR + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-bytes", transfer->curpos - data->startpos); +#endif } static int chattr(struct transfer *transfer, wchar_t *attrib, struct trdata *data) @@ -117,7 +164,7 @@ static int chfile(struct configvar *var, void *uudata) { if(fn != NULL) free(fn); - if(var->val.str[0] == L'0') { + if(var->val.str[0] == L'\0') { fn = NULL; } else { if((fn = icwcstombs(var->val.str, NULL)) == NULL) @@ -140,6 +187,12 @@ static struct configvar myvars[] = { /** The name of a file to log upload request information to. If * unspecified, upload requests will not be logged. */ {CONF_VAR_STRING, "file", {.str = L""}}, + /** If set to true, upload statistics of files will be accumulated + * in counters stored in extends attributes (see attr(5)) on the + * files themselves. The data accumulated is the number of + * requests, the number of successfully started uploads and the + * number of uploaded bytes. */ + {CONF_VAR_BOOL, "xa", {.num = 0}}, {CONF_VAR_END} };